Lumenarium/src_v2/platform/win32/lumenarium_win32_window.cpp

204 lines
5.5 KiB
C++

typedef u32 Win32_Window_Event_Flags;
enum
{
WindowEventFlag_None = 0,
WindowEventFlag_CloseRequested = 1,
WindowEventFlag_WindowIsActive = 2,
};
struct Win32_Window_OpenGL_Info
{
BYTE bits_color;
BYTE bits_alpha;
BYTE bits_depth;
HGLRC rc;
};
struct Win32_Window
{
char* name;
char* class_name;
s32 width;
s32 height;
WNDCLASS window_class;
WNDPROC window_event_handler;
HWND window_handle;
HDC dc;
Win32_Window_OpenGL_Info opengl_info;
};
//////////////////////////////////////////
// Main Window
//
// At the moment, we only need one window, so this is easier to
// track globally. Replace this if we need more windows
global Win32_Window_Event_Flags win32_window_event_flags = 0;
global Win32_Window win32_main_window = {};
//////////////////////////////////////////
//
internal Win32_Window
win32_window_create(
HINSTANCE hinstance,
char* window_name,
s32 width,
s32 height,
WNDPROC window_event_handler
)
{
Win32_Window result = {};
result.name = window_name;
result.class_name = window_name;
result.width = width;
result.height = height;
result.window_event_handler = window_event_handler;
result.window_class = {};
result.window_class.style = CS_HREDRAW | CS_VREDRAW;
result.window_class.lpfnWndProc = window_event_handler;
result.window_class.hInstance = hinstance;
result.window_class.lpszClassName = window_name;
if (RegisterClass(&result.window_class))
{
result.window_handle = CreateWindowEx(
0,
result.window_class.lpszClassName,
window_name,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
0,
0,
hinstance,
0
);
result.dc = GetDC(result.window_handle);
}
return result;
}
internal void
win32_window_update_dim(Win32_Window* win)
{
RECT client_rect;
GetClientRect(win->window_handle, &client_rect);
win->width = client_rect.right - client_rect.left;
win->height = client_rect.bottom - client_rect.top;
}
LRESULT CALLBACK
win32_window_event_handler(HWND window_handle, UINT msg, WPARAM wparam, LPARAM lparam)
{
LRESULT result = 0;
switch (msg)
{
case WM_SIZE:
{
win32_window_update_dim(&win32_main_window);
}break;
case WM_CLOSE:
{
result = DefWindowProc(window_handle, msg, wparam, lparam);
add_flag(win32_window_event_flags, WindowEventFlag_CloseRequested);
}break;
case WM_DESTROY:
{
}break;
case WM_PAINT:
{
PAINTSTRUCT paint_struct;
HDC device_ctx;
b32 paint_result;
device_ctx = BeginPaint(window_handle, &paint_struct);
paint_result = EndPaint(window_handle, &paint_struct);
}break;
case WM_ACTIVATE:
{
bool WindowIsActive = (
LOWORD(wparam) == WA_ACTIVE || LOWORD(wparam) == WA_CLICKACTIVE
);
if (WindowIsActive)
{
add_flag(win32_window_event_flags, WindowEventFlag_WindowIsActive);
}
else
{
rem_flag(win32_window_event_flags, WindowEventFlag_WindowIsActive);
}
}break;
default:
{
result = DefWindowProc(window_handle, msg, wparam, lparam);
}
}
return result;
}
internal void
win32_window_opengl_ctx_create(Win32_Window* win, Win32_Window_OpenGL_Info info)
{
// Setup pixel format
{
PIXELFORMATDESCRIPTOR pixel_format_desc = { 0 };
// TODO: Program seems to work perfectly fine without all other params except dwFlags.
// Can we skip other params for the sake of brevity?
pixel_format_desc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixel_format_desc.nVersion = 1;
pixel_format_desc.dwFlags = (
PFD_SUPPORT_OPENGL |
PFD_DRAW_TO_WINDOW |
PFD_DOUBLEBUFFER
);
pixel_format_desc.cColorBits = info.bits_color;
pixel_format_desc.cAlphaBits = info.bits_alpha;
pixel_format_desc.cDepthBits = info.bits_depth;
// TODO(Peter): include these in win32_opengl_window_info?
pixel_format_desc.iPixelType = PFD_TYPE_RGBA;
pixel_format_desc.dwLayerMask = PFD_MAIN_PLANE;
s32 pixel_fmt = ChoosePixelFormat(win->dc, &pixel_format_desc);
if (!pixel_fmt) { invalid_code_path; }
if (!SetPixelFormat(win->dc, pixel_fmt, &pixel_format_desc))
{
invalid_code_path;
}
}
// Create rendering context
{
// TODO: Create "proper" context?
// https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation
info.rc = wglCreateContext(win->dc);
wglMakeCurrent(win->dc, info.rc);
// TODO(Peter): do we want this?
/*
glGetIntegerv(GL_MAJOR_VERSION, );
glGetIntegerv(GL_MINOR_VERSION, );
(char*)glGetString(GL_VENDOR);
(char*)glGetString(GL_RENDERER);
*/
}
win->opengl_info = info;
}