SDL:Tutorial:OpenGL Extensions with SDL

From GPWiki
Jump to: navigation, search

OpenGL Extensions with SDL

Intro

As you know, SDL is integrated with OpenGL; if you want to manage the window, SDL is the way, but if you want to manage the 3D world drawn in the window, OpenGL is the way. SDL also provides everything necessary for initialization of an OpenGL context.

With the diffusion and the high rate of growth of graphics hardware, two things have become important when speaking of OpenGL: Shaders and Extensions.

SDL provides a simple and effective way to use OpenGL extensions.

Checking extensions, the classic way

The classic way (that is, the one that doesn't employ external libraries like GLEW or GLee) to check if an extension is present is to include the glext.h header and use it. To use the extensions in compile-time, you should do something like:

#include <GL/glext.h>
 
#ifdef GL_EXT_extensionname
// The extension is present
#else
// Extension not present
#endif

But usually you may prefer a dynamic loading of the extensions. To do this you need to ask the OpenGL implementation which extensions it supports, and then check if the one you need is there:

// Proto: const GLubyte * glGetString( GLenum name )
char *extensions = (char *)glGetString(GL_EXTENSIONS)
 
// Check your extension
if (strstr(extensions, "EXT_extensionname"))
    // The extension present
else
    // Extension not present

Loading with SDL

When you are sure that an extension is in the OpenGL implementation, you need to load it. With SDL, the key is using the SDL_GL_GetProcAddress() function.

First: declare a pointer to the function ret_type (APIENTRY * glExtensionName)(parameters) = NULL;

Note that SDL requires the APIENTRY declaration before the pointer.

Then you need to load the address and after checking that everything is 0K, use that function:

glExtensionName = (glExtensionName) SDL_GL_GetProcAddress("glExtensionFunction");

if (glExtensionName)

   // Use that extension

else

   // Other way

Example

Suppose we wanted to use our own transformation matrices and we are storing them in memory in a row-major order. Internally, OpenGL works with column-major matrices only, because of performance concerns; however, this should not limit us in the way we give the matrix to the OpenGL implementation. We have two functions available to us for this:

void LoadTransposeMatrix{fd}ARB(T m[16]);
void MultTransposeMatrix{fd}ARB(T m[16]);

These functions were introduced in OpenGL version 1.2, and as we know only OpenGL 1.1 is shipped with Windows.

The first thing to do is to make sure the extension is actually provided by the OpenGL implementation by calling glGetString(GL_EXTENSIONS) and checking for the existence of GL_ARB_transpose_matrix.

All is left is to do something like:

typedef void (APIENTRY * glLoadTransposeMatrixfARB_Func)(const GLfloat *m);
 
glLoadTransposeMatrixfARB_Func glLoadTransposeMatrixfARB = NULL;
 
void GL_Load_Extensions(void)
{
	/* Some code to check whether extensions are available */
	glLoadTransposeMatrixfARB = (glLoadTransposeMatrixfARB_Func) \
		SDL_GL_GetProcAddress("glLoadTransposeMatrixfARB");
	/* Some code to check whether everything went fine */
}

We can now call glLoadTransposeMatrixf() by dereferencing the function pointer glLoadTransposeMatrixfARB.

External Links