Minimal GLX OpenGL3.0 example

New drivers OpenGl 3.0 capable drivers are out, but nowhere is an example to test it or start own experiments. Here is my minimal c++ example:


#include <GL/glx.h>
#include <GL/gl.h>
#include <unistd.h>
#include <iostream>

#define GLX_CONTEXT_MAJOR_VERSION_ARB		0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB		0x2092
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);


int main (int argc, char ** argv){
	Display *dpy = XOpenDisplay(0);

	int nelements;
	GLXFBConfig *fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), 0, &nelements);

	static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };
	XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy),attributeList);

	XSetWindowAttributes swa;
	swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
	swa.border_pixel = 0;
	swa.event_mask = StructureNotifyMask;
	Window win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);

	XMapWindow (dpy, win);

	//oldstyle context:
	//	GLXContext ctx = glXCreateContext(dpy, vi, 0, GL_TRUE);

	std::cout << "glXCreateContextAttribsARB " << (void*) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB") << std::endl;
	GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");

	int attribs[] = {
		GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
		GLX_CONTEXT_MINOR_VERSION_ARB, 0,
		0};

	GLXContext ctx = glXCreateContextAttribsARB(dpy, *fbc, 0, true, attribs);

	glXMakeCurrent (dpy, win, ctx);

		glClearColor (0, 0.5, 1, 1);
		glClear (GL_COLOR_BUFFER_BIT);
		glXSwapBuffers (dpy, win);

		sleep(1);

		glClearColor (1, 0.5, 0, 1);
		glClear (GL_COLOR_BUFFER_BIT);
		glXSwapBuffers (dpy, win);

		sleep(1);

	ctx = glXGetCurrentContext(); 
	glXDestroyContext(dpy, ctx); 
	}

g++ gl3example.cpp -o gl3example -lX11 -lGL

Thanks a lot.
Best regards,

Manuel

one issue:

it should be

static int attributeList[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };

and then

GLXFBConfig *fbc = glXChooseFBConfig(dpy, vi->screen, attributeList, &nelements);

and somewhere after that:

XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, fbc[0]);

otherwise you get a badmatch when calling MakeCurrent().

I am bumping this thread to post some updated code for OpenGL 3.0 on GLX. I wouldn’t normally do that, but this thread is showing up prominently in search results and the current code is flawed (works on nvidia but not on ati drivers).

As before, save as gl3.cpp and compile with “g++ gl3.cpp -o gl3 -lX11 -lGL”.


#include <GL/glx.h>
#include <GL/gl.h>
#include <unistd.h>
#include <iostream>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);

int main (int argc, char ** argv)
{
    Display *display = XOpenDisplay(0);

    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = NULL;

    const char *extensions = glXQueryExtensionsString(display, DefaultScreen(display));
    std::cout << extensions << std::endl;

    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
     };

    std::cout << "Getting framebuffer config" << std::endl;
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);
    if (!fbc)
    {
        std::cout << "Failed to retrieve a framebuffer config" << std::endl;
        return 1;
    }

    std::cout << "Getting XVisualInfo" << std::endl;
    XVisualInfo *vi = glXGetVisualFromFBConfig(display, fbc[0]);

    XSetWindowAttributes swa;
    std::cout << "Creating colormap" << std::endl;
    swa.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone);
    swa.border_pixel = 0;
    swa.event_mask = StructureNotifyMask;

    std::cout << "Creating window" << std::endl;
    Window win = XCreateWindow(display, RootWindow(display, vi->screen), 0, 0, 100, 100, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
    if (!win)
    {
        std::cout << "Failed to create window." << std::endl;
        return 1;
    }

    std::cout << "Mapping window" << std::endl;
    XMapWindow(display, win);

    // Create an oldstyle context first, to get the correct function pointer for glXCreateContextAttribsARB
    GLXContext ctx_old = glXCreateContext(display, vi, 0, GL_TRUE);
    glXCreateContextAttribsARB =  (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
    glXMakeCurrent(display, 0, 0);
    glXDestroyContext(display, ctx_old);

    if (glXCreateContextAttribsARB == NULL)
    {
        std::cout << "glXCreateContextAttribsARB entry point not found. Aborting." << std::endl;
        return false;
    }

    static int context_attribs[] =
    {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        GLX_CONTEXT_MINOR_VERSION_ARB, 0,
        None
    };

    std::cout << "Creating context" << std::endl;
    GLXContext ctx = glXCreateContextAttribsARB(display, fbc[0], NULL, true, context_attribs);
    if (!ctx)
    {
        std::cout << "Failed to create GL3 context." << std::endl;
        return 1;
    }

    std::cout << "Making context current" << std::endl;
    glXMakeCurrent(display, win, ctx);

        glClearColor (0, 0.5, 1, 1);
        glClear (GL_COLOR_BUFFER_BIT);
        glXSwapBuffers (display, win);

        sleep(1);

        glClearColor (1, 0.5, 0, 1);
        glClear (GL_COLOR_BUFFER_BIT);
        glXSwapBuffers (display, win);

        sleep(1);

    ctx = glXGetCurrentContext();
    glXMakeCurrent(display, 0, 0);
    glXDestroyContext(display, ctx);
}

1 Like

On GL2.1 (NVidia GL3 capable drivers, but GL2.1-capable hardware (GeForce 6800 Ultra)), I get a fatal on X error:


> ./gl3
GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGIX_fbconfig GLX_SGIX_pbuffer GLX_SGI_video_sync GLX_SGI_swap_control GLX_EXT_texture_from_pixmap GLX_ARB_create_context GLX_ARB_multisample GLX_NV_float_buffer GLX_ARB_fbconfig_float GLX_ARB_get_proc_address
Getting framebuffer config
Getting XVisualInfo
Creating colormap
Creating window
Mapping window
Creating context
Making context current
X Error of failed request:  BadAlloc (insufficient resources for operation)
  Major opcode of failed request:  144 (GLX)
  Minor opcode of failed request:  34 ()
  Serial number of failed request:  30
  Current serial number in output stream:  31
libxcb: WARNING! Program tries to lock an already locked connection,
        which indicates a programming error.
        There will be no further warnings about this issue.

GL_VERSION is “2.1.2 NVIDIA 180.29”.

That’s normal behavior I think

Well, I guess my implicit point was there’s no reason to check or successful creation if the code is just going to core dump on a non-GL3 box. Therefore either the current checks are insufficent, or there’s a bug in NVidia’s GL3 API implementation.

Okay. I get an Segmentation Fault from the source of the first posting:

rain@rain:~/Dokumente/OpenGL/Minimal Example$ ./gl3example.cpp
glXCreateContextAttribsARB 0
Segmentation fault

An this is the output i get from Stephan A code:

rain@rain:~/Dokumente/OpenGL/Minimal Example$ ./gl3exa
GLX_ARB_get_proc_address GLX_ARB_multisample GLX_EXT_import_context GLX_EXT_visual_info GLX_EXT_visual_rating GLX_MESA_copy_sub_buffer GLX_MESA_swap_control GLX_MESA_swap_frame_usage GLX_OML_swap_method GLX_SGI_make_current_read GLX_SGI_swap_control GLX_SGI_video_sync GLX_SGIS_multisample GLX_SGIX_fbconfig GLX_SGIX_visual_select_group
Getting framebuffer config
Getting XVisualInfo
Creating colormap
Creating window
Mapping window
glXCreateContextAttribsARB entry point not found. Aborting.

Can you tell me what i’m doing wrong?

I’m getting the same problem as TheRain.It compiles fine, but running it with ./<filename> I get the same problem…

I did some more research on the issue, though, and it is because the variable glXCreateContextAttribsARB is NULL. The only point where it can go from NULL to a value is when it is set to equal the return value of the function:

glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)“glXCreateContextAttribsARB”.
This command returns NULL when:
“function requested [glXCreateContextAttribsARB?] is not supported in the implementation being queried.”
I found this at http://www.opengl.org/sdk/docs/man/, however, it doesn’t specify: implementation of what? Is it a graphics card issue (I have Intel, not ATI) or just my freeglut version of glx?

Intel has not released any OpenGL 3.0-capable drivers. You need a recent Nvidia, Ati or Chrome card for OpenGL 3.0.

Thanks for clearing up this, as well as many other odd issues with glut… This is actually terrible for me. But at least I know where to go from here, so I really appreciate that, because this has been bugging me for a long time. But is there no way at all to get around this? (Like some sort of unofficial driver that works with an Intel card, if that even exists or is legal).

Open-source Linux drivers tend to provide more features for Intel IGPs, compared to their closed-source Windows counterparts (e.g. the former support FBOs on older IGPs, the latter don’t). However, they don’t provide 3.0 support either.

The only solution would be to use Mesa3d, which is a software implementation of OpenGL (no GPU acceleration). I think Mesa3d 7.5 adds initial 3.0 support, but don’t quote me on that. :slight_smile:

7.5 not our yet, but coming soon apparently:

In a quick google, didn’t trip over any confirmations that 7.5 has GL3, but it’s possible.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.