Table of contents

8.1.2010The year I started blogging
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
11.1.2010Eurographics 2010 here I come!
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



11.1.2010

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:

#define GL_GLEXT_PROTOTYPES
#define GLX_GLXEXT_PROTOTYPES

#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_RGBA,
    GLX_RED_SIZE, 1,
    GLX_GREEN_SIZE, 1,
    GLX_BLUE_SIZE, 1,
    GLX_DOUBLEBUFFER,
    GLX_DEPTH_SIZE, 1,
    None
};

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");
else
    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, 0, 0, width, height, 0,
        visinfo->depth, InputOutput, visinfo->visual, mask, &winattr);

// OpenGL 3.2
int gl3attr[] = {
    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
    GLX_CONTEXT_MINOR_VERSION_ARB, 2,
    GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
    None
};

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

XFree(visinfo);

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\textensions %s\n",
        glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION),
        glGetString(GL_SHADING_LANGUAGE_VERSION), glGetString(GL_EXTENSIONS));
int texunits;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &texunits);
printf("\t%d texture mapping units\n", texunits);

glViewport(0, 0, width, height);

Comments


Nick     E-mail  

Is this spam?