Skip to content

Instantly share code, notes, and snippets.

@HiImJulien
Last active August 13, 2020 22:49
Show Gist options
  • Save HiImJulien/8388554126ea4d36a3406c4455c8e1e7 to your computer and use it in GitHub Desktop.
Save HiImJulien/8388554126ea4d36a3406c4455c8e1e7 to your computer and use it in GitHub Desktop.
A "pull request" for Apporva Joshi's [article](https://apoorvaj.io/creating-a-modern-opengl-context/), which simplifies the creation of an OpenGL 4.0 Context using GLX.
/* gcc this.c -lGL -lX11 */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
/*
License: Public domain
Contents
--------
- Create_display_and_window
- Create_the_modern_OpenGL_context
- Show_the_window
- Application_loop
*/
typedef GLXContext (*glXCreateContextAttribsARBProc)
(Display*, GLXFBConfig, GLXContext, Bool, const int*);
int main()
{
Display* disp = 0;
Window win = 0;
/* Create_display_and_window
-------------------------
Skip if you already have a display and window */
disp = XOpenDisplay(0);
win = XCreateSimpleWindow(disp, DefaultRootWindow(disp),
10, 10, /* x, y */
800, 600, /* width, height */
0, 0, /* border_width, border */
0); /* background */
/* Create_the_modern_OpenGL_context
-------------------------------- */
static int visual_attribs[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_DOUBLEBUFFER, true,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
None
};
int num_fbc = 0;
GLXFBConfig *fbc = glXChooseFBConfig(disp,
DefaultScreen(disp),
visual_attribs, &num_fbc);
if (!fbc) {
printf("glXChooseFBConfig() failed\n");
exit(1);
}
/* Create old OpenGL context to get correct function pointer for
glXCreateContextAttribsARB() */
XVisualInfo *vi = glXGetVisualFromFBConfig(disp, fbc[0]);
// In contrast to WGL, GLX does NOT require you create a dummy context first.
// It doesn't even require you to create a window.
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB =
(glXCreateContextAttribsARBProc)
glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
if (!glXCreateContextAttribsARB) {
printf("glXCreateContextAttribsARB() not found\n");
exit(1);
}
/* Set desired minimum OpenGL version */
static int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
None
};
/* Create modern OpenGL context */
GLXContext ctx = glXCreateContextAttribsARB(disp, fbc[0], NULL, true,
context_attribs);
if (!ctx) {
printf("Failed to create OpenGL context. Exiting.\n");
exit(1);
}
/* Show_the_window
--------------- */
XMapWindow(disp, win);
glXMakeCurrent(disp, win, ctx);
int major = 0, minor = 0;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
printf("OpenGL context created.\nVersion %d.%d\nVendor %s\nRenderer %s\n",
major, minor,
glGetString(GL_VENDOR),
glGetString(GL_RENDERER));
/* Application_loop
---------------- */
while(1) {}
return 0;
}

The deleted lines include:

  • line 62: GLXContext ctx_old = glXCreateContext(disp, vi, 0, GL_TRUE);
  • line 67-69:
    /* Destroy old context */
    glXMakeCurrent(disp, 0, 0);
    glXDestroyContext(disp, ctx_old);

Creating a dummy context is not required with GLX, as the specification for glXGetProcAddress states:

Are function pointers context-independent? Yes. The pointer to an extension function can be used with any context [...]

which is in direct contrast to WGL's wglGetProcAddress.

Furthermore, the reference DOES NOT specify explicitly, that a current context must be present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment