Table of

8.1.2010The year I started blogging (blogware)
9.1.2010Linux initramfs with iSCSI and bonding support for PXE booting
9.1.2010Using manually tweaked PTX assembly in your CUDA 2 program
9.1.2010OpenCL autoconf m4 macro
9.1.2010Mandelbrot with MPI
10.1.2010Using dynamic libraries for modular client threads
11.1.2010Creating an OpenGL 3 context with GLX
11.1.2010Creating a double buffered X window with the DBE X extension
12.1.2010A simple random file read benchmark
14.12.2011Change local passwords via RoundCube safer
5.1.2012Multi-GPU CUDA stress test
6.1.2012CUDA (Driver API) + nvcc autoconf macro
29.5.2012CUDA (or OpenGL) video capture in Linux
31.7.2012GPGPU abstraction framework (CUDA/OpenCL + OpenGL)
7.8.2012OpenGL (4.3) compute shader example
10.12.2012GPGPU face-off: K20 vs 7970 vs GTX680 vs M2050 vs GTX580
4.8.2013DAViCal with Windows Phone 8 GDR2
5.5.2015Sample pattern generator


Creating an OpenGL 3 context with GLX

This might be well-known by now, but when I was creating my OpenGL 3.0 contexts for the first time, information online was scarce, or at the very least hard to find.

Anyway, this is how to create an OpenGL 3.2 (works for any 3.x) context with just the GLX:


#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>

// These are obsolete in most distributions, hence provided explicitly.
#include "GL/glxext.h"
#include "GL/glext.h"

Display *d_dpy;
Window d_win;
GLXContext d_ctx;

// Set to NULL for getting it from the environment variable
const char *display = ":0"
int width = 2560;
int height = 1600;

if (!(d_dpy = XOpenDisplay(display))) {
    throw std::string("Couldn't open X11 display\n");

int attr[] = {
    GLX_RED_SIZE, 1,

int scrnum = DefaultScreen(d_dpy);
Window root = RootWindow(d_dpy, scrnum);

// We need this for OpenGL3
int elemc;
GLXFBConfig *fbcfg = glXChooseFBConfig(d_dpy, scrnum, NULL, &elemc);
if (!fbcfg) 
    throw std::string("Couldn't get FB configs\n");
    printf("Got %d FB configs\n", elemc);

XVisualInfo *visinfo = glXChooseVisual(d_dpy, scrnum, attr);

if (!visinfo)
    throw std::string("Couldn't get a visual\n");

// Window parameters
XSetWindowAttributes winattr;
winattr.background_pixel = 0;
winattr.border_pixel = 0;
winattr.colormap = XCreateColormap(d_dpy, root, visinfo->visual, AllocNone);
winattr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

printf("Window depth %d, w %d h %d\n", visinfo->depth, width, height);
d_win = XCreateWindow(d_dpy, root, 00, width, height, 0
        visinfo->depth, InputOutput, visinfo->visual, mask, &winattr);

// OpenGL 3.2
int gl3attr[] = {

d_ctx = glXCreateContextAttribsARB(d_dpy, fbcfg[0], NULLtrue, gl3attr);


XMapWindow(d_dpy, d_win);
glXMakeCurrent(d_dpy, d_win, d_ctx);

printf("OpenGL:\n\tvendor %s\n\trenderer %s\n\tversion %s\n\tshader language %s\n\n",
        glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION),

int extCount;
glGetIntegerv(GL_NUM_EXTENSIONS, &extCount);
for (int i = 0; i < extCount; ++i)
    printf("Extension %d/%d%s\n", i+1, extCount, glGetStringi(GL_EXTENSIONS, i));

glViewport(00, width, height);


Nick     E-mail   (optional)

Is this spam? (answer opposite of "yes" and add "pe")