Aaro Saila před 3 měsíci
rodič
revize
69b09a7d7a
5 změnil soubory, kde provedl 173 přidání a 85 odebrání
  1. 3 2
      meson.build
  2. 124 53
      src/main.c
  3. 23 17
      src/pltf/gl_funcs.h
  4. 23 0
      src/pltf/glx/gl_funcs.c
  5. 0 13
      src/pltf/linux/gl_funcs.c

+ 3 - 2
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(

+ 124 - 53
src/main.c

@@ -1,4 +1,3 @@
-#include <X11/X.h>
 #ifdef _WIN32
 
 #include <assert.h>
@@ -115,17 +114,20 @@ int main() {
 
 #ifdef __linux__
 
+#include <GL/glcorearb.h>
 #include <GL/glx.h>
+#include <GL/glxext.h>
+#include <X11/X.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/cursorfont.h>
 #include <stdio.h>
-#include <unistd.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
-#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);
 

+ 23 - 17
src/pltf/gl_funcs.h

@@ -4,37 +4,43 @@
 #include <GL/glcorearb.h>
 
 #define PLTF_GL_FUNCS(X) \
-X(PFNGLGETINTEGERVPROC, glGetIntegerv); \
-X(PFNGLGETFLOATVPROC, glGetFloatv); \
-X(PFNGLCLEARCOLORPROC, glClearColor); \
-X(PFNGLCLEARPROC, glClear); \
-X(PFNGLGETERRORPROC, glGetError); \
-X(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \
-X(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \
-X(PFNGLGENBUFFERSPROC, glGenBuffers); \
-X(PFNGLBINDBUFFERPROC, glBindBuffer); \
-X(PFNGLBUFFERDATAPROC, glBufferData); \
-X(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \
-X(PFNGLCREATESHADERPROC, glCreateShader); \
 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(PFNGLUSEPROGRAMPROC, glUseProgram); \
-X(PFNGLDRAWARRAYSPROC, glDrawArrays); \
-X(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \
 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
+#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_

+ 23 - 0
src/pltf/glx/gl_funcs.c

@@ -0,0 +1,23 @@
+#ifdef __linux__
+
+#include <stddef.h>
+#include <GL/glcorearb.h>
+
+#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__

+ 0 - 13
src/pltf/linux/gl_funcs.c

@@ -1,13 +0,0 @@
-#ifdef __linux__
-
-#include <stddef.h>
-
-#include "../gl_funcs.h"
-
-#define X(type, name) \
-type name = NULL
-
-PLTF_GL_FUNCS(X)
-#undef X
-
-#endif // __linux__