| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #ifdef _WIN32
- #include <GL/glcorearb.h>
- #include <GL/wglext.h>
- #include <assert.h>
- #include <stdio.h>
- #include <windows.h>
- #include <windowsx.h>
- #include "../gl_funcs.h"
- #include "../pltf.h"
- #include "DynArray.h"
- #include "DynString.h"
- #include "internal.h"
- #include "log.h"
- #include "win_proc.h"
- void pltf_init() {
- pltf_state.exe_module = GetModuleHandle(NULL);
- if (pltf_state.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 = pltf_state.exe_module;
- wc.lpszClassName = pltf_state.wc_name;
- wc.style = CS_OWNDC;
- RegisterClass(&wc);
- }
- void pltf_deinit() {
- UnregisterClass(pltf_state.wc_name, pltf_state.exe_module);
- }
- void pltf_window_create() {
- // Create the window
- pltf_state.hwnd = CreateWindowEx(
- 0, // Optional window styles
- pltf_state.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
- pltf_state.exe_module, // Instance handle
- &pltf_state.window_state // Additional application data
- );
- if (pltf_state.hwnd == NULL) {
- LOG_FATAL("ERROR: hwnd was NULL");
- }
- pltf_state.hdc = GetDC(pltf_state.hwnd);
- if (pltf_state.hdc == NULL) {
- LOG_FATAL("Failed to get HDC");
- }
- ShowWindow(pltf_state.hwnd, SW_SHOWDEFAULT);
- }
- void pltf_window_close() {
- PostMessage(pltf_state.hwnd, WM_CLOSE, 0, 0);
- }
- void pltf_window_destroy() {
- if (pltf_state.hwnd != NULL) {
- DestroyWindow(pltf_state.hwnd);
- pltf_state.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(pltf_state.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;
- }
- pltf_state.window_state.gl_ctx = wglCreateContext(hdc);
- if (pltf_state.window_state.gl_ctx == NULL) {
- LOG_ERRORF("Failed to create OpenGL context. Error: %d", GetLastError());
- return;
- }
- if (wglMakeCurrent(hdc, pltf_state.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");
- // Copy to prevent modifying the original string. Might be useless but doing it just in case.
- char* wgl_extensions_str = strdup(wglGetExtensionsStringARB(hdc));
- if (!DynArray_DynString_alloc(&pltf_state.wgl_extensions)) {
- LOG_ERROR("Failed to allocate wgl_extensions");
- return;
- }
- char* ext = strtok(wgl_extensions_str, " ");
- 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(&pltf_state.wgl_extensions, &ext_dstr)) {
- LOG_ERROR("Failed to push back extension string");
- return;
- }
- ext = strtok(NULL, " ");
- if (ext == NULL) {
- break;
- }
- }
- free(wgl_extensions_str);
- if (!pltf_has_wgl_extension("WGL_ARB_pixel_format")) {
- LOG_FATAL("WGL_ARB_create_context extension required.");
- }
- if (!pltf_has_wgl_extension("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(pltf_state.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
- };
- pltf_state.window_state.gl_ctx = wglCreateContextAttribsARB(hdc, NULL, attribIList);
- if (pltf_state.window_state.gl_ctx == NULL) {
- LOG_FATAL("wglCreateContextAttribsARB did not create a context");
- }
- }
- if (wglMakeCurrent(hdc, pltf_state.window_state.gl_ctx) == FALSE) {
- LOG_FATAL("Failed to set proper context as current");
- }
- }
- void pltf_gl_ctx_destroy() {
- wglDeleteContext(pltf_state.window_state.gl_ctx);
- pltf_state.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(pltf_state.hdc, WGL_SWAP_MAIN_PLANE);
- }
- PltfWindowEvent pltf_window_event_handle() {
- MSG msg = { 0 };
- if (PeekMessage(&msg, pltf_state.hwnd, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- switch (msg.message) {
- case WM_DESTROY:
- return PLTF_WE_DESTROY;
- }
- }
- return PLTF_WE_NONE;
- }
- #define PLTF_KEYS_X(lower, upper) \
- case PLTF_KEY_##upper: { \
- pltf_state.key_##lower##_cb = cb; \
- pltf_state.key_##lower##_cb_user_data = (void*) user_data; \
- break; \
- }
- void pltf_key_callback_set(
- const PltfKey key,
- const PltfKeyCallback cb,
- void* user_data
- ) {
- switch (key) {
- case PLTF_KEY_NONE:
- break;
- PLTF_KEYS(PLTF_KEYS_X);
- }
- }
- #undef PLTF_KEYS_X
- #endif // _WIN32
|