Part 1 - Setting Up SDL and Color Buffer

Overview of Progress

 I spent today setting up the project with SDL, setting up the color buffer to map to the pixels on our display, and getting a rectangle drawing on the screen.








Project Setup

Language and Technologies

I'll be programming this software renderer using C and SDL2. I'm using C to force myself to learn what's happening under the hood and implement functionality myself, and SDL2 to avoid having to write cross-platform functionality so that I can focus on the graphics programming concepts.

Details Of Progress

I started with a main function that initializes the window, calls setup, and handles a naive game loop. The game loop currently handles three things: processing input, updating, and rendering.

Initializing The Window

SDL provides a lot of the logic needed for this step, so I just called the relevant methods and made sure to return errors if anything fails. One thing to note is a bug where if you tell SDL to run in full-screen mode, you can't click on anything if your program hits a breakpoint. To get around this, I added the SDL_SetHint line, which will allow you to interact with other programs if this happens.

Setting Up The Color Buffer

In my Setup function, I allocate memory for the color buffer using malloc and then multiply the number of pixels on screen by the size of a uint32_t. I'm using uint32_t because we want to make sure that across different architectures and compilers that our color format is 32 bits. Next, I just create a texture that covers the screen.

Render

The last step is to render something to the screen! To do this I set the draw color, clear the renderer, and then draw whatever I want (in this case a grid, rectangle and the background color).













Drawing a Grid and Rectangle

I ended up drawing a dotted grid, so I just iterated over the pixels in the color buffer and colored in a dot every 10 pixels. In code this looks like:

For the rectangle, I take in starting positions for x and y, the height and width, and the desired color. I then loop through the pixels of this rectangle starting my loops at 0 and then offsetting them by the current index in the loop. In code this looks like:

The key takeaway here is that to map our one dimensional color buffer array to a two dimensional array of pixels, we use the formula color_buffer[window_width * desired column * desired row].

Learnings

Modulus Operator

I started with a traditional grid where you have full lines drawn vertically and horizontally. The way I originally did this was with two nested for loops (ew gross I know) where one loop handled drawing the vertical lines and the other handled horizontal lines. I learned afterwards a simple optimization would be to use the modulus operator inside one nested for loop. Doing this you can simply say if (x % 10 == 0 || y % 10 == 0) draw pixel. I liked the look of the dotted grid best though, so I went that direction instead.

Comments