From 69b09a7d7a394fec1186aee64545285a22328c77 Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Thu, 6 Aug 2026 21:48:37 +0300 Subject: [PATCH] Blue screen --- meson.build | 5 +- src/main.c | 177 ++++++++++++++++++++++++++------------ src/pltf/gl_funcs.h | 42 +++++---- src/pltf/glx/gl_funcs.c | 23 +++++ src/pltf/linux/gl_funcs.c | 13 --- 5 files changed, 174 insertions(+), 86 deletions(-) create mode 100644 src/pltf/glx/gl_funcs.c delete mode 100644 src/pltf/linux/gl_funcs.c diff --git a/meson.build b/meson.build index b4cffb7..4a9b66d 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ pltf_src = [] cargs = [ '-std=c99', '-DSHADERS_PATH="../src/shaders/"', - # '-DDEBUG=1' + '-DDEBUG' ] dependencies = [ @@ -28,13 +28,14 @@ test_include_dirs = [ if host_machine.system() == 'linux' pltf_src = [ - 'src/pltf/linux/gl_funcs.c' + 'src/pltf/glx/gl_funcs.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 5870ef8..37ca357 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ -#include #ifdef _WIN32 #include @@ -115,17 +114,20 @@ int main() { #ifdef __linux__ +#include #include +#include +#include #include #include #include #include -#include -#include #include +#include +#include -#include "log.h" #include "DynString.h" +#include "log.h" void print_pixmap_format_values(const XPixmapFormatValues* px) { puts("{"); @@ -260,11 +262,11 @@ void glx_print_server_info(Display* display) { void print_glxfbconfig(Display* display, const GLXFBConfig* cfg) { int value = 0; -#define PRINT_GLXFBCONFIG_VALUE(attrib) \ - value = 0; \ +#define PRINT_GLXFBCONFIG_VALUE(attrib) \ + value = 0; \ if (glXGetFBConfigAttrib(display, *cfg, attrib, &value) != Success) { \ - LOG_FATALF("Invalid attrib %s", #attrib); \ - } \ + LOG_FATALF("Invalid attrib %s", #attrib); \ + } \ printf(" %s: %d\n", #attrib, value) puts("{"); @@ -344,51 +346,120 @@ int main() { printf(" %s\n", DynString_c_str(glx_extensions + i)); } - // XVisualInfo visual_info = { 0 }; - // Status xstatus = XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &visual_info); - // if (xstatus == 0) { - // LOG_FATAL("XMatchVisualInfo failed"); - // } - // printf("Matched visual:\n"); - // print_visual_info(&visual_info); - // - // Cursor cursor = XCreateFontCursor(display, XC_iron_cross); - // XSetWindowAttributes win_attr = { - // .background_pixel = 0x00000000, - // .border_pixel = 0xFF000000, - // .colormap = XCreateColormap(display, DefaultRootWindow(display), visual_info.visual, AllocNone), - // .event_mask = Expose, - // .backing_store = WhenMapped, - // .cursor = cursor, - // }; - // - // Window window = XCreateWindow( - // display, - // DefaultRootWindow(display), - // 0, - // 0, - // PLTF_DEFAULT_WINDOW_WIDTH, - // PLTF_DEFAULT_WINDOW_HEIGHT, - // 0, - // visual_info.depth, - // InputOutput, - // visual_info.visual, - // CWBackPixel | - // CWBorderPixel | - // CWColormap | - // CWEventMask | - // CWBackingStore | - // CWCursor, - // &win_attr - // ); - // - // XMapWindow(display, window); - // - // XFlush(display); - // - // pause(); - // - // XDestroyWindow(display, window); + // 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); diff --git a/src/pltf/gl_funcs.h b/src/pltf/gl_funcs.h index 09eb46c..be68803 100644 --- a/src/pltf/gl_funcs.h +++ b/src/pltf/gl_funcs.h @@ -4,37 +4,43 @@ #include #define PLTF_GL_FUNCS(X) \ -X(PFNGLGETINTEGERVPROC, glGetIntegerv); \ -X(PFNGLGETFLOATVPROC, glGetFloatv); \ -X(PFNGLCLEARCOLORPROC, glClearColor); \ -X(PFNGLCLEARPROC, glClear); \ -X(PFNGLGETERRORPROC, glGetError); \ +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(PFNGLCREATESHADERPROC, glCreateShader); \ -X(PFNGLSHADERSOURCEPROC, glShaderSource); \ -X(PFNGLCOMPILESHADERPROC, glCompileShader); \ -X(PFNGLGETSHADERIVPROC, glGetShaderiv); \ -X(PFNGLCREATEPROGRAMPROC, glCreateProgram); \ -X(PFNGLATTACHSHADERPROC, glAttachShader); \ -X(PFNGLLINKPROGRAMPROC, glLinkProgram); \ -X(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \ +X(PFNGLCLEARCOLORPROC, glClearColor); \ +X(PFNGLCLEARPROC, glClear); \ X(PFNGLUSEPROGRAMPROC, glUseProgram); \ X(PFNGLDRAWARRAYSPROC, glDrawArrays); \ -X(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \ -X(PFNGLDELETESHADERPROC, glDeleteShader); \ -X(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ +X(PFNGLGETINTEGERVPROC, glGetIntegerv); \ +X(PFNGLGETFLOATVPROC, glGetFloatv); \ +X(PFNGLGETERRORPROC, glGetError); \ -#define X(type, name) extern type name +#define X(type, name) \ +extern type name; PLTF_GL_FUNCS(X) #undef X -void* pltf_gl_function_load(const char* name); +#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_ diff --git a/src/pltf/glx/gl_funcs.c b/src/pltf/glx/gl_funcs.c new file mode 100644 index 0000000..7af03f8 --- /dev/null +++ b/src/pltf/glx/gl_funcs.c @@ -0,0 +1,23 @@ +#ifdef __linux__ + +#include +#include + +#include "../gl_funcs.h" + +#define X(type, name) \ +type name = NULL + +PLTF_GL_FUNCS(X) +#undef X + +// #define X(type, name) \ +// name = (type) pltf_gl_function_load((const GLubyte*) #name); + +// void pltf_gl_funcs_load() { + // PLTF_GL_FUNCS(X) +// } + +// #undef X + +#endif // __linux__ diff --git a/src/pltf/linux/gl_funcs.c b/src/pltf/linux/gl_funcs.c deleted file mode 100644 index 84266bc..0000000 --- a/src/pltf/linux/gl_funcs.c +++ /dev/null @@ -1,13 +0,0 @@ -#ifdef __linux__ - -#include - -#include "../gl_funcs.h" - -#define X(type, name) \ -type name = NULL - -PLTF_GL_FUNCS(X) -#undef X - -#endif // __linux__