Writing the OpenGL context creation plumbing on Linux isn’t 100% intuitive. It’s always good to have a handy getting started guide. With developers increasingly using engines such as Unity, the number of people writing directly to OpenGL is shrinking – and so are some of the online resources to get over this initial step. I decided to collect a few links and copy critical sample code here for when I need to whip something up quickly.
Some links to good ‘hello world’ Linux GL samples:
https://github.com/jckarter/hello-gl
https://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
http://www-f9.ijs.si/~matevz/docs/007-2392-003/sgi_html/ch04.html
Code:
Taken from: https://www.opengl.org/sdk/docs/man2/xhtml/glXIntro.xml
Below is a minimal example of creating an RGBA-format X window that’s compatible with OpenGL using GLX 1.3 commands. The window is cleared to yellow when the program runs. The program does minimal error checking; all return values should be checked.
#include < stdio.h >
#include < stdlib.h >
#include < GL/gl.h >
#include < GL/glx.h >
int singleBufferAttributess[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1, /* Request a single buffered color buffer */
GLX_GREEN_SIZE, 1, /* with the maximum number of color bits */
GLX_BLUE_SIZE, 1, /* for each component */
None
};
int doubleBufferAttributes[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, True, /* Request a double-buffered color buffer with */
GLX_RED_SIZE, 1, /* the maximum number of bits per component */
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
None
};
static Bool WaitForNotify( Display *dpy, XEvent *event, XPointer arg ) {
return (event->type == MapNotify) && (event->xmap.window == (Window) arg);
}
int main( int argc, char *argv[] )
{
Display *dpy;
Window xWin;
XEvent event;
XVisualInfo *vInfo;
XSetWindowAttributes swa;
GLXFBConfig *fbConfigs;
GLXContext context;
GLXWindow glxWin;
int swaMask;
int numReturned;
int swapFlag = True;
/* Open a connection to the X server */
dpy = XOpenDisplay( NULL );
if ( dpy == NULL ) {
printf( "Unable to open a connection to the X servern" );
exit( EXIT_FAILURE );
}
/* Request a suitable framebuffer configuration - try for a double
** buffered configuration first */
fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy),
doubleBufferAttributes, &numReturned );
if ( fbConfigs == NULL ) { /* no double buffered configs available */
fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy),
singleBufferAttributess, &numReturned );
swapFlag = False;
}
/* Create an X colormap and window with a visual matching the first
** returned framebuffer config */
vInfo = glXGetVisualFromFBConfig( dpy, fbConfigs[0] );
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
swa.colormap = XCreateColormap( dpy, RootWindow(dpy, vInfo->screen),
vInfo->visual, AllocNone );
swaMask = CWBorderPixel | CWColormap | CWEventMask;
xWin = XCreateWindow( dpy, RootWindow(dpy, vInfo->screen), 0, 0, 256, 256,
0, vInfo->depth, InputOutput, vInfo->visual,
swaMask, &swa );
/* Create a GLX context for OpenGL rendering */
context = glXCreateNewContext( dpy, fbConfigs[0], GLX_RGBA_TYPE,
NULL, True );
/* Create a GLX window to associate the frame buffer configuration
** with the created X window */
glxWin = glXCreateWindow( dpy, fbConfigs[0], xWin, NULL );
/* Map the window to the screen, and wait for it to appear */
XMapWindow( dpy, xWin );
XIfEvent( dpy, &event, WaitForNotify, (XPointer) xWin );
/* Bind the GLX context to the Window */
glXMakeContextCurrent( dpy, glxWin, glxWin, context );
/* OpenGL rendering ... */
glClearColor( 1.0, 1.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glFlush();
if ( swapFlag )
glXSwapBuffers( dpy, glxWin );
sleep( 10 );
exit( EXIT_SUCCESS );
}