explored GDI (Graphics Device Interface) | 2D vectors, text, fonts, and UI buttons | Windows exclusively (tied to Win32 API)
A reference guide summarizing key insights, data structures, and architectural patterns gained from examining native Win32 platform layer code and software rasterization fundamentals.
The Microsoft Windows Graphics Device Interface (GDI) exposes low-level graphics and device-independent drawing capabilities for C/C++ developers:
- Bitmaps: Used to create, manipulate (scale, scroll, rotate, paint), and store raster graphics in memory or on disk.
- Device Contexts (HDC): A handle to a display device structure that defines graphics objects, their attributes, and output modes.
- Painting and Drawing: Message-driven canvas updates driven by OS events (
WM_PAINT,BeginPaint,EndPaint). - Coordinate Spaces & Transformations: Translating world/logical coordinates into physical screen coordinates.
- Primitives & Geometry: Pens, Brushes, Filled Shapes, Rectangles, Regions, Paths, Lines, and Curves.
- System Graphics Handling: Colors, Fonts and Text, Clipping, Metafiles, Printing/Print Spooler, and Multiple Display Monitors.
When allocating a raw software framebuffer in RAM and displaying it on a native window, the Windows API uses BITMAPINFO to interpret the byte layout:
bmiHeader(BITMAPINFOHEADER):
- Dimensions:
biWidthandbiHeight(a negative height specifies a top-down orientation). - Color Depth:
biBitCount(e.g., 32-bit color: 8 bits Red, 8 bits Green, 8 bits Blue, 8 bits Padding/Alpha). - Compression:
biCompression(e.g.,BI_RGBfor uncompressed raw pixel arrays). - Planes:
biPlanes(must be set to 1).
bmiColors(RGBQUAD):
- An array defining palette entries (for 8-bit or lower indexed color modes) or bit masks.
Functions like StretchDIBits or SetDIBitsToDevice use BITMAPINFO to transfer the custom memory framebuffer directly to a window's Device Context (HDC).
Low-level systems programming and software rendering require fixed-width integer types to guarantee predictable memory sizing, alignment, and bit-shifting across target architectures:
int8_t/uint8_t: 8-bit signed / unsigned integer (1 byte)int16_t/uint16_t: 16-bit signed / unsigned integer (2 bytes)int32_t/uint32_t: 32-bit signed / unsigned integer (4 bytes)int64_t/uint64_t: 64-bit signed / unsigned integer (8 bytes)
intptr_t/uintptr_t: Integer types guaranteed to match the target platform's pointer size (32-bit or 64-bit), enabling safe pointer arithmetic and casting without data loss.
intmax_t/uintmax_t: The largest integer type supported by the target compiler.
[ RAM Framebuffer ] ---> (Populate 0x00RRGGBB Pixels)
|
v
[ BITMAPINFO ] ---> (Defines Dimensions, Pitch, and 32-bit Depth)
|
v
[ StretchDIBits ] ---> (Blits RAM pixels to Window HDC)
- Virtual Memory Allocation: Allocate a contiguous block of memory using
VirtualAlloc. - Pixel Manipulation: Loop over the buffer using
uint32_tpointers to write raw RGB color bytes ((Red << 16) | (Green << 8) | Blue). - OS Window Presentation: Intercept
WM_PAINTor run a continuousPeekMessageloop to present the framebuffer usingStretchDIBits.
Here are the two exact compilation commands using g++ (MinGW) along with the breakdown of why each flag is necessary:
g++ main.cpp -o main.exe -lgdi32 -mwindows
./main.exe
-lgdi32(Link Graphics Library): Links theGdi32system library (libgdi32.a). This prevents "undefined reference" linker errors for low-level graphics functions likeStretchDIBitsandCreateDIBSectionthat live insidegdi32.dll.-mwindows(Set Windows GUI Subsystem): Configures the executable to use the Windows Subsystem (WinMainentry point) instead of the console subsystem. This opens your custom window directly without spawning an extra black command prompt window in the background.