allocating a backbuffer
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
comp:
|
comp:
|
||||||
zig c++ --target=x86_64-windows -o ../build/win32_handmade.exe win32_handmade.cpp -lgdi32
|
zig c++ --target=x86_64-windows -o ../build/win32_handmade.exe win32_handmade.cpp -lgdi32 -g
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm ../build/*
|
rm ../build/*
|
||||||
|
|||||||
+62
-16
@@ -2,17 +2,64 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
|
|
||||||
LRESULT CALLBACK MainWindowCallback(HWND window, UINT message, WPARAM wParam,
|
#define internal static
|
||||||
LPARAM lParam) {
|
#define local_persist static
|
||||||
|
#define global_variable static
|
||||||
|
|
||||||
|
// NOTE: this is a global for now
|
||||||
|
global_variable bool running;
|
||||||
|
global_variable BITMAPINFO bitmapInfo;
|
||||||
|
global_variable void *bitmapMemory;
|
||||||
|
global_variable HBITMAP bitmapHandle;
|
||||||
|
global_variable HDC bitmapDeviceContext;
|
||||||
|
|
||||||
|
internal void Win32ResizeDIBSection(int width, int height) {
|
||||||
|
// TODO: bulletproof this.
|
||||||
|
// perhaps don't free first, free after, then free first if that fails
|
||||||
|
|
||||||
|
if (bitmapHandle) {
|
||||||
|
DeleteObject(bitmapHandle);
|
||||||
|
}
|
||||||
|
if (!bitmapDeviceContext) {
|
||||||
|
// TODO: should we recreate these under certain special circumstances?
|
||||||
|
bitmapDeviceContext = CreateCompatibleDC(0);
|
||||||
|
}
|
||||||
|
bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader);
|
||||||
|
bitmapInfo.bmiHeader.biWidth = width;
|
||||||
|
bitmapInfo.bmiHeader.biHeight = height;
|
||||||
|
bitmapInfo.bmiHeader.biPlanes = 1;
|
||||||
|
bitmapInfo.bmiHeader.biBitCount = 24;
|
||||||
|
bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
bitmapHandle = CreateDIBSection(bitmapDeviceContext, &bitmapInfo,
|
||||||
|
DIB_RGB_COLORS, &bitmapMemory, 0, 0);
|
||||||
|
}
|
||||||
|
internal void Win32UpdateWindow(HDC deviceContext, int x, int y, int width,
|
||||||
|
int height) {
|
||||||
|
StretchDIBits(deviceContext, x, y, width, height, x, y, width, height,
|
||||||
|
bitmapMemory, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK Win32MainWindowCallback(HWND window, UINT message,
|
||||||
|
WPARAM wParam, LPARAM lParam) {
|
||||||
LRESULT res = 0;
|
LRESULT res = 0;
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_SIZE: {
|
case WM_SIZE: {
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(window, &rect);
|
||||||
|
int width = rect.right - rect.left;
|
||||||
|
int height = rect.top - rect.bottom;
|
||||||
|
Win32ResizeDIBSection(width, height);
|
||||||
printf("WM_SIZE\n");
|
printf("WM_SIZE\n");
|
||||||
} break;
|
} break;
|
||||||
case WM_DESTROY: {
|
case WM_DESTROY: {
|
||||||
|
running = false;
|
||||||
|
// TODO: handle this as an error - recreate window?
|
||||||
printf("WM_DESTROY\n");
|
printf("WM_DESTROY\n");
|
||||||
} break;
|
} break;
|
||||||
case WM_CLOSE: {
|
case WM_CLOSE: {
|
||||||
|
// TODO: handle this as a message to the user?
|
||||||
|
running = false;
|
||||||
printf("WM_CLOSE\n");
|
printf("WM_CLOSE\n");
|
||||||
} break;
|
} break;
|
||||||
case WM_PAINT: {
|
case WM_PAINT: {
|
||||||
@@ -22,14 +69,8 @@ LRESULT CALLBACK MainWindowCallback(HWND window, UINT message, WPARAM wParam,
|
|||||||
int width = paint.rcPaint.right - paint.rcPaint.left;
|
int width = paint.rcPaint.right - paint.rcPaint.left;
|
||||||
int x = paint.rcPaint.left;
|
int x = paint.rcPaint.left;
|
||||||
int y = paint.rcPaint.top;
|
int y = paint.rcPaint.top;
|
||||||
|
Win32UpdateWindow(deviceContext, x, y, width, height);
|
||||||
|
|
||||||
static DWORD operation = WHITENESS;
|
|
||||||
PatBlt(deviceContext, x, y, width, height, operation);
|
|
||||||
if (operation == WHITENESS) {
|
|
||||||
operation = BLACKNESS;
|
|
||||||
} else {
|
|
||||||
operation = WHITENESS;
|
|
||||||
}
|
|
||||||
EndPaint(window, &paint);
|
EndPaint(window, &paint);
|
||||||
} break;
|
} break;
|
||||||
case WM_ACTIVATEAPP: {
|
case WM_ACTIVATEAPP: {
|
||||||
@@ -44,11 +85,15 @@ LRESULT CALLBACK MainWindowCallback(HWND window, UINT message, WPARAM wParam,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef RegisterClass
|
||||||
|
#undef CreateWindowEx
|
||||||
|
#undef GetMessage
|
||||||
|
#undef DispatchMessage
|
||||||
|
|
||||||
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance,
|
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance,
|
||||||
LPSTR commandLine, int showCode) {
|
LPSTR commandLine, int showCode) {
|
||||||
WNDCLASS WindowClass = {0};
|
WNDCLASS WindowClass = {0};
|
||||||
WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
|
WindowClass.lpfnWndProc = Win32MainWindowCallback;
|
||||||
WindowClass.lpfnWndProc = MainWindowCallback;
|
|
||||||
// WindowClass.cbClsExtra = ;
|
// WindowClass.cbClsExtra = ;
|
||||||
// WindowClass.cbWndExtra = ;
|
// WindowClass.cbWndExtra = ;
|
||||||
WindowClass.hInstance = instance;
|
WindowClass.hInstance = instance;
|
||||||
@@ -57,18 +102,19 @@ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance,
|
|||||||
// WindowClass.lpszMenuName = ;
|
// WindowClass.lpszMenuName = ;
|
||||||
WindowClass.lpszClassName = "HandmadeHeroWindowClass";
|
WindowClass.lpszClassName = "HandmadeHeroWindowClass";
|
||||||
|
|
||||||
if (RegisterClass(&WindowClass)) {
|
if (RegisterClassA(&WindowClass)) {
|
||||||
HWND windowHandle = CreateWindowEx(
|
HWND windowHandle = CreateWindowExA(
|
||||||
0, WindowClass.lpszClassName, "Handmade Hero",
|
0, WindowClass.lpszClassName, "Handmade Hero",
|
||||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instance, 0);
|
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instance, 0);
|
||||||
if (windowHandle) {
|
if (windowHandle) {
|
||||||
|
running = true;
|
||||||
MSG message;
|
MSG message;
|
||||||
for (;;) {
|
while (running) {
|
||||||
BOOL msgResult = GetMessage(&message, 0, 0, 0);
|
BOOL msgResult = GetMessageA(&message, 0, 0, 0);
|
||||||
if (msgResult > 0) {
|
if (msgResult > 0) {
|
||||||
TranslateMessage(&message);
|
TranslateMessage(&message);
|
||||||
DispatchMessage(&message);
|
DispatchMessageA(&message);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user