From dc65a5c07e9101cb4909bb2e2dd0a194dcabb634 Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Fri, 7 Aug 2026 14:31:06 +0300 Subject: [PATCH] Working glx pltf implementation --- generate_gl_func_alias.py | 29 +++ meson.build | 6 +- src/main.c | 400 ++---------------------------- src/pltf/gl_funcs.h | 49 +--- src/pltf/glx/gl_funcs.c | 19 +- src/pltf/glx/internal.c | 16 ++ src/pltf/glx/internal.h | 28 +++ src/pltf/glx/pltf.c | 204 +++++++++++++++ src/pltf/glx/util.c | 190 ++++++++++++++ src/pltf/internal/gl_func_alias.h | 27 ++ src/pltf/internal/gl_func_decl.h | 38 +++ src/pltf/pltf.h | 11 +- src/pltf/win32/gl_funcs.c | 4 +- src/pltf/win32/internal.c | 11 +- src/pltf/win32/internal.h | 13 +- src/pltf/win32/pltf.c | 59 +---- src/pltf/win32/win_proc.c | 15 +- 17 files changed, 592 insertions(+), 527 deletions(-) create mode 100644 generate_gl_func_alias.py create mode 100644 src/pltf/glx/internal.c create mode 100644 src/pltf/glx/internal.h create mode 100644 src/pltf/glx/pltf.c create mode 100644 src/pltf/glx/util.c create mode 100644 src/pltf/internal/gl_func_alias.h create mode 100644 src/pltf/internal/gl_func_decl.h diff --git a/generate_gl_func_alias.py b/generate_gl_func_alias.py new file mode 100644 index 0000000..0428066 --- /dev/null +++ b/generate_gl_func_alias.py @@ -0,0 +1,29 @@ +import os +from sys import argv + +sc_dir = os.path.dirname(os.path.realpath(argv[0])) +os.chdir(sc_dir) + +hg_tag = "PLTF_GL_FUNC_ALIAS_H_" + +lines: list[str] = [ + f"#ifndef {hg_tag}\n", + f"#define {hg_tag}\n" +] + +with open("./src/pltf/internal/gl_func_decl.h", "r") as f: + header = f.readlines() + for h_line in header: + h_split = h_line.split(" ") + for token in h_split: + if token[0] == "g" and token[1] == "l": + token = token.removesuffix(");") + line = f"#define {token} pltf_{token}\n" + lines.append(line) + +lines.append(f"#endif // {hg_tag}\n") +# for line in lines: +# print(line) + +with open("./src/pltf/internal/gl_func_alias.h", "w") as f: + f.writelines(lines) diff --git a/meson.build b/meson.build index a763220..b29a916 100644 --- a/meson.build +++ b/meson.build @@ -28,14 +28,16 @@ test_include_dirs = [ if host_machine.system() == 'linux' pltf_src = [ - 'src/pltf/glx/gl_funcs.c' + 'src/pltf/glx/gl_funcs.c', + 'src/pltf/glx/internal.c', + 'src/pltf/glx/pltf.c', + 'src/pltf/glx/util.c', ] dependencies += [ dependency('x11'), dependency('glx'), dependency('libglvnd'), - dependency('opengl'), ] libcmocka = cc.find_library( diff --git a/src/main.c b/src/main.c index 37ca357..3ed0e98 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,3 @@ -#ifdef _WIN32 - #include #include #include @@ -9,26 +7,25 @@ #include "pltf/pltf.h" #include "shader.h" -typedef struct { - const char* up_msg; - const char* down_msg; - int up_count; - int down_count; -} MsgState; - -void msg_cb(const PltfKeyAction action, void* user_data) { - MsgState* state = (MsgState*) user_data; - switch (action) { - case PLTF_KEY_DOWN: - printf("Key: %s Count: %d\n", state->down_msg, state->down_count); - state->down_count++; +void key_cb(const PltfKey key, const PltfKeyAction action) { + switch (key) { + case PLTF_KEY_ESC: + pltf_window_destroy(); break; - case PLTF_KEY_UP: - printf("Key: %s Count: %d\n", state->up_msg, state->up_count); - state->up_count++; + case PLTF_KEY_Q: + { + switch (action) { + case PLTF_KEY_UP: + printf("Q up\n"); + break; + case PLTF_KEY_DOWN: + printf("Q down\n"); + break; + } break; + } default: - printf("INVALID PltfKeyAction. Was %d\n", action); + break; } } @@ -38,13 +35,9 @@ int main() { pltf_gl_ctx_create(); pltf_gl_funcs_load(); - pltf_gl_ctx_info_print(); + pltf_key_callback_set(key_cb); - pltf_key_callback_set(PLTF_KEY_ESC, pltf_window_close, NULL); - MsgState msg_state = { .up_msg = "UP", .down_msg = "DOWN", .up_count = 0, .down_count = 0 }; - pltf_key_callback_set(PLTF_KEY_Q, msg_cb, &msg_state); - - // clang-format off + // clang-format off const float triangle_verts[] = { // pos 0.0f, 0.5f, 0.0f, // top @@ -110,360 +103,3 @@ int main() { return 0; } -#endif // _WIN32 - -#ifdef __linux__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "DynString.h" -#include "log.h" - -void print_pixmap_format_values(const XPixmapFormatValues* px) { - puts("{"); - printf(" depth : %d\n", px->depth); - printf(" bits_per_pixel: %d\n", px->bits_per_pixel); - printf(" scanline_pad : %d\n", px->scanline_pad); - puts("}"); -} - -void print_visual_info(const XVisualInfo* vi) { - puts("{"); - printf(" visual : %p\n", vi->visual); - printf(" visualid : %lu\n", vi->visualid); - printf(" screen : %d\n", vi->screen); - printf(" depth : %u\n", vi->depth); - printf(" class : %d\n", vi->class); - printf(" red_mask : %lu\n", vi->red_mask); - printf(" green_mask : %lu\n", vi->green_mask); - printf(" blue_mask : %lu\n", vi->blue_mask); - printf(" colormap_size: %d\n", vi->colormap_size); - printf(" bits_per_rgb : %d\n", vi->bits_per_rgb); - puts("}"); -} - -void print_info(Display* display) { - const int screen_num = DefaultScreen(display); - Colormap color_map = DefaultColormap(display, screen_num); - int default_depth = DefaultDepth(display, screen_num); - int depths_count = 0; - int* depths = XListDepths(display, screen_num, &depths_count); - if (depths == NULL) { - LOG_FATAL("XListDepths failed"); - } - int cells = DisplayCells(display, screen_num); - int color_depth = DisplayPlanes(display, screen_num); - char* display_string = DisplayString(display); - int queue_length = QLength(display); - int screen_count = ScreenCount(display); - char* server_vendor = ServerVendor(display); - int vendor_release = VendorRelease(display); - - printf("DefaultScreen : %d\n", screen_num); - printf("DefaultColormap: %lu\n", color_map); - printf("DefaultDepth : %d\n", default_depth); - printf("XListDepths : "); - for (int i = 0; i < depths_count; i++) { - printf("%d ", depths[i]); - } - puts(""); - printf("DisplayCells : %d\n", cells); - printf("DisplayPlanes : %d\n", color_depth); - printf("DisplayString : %s\n", display_string); - printf("QLength : %d\n", queue_length); - printf("ScreenCount : %d\n", screen_count); - printf("ServerVendor : %s\n", server_vendor); - printf("VendorRelease : %d\n", vendor_release); - - XFree(depths); - - int d_supported_pixmap_formats_n = 0; - XPixmapFormatValues* d_supported_pixmap_formats = XListPixmapFormats(display, &d_supported_pixmap_formats_n); - if (d_supported_pixmap_formats == NULL) { - LOG_FATAL("XListPixmapFormats failed"); - } - int img_byte_order = ImageByteOrder(display); - int bitmap_unit = XBitmapUnit(display); - int bitmap_bit_order = BitmapBitOrder(display); - int bitmap_pad = BitmapPad(display); - int s_height_px = DisplayHeight(display, screen_num); - int s_height_mm = DisplayHeightMM(display, screen_num); - int s_width_px = DisplayWidth(display, screen_num); - int s_width_mm = DisplayWidthMM(display, screen_num); - - puts(""); - printf("XListPixmapFormats (%d):\n", d_supported_pixmap_formats_n); - for (int i = 0; i < d_supported_pixmap_formats_n; i++) { - print_pixmap_format_values(d_supported_pixmap_formats + i); - } - printf("ImageByteOrder : %s\n", img_byte_order == LSBFirst ? "LSBFirst" : "MSBFirst"); - printf("XBitmapUnit : %d\n", bitmap_unit); - printf("BitmapBitOrder : %s\n", bitmap_bit_order == LSBFirst ? "LSBFirst" : "MSBFirst"); - printf("BitmapPad : %d\n", bitmap_pad); - printf("DisplayHeight (DefaultScreen): %d\n", s_height_px); - printf("DisplayHeightMM (DefaultScreen): %d\n", s_height_mm); - printf("DisplayWidth (DefaultScreen): %d\n", s_width_px); - printf("DisplayWidthMM (DefaultScreen): %d\n", s_width_mm); - - XFree(d_supported_pixmap_formats); - - Screen* screen = ScreenOfDisplay(display, screen_num); - unsigned long s_black_pixel = BlackPixelOfScreen(screen); - unsigned long s_white_pixel = WhitePixelOfScreen(screen); - int s_cells = CellsOfScreen(screen); - int s_default_depth = DefaultDepthOfScreen(screen); - int does_backing_store = DoesBackingStore(screen); - bool does_save_unders = DoesSaveUnders(screen); - int s_max_colormaps = MaxCmapsOfScreen(screen); - int s_min_colormaps = MinCmapsOfScreen(screen); - int s_planes_n = PlanesOfScreen(screen); - - puts("\n(Default Screen)"); - printf("BlackPixelOfScreen : %lu\n", s_black_pixel); - printf("WhitePixelOfScreen : %lu\n", s_white_pixel); - printf("CellsOfScreen : %d\n", s_cells); - printf("DefaultDepthOfScreen: %d\n", s_default_depth); - printf("DoesBackingStore : %s\n", does_backing_store == WhenMapped ? "WhenMapped" : (does_backing_store == NotUseful ? "NotUseful" : "Always")); - printf("DoesSaveUnders : %s\n", does_save_unders ? "true" : "false"); - printf("MaxCmapsOfScreen : %d\n", s_max_colormaps); - printf("MinCmapsOfScreen : %d\n", s_min_colormaps); - printf("PlanesOfScreen : %d\n", s_planes_n); - puts(""); -} - -void glx_print_client_info(Display* display) { - const char* glx_client_vendor_str = glXGetClientString(display, GLX_VENDOR); - printf("Client GLX_VENDOR: %s\n", glx_client_vendor_str); - const char* glx_client_version_str = glXGetClientString(display, GLX_VERSION); - printf("Client GLX_VERSION: %s\n", glx_client_version_str); - const char* glx_client_extensions_str = glXGetClientString(display, GLX_EXTENSIONS); - printf("Client GLX_EXTENSIONS: %s\n", glx_client_extensions_str); -} - -void glx_print_server_info(Display* display) { - const char* glx_server_vendor_str = glXQueryServerString(display, DefaultScreen(display), GLX_VENDOR); - printf("Server GLX_VENDOR: %s\n", glx_server_vendor_str); - const char* glx_server_version_str = glXQueryServerString(display, DefaultScreen(display), GLX_VERSION); - printf("Server GLX_VERSION: %s\n", glx_server_version_str); - const char* glx_server_extensions_str = glXQueryServerString(display, DefaultScreen(display), GLX_EXTENSIONS); - printf("Server GLX_EXTENSIONS: %s\n", glx_server_extensions_str); -} - -void print_glxfbconfig(Display* display, const GLXFBConfig* cfg) { - int value = 0; - -#define PRINT_GLXFBCONFIG_VALUE(attrib) \ - value = 0; \ - if (glXGetFBConfigAttrib(display, *cfg, attrib, &value) != Success) { \ - LOG_FATALF("Invalid attrib %s", #attrib); \ - } \ - printf(" %s: %d\n", #attrib, value) - - puts("{"); - PRINT_GLXFBCONFIG_VALUE(GLX_FBCONFIG_ID); - PRINT_GLXFBCONFIG_VALUE(GLX_BUFFER_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_LEVEL); - PRINT_GLXFBCONFIG_VALUE(GLX_DOUBLEBUFFER); - PRINT_GLXFBCONFIG_VALUE(GLX_STEREO); - PRINT_GLXFBCONFIG_VALUE(GLX_AUX_BUFFERS); - PRINT_GLXFBCONFIG_VALUE(GLX_RED_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_GREEN_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_BLUE_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_ALPHA_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_DEPTH_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_STENCIL_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_RED_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_GREEN_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_BLUE_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_ALPHA_SIZE); - PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLE_BUFFERS); - PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLES); - PRINT_GLXFBCONFIG_VALUE(GLX_RENDER_TYPE); - PRINT_GLXFBCONFIG_VALUE(GLX_DRAWABLE_TYPE); - PRINT_GLXFBCONFIG_VALUE(GLX_X_RENDERABLE); - PRINT_GLXFBCONFIG_VALUE(GLX_X_VISUAL_TYPE); - PRINT_GLXFBCONFIG_VALUE(GLX_CONFIG_CAVEAT); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_TYPE); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_INDEX_VALUE); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_RED_VALUE); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_GREEN_VALUE); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_BLUE_VALUE); - PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_ALPHA_VALUE); - PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_WIDTH); - PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_HEIGHT); - PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_PIXELS); - PRINT_GLXFBCONFIG_VALUE(GLX_VISUAL_ID); - puts("}"); - -#undef PRINT_GLXFBCONFIG_VALUE -} - -int main() { - Display* display = XOpenDisplay(NULL); - if (display == NULL) { - LOG_FATAL("XOpenDisplay failed."); - } - - int err_base = 0; - int event_base = 0; - if (!glXQueryExtension(display, &err_base, &event_base)) { - LOG_FATALF( - "GLX extension not supported. err_base: %d, event_base: %d", - err_base, - event_base - ); - } - - int glx_major = 0; - int glx_minor = 0; - if (glXQueryVersion(display, &glx_major, &glx_minor)) { - printf("GLX Version %d.%d\n", glx_major, glx_minor); - if (glx_minor < 1) { - LOG_FATAL("GLX Version must be at least 1.1"); - } - } else { - LOG_ERROR("glXQueryVersion failed"); - } - - const char* glx_extensions_c_str = glXQueryExtensionsString(display, DefaultScreen(display)); - printf("glx_extensions_c_str: %s\n", glx_extensions_c_str); - DynString glx_extensions_str = DynString_alloc(glx_extensions_c_str, strlen(glx_extensions_c_str)); - size_t glx_ext_n = 0; - DynString* glx_extensions = DynString_split(&glx_extensions_str, " ", &glx_ext_n); - - printf("GLX extensions:\n"); - for (size_t i = 0; i < glx_ext_n; i++) { - printf(" %s\n", DynString_c_str(glx_extensions + i)); - } - - // clang-format off - int fb_cfg_attrib_list[] = { - GLX_BUFFER_SIZE, 32, - GLX_DOUBLEBUFFER, true, - GLX_DEPTH_SIZE, 24, - GLX_STENCIL_SIZE, 8, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - None - }; - // clang-format on - int fb_cfg_n = 0; - GLXFBConfig* fb_cfg = glXChooseFBConfig(display, DefaultScreen(display), fb_cfg_attrib_list, &fb_cfg_n); - if (fb_cfg == NULL) { - LOG_FATAL("Invalid input to glXChooseFBConfig"); - } - if (fb_cfg_n == 0) { - LOG_FATAL("Could not get a fitting GLXFBConfig"); - } - printf("GLXFBConfig: "); - print_glxfbconfig(display, fb_cfg); - - XVisualInfo* visual_info = glXGetVisualFromFBConfig(display, *fb_cfg); - - XSetWindowAttributes win_attr = { - .colormap = XCreateColormap( - display, - RootWindowOfScreen(DefaultScreenOfDisplay(display)), - visual_info->visual, - AllocNone - ) - }; - - // clang-format off - Window window = XCreateWindow( - display, - RootWindowOfScreen(DefaultScreenOfDisplay(display)), - 0, 0, - 800, 600, - 0, - visual_info->depth, - InputOutput, - visual_info->visual, - CWColormap, - &win_attr - ); - // clang-format on - - GLXWindow glx_window = glXCreateWindow( - display, - *fb_cfg, - window, - NULL - ); - - XStoreName(display, window, "GLX"); - - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); - - // clang-format off - GLXContext gl_ctx = glXCreateContextAttribsARB( - display, - *fb_cfg, - NULL, - true, - (int[]) { - GLX_CONTEXT_MAJOR_VERSION_ARB, 4, - GLX_CONTEXT_MINOR_VERSION_ARB, 6, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - None - } - ); - // clang-format on - - glXMakeCurrent( - display, - window, - gl_ctx - ); - - glXWaitX(); - XSync(display, false); - - XMapWindow(display, window); - - printf("OpenGL %s\n", glGetString(GL_VERSION)); - - PFNGLGETINTEGERVPROC glGetIntegerv = (PFNGLGETINTEGERVPROC) glXGetProcAddress((const GLubyte*) "glGetIntegerv"); - PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) glXGetProcAddress((const GLubyte*) "glClear"); - PFNGLCLEARCOLORPROC glClearColor = (PFNGLCLEARCOLORPROC) glXGetProcAddress((const GLubyte*) "glClearColor"); - - int gl_major = 0; - int gl_minor = 0; - int gl_ctx_profile_mask = 0; - glGetIntegerv(GL_MAJOR_VERSION, &gl_major); - glGetIntegerv(GL_MINOR_VERSION, &gl_minor); - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &gl_ctx_profile_mask); - printf( - "OpenGL %d.%d %s\n", - gl_major, - gl_minor, - gl_ctx_profile_mask == GL_CONTEXT_CORE_PROFILE_BIT - ? "Core" - : "Compatibility" - ); - - glClearColor(0.0, 0.0, 0.8, 1.0); - - while (1) { - glClear(GL_COLOR_BUFFER_BIT); - glXSwapBuffers(display, window); - } - - XFree(visual_info); - - XCloseDisplay(display); - - return 0; -} - -#endif // __linux__ diff --git a/src/pltf/gl_funcs.h b/src/pltf/gl_funcs.h index be68803..3431d1e 100644 --- a/src/pltf/gl_funcs.h +++ b/src/pltf/gl_funcs.h @@ -1,46 +1,7 @@ -#ifndef GL_FUNCS_H_ -#define GL_FUNCS_H_ +#ifndef PLTF_GL_FUNCS_H_ +#define PLTF_GL_FUNCS_H_ -#include +#include "internal/gl_func_decl.h" // IWYU pragma: export +#include "internal/gl_func_alias.h" // IWYU pragma: export -#define PLTF_GL_FUNCS(X) \ -X(PFNGLSHADERSOURCEPROC, glShaderSource); \ -X(PFNGLCREATESHADERPROC, glCreateShader); \ -X(PFNGLCOMPILESHADERPROC, glCompileShader); \ -X(PFNGLGETSHADERIVPROC, glGetShaderiv); \ -X(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \ -X(PFNGLCREATEPROGRAMPROC, glCreateProgram); \ -X(PFNGLATTACHSHADERPROC, glAttachShader); \ -X(PFNGLLINKPROGRAMPROC, glLinkProgram); \ -X(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \ -X(PFNGLDELETESHADERPROC, glDeleteShader); \ -X(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \ -X(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \ -X(PFNGLGENBUFFERSPROC, glGenBuffers); \ -X(PFNGLBINDBUFFERPROC, glBindBuffer); \ -X(PFNGLBUFFERDATAPROC, glBufferData); \ -X(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ -X(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \ -X(PFNGLCLEARCOLORPROC, glClearColor); \ -X(PFNGLCLEARPROC, glClear); \ -X(PFNGLUSEPROGRAMPROC, glUseProgram); \ -X(PFNGLDRAWARRAYSPROC, glDrawArrays); \ -X(PFNGLGETINTEGERVPROC, glGetIntegerv); \ -X(PFNGLGETFLOATVPROC, glGetFloatv); \ -X(PFNGLGETERRORPROC, glGetError); \ - -#define X(type, name) \ -extern type name; - -PLTF_GL_FUNCS(X) -#undef X - -#ifdef __linux__ - void* pltf_gl_function_load(const unsigned char* name); -#else - void* pltf_gl_function_load(const char* name); -#endif // __linux__ - -void pltf_gl_funcs_load(); - -#endif // GL_FUNCS_H_ +#endif // PLTF_GL_FUNCS_H_ diff --git a/src/pltf/glx/gl_funcs.c b/src/pltf/glx/gl_funcs.c index 7af03f8..c3bede7 100644 --- a/src/pltf/glx/gl_funcs.c +++ b/src/pltf/glx/gl_funcs.c @@ -2,22 +2,27 @@ #include #include +#include #include "../gl_funcs.h" #define X(type, name) \ -type name = NULL +type pltf_##name = NULL PLTF_GL_FUNCS(X) #undef X -// #define X(type, name) \ -// name = (type) pltf_gl_function_load((const GLubyte*) #name); +#define X(type, name) \ +pltf_##name = (type) pltf_gl_function_load(#name); -// void pltf_gl_funcs_load() { - // PLTF_GL_FUNCS(X) -// } +void* pltf_gl_function_load(const char* name) { + return glXGetProcAddress((const GLubyte*) name); +} -// #undef X +void pltf_gl_funcs_load() { + PLTF_GL_FUNCS(X) +} + +#undef X #endif // __linux__ diff --git a/src/pltf/glx/internal.c b/src/pltf/glx/internal.c new file mode 100644 index 0000000..f4555d0 --- /dev/null +++ b/src/pltf/glx/internal.c @@ -0,0 +1,16 @@ +#ifdef __linux__ + +#include "./internal.h" + +PltfStateGlx pltf_state = {}; + +bool has_glx_extension(const char *name) { + for (size_t i = 0; i < pltf_state.glx_extensions.len; i++) { + if (DynString_equal_c_str(DynArray_DynString_at(&pltf_state.glx_extensions, i), name)) { + return true; + } + } + return false; +} + +#endif // __linux__ diff --git a/src/pltf/glx/internal.h b/src/pltf/glx/internal.h new file mode 100644 index 0000000..307bd73 --- /dev/null +++ b/src/pltf/glx/internal.h @@ -0,0 +1,28 @@ +#ifdef __linux__ + +#ifndef PLTF_GLX_INTERNAL_H_ +#define PLTF_GLX_INTERNAL_H_ + +#include +#include + +#include "../pltf.h" +#include "DynArray.h" + +typedef struct { + Display* display; + Window window; + GLXWindow glx_window; + GLXFBConfig* fb_cfg; + GLXContext gl_ctx; + DynArray_DynString glx_extensions; + PltfKeyCallback key_cb; +} PltfStateGlx; + +extern PltfStateGlx pltf_state; + +bool has_glx_extension(const char* name); + +#endif // PLTF_GLX_INTERNAL_H_ + +#endif // __linux__ diff --git a/src/pltf/glx/pltf.c b/src/pltf/glx/pltf.c new file mode 100644 index 0000000..67d2abc --- /dev/null +++ b/src/pltf/glx/pltf.c @@ -0,0 +1,204 @@ +#include +#ifdef __linux__ + +#include + +#include +#include +#include + +#include "../pltf.h" +#include "./internal.h" +#include "DynArray.h" +#include "DynString.h" +#include "log.h" + +static PltfKey keysym_to_pltf_key(const KeySym sym) { + switch (sym) { + case XK_Escape: + return PLTF_KEY_ESC; + case XK_Q: + case XK_q: + return PLTF_KEY_Q; + } + + return PLTF_KEY_NONE; +} + +void pltf_init() { + pltf_state.display = XOpenDisplay(NULL); + if (pltf_state.display == NULL) { + LOG_FATAL("XOpenDisplay failed."); + } + + if (!DynArray_DynString_alloc(&pltf_state.glx_extensions)) { + LOG_FATAL("Failed to allocate pltf_state.glx_extensions"); + } + const char* glx_extensions_c_str = glXQueryExtensionsString(pltf_state.display, DefaultScreen(pltf_state.display)); + // Copying the extension string to prevent modifying the original. Might be pointless, doing this just in case. + DynString glx_extensions_str = DynString_alloc(glx_extensions_c_str, strlen(glx_extensions_c_str)); + size_t glx_ext_n = 0; + DynString* glx_extensions = DynString_split(&glx_extensions_str, " ", &glx_ext_n); + for (size_t i = 0; i < glx_ext_n; i++) { + DynArray_DynString_push_back(&pltf_state.glx_extensions, glx_extensions + i); + } + DynString_free(&glx_extensions_str); +} + +void pltf_deinit() { + XCloseDisplay(pltf_state.display); +} + +void pltf_window_create() { + // clang-format off + int fb_cfg_attrib_list[] = { + GLX_BUFFER_SIZE, 32, + GLX_DOUBLEBUFFER, true, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + None + }; + // clang-format on + int fb_cfg_n = 0; + pltf_state.fb_cfg = glXChooseFBConfig(pltf_state.display, DefaultScreen(pltf_state.display), fb_cfg_attrib_list, &fb_cfg_n); + if (pltf_state.fb_cfg == NULL) { + LOG_FATAL("Invalid input to glXChooseFBConfig"); + } + if (fb_cfg_n == 0) { + LOG_FATAL("Could not get a fitting GLXFBConfig"); + } + + XVisualInfo* visual_info = glXGetVisualFromFBConfig(pltf_state.display, *pltf_state.fb_cfg); + + XSetWindowAttributes win_attr = { + .colormap = XCreateColormap( + pltf_state.display, + RootWindowOfScreen(DefaultScreenOfDisplay(pltf_state.display)), + visual_info->visual, + AllocNone + ), + .event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask + }; + + // clang-format off + pltf_state.window = XCreateWindow( + pltf_state.display, + RootWindowOfScreen(DefaultScreenOfDisplay(pltf_state.display)), + 0, 0, + PLTF_DEFAULT_WINDOW_WIDTH, PLTF_DEFAULT_WINDOW_HEIGHT, + 0, + visual_info->depth, + InputOutput, + visual_info->visual, + CWColormap | + CWEventMask, + &win_attr + ); + // clang-format on + + XFree(visual_info); + visual_info = NULL; + + pltf_state.glx_window = glXCreateWindow( + pltf_state.display, + *pltf_state.fb_cfg, + pltf_state.window, + NULL + ); + + XStoreName(pltf_state.display, pltf_state.window, "GLX"); + + XMapWindow(pltf_state.display, pltf_state.window); + + XFlush(pltf_state.display); +} + +void pltf_window_destroy() { + XEvent ev = { + .type = DestroyNotify + }; + XSendEvent( + pltf_state.display, + pltf_state.window, + false, + StructureNotifyMask, + &ev + ); +} + +void pltf_gl_ctx_create() { + if (!has_glx_extension("GLX_ARB_create_context")) { + LOG_FATAL("GLX extension GLX_ARB_create_context is required"); + } + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); + + // clang-format off + pltf_state.gl_ctx = glXCreateContextAttribsARB( + pltf_state.display, + *pltf_state.fb_cfg, + NULL, + true, + (int[]) { + GLX_CONTEXT_MAJOR_VERSION_ARB, 4, + GLX_CONTEXT_MINOR_VERSION_ARB, 6, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + } + ); + // clang-format on + + glXMakeCurrent( + pltf_state.display, + pltf_state.window, + pltf_state.gl_ctx + ); +} + +void pltf_gl_ctx_destroy() { + glXDestroyContext(pltf_state.display, pltf_state.gl_ctx); + XFlush(pltf_state.display); +} + +void pltf_swap_buffers() { + glXSwapBuffers(pltf_state.display, pltf_state.window); +} + +static int x_check_if_event_predicate(Display* d, XEvent* e, XPointer p) { + return true; +} + +PltfWindowEvent pltf_window_event_handle() { + PltfWindowEvent ret_ev = PLTF_WE_NONE; + XEvent ev = { }; + if (XCheckIfEvent(pltf_state.display, &ev, x_check_if_event_predicate, NULL)) { + switch (ev.type) { + case DestroyNotify: + ret_ev = PLTF_WE_DESTROY; + break; + + case KeyRelease: + { + KeySym sym = XLookupKeysym(&ev.xkey, 0); + pltf_state.key_cb(keysym_to_pltf_key(sym), PLTF_KEY_UP); + break; + } + + case KeyPress: + { + KeySym sym = XLookupKeysym(&ev.xkey, 0); + pltf_state.key_cb(keysym_to_pltf_key(sym), PLTF_KEY_DOWN); + break; + } + } + } + + return ret_ev; +} + +void pltf_key_callback_set(const PltfKeyCallback cb) { + pltf_state.key_cb = cb; +} + +#endif // __linux__ diff --git a/src/pltf/glx/util.c b/src/pltf/glx/util.c new file mode 100644 index 0000000..8eabe60 --- /dev/null +++ b/src/pltf/glx/util.c @@ -0,0 +1,190 @@ +#ifdef __linux__ + +#include +#include + +#include +#include + +#include "log.h" + +void pltf_glx_print_pixmap_format_values(const XPixmapFormatValues* px) { + puts("{"); + printf(" depth : %d\n", px->depth); + printf(" bits_per_pixel: %d\n", px->bits_per_pixel); + printf(" scanline_pad : %d\n", px->scanline_pad); + puts("}"); +} + +void pltf_glx_print_visual_info(const XVisualInfo* vi) { + puts("{"); + printf(" visual : %p\n", vi->visual); + printf(" visualid : %lu\n", vi->visualid); + printf(" screen : %d\n", vi->screen); + printf(" depth : %u\n", vi->depth); + printf(" class : %d\n", vi->class); + printf(" red_mask : %lu\n", vi->red_mask); + printf(" green_mask : %lu\n", vi->green_mask); + printf(" blue_mask : %lu\n", vi->blue_mask); + printf(" colormap_size: %d\n", vi->colormap_size); + printf(" bits_per_rgb : %d\n", vi->bits_per_rgb); + puts("}"); +} + +void pltf_glx_print_info(Display* display) { + const int screen_num = DefaultScreen(display); + Colormap color_map = DefaultColormap(display, screen_num); + int default_depth = DefaultDepth(display, screen_num); + int depths_count = 0; + int* depths = XListDepths(display, screen_num, &depths_count); + if (depths == NULL) { + LOG_FATAL("XListDepths failed"); + } + int cells = DisplayCells(display, screen_num); + int color_depth = DisplayPlanes(display, screen_num); + char* display_string = DisplayString(display); + int queue_length = QLength(display); + int screen_count = ScreenCount(display); + char* server_vendor = ServerVendor(display); + int vendor_release = VendorRelease(display); + + printf("DefaultScreen : %d\n", screen_num); + printf("DefaultColormap: %lu\n", color_map); + printf("DefaultDepth : %d\n", default_depth); + printf("XListDepths : "); + for (int i = 0; i < depths_count; i++) { + printf("%d ", depths[i]); + } + puts(""); + printf("DisplayCells : %d\n", cells); + printf("DisplayPlanes : %d\n", color_depth); + printf("DisplayString : %s\n", display_string); + printf("QLength : %d\n", queue_length); + printf("ScreenCount : %d\n", screen_count); + printf("ServerVendor : %s\n", server_vendor); + printf("VendorRelease : %d\n", vendor_release); + + XFree(depths); + + int d_supported_pixmap_formats_n = 0; + XPixmapFormatValues* d_supported_pixmap_formats = XListPixmapFormats(display, &d_supported_pixmap_formats_n); + if (d_supported_pixmap_formats == NULL) { + LOG_FATAL("XListPixmapFormats failed"); + } + int img_byte_order = ImageByteOrder(display); + int bitmap_unit = XBitmapUnit(display); + int bitmap_bit_order = BitmapBitOrder(display); + int bitmap_pad = BitmapPad(display); + int s_height_px = DisplayHeight(display, screen_num); + int s_height_mm = DisplayHeightMM(display, screen_num); + int s_width_px = DisplayWidth(display, screen_num); + int s_width_mm = DisplayWidthMM(display, screen_num); + + puts(""); + printf("XListPixmapFormats (%d):\n", d_supported_pixmap_formats_n); + for (int i = 0; i < d_supported_pixmap_formats_n; i++) { + pltf_glx_print_pixmap_format_values(d_supported_pixmap_formats + i); + } + printf("ImageByteOrder : %s\n", img_byte_order == LSBFirst ? "LSBFirst" : "MSBFirst"); + printf("XBitmapUnit : %d\n", bitmap_unit); + printf("BitmapBitOrder : %s\n", bitmap_bit_order == LSBFirst ? "LSBFirst" : "MSBFirst"); + printf("BitmapPad : %d\n", bitmap_pad); + printf("DisplayHeight (DefaultScreen): %d\n", s_height_px); + printf("DisplayHeightMM (DefaultScreen): %d\n", s_height_mm); + printf("DisplayWidth (DefaultScreen): %d\n", s_width_px); + printf("DisplayWidthMM (DefaultScreen): %d\n", s_width_mm); + + XFree(d_supported_pixmap_formats); + + Screen* screen = ScreenOfDisplay(display, screen_num); + unsigned long s_black_pixel = BlackPixelOfScreen(screen); + unsigned long s_white_pixel = WhitePixelOfScreen(screen); + int s_cells = CellsOfScreen(screen); + int s_default_depth = DefaultDepthOfScreen(screen); + int does_backing_store = DoesBackingStore(screen); + bool does_save_unders = DoesSaveUnders(screen); + int s_max_colormaps = MaxCmapsOfScreen(screen); + int s_min_colormaps = MinCmapsOfScreen(screen); + int s_planes_n = PlanesOfScreen(screen); + + puts("\n(Default Screen)"); + printf("BlackPixelOfScreen : %lu\n", s_black_pixel); + printf("WhitePixelOfScreen : %lu\n", s_white_pixel); + printf("CellsOfScreen : %d\n", s_cells); + printf("DefaultDepthOfScreen: %d\n", s_default_depth); + printf("DoesBackingStore : %s\n", does_backing_store == WhenMapped ? "WhenMapped" : (does_backing_store == NotUseful ? "NotUseful" : "Always")); + printf("DoesSaveUnders : %s\n", does_save_unders ? "true" : "false"); + printf("MaxCmapsOfScreen : %d\n", s_max_colormaps); + printf("MinCmapsOfScreen : %d\n", s_min_colormaps); + printf("PlanesOfScreen : %d\n", s_planes_n); + puts(""); +} + +void pltf_glx_print_client_info(Display* display) { + const char* glx_client_vendor_str = glXGetClientString(display, GLX_VENDOR); + printf("Client GLX_VENDOR: %s\n", glx_client_vendor_str); + const char* glx_client_version_str = glXGetClientString(display, GLX_VERSION); + printf("Client GLX_VERSION: %s\n", glx_client_version_str); + const char* glx_client_extensions_str = glXGetClientString(display, GLX_EXTENSIONS); + printf("Client GLX_EXTENSIONS: %s\n", glx_client_extensions_str); +} + +void pltf_glx_print_server_info(Display* display) { + const char* glx_server_vendor_str = glXQueryServerString(display, DefaultScreen(display), GLX_VENDOR); + printf("Server GLX_VENDOR: %s\n", glx_server_vendor_str); + const char* glx_server_version_str = glXQueryServerString(display, DefaultScreen(display), GLX_VERSION); + printf("Server GLX_VERSION: %s\n", glx_server_version_str); + const char* glx_server_extensions_str = glXQueryServerString(display, DefaultScreen(display), GLX_EXTENSIONS); + printf("Server GLX_EXTENSIONS: %s\n", glx_server_extensions_str); +} + +void pltf_glx_print_fbconfig(Display* display, const GLXFBConfig* cfg) { + int value = 0; + +#define PRINT_GLXFBCONFIG_VALUE(attrib) \ + value = 0; \ + if (glXGetFBConfigAttrib(display, *cfg, attrib, &value) != Success) { \ + LOG_FATALF("Invalid attrib %s", #attrib); \ + } \ + printf(" %s: %d\n", #attrib, value) + + puts("{"); + PRINT_GLXFBCONFIG_VALUE(GLX_FBCONFIG_ID); + PRINT_GLXFBCONFIG_VALUE(GLX_BUFFER_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_LEVEL); + PRINT_GLXFBCONFIG_VALUE(GLX_DOUBLEBUFFER); + PRINT_GLXFBCONFIG_VALUE(GLX_STEREO); + PRINT_GLXFBCONFIG_VALUE(GLX_AUX_BUFFERS); + PRINT_GLXFBCONFIG_VALUE(GLX_RED_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_GREEN_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_BLUE_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_ALPHA_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_DEPTH_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_STENCIL_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_RED_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_GREEN_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_BLUE_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_ACCUM_ALPHA_SIZE); + PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLE_BUFFERS); + PRINT_GLXFBCONFIG_VALUE(GLX_SAMPLES); + PRINT_GLXFBCONFIG_VALUE(GLX_RENDER_TYPE); + PRINT_GLXFBCONFIG_VALUE(GLX_DRAWABLE_TYPE); + PRINT_GLXFBCONFIG_VALUE(GLX_X_RENDERABLE); + PRINT_GLXFBCONFIG_VALUE(GLX_X_VISUAL_TYPE); + PRINT_GLXFBCONFIG_VALUE(GLX_CONFIG_CAVEAT); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_TYPE); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_INDEX_VALUE); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_RED_VALUE); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_GREEN_VALUE); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_BLUE_VALUE); + PRINT_GLXFBCONFIG_VALUE(GLX_TRANSPARENT_ALPHA_VALUE); + PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_WIDTH); + PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_HEIGHT); + PRINT_GLXFBCONFIG_VALUE(GLX_MAX_PBUFFER_PIXELS); + PRINT_GLXFBCONFIG_VALUE(GLX_VISUAL_ID); + puts("}"); + +#undef PRINT_GLXFBCONFIG_VALUE +} + +#endif // __linux__ diff --git a/src/pltf/internal/gl_func_alias.h b/src/pltf/internal/gl_func_alias.h new file mode 100644 index 0000000..1cd9739 --- /dev/null +++ b/src/pltf/internal/gl_func_alias.h @@ -0,0 +1,27 @@ +#ifndef PLTF_GL_FUNC_ALIAS_H_ +#define PLTF_GL_FUNC_ALIAS_H_ +#define glShaderSource pltf_glShaderSource +#define glCreateShader pltf_glCreateShader +#define glCompileShader pltf_glCompileShader +#define glGetShaderiv pltf_glGetShaderiv +#define glGetShaderInfoLog pltf_glGetShaderInfoLog +#define glCreateProgram pltf_glCreateProgram +#define glAttachShader pltf_glAttachShader +#define glLinkProgram pltf_glLinkProgram +#define glGetProgramiv pltf_glGetProgramiv +#define glDeleteShader pltf_glDeleteShader +#define glGenVertexArrays pltf_glGenVertexArrays +#define glBindVertexArray pltf_glBindVertexArray +#define glGenBuffers pltf_glGenBuffers +#define glBindBuffer pltf_glBindBuffer +#define glBufferData pltf_glBufferData +#define glEnableVertexAttribArray pltf_glEnableVertexAttribArray +#define glVertexAttribPointer pltf_glVertexAttribPointer +#define glClearColor pltf_glClearColor +#define glClear pltf_glClear +#define glUseProgram pltf_glUseProgram +#define glDrawArrays pltf_glDrawArrays +#define glGetIntegerv pltf_glGetIntegerv +#define glGetFloatv pltf_glGetFloatv +#define glGetError pltf_glGetError +#endif // PLTF_GL_FUNC_ALIAS_H_ diff --git a/src/pltf/internal/gl_func_decl.h b/src/pltf/internal/gl_func_decl.h new file mode 100644 index 0000000..ca2759a --- /dev/null +++ b/src/pltf/internal/gl_func_decl.h @@ -0,0 +1,38 @@ +#ifndef PLTF_GL_FUNC_DECL_H_ +#define PLTF_GL_FUNC_DECL_H_ + +#include + +#define PLTF_GL_FUNCS(X) \ +X(PFNGLSHADERSOURCEPROC, glShaderSource); \ +X(PFNGLCREATESHADERPROC, glCreateShader); \ +X(PFNGLCOMPILESHADERPROC, glCompileShader); \ +X(PFNGLGETSHADERIVPROC, glGetShaderiv); \ +X(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \ +X(PFNGLCREATEPROGRAMPROC, glCreateProgram); \ +X(PFNGLATTACHSHADERPROC, glAttachShader); \ +X(PFNGLLINKPROGRAMPROC, glLinkProgram); \ +X(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \ +X(PFNGLDELETESHADERPROC, glDeleteShader); \ +X(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \ +X(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \ +X(PFNGLGENBUFFERSPROC, glGenBuffers); \ +X(PFNGLBINDBUFFERPROC, glBindBuffer); \ +X(PFNGLBUFFERDATAPROC, glBufferData); \ +X(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ +X(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \ +X(PFNGLCLEARCOLORPROC, glClearColor); \ +X(PFNGLCLEARPROC, glClear); \ +X(PFNGLUSEPROGRAMPROC, glUseProgram); \ +X(PFNGLDRAWARRAYSPROC, glDrawArrays); \ +X(PFNGLGETINTEGERVPROC, glGetIntegerv); \ +X(PFNGLGETFLOATVPROC, glGetFloatv); \ +X(PFNGLGETERRORPROC, glGetError); \ + +#define X(type, name) \ +extern type pltf_##name; + +PLTF_GL_FUNCS(X) +#undef X + +#endif // PLTF_GL_FUNC_DECL_H_ diff --git a/src/pltf/pltf.h b/src/pltf/pltf.h index d0682ed..bd8b0c4 100644 --- a/src/pltf/pltf.h +++ b/src/pltf/pltf.h @@ -31,22 +31,21 @@ typedef enum { PLTF_KEY_DOWN } PltfKeyAction; -typedef void (*PltfKeyCallback)(const PltfKeyAction action, void* user_data); +typedef void (*PltfKeyCallback)(const PltfKey key, const PltfKeyAction action); void pltf_init(); void pltf_deinit(); void pltf_window_create(); -void pltf_window_close(); 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(); void pltf_key_callback_set( - const PltfKey key, - const PltfKeyCallback cb, - void* user_data + const PltfKeyCallback cb ); +void* pltf_gl_function_load(const char* name); +void pltf_gl_funcs_load(); + #endif // PLTF_H_ diff --git a/src/pltf/win32/gl_funcs.c b/src/pltf/win32/gl_funcs.c index 0154845..0bb12cf 100644 --- a/src/pltf/win32/gl_funcs.c +++ b/src/pltf/win32/gl_funcs.c @@ -5,13 +5,13 @@ #include "internal.h" #define X(type, name) \ -type name = NULL +type pltf_##name = NULL PLTF_GL_FUNCS(X) #undef X #define X(type, name) \ -name = (type) pltf_gl_function_load(#name) +pltf_##name = (type) pltf_gl_function_load(#name) void* pltf_gl_function_load(const char* name) { void* gl_func = (void*) wglGetProcAddress(name); diff --git a/src/pltf/win32/internal.c b/src/pltf/win32/internal.c index c45c25c..71df3be 100644 --- a/src/pltf/win32/internal.c +++ b/src/pltf/win32/internal.c @@ -7,11 +7,7 @@ HMODULE opengl_module = NULL; -#define PLTF_KEYS_X(lower, upper) \ - .key_##lower##_cb = NULL, \ - .key_##lower##_cb_user_data = NULL, - -PltfWin32State pltf_state = { +PltfStateWin32 pltf_state = { .wc_name = L"Scuffedcraft Window Class", .exe_module = NULL, .hwnd = NULL, @@ -19,12 +15,9 @@ PltfWin32State pltf_state = { .wgl_extensions = { 0 }, .window_state = (WinState) { .gl_ctx = NULL }, - - PLTF_KEYS(PLTF_KEYS_X) + .key_cb = NULL }; -#undef PLTF_KEYS_X - bool pltf_has_wgl_extension(const char* name) { for (size_t i = 0; i < pltf_state.wgl_extensions.len; i++) { if (DynString_equal_c_str(DynArray_DynString_at(&pltf_state.wgl_extensions, i), name)) { diff --git a/src/pltf/win32/internal.h b/src/pltf/win32/internal.h index 78c26bf..cf40afe 100644 --- a/src/pltf/win32/internal.h +++ b/src/pltf/win32/internal.h @@ -12,10 +12,6 @@ typedef struct { HGLRC gl_ctx; } WinState; -#define PLTF_KEYS_X(lower, upper) \ - PltfKeyCallback key_##lower##_cb; \ - void* key_##lower##_cb_user_data; - typedef struct { const wchar_t* wc_name; HMODULE exe_module; @@ -23,13 +19,10 @@ typedef struct { HDC hdc; DynArray_DynString wgl_extensions; WinState window_state; + PltfKeyCallback key_cb; +} PltfStateWin32; - PLTF_KEYS(PLTF_KEYS_X); -} PltfWin32State; - -#undef PLTF_KEYS_X - -extern PltfWin32State pltf_state; +extern PltfStateWin32 pltf_state; extern HMODULE opengl_module; bool pltf_has_wgl_extension(const char* name); diff --git a/src/pltf/win32/pltf.c b/src/pltf/win32/pltf.c index cdcedc6..ac0900a 100644 --- a/src/pltf/win32/pltf.c +++ b/src/pltf/win32/pltf.c @@ -9,7 +9,6 @@ #include #include -#include "../gl_funcs.h" #include "../pltf.h" #include "DynArray.h" #include "DynString.h" @@ -85,14 +84,9 @@ void pltf_window_create() { 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; + PostMessage(pltf_state.hwnd, WM_DESTROY, 0, 0); } } @@ -233,36 +227,6 @@ void pltf_gl_ctx_destroy() { 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); } @@ -281,27 +245,10 @@ PltfWindowEvent pltf_window_event_handle() { 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 + const PltfKeyCallback cb ) { - - switch (key) { - case PLTF_KEY_NONE: - break; - - PLTF_KEYS(PLTF_KEYS_X); - } + pltf_state.key_cb = cb; } -#undef PLTF_KEYS_X - #endif // _WIN32 diff --git a/src/pltf/win32/win_proc.c b/src/pltf/win32/win_proc.c index 5d16f58..365f673 100644 --- a/src/pltf/win32/win_proc.c +++ b/src/pltf/win32/win_proc.c @@ -8,18 +8,15 @@ #define PLTF_KEYS_X(lower, upper) \ case PLTF_KEY_##upper: \ if (pltf_state.key_##lower##_cb != NULL) { \ - pltf_state.key_##lower##_cb(action, pltf_state.key_##lower##_cb_user_data); \ + pltf_state.key_##lower##_cb(action); \ } \ break; static void handle_key(const WPARAM key, const PltfKeyAction action) { const PltfKey pltf_key = vk_to_pltf_key(key); - switch (pltf_key) { - case PLTF_KEY_NONE: - break; - - PLTF_KEYS(PLTF_KEYS_X); + if (pltf_state.key_cb != NULL) { + pltf_state.key_cb(pltf_key, action); } } @@ -63,9 +60,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; case WM_CLOSE: - if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { - PostMessage(hwnd, WM_DESTROY, 0, 0); - } + // if (MessageBox(hwnd, L"Really quit?", L"My Application", MB_OKCANCEL) == IDOK) { + // } + PostMessage(hwnd, WM_DESTROY, 0, 0); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam);