|
|
@@ -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);
|
|
|
|