I have also been trying to implement the HandmadeHero series using Nim. The
reason why WNDCLASS was failing to initialize, is because it is required that
it is gcsafe.
However, WNDCLASS needs to call MainWindowCallBack, and MainWindowCallBack
accesses the Win32OffScreenBuffer type. The problem with this is that the
Win32OffScreenBuffer type contains the seq[uint32] that you were going to use
for the backbuffer, which means the compiler can't infer that
MainWindowCallBack is gcsafe.
Reassuring the compiler by adding the {.gcsafe.} pragma to MainWindowCallBack
allows it to compile (with warnings). From there, it isn't too hard to hook
things up so that windows can use the seq[uint32] to blit to the screen.
In the end though, I'm not sure much is gained by using a seq instead of a raw
pointer. The code doesn't feel much more idiomatic, and the memory footprint is
a lot bigger. The draw speed is the same though.
There was also a small bug in the way you were casting your colour information
to the pixels, this fixes it:
proc renderWeirdGradient(buffer: var Win32OffscreenBuffer, greenOffset: var
int; blueOffset: var int) =
var row = cast[uint32](buffer.memory)
for y in 0 .. <buffer.height:
var pixel = row
for x in 0 .. <buffer.width:
cast[ptr uint32](pixel)[] = (uint32(uint8(greenOffset + y)) shl
8 or uint32(uint8(blueOffset + x)))
inc(pixel, 4)
inc(row, buffer.pitch)