Josh Beam's Website

Home

Welcome to my website. I’m a software engineer whose interests include web development, 3D graphics programming, open source software, Linux, and Apple’s platforms.

I have extensive experience developing software for professional and educational purposes, as well as developing open source software in my spare time. I have Bachelor of Science in Computer Science and Master of Software Engineering degrees from Auburn University. More information about my education and professional experience can be found on my LinkedIn profile.

I have written some articles over the years, primarily related to OpenGL and graphics programming. I have also written some open source software that you may find interesting (see my GitHub profile for more).

I can be contacted by email at josh@joshbeam.com.


Getting Started with SDL

January 3, 2019

A number of years ago, I wrote a couple of tutorials on software-based rendering (Simple Line Drawing and Triangle Rasterization). I created sample programs to go along with those articles; those programs originally used SDL 1.2 in order to get graphics onto the screen, and I recently updated them to use SDL version 2. Having been away from SDL for a while, I was glad to see that it has continued to improve and remains very easy to use.

SDL (or “Simple DirectMedia Layer”) is an excellent library for developing games or other media applications that need to perform tasks such as rendering graphics, playing audio, and handling user input. It’s well-known for its cross-platform capabilities, but its well-designed and simple API make it a good choice even when cross-platform development is not a concern.

With SDL, it’s very easy to get a window onto the screen, render graphics, and handle input events. Here’s some C code for doing so:

#include <stdio.h>
// Define SDL_MAIN_HANDLED so that we don't create a WinMain function on Windows.
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>

// Define the window dimensions and the size of a square to render.
const int WIDTH = 320;
const int HEIGHT = 240;
const int SQUARE_SIZE = 32;

int main(int argc, const char *argv[]) {
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Rect rect = {
        (WIDTH - SQUARE_SIZE) / 2,
        (HEIGHT - SQUARE_SIZE) / 2,
        SQUARE_SIZE,
        SQUARE_SIZE
    };
    int running = 1;

    // Initialize SDL with video rendering only.
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        fprintf(stderr, "SDL_Init failed");
        return 1;
    }

    window = SDL_CreateWindow("Hello",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        WIDTH, HEIGHT, 0);
    if (!window) {
        fprintf(stderr, "SDL_CreateWindow failed");
        return 2;
    }

    renderer = SDL_CreateRenderer(window, -1, 0);
    if (!renderer) {
        fprintf(stderr, "SDL_CreateRenderer failed");
        return 3;
    }

    // Render a black background with a white square in the center.
    // Note that the functions used below may return error codes;
    // error checking is omitted for brevity.
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
    SDL_RenderFillRect(renderer, &rect);
    SDL_RenderPresent(renderer);

    // Wait until we've received a window close or key event.
    while (running) {
        SDL_Event e;
        if (SDL_WaitEvent(&e)) {
            switch (e.type) {
                default:
                    break;
                case SDL_QUIT:
                case SDL_KEYDOWN:
                    running = 0;
                    break;
            }
        }
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Given the API’s logical design and descriptive function names, the code above should be fairly self-explanatory. SDL provides a number of functions (such as SDL_RenderFillRect, seen above) for high-performance graphics rendering. Behind the scenes, SDL uses whichever mechanism is appropriate for the host system, such as Direct3D on Windows, Metal on macOS, and OpenGL on Linux. It can also work with APIs such as OpenGL and Vulkan in case you need to do more advanced rendering. Be sure to check out the SDL website for more information.


Making a Bootable Windows 10 USB Drive on macOS High Sierra

November 23, 2017

I recently put together a new gaming PC for the first time in several years. This was my first time installing Windows 10, and it turned out to be a bit of a challenge, as I opted to purchase a downloadable copy through Microsoft’s website and transfer it to a USB drive on my Mac running macOS High Sierra. Microsoft provides a tool for creating a bootable Windows 10 installation drive from an existing Windows system, but not for macOS, and there is some conflicting information online about how to go about doing that.

My first instinct was to use dd to copy the ISO to the USB drive (as one typically does when installing a Linux distribution, for example), but it turns out that this does not satisfy the UEFI boot process. After some research and a lot of trial and error, I found that the USB drive must be formatted with a FAT32 partition and the MBR partitioning scheme, after which you can simply mount the Windows 10 ISO in macOS and copy the files to the drive.

Formatting the USB drive can be done from the command-line fairly easily. First, run diskutil list and find the identifier of the USB drive (this will be something like disk2 or disk3; make sure you find the right one, since you could erase the wrong drive and lose data if you don’t use the correct identifier). Next, the following command can be used to format the drive (replace disk# with the actual identifier for your USB drive) and mount it as a volume named WINDOWS10:

diskutil eraseDisk MS-DOS "WINDOWS10" MBR disk#

Now you can mount the Windows 10 ISO by opening it through Finder and copy its contents to the USB drive. Oddly enough, copying the files through Finder did not work for me - I received an error about the files being too large, even though the partition on the drive was definitely big enough, and no individual file appeared to be too large for the FAT32 file system. Eventually I found that using cp from the command-line did work without any issues. When I opened the Windows 10 Fall Creators Update ISO, it mounted as a volume named CCCOMA_X64FRE_EN-US_DV9, so I used the following command to copy its contents to the USB drive:

cp -rp /Volumes/CCCOMA_X64FRE_EN-US_DV9/* /Volumes/WINDOWS10/

This command will take a while, and once it finishes, you can safely eject the drive through Finder and you should be able to boot from it to install Windows 10 on a PC.


Using Swift for OpenGL development on OS X

June 25, 2015

I’ve been working with Swift lately and enjoying it quite a bit. Having done a lot of OpenGL development in my spare time in the past, I decided to try my hand at writing some OpenGL code in Swift.

I used a simple OpenGL demo application that I had previously written in Objective-C as the basis of a new Swift version, and the results can be found on GitHub. It’s a Cocoa-based OS X application.

Swift has pretty good facilities for working with C APIs, so using it for OpenGL development isn’t too much trouble, although there are some minor annoyances. For example, the parameters to a number of OpenGL functions are GLenums or GLbooleans, but the constants used as arguments are usually defined as GLints, so you have to cast things frequently:

glBindBuffer(GLenum(GL_ARRAY_BUFFER), bufferIds[1])
glBufferData(GLenum(GL_ARRAY_BUFFER), sizeof(Float) * tcSize, tc, GLenum(GL_STATIC_DRAW))

Similarly, there are signed/unsigned inconsistencies; the signed result of one function may need to be passed in as an unsigned argument to another. For example, glGetAttribLocation returns a GLint, but glVertexAttribPointer expects to receive the location as a GLuint. With C/C++/Objective-C, the conversions would be performed implicitly, but Swift makes you convert them explicitly (and that’s a good thing, in my opinion).

Aside from those minor issues, OpenGL development with Swift appears to be fairly painless.