From 10a96ec02b16e943d60d4abd54fdc7a87b6391bc Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Fri, 3 Jul 2026 17:32:50 +0300 Subject: [PATCH] win32 stuff moved under pltf --- meson.build | 6 +- src/main.c | 382 ++------------------------------ src/pltf/gl_funcs.h | 2 +- src/pltf/pltf.c | 14 -- src/pltf/pltf.h | 15 +- src/pltf/{ => win32}/gl_funcs.c | 6 +- src/pltf/win32/pltf.c | 343 ++++++++++++++++++++++++++++ src/pltf/win32/pltf_win32.h | 8 + 8 files changed, 385 insertions(+), 391 deletions(-) delete mode 100644 src/pltf/pltf.c rename src/pltf/{ => win32}/gl_funcs.c (92%) create mode 100644 src/pltf/win32/pltf.c create mode 100644 src/pltf/win32/pltf_win32.h diff --git a/meson.build b/meson.build index 896601a..3e36e89 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ cargs = [ '-Og', '-g', '-DBOUNDS_CHECK', - '-DSHADERS_PATH="../src/shaders/"' + '-DSHADERS_PATH="../src/shaders/"', ] dependencies = [ @@ -53,8 +53,8 @@ endif executable( 'scuffedcraft', - 'src/pltf/gl_funcs.c', - 'src/pltf/pltf.c', + 'src/pltf/win32/gl_funcs.c', + 'src/pltf/win32/pltf.c', 'src/DynArray.c', 'src/DynString.c', 'src/log.c', diff --git a/src/main.c b/src/main.c index eae18da..6e3d65c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,366 +1,19 @@ -#include -#include #include -#include #include #include #include -#include -#include -#include -#include -#include "DynArray.h" -#include "DynString.h" -#include "log.h" -#include "pltf/gl_funcs.h" #include "pltf/pltf.h" +#include "pltf/gl_funcs.h" #include "shader.h" -// int _main() { -// return 0; -// } - -// #ifdef __MINGW32__ - -DynArray_DynString wgl_extensions = { 0 }; - -typedef struct { - HGLRC gl_ctx; -} State; - -bool has_wgl_extension(const DynString* name) { - assert(!DynString_is_null(name)); - assert(!DynArray_DynString_is_null(&wgl_extensions)); - - for (size_t i = 0; i < wgl_extensions.len; i++) { - if (DynString_equal(name, DynArray_DynString_at(&wgl_extensions, i))) { - return true; - } - } - - return false; -} - -bool has_wgl_extension_c_str(const char* name) { - DynString name_dstr = DynString_alloc(name, strlen(name)); - const bool res = has_wgl_extension(&name_dstr); - DynString_free(&name_dstr); - return res; -} - -void print_opengl_info() { - // assert(glGetIntegerv != NULL); - - if (glGetIntegerv == NULL) { - glGetIntegerv = (PFNGLGETINTEGERVPROC) pltf_gl_function_load("glGetIntegerv"); - if (glGetIntegerv == NULL) { - LOG_FATAL("Could not load glGetIntegerv"); - } - } - - int major = 0; - int minor = 0; - glGetIntegerv(GL_MAJOR_VERSION, &major); - glGetIntegerv(GL_MINOR_VERSION, &minor); - - int profile_mask = 0; - char profile[sizeof("compatibility")] = { 0 }; - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask); - if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) { - strncpy(profile, "core", strlen("core")); - } else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) { - strncpy(profile, "compatibility", strlen("compatibility")); - } else { - LOG_ERRORF( - "GL_CONTEXT_PROFILE_MASK did not contain either bit. profile_mask: %d", - profile_mask - ); - } - printf("OpenGL version %d.%d %s\n", major, minor, profile); -} - -void OnSize(HWND hwnd, UINT flag, int width, int height) { - printf("Window resize: flag: %d, width: %d, height: %d\n", flag, width, height); -} - -LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - State* pState = NULL; - if (uMsg == WM_CREATE) { - CREATESTRUCT* pCreate = (CREATESTRUCT*) lParam; - pState = (State*) pCreate->lpCreateParams; - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pState); - } else { - LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA); - pState = (State*) ptr; - } - - switch (uMsg) { - // case WM_LBUTTONDOWN: { - // printf("State: msg: %s, num: %d\n", pState->msg, pState->num); - // - // printf("lParam: %llx\n", lParam); - // int mouse_x = GET_X_LPARAM(lParam); - // printf("mouse_x: %x\n", mouse_x); - // int mouse_y = GET_Y_LPARAM(lParam); - // printf("mouse_y: %x\n", mouse_y); - // printf("x: %d y: %d\n", mouse_x, mouse_y); - // - // return 0; - // } - - case WM_CREATE: { - const PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, - 32, // Color depth - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 24, // Depth buffer bits - 8, // Stencil buffer bits - 0, - }; - - HDC hdc = GetDC(hwnd); - if (hdc == NULL) { - LOG_ERROR("Failed to get window DC"); - return 1; - } - const int pixel_format = ChoosePixelFormat(hdc, &pfd); - if (SetPixelFormat(hdc, pixel_format, &pfd) == FALSE) { - LOG_ERRORF("Failed to set pixel format. Error: %d", GetLastError()); - return 1; - } - - pState->gl_ctx = wglCreateContext(hdc); - if (pState->gl_ctx == NULL) { - LOG_ERRORF("Failed to create OpenGL context. Error: %d", GetLastError()); - return 1; - } - - if (wglMakeCurrent(hdc, pState->gl_ctx) == FALSE) { - LOG_ERRORF("Failed to make OpenGL context current. Error: %d", GetLastError()); - return 1; - } - - printf("Dummy context info: "); - print_opengl_info(); - - PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) pltf_gl_function_load("wglGetExtensionsStringARB"); - - char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc); - - char* wgl_extensions_str_copy = strdup(wgl_extensions_str); - - if (!DynArray_DynString_alloc(&wgl_extensions)) { - LOG_ERROR("Failed to allocate wgl_extensions"); - return 1; - } - - char* ext = strtok(wgl_extensions_str_copy, " "); - if (ext == NULL) { - LOG_ERROR("wgl_extensions_str was empty"); - return 1; - } - while (ext != NULL) { - DynString ext_dstr = DynString_alloc(ext, strlen(ext)); - - if (!DynArray_DynString_push_back(&wgl_extensions, &ext_dstr)) { - LOG_ERROR("Failed to push back extension string"); - return 1; - } - - ext = strtok(NULL, " "); - if (ext == NULL) { - break; - } - } - - free(wgl_extensions_str_copy); - - // printf("Available WGL extensions:\n"); - // for (size_t i = 0; i < wgl_extensions.len; i++) { - // const DynString* ext = DynArray_DynString_at(&wgl_extensions, i); - // printf("%.*s\n", DYN_STRING_FMT(*ext)); - // } - - if (!has_wgl_extension_c_str("WGL_ARB_pixel_format")) { - LOG_FATAL("WGL_ARB_create_context extension required."); - } - if (!has_wgl_extension_c_str("WGL_ARB_create_context")) { - LOG_FATAL("WGL_ARB_create_context extension is required"); - } - - PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) pltf_gl_function_load("wglChoosePixelFormatARB"); - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) pltf_gl_function_load("wglCreateContextAttribsARB"); - - int wgl_pixel_format = 0; - { - UINT num_formats = 0; - const int attribIList[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_COLOR_BITS_ARB, 32, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - 0 - }; - if (wglChoosePixelFormatARB(hdc, attribIList, NULL, 1, &wgl_pixel_format, &num_formats) == FALSE) { - LOG_FATAL("Failed to get pixel format with wglChoosePixelFormatARB"); - } - } - - if (SetPixelFormat(hdc, wgl_pixel_format, &pfd) == FALSE) { - LOG_FATAL("Failed to set wgl_pixel_format"); - } - - if (wglDeleteContext(pState->gl_ctx) == FALSE) { - LOG_FATAL("Failed to delete dummy context"); - } - - { - const int attribIList[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 6, - WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB - }; - pState->gl_ctx = wglCreateContextAttribsARB(hdc, NULL, attribIList); - if (pState->gl_ctx == NULL) { - LOG_FATAL("wglCreateContextAttribsARB did not create a context"); - } - } - - if (wglMakeCurrent(hdc, pState->gl_ctx) == FALSE) { - LOG_FATAL("Failed to set proper context as current"); - } - - printf("Proper context info: "); - print_opengl_info(); - - pltf_load_gl_funcs(); - - return 0; - } - - case WM_KEYDOWN: - if (wParam == VK_ESCAPE) { - PostMessage(hwnd, WM_DESTROY, 0, 0); - } - return 0; - - case WM_DESTROY: - wglDeleteContext(pState->gl_ctx); - PostQuitMessage(0); - return 0; - - case WM_CLOSE: - if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { - DestroyWindow(hwnd); - } - return 0; - - case WM_SIZE: { - int width = LOWORD(lParam); - int height = HIWORD(lParam); - OnSize(hwnd, (UINT) wParam, width, height); - return 0; - } - - // case WM_PAINT: { - // PAINTSTRUCT ps; - // HDC hdc = BeginPaint(hwnd, &ps); - // - // FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW + 1)); - // RECT blue = { - // .bottom = 100, - // .left = 0, - // .right = 100, - // .top = 0 - // }; - // FillRect(hdc, &blue, (HBRUSH) (COLOR_BACKGROUND + 1)); - // - // EndPaint(hwnd, &ps); - // return 0; - // } - } - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - int main() { pltf_init(); + pltf_window_create(); + pltf_gl_ctx_create(); + pltf_gl_funcs_load(); - HMODULE module = GetModuleHandle(NULL); - if (module == NULL) { - LOG_FATAL("Failed to get module"); - } - - // Register the window class - const wchar_t* CLASS_NAME = L"Sample Window Class"; - - WNDCLASS wc = { }; - wc.lpfnWndProc = WindowProc; - wc.hInstance = module; - wc.lpszClassName = CLASS_NAME; - wc.style = CS_OWNDC; - - RegisterClass(&wc); - - State s = { - .gl_ctx = NULL - }; - - // Create the window - HWND hwnd = CreateWindowEx( - 0, // Optional window styles - CLASS_NAME, // Window class - L"Learn to Program Windows", // Window text - WS_OVERLAPPEDWINDOW, // Window style - - // Size and position - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - - NULL, // Parent window - NULL, // Menu - module, // Instance handle - &s // Additional application data - ); - - if (hwnd == NULL) { - LOG_ERROR("ERROR: hwnd was NULL\n"); - return 1; - } - - ShowWindow(hwnd, SW_SHOWDEFAULT); - - // Message loop - - GLenum gl_err = 0; - glClearColor(0.0f, 0.0f, 0.8f, 1.0f); - float colors[4] = { 0 }; - glGetFloatv(GL_COLOR_CLEAR_VALUE, colors); - printf("Clear color: %f, %f, %f, %f\n", colors[0], colors[1], colors[2], colors[3]); - gl_err = glGetError(); - if (gl_err != GL_NO_ERROR) { - LOG_FATALF("gl error: %d", gl_err); - } - - HDC hdc = GetDC(hwnd); + pltf_gl_ctx_info_print(); // clang-format off const float triangle_verts[] = { @@ -404,33 +57,26 @@ int main() { "shader.frag" ); - MSG msg = { 0 }; - int exit_code = 0; + glClearColor(0.0f, 0.0f, 0.8f, 1.0f); + while (true) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - if (msg.message == WM_QUIT) { - exit_code = msg.wParam; - goto cleanup; - } + if (pltf_window_event_handle() == PLTF_WE_QUIT) { + goto cleanup; } glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader); glBindVertexArray(triangle_vao); - glDrawArrays(GL_TRIANGLE_STRIP, 0, triangle_vert_count); + glDrawArrays(GL_TRIANGLES, 0, triangle_vert_count); - wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE); + pltf_swap_buffers(); } - return 0; - cleanup: - UnregisterClass(CLASS_NAME, module); - return exit_code; - + pltf_gl_ctx_destroy(); + pltf_window_destroy(); + pltf_deinit(); return 0; } diff --git a/src/pltf/gl_funcs.h b/src/pltf/gl_funcs.h index 0ff4781..09eb46c 100644 --- a/src/pltf/gl_funcs.h +++ b/src/pltf/gl_funcs.h @@ -35,6 +35,6 @@ PLTF_GL_FUNCS(X) #undef X void* pltf_gl_function_load(const char* name); -void pltf_load_gl_funcs(); +void pltf_gl_funcs_load(); #endif // GL_FUNCS_H_ diff --git a/src/pltf/pltf.c b/src/pltf/pltf.c deleted file mode 100644 index f597d36..0000000 --- a/src/pltf/pltf.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -#include "pltf.h" -#include "log.h" - -HMODULE opengl_module = NULL; - -void pltf_init() { - opengl_module = LoadLibraryA("opengl32.dll"); - if (opengl_module == NULL) { - LOG_FATAL("Failed to load opengl32.dll"); - } -} diff --git a/src/pltf/pltf.h b/src/pltf/pltf.h index 7363622..ff0c8bc 100644 --- a/src/pltf/pltf.h +++ b/src/pltf/pltf.h @@ -1,10 +1,21 @@ #ifndef PLTF_H_ #define PLTF_H_ -#include +#include -extern HMODULE opengl_module; +typedef enum { + PLTF_WE_NULL, + PLTF_WE_QUIT +} PltfWindowEvent; void pltf_init(); +void pltf_deinit(); +void pltf_window_create(); +void pltf_window_destroy(); +void pltf_gl_ctx_create(); +void pltf_gl_ctx_destroy(); +void pltf_gl_ctx_info_print(); +void pltf_swap_buffers(); +PltfWindowEvent pltf_window_event_handle(); #endif // PLTF_H_ diff --git a/src/pltf/gl_funcs.c b/src/pltf/win32/gl_funcs.c similarity index 92% rename from src/pltf/gl_funcs.c rename to src/pltf/win32/gl_funcs.c index 7b02e0a..0555c5c 100644 --- a/src/pltf/gl_funcs.c +++ b/src/pltf/win32/gl_funcs.c @@ -1,6 +1,6 @@ -#include "gl_funcs.h" +#include "../gl_funcs.h" #include "log.h" -#include "pltf.h" +#include "pltf_win32.h" #define X(type, name) \ type name = NULL @@ -27,7 +27,7 @@ void* pltf_gl_function_load(const char* name) { return gl_func; } -void pltf_load_gl_funcs() { +void pltf_gl_funcs_load() { PLTF_GL_FUNCS(X) } diff --git a/src/pltf/win32/pltf.c b/src/pltf/win32/pltf.c new file mode 100644 index 0000000..5fd3273 --- /dev/null +++ b/src/pltf/win32/pltf.c @@ -0,0 +1,343 @@ +#include +#include +#include +#include +#include +#include + +#include "../gl_funcs.h" +#include "../pltf.h" +#include "DynArray.h" +#include "DynString.h" +#include "log.h" + +typedef struct { + HGLRC gl_ctx; +} State; + +HMODULE opengl_module = NULL; + +static const wchar_t* wc_name = L"Sample Window Class"; +static HMODULE exe_module = NULL; +static HWND hwnd = NULL; +static HDC hdc = NULL; +static DynArray_DynString wgl_extensions = { 0 }; +static State window_state = { + .gl_ctx = NULL +}; + +static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +void pltf_init() { + exe_module = GetModuleHandle(NULL); + if (exe_module == NULL) { + LOG_FATAL("Failed to get module"); + } + + opengl_module = LoadLibraryA("opengl32.dll"); + if (opengl_module == NULL) { + LOG_FATAL("Failed to load opengl32.dll"); + } + + // Register the window class + WNDCLASS wc = { }; + wc.lpfnWndProc = WindowProc; + wc.hInstance = exe_module; + wc.lpszClassName = wc_name; + wc.style = CS_OWNDC; + + RegisterClass(&wc); +} + +void pltf_deinit() { + UnregisterClass(wc_name, exe_module); +} + +static bool pltf_has_wgl_extension(const DynString* name) { + for (size_t i = 0; i < wgl_extensions.len; i++) { + if (DynString_equal(name, DynArray_DynString_at(&wgl_extensions, i))) { + return true; + } + } + + return false; +} + +static bool pltf_has_wgl_extension_c_str(const char* name) { + DynString name_dstr = DynString_alloc(name, strlen(name)); + const bool res = pltf_has_wgl_extension(&name_dstr); + DynString_free(&name_dstr); + return res; +} + +void pltf_window_create() { + // Create the window + hwnd = CreateWindowEx( + 0, // Optional window styles + wc_name, // Window class + L"Learn to Program Windows", // Window text + WS_OVERLAPPEDWINDOW, // Window style + + // Size and position + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + + NULL, // Parent window + NULL, // Menu + exe_module, // Instance handle + &window_state // Additional application data + ); + + if (hwnd == NULL) { + LOG_FATAL("ERROR: hwnd was NULL"); + } + + hdc = GetDC(hwnd); + if (hdc == NULL) { + LOG_FATAL("Failed to get HDC"); + } + + ShowWindow(hwnd, SW_SHOWDEFAULT); +} + +void pltf_window_destroy() { + if (hwnd != NULL) { + DestroyWindow(hwnd); + hwnd = NULL; + } +} + +void pltf_gl_ctx_create() { + const PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 32, // Color depth + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 24, // Depth buffer bits + 8, // Stencil buffer bits + 0, + }; + + HDC hdc = GetDC(hwnd); + if (hdc == NULL) { + LOG_ERROR("Failed to get window DC"); + return; + } + const int pixel_format = ChoosePixelFormat(hdc, &pfd); + if (SetPixelFormat(hdc, pixel_format, &pfd) == FALSE) { + LOG_ERRORF("Failed to set pixel format. Error: %d", GetLastError()); + return; + } + + window_state.gl_ctx = wglCreateContext(hdc); + if (window_state.gl_ctx == NULL) { + LOG_ERRORF("Failed to create OpenGL context. Error: %d", GetLastError()); + return; + } + + if (wglMakeCurrent(hdc, window_state.gl_ctx) == FALSE) { + LOG_ERRORF("Failed to make OpenGL context current. Error: %d", GetLastError()); + return; + } + + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) pltf_gl_function_load("wglGetExtensionsStringARB"); + + char* wgl_extensions_str = (char*) wglGetExtensionsStringARB(hdc); + + char* wgl_extensions_str_copy = strdup(wgl_extensions_str); + + if (!DynArray_DynString_alloc(&wgl_extensions)) { + LOG_ERROR("Failed to allocate wgl_extensions"); + return; + } + + char* ext = strtok(wgl_extensions_str_copy, " "); + if (ext == NULL) { + LOG_ERROR("wgl_extensions_str was empty"); + return; + } + while (ext != NULL) { + DynString ext_dstr = DynString_alloc(ext, strlen(ext)); + + if (!DynArray_DynString_push_back(&wgl_extensions, &ext_dstr)) { + LOG_ERROR("Failed to push back extension string"); + return; + } + + ext = strtok(NULL, " "); + if (ext == NULL) { + break; + } + } + + free(wgl_extensions_str_copy); + + if (!pltf_has_wgl_extension_c_str("WGL_ARB_pixel_format")) { + LOG_FATAL("WGL_ARB_create_context extension required."); + } + if (!pltf_has_wgl_extension_c_str("WGL_ARB_create_context")) { + LOG_FATAL("WGL_ARB_create_context extension is required"); + } + + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) pltf_gl_function_load("wglChoosePixelFormatARB"); + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) pltf_gl_function_load("wglCreateContextAttribsARB"); + + int wgl_pixel_format = 0; + { + UINT num_formats = 0; + const int attribIList[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_COLOR_BITS_ARB, 32, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + 0 + }; + if (wglChoosePixelFormatARB(hdc, attribIList, NULL, 1, &wgl_pixel_format, &num_formats) == FALSE) { + LOG_FATAL("Failed to get pixel format with wglChoosePixelFormatARB"); + } + } + + if (SetPixelFormat(hdc, wgl_pixel_format, &pfd) == FALSE) { + LOG_FATAL("Failed to set wgl_pixel_format"); + } + + if (wglDeleteContext(window_state.gl_ctx) == FALSE) { + LOG_FATAL("Failed to delete dummy context"); + } + + { + const int attribIList[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 6, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB + }; + window_state.gl_ctx = wglCreateContextAttribsARB(hdc, NULL, attribIList); + if (window_state.gl_ctx == NULL) { + LOG_FATAL("wglCreateContextAttribsARB did not create a context"); + } + } + + if (wglMakeCurrent(hdc, window_state.gl_ctx) == FALSE) { + LOG_FATAL("Failed to set proper context as current"); + } +} + +void pltf_gl_ctx_destroy() { + wglDeleteContext(window_state.gl_ctx); + window_state.gl_ctx = NULL; +} + +void pltf_gl_ctx_info_print() { + if (glGetIntegerv == NULL) { + glGetIntegerv = (PFNGLGETINTEGERVPROC) pltf_gl_function_load("glGetIntegerv"); + if (glGetIntegerv == NULL) { + LOG_FATAL("Could not load glGetIntegerv"); + } + } + + int major = 0; + int minor = 0; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + + int profile_mask = 0; + char* profile; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask); + if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) { + profile = "core"; + } else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) { + profile = "compatibility"; + } else { + LOG_ERRORF( + "GL_CONTEXT_PROFILE_MASK did not contain either bit. profile_mask: %d", + profile_mask + ); + return; + } + printf("OpenGL version %d.%d %s\n", major, minor, profile); +} + +void pltf_swap_buffers() { + wglSwapLayerBuffers(hdc, WGL_SWAP_MAIN_PLANE); +} + +PltfWindowEvent pltf_window_event_handle() { + MSG msg = { 0 }; + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + if (msg.message == WM_QUIT) { + return PLTF_WE_QUIT; + } + } + + return PLTF_WE_NULL; +} + +static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + State* pState = NULL; + if (uMsg == WM_CREATE) { + CREATESTRUCT* pCreate = (CREATESTRUCT*) lParam; + pState = (State*) pCreate->lpCreateParams; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pState); + } else { + LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA); + pState = (State*) ptr; + } + + switch (uMsg) { + // case WM_LBUTTONDOWN: { + // printf("State: msg: %s, num: %d\n", pState->msg, pState->num); + // + // printf("lParam: %llx\n", lParam); + // int mouse_x = GET_X_LPARAM(lParam); + // printf("mouse_x: %x\n", mouse_x); + // int mouse_y = GET_Y_LPARAM(lParam); + // printf("mouse_y: %x\n", mouse_y); + // printf("x: %d y: %d\n", mouse_x, mouse_y); + // + // return 0; + // } + + case WM_CREATE: { + + return 0; + } + + case WM_KEYDOWN: + if (wParam == VK_ESCAPE) { + PostMessage(hwnd, WM_DESTROY, 0, 0); + } + return 0; + + case WM_DESTROY: + wglDeleteContext(pState->gl_ctx); + PostQuitMessage(0); + return 0; + + case WM_CLOSE: + if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { + DestroyWindow(hwnd); + } + return 0; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + diff --git a/src/pltf/win32/pltf_win32.h b/src/pltf/win32/pltf_win32.h new file mode 100644 index 0000000..ad6b552 --- /dev/null +++ b/src/pltf/win32/pltf_win32.h @@ -0,0 +1,8 @@ +#ifndef PLTF_WIN32_H_ +#define PLTF_WIN32_H_ + +#include + +extern HMODULE opengl_module; + +#endif // PLTF_WIN32_H_