Tutorial1: Creating a Cross Platform OpenGL 3.2 Context in SDL (C / SDL)
Overview
This tutorial is designed to help explain the process of creating an OpenGL 3.2 context using libsdl.
This tutorial has the following requirements:
-
An OpenGL 3.2 compatible video card. (Currently an NVDIA G80 or ATI R600 or newer GPU)
An OpenGL 3.2 video driver. (Currently they are all beta versions)
libsdl-1.3 which is currently in development phase, but includes support for OpenGL 3 style contexts.
gl3.h installed in a 'GL3' directory. (e.g. mkdir /usr/include/GL3 ; mv gl3.h /usr/include/GL3)
The benefits of using libsdl are numerous, but in particular, it will allow our code to run on windows, mac, and unix / linux. My only computer which meets the above requirements runs linux, so I can guarantee compatibility with linux only. If you find problems compiling the code on other platforms, please make a note of it.
Creating a window in libsdl and binding an OpenGL 3.2 context to it uses these steps:
-
Initialize the SDL video subsystem using SDL_Init or SDL_VideoInit. (We use SDL_Init in this example)
Set the parameters we require for opengl using SDL_GL_SetAttribute.
Create a window using SDL_CreateWindow.
Bind an OpenGL context to the window using SDL_GL_CreateContext.
The Code
#include <stdio.h> #include <stdlib.h> /* Ensure we are using opengl's core profile only */ #define GL3_PROTOTYPES 1 #include <GL3/gl3.h> #include <SDL/SDL.h> #define PROGRAM_NAME "Tutorial1" /* A simple function that prints a message, the error code returned by SDL, * and quits the application */ void sdldie(char *msg) { printf("%s: %s\n", msg, SDL_GetError()); SDL_Quit(); exit(1); } /* Our program's entry point */ int main(int argc, char *argv[]) { SDL_WindowID mainwindow; /* Our window handle */ SDL_GLContext maincontext; /* Our opengl context handle */ if (SDL_Init(SDL_INIT_VIDEO) < 0) /* Initialize SDL's Video subsystem */ sdldie("Unable to initialize SDL"); /* Or die on error */ /* Request an opengl 3.2 context. * SDL doesn't have the ability to choose which profile at this time of writing, * but it should default to the core profile */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); /* Turn on double buffering with a 24bit Z buffer. * You may need to change this to 16 or 32 for your system */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); /* Create our window centered at 512x512 resolution */ mainwindow = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if (!mainwindow) /* Die if creation failed */ sdldie("Unable to create window"); /* Create our opengl context and attach it to our window */ maincontext = SDL_GL_CreateContext(mainwindow); /* This makes our buffer swap syncronized with the monitor's vertical refresh */ SDL_GL_SetSwapInterval(1); /* Clear our buffer with a red background */ glClearColor ( 1.0, 0.0, 0.0, 1.0 ); glClear ( GL_COLOR_BUFFER_BIT ); /* Swap our back buffer to the front */ SDL_GL_SwapWindow(mainwindow); /* Wait 2 seconds */ SDL_Delay(2000); /* Same as above, but green */ glClearColor ( 0.0, 1.0, 0.0, 1.0 ); glClear ( GL_COLOR_BUFFER_BIT ); SDL_GL_SwapWindow(mainwindow); SDL_Delay(2000); /* Same as above, but blue */ glClearColor ( 0.0, 0.0, 1.0, 1.0 ); glClear ( GL_COLOR_BUFFER_BIT ); SDL_GL_SwapWindow(mainwindow); SDL_Delay(2000); /* Delete our opengl context, destroy our window, and shutdown SDL */ SDL_GL_DeleteContext(maincontext); SDL_DestroyWindow(mainwindow); SDL_Quit(); return 0; }
Compilation
On linux:
gcc tutorial1.c -o tutorial1 -lGL -lSDL
If you installed libsdl-1.3 to /usr/local then do:
gcc -I/usr/local/include -L/usr/local/lib tutorial1.c -o tutorial1 -lGL -lSDL
Execution
./tutorial1
The result should be a 512x512 window centered on your display showing a red, green, then blue background.