Michael Conrad


X11::GLX - GLX API (OpenGL on X11)


version 0.03


This module acts as an extension to X11::Xlib, providing the API that sets up OpenGL on X11. The OpenGL perl module can provide some of this API, but doesn't in it's default configuration.

This is the C-style API. For something more friendly, see X11::GLX::DWIM.



  X11::GLX::glXQueryVersion($display, my ($major, $minor))
        or die "glXQueryVersion failed";
  print "GLX Version $major.$minor\n";


  my $str= glXQueryExtensionsString($display, $screen_num);
  my $str= glXQueryExtensionsString($display); # default screen

Get a string of all the GL extensions available.


  my $vis_info= glXChooseVisual($display, $screen, \@attributes);
  my $vis_info= glXChooseVisual($display, $screen);
  my $vis_info= glXChooseVisual($display); # default screen

This function picks an OpenGL-compatible visual. @attributes is an array of integers (see GLX documentation). The terminating "None" is added automatically. If undefined, this module uses a default of:


Returns an XVisualInfo, or empty list on failure.

This method is deprecated in GLX 1.3 in favor of glXChooseFBConfig.


  if ($glx_version >= 1.3) {
        my @configs= glXChooseFBConfig($display, $screen, \@attributes);

Return a list of compatible framebuffer configurations (GLXFBConfig) matching the desired @attributes. This method deals with lower level details than glXChooseVisual, needed for more advanced GL usage like rendering a fully transparent window. For @attributes, consult the khronos docs

Returns an empty list on failure.


  my @fbconfigs= glXGetFBConfigs($display, $screen);

Return all GLXFBConfig available on this screen.


  glXGetFBConfigAttrib($display, $fbconfig, $attr_id, my $value) == Success
        or die "glXGetFBConfigAttrib failed";

Yes you read that right. Horribly awkward interface for accessing attributes of a struct. Use the attributes of GLXFBConfig instead.


  if ($glx_version >= 1.3) {
        my $vis_info= glXGetVisualFromFBConfig($display, $glxfbconfig);
        # It's an XVisualInfo, not Visual, despite the name

Return the XVisualInfo associated with the FBConfig.


  my $context= glXCreateContext($display, $visual_info, $shared_with, $direct);

$visual_info is an instance of XVisualInfo, most likely returned by glXChooseVisual.

$shared_with is an optional X11::GLX::GLXContext with which to share display lists, and possibly other objects like textures. See "Shared GL Contexts".

$direct is a boolean indicating whether you would like a direct rendering context. i.e. have the application directly open a handle to the graphics hardware that bypasses X11 protocol. You are not guaranteed to get a direct context if setting it to true, and indeed won't if you are connected to a remote X11 server. However if you set it to false this call may fail entirely if you are connected to a X11 server which has disabled indirect rendering.


  my $context= glXCreateNewContext($display, $fbconfig, $render_type, $share, $direct);

Like "glXCreateContext", except it takes a X11::GLX::FBConfig instead of a X11::Xlib::XVisualInfo. There is also a $render_type that can be GLX_RGBA_TYPE or GLX_COLOR_INDEX_TYPE, but I'm not sure why anyone would ever be using the second one ;-)


  glXMakeCurrent($display, $drawable, $glcontext)
    or die "glXMakeCurrent failed";

Set the target drawable (window or GLX pixmap) to which this GL context should render. Note that pixmaps must have been created with "glXCreateGLXPixmap" and can't be just regular X11 pixmaps.


  glXSwapBuffers($display, $glxcontext)

For a double-buffered drawable, show the back buffer and begin rendering to the former front buffer.


  glXDestroyContext($display, $glxcontext);

Destroy a context created by glXCreateContext. This destroys it on the server side.


  my $glxpixmap= glXCreateGLXPixmap($display, $visualinfo, $pixmap)

Create a new pixmap from an existing pixmap which has the extra GLX baggage necessary to use it as a rendering target.


  glXDestroyGLXPixmap($display, $glxpixmap)

Free a GLX pixmap. You need to call this function instead of the usual XDestroyPixmap.

Extension GLX_EXT_import_context

These functions are only available if X11::GLX::glXQueryExtensionsString includes "GLX_EXT_import_context". See "Shared GL Contexts".


  my $xid= glXGetContextIDEXT($glxcontext)

Returns the X11 display object ID of the GL context. This XID can be passed to "glXImportContextEXT" by any other process to get a GLXContext pointer in their address space for this context.


  my $glx_context= glXImportContextEXT($display, $context_xid);

Create a local GLXContext data structure that references a shared indirect GLXContext on the X11 server.



Free the context data structures created by "glXImportContextEXT".


  glXQueryContextInfoEXT($display, $glxcontext, $attr, my $attr_val)
        or die "glXQueryContextInfoEXT failed";

Retrieve the value of an attribute of the GLX Context. The attribute is returned in the final argument. The return value is a boolean indicating success.


  GLX_VISUAL_ID_EXT      - Returns the XID of the GLX Visual associated with ctx.
  GLX_SCREEN_EXT         - Returns the screen number associated with ctx.

Shared GL Contexts

Sometimes you want to let more than one thread or process access the same OpenGL objects, like Display Lists, Textures, etc. For threads, all you have to do is pass the first thread's context pointer to glXCreateContext for the second thread.

For processes, it is more difficult. To set it up, each process must create an indirect context (to the same Display obviously), and the server and both clients must support the extension GLX_EXT_import_context. Client #1 creates an indirect context, finds the ID, passes that to Client #2 via some method, then client #2 imports the context, then creates a new context shared with the imported one, then frees the imported one. To make a long story short, see test case 03-import-context.t for an example.

Note that many distros have started disabling indirect mode (as of 2016) for OpenGL on Xorg, for security concerns. You can enable it by passing "+iglx" to the Xorg command line. (finding where to specify the commandline for Xorg can be an exercise in frustration... good luck. On Linux Mint it is found in /etc/X11/xinit/xserverrc. The quick and dirty approach is to rename the Xorg binary and stick a script in its place that exec's the original with the desired command line.)


Michael Conrad <mike@nrdvana.net>


This software is copyright (c) 2017 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.