We have been waiting OpenGL 3.0 for ages, we were all very excited about the wonderful features ARB was promising, then, on the 11th of August 2008, the specs were released…
I, like everyone else, was really disappointed, the Architecture Review Board was not only really late on schedule but it didn’t keep its word about many key features that should have been introduced with this release.
Nevertheless I’m still confident in the future, when older API functions will be removed and not simply, as in the current version, tagged as deprecated.
Now, after the long but needed introduction, let’s talk about things that matter: today the ArchLinux team moved the new stable 180.22 driver release from the [testing] to the [extra] repository.
Well, apart from the equally important CUDA 2.1 and VDPAU support, this release has been bundled with OpenGL 3 and GLSL 1.30 support, so have a look at how to create an OpenGL 3.0 context.
First of all, it seems like there’s no other way to open the new context without getting your hands dirty, that is talking directly with GLX.
What follows is a snippet to create an OpenGL 3.0 context integrated in SDL 1.2, which still doesn’t support it natively.
First of all you need some new defines.
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 #define GLX_CONTEXT_FLAGS_ARB 0x2094
You need also to retrieve the address of the following new GLX function.
typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((GLubyte*)"glXCreateContextAttribsARB");
Then you have to define a bunch of GLX related variables.
Display *dpy; GLXDrawable draw, read; GLXContext ctx, ctx3; GLXFBConfig *cfg; int nelements; int attribs[]= { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0 };
At last, after having called SDL_SetVideoMode(), create a new context, make it current and destroy the old one.
ctx = glXGetCurrentContext(); dpy = glXGetCurrentDisplay(); draw = glXGetCurrentDrawable(); read = glXGetCurrentReadDrawable(); cfg = glXGetFBConfigs(dpy, 0, &nelements); ctx3 = glXCreateContextAttribsARB(dpy, *cfg, 0, 1, attribs); glXMakeContextCurrent(dpy, draw, read, ctx3); glXDestroyContext(dpy, ctx);
Don’t forget to put some querying code, just to be sure the whole process worked. 😀
const GLubyte* string; string = glGetString(GL_VENDOR); printf("Vendor: %s\n", string); string = glGetString(GL_RENDERER); printf("Renderer: %s\n", string); string = glGetString(GL_VERSION); printf("OpenGL Version: %s\n", string); string = glGetString(GL_SHADING_LANGUAGE_VERSION); printf("GLSL Version: %s\n\n", string);
On my workstation I get this:
Vendor: NVIDIA Corporation
Renderer: GeForce 8600 GT/PCI/SSE2
OpenGL Version: 3.0 NVIDIA 180.22
GLSL Version: 1.30 NVIDIA via Cg compiler
If you want to retrieve also the extension list, a new function can help you simplify the process.
typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC)glXGetProcAddress((GLubyte*)"glGetStringi");
You can then use it like this:
GLint numExtensions = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
printf(“Extension list: \n”);
for (int i = 0; i < numExtensions; ++i)
{
printf("%s ", glGetStringi(GL_EXTENSIONS, i));
}
printf("\n");
[/sourcecode]
This new OpenGL version seems to perform just like the old one at the moment, drivers do not honour the GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB attribute, this means everything is still in place, backward compatible and unoptimized. 🙁
PFNGLXCREATECONTEXTATTRIBSARBPROC, seriously? Who the hell names these types?
Thanks heaps Encelo, can’t wait for SDL 1.3 to finally get released so it can do this for me 🙂