Difference between revisions of "Tutorial1: Creating a Cross Platform OpenGL 3.2 Context in SDL (C / SDL)"

From OpenGL Wiki
Jump to navigation Jump to search
Line 133: Line 133:
  
 
gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs)
 
gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs)
 +
 +
If you didn't install the gl3.h header file to /usr/include/GL3, you also have to specify the include directory:
 +
 +
gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs) -I[DIRECTORY_TO_GL3_DIRECTORY]
 +
e. g.: gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs) -I/home/someuser/local/include
  
 
== Execution ==
 
== Execution ==

Revision as of 06:51, 15 September 2011

Overview

This tutorial is designed to help explain the process of creating an OpenGL 3.2 context using SDL.

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. (Most of the newer drivers)
  • SDL 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)
OR

The benefits of using SDL are numerous, but in particular, it will allow our code to run on windows, mac, and unix / linux. This code has been tested on linux and windows only but should work fine on other systems also.

Creating a window in SDL 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>
/* If using gl3.h */
/* Ensure we are using opengl's core profile only */
#define GL3_PROTOTYPES 1
#include <GL3/gl3.h>

#include <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(const char *msg)
{
    printf("%s: %s\n", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}


void checkSDLError(int line = -1)
{
#ifndef NDEBUG
	const char *error = SDL_GetError();
	if (*error != '\0')
	{
		printf("SDL Error: %s\n", error);
		if (line != -1)
			printf(" + line: %i\n", line);
		SDL_ClearError();
	}
#endif
}
 

/* Our program's entry point */
int main(int argc, char *argv[])
{
    SDL_Window *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");

    checkSDLError(__LINE__);

    /* Create our opengl context and attach it to our window */
    maincontext = SDL_GL_CreateContext(mainwindow);
    checkSDLError(__LINE__);

    /* 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 $(sdl-config --cflags --libs)


If you have libsdl-1.2 and libsdl-1.3 both installed, make sure to run the appropriate version of sdl-config. For example if you installed sdl-1.3 to /usr/local:

gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs)

If you didn't install the gl3.h header file to /usr/include/GL3, you also have to specify the include directory:

gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs) -I[DIRECTORY_TO_GL3_DIRECTORY] e. g.: gcc tutorial1.c -o tutorial1 -lGL $(/usr/local/bin/sdl-config --cflags --libs) -I/home/someuser/local/include

Execution

./tutorial1 The result should be a 512x512 window centered on your display showing a red, green, then blue background.