SDL and OpenGL
Welcome to this tutorial !
I will explain you how to code with both SDL and OpenGL library. But I expect you already know how to use SDL and OpenGL basics. If you don't I recommend you to go to this wiki page for SDL :
http://wiki.vislab.usyd.edu.au/moinwiki/Ostrich/ToolsEvaluation/SDLEvaluation. You will find some links for SDL tutorials. And this one for OpenGL basics :
http://wiki.vislab.usyd.edu.au/moinwiki/Multimedia_Computing_and_Processing/Tutorials/OpenGL_Basics
Why using SDL ?
SDL is a low level Multimedia library. Using SDL make programming events, using pictures ... easier !
Prepare SDL project for OpenGL
First of all, you will need OpenGL and SDL libraries. For the first one I advise you to download the latest GLUT pack. It includes everything we need for OpenGL programming. For The seconde one you just have to install the SDL library properly.
In both cases, don't forgot to link these libraries : SDL.lib SDLmain.lib opengl32.lib glu32.lib to your project.
Let's begin, this is the minimal code (just an example but it's easy to begin with) for a SDL project :
1
2 #include <SDL/SDL.h>
3
4 int main(int argc, char *argv[])
5
6 {
7 SDL_Init(SDL_INIT_VIDEO);
8
9 SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
10
11 SDL_Flip(screen);
12
13 bool keepdoing = true;
14 SDL_Event event;
15
16 while (keepdoing)
17 {
18 SDL_WaitEvent(&event);
19 switch(event.type)
20 {
21 case SDL_QUIT:
22 keepdoing = false;
23 }
24 }
25
26 SDL_Quit();
27
28 return 0;
29 }
30
This code creates a simple window (640X480 32bit). It also defines the screen as surface to set video.
As we want to use OpenGL library, we have to change the
1 SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
by this one
1 SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
The SDL_DOUBLEBUF is no need anymore. The OpenGL equivalent is activate by default.
Now let's include the OpenGL library (Glut in this case)
1 #include <windows.h> // This is only necessary with Visual C++
2 #include <GL/gl.h> // We are using the Glut library
3 #include <GL/glut.h>
For the example we will draw a basic 2D triangle.
1 glClear(GL_COLOR_BUFFER_BIT);
2
3 glBegin(GL_TRIANGLES);
4 glColor3ub(255,0,0); glVertex2d(-0.75,-0.75);
5 glColor3ub(0,255,0); glVertex2d(0,0.75);
6 glColor3ub(0,0,255); glVertex2d(0.75,-0.75);
7 glEnd();
We also need to change the
1 SDL_Flip(screen);
By this new fonction
1 glFlush();
2 SDL_GL_SwapBuffers();
3
4
glFlush(); checks every OpenGL commands have been done SDL_GL_SwapBuffers(); is the equivalant of SDL_Flip
Here is the complete code !
1 #include <windows.h>
2 #include <SDL/SDL.h>
3 #include <GL/gl.h>
4 #include <GL/glu.h>
5
6 int main(int argc, char *argv[])
7 {
8 SDL_Init(SDL_INIT_VIDEO);
9 SDL_WM_SetCaption("My first OpenGL programm !",NULL);
10 SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
11
12 bool keepdoing = true;
13 SDL_Event event;
14
15 while (keepdoing)
16 {
17 SDL_WaitEvent(&event);
18 switch(event.type)
19 {
20 case SDL_QUIT:
21 keepdoing = false;
22 }
23
24 glClear(GL_COLOR_BUFFER_BIT);
25
26 glBegin(GL_TRIANGLES);
27 glColor3ub(255,0,0); glVertex2d(-0.75,-0.75);
28 glColor3ub(0,255,0); glVertex2d(0,0.75);
29 glColor3ub(0,0,255); glVertex2d(0.75,-0.75);
30 glEnd();
31
32 glFlush();
33 SDL_GL_SwapBuffers();
34 }
35
36 SDL_Quit();
37
38 return 0;
39 }
OpenGL Functions
OpenGL functions are easy to locate because they all begin with gl. Even I tolld you I won't explain you openGl Basics, I'll just remember essentials functions. This is a litttle .gif I found on an internet tutorial. Very usefull for drawing functions. In this example
Here is a little 2D exercise to train using OpenGL transformations, drawing functions and SDL events.
Here is just the code with commens, to be continued ...
1
2 // 2D Crane exercise //
3
4
5 #include <windows.h>
6 #include <SDL/SDL.h>
7 #include <GL/gl.h>
8 #include <GL/glu.h>
9
10 // There we define the Crane's important length for arms, base...//
11
12 #define ARM1_WIDTH 150
13 #define ARM1_HEIGHT 20
14
15 #define ARM2_WIDTH 100
16 #define ARM2_HEIGHT 20
17
18 #define BASE_WIDTH 100
19 #define BASE_HEIGHT 50
20
21 #define CHAIN_HEIGHT 4
22
23 // The screen size is define with Crane size.
24 // Then you can resize the Crane, the Screen will resize automatically
25
26 #define SCREEN_WIDTH (BASE_WIDTH+ARM1_WIDTH+ARM2_WIDTH+200)
27 #define SCREEN_HEIGHT (BASE_HEIGHT+ARM1_WIDTH+ARM2_WIDTH+200)
28
29 // Here are the variables we want to control
30
31 int angle1 = 45; // first angle between the base and the first arm
32 int angle2 = -20; // second angle between the first and the second arm
33 int chain_length = 100; // Length of the chain
34
35
36 // We are going to draw a rectangle with the center in the middle of the left line //
37 // We will use this function to draw every rectangle of the scene //
38
39
40 void drawrectangle(double width,double height,GLubyte red,GLubyte green,GLubyte blue)
41
42 {
43
44 glBegin(GL_QUADS); // Quads draw rectangle
45
46 glColor3ub(red,green,blue); // Color the rectangle
47 glVertex2d(0,height/2); // These are the vertices
48 glVertex2d(0,-height/2); // be careful, ordering points does matter
49 glVertex2d(width,-height/2);
50 glVertex2d(width,height/2);
51
52 glEnd();
53
54 }
55
56 // Here is the function that draw the scene, using transformations and the drawrectangle fonction
57
58
59 void draw()
60
61 {
62
63 glClear( GL_COLOR_BUFFER_BIT ); // Clear the color buffer
64
65 glMatrixMode( GL_MODELVIEW ); //
66 glLoadIdentity( ); // First thing to do before using Matrix !
67
68 glPushMatrix();
69 glTranslated(BASE_WIDTH/2,BASE_HEIGHT,0); // Change Coordinates system
70 drawrectangle(BASE_WIDTH,BASE_HEIGHT,0,255,0); // draw the base
71 glTranslated(BASE_WIDTH/2,BASE_HEIGHT/2,0); // Go to the middle of rectangle's top line
72 glRotated(angle1,0,0,1); // Rotation around Z, first angle
73
74 drawrectangle(ARM1_WIDTH,ARM1_HEIGHT,0,0,255); // draw first arm
75
76 glTranslated(ARM1_WIDTH,0,0); // Change Coordinates system one more time
77 glRotated(angle2,0,0,1);
78
79 drawrectangle(ARM2_WIDTH,ARM2_HEIGHT,0,0,255); // draw second arm
80
81 glTranslated(ARM2_WIDTH,0,0); // Change Coordinates system one more time
82 glRotated(-angle1-angle2-90,0,0,1);
83
84 drawrectangle(chain_length,CHAIN_HEIGHT,255,0,0); // draw the chain
85
86 glTranslated(chain_length,0,0);
87
88 drawrectangle(50,50,255,255,0);
89
90 glPopMatrix();
91
92 glFlush();
93 SDL_GL_SwapBuffers();
94
95 }
96
97 // This is the main function, including the event that permit arms to move
98
99 int main(int argc, char *argv[])
100 {
101
102 SDL_Event event; // This is the only SDL_Event type variable we will need.
103
104 SDL_Init(SDL_INIT_VIDEO); // Initialize SDL video
105 atexit(SDL_Quit);
106
107 // Change Window's name
108 SDL_WM_SetCaption("Exercise",NULL);
109
110 // Set video Screen size, Color depth and Precise OpenGL use
111 SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_OPENGL);
112
113
114 glMatrixMode( GL_PROJECTION );
115 glLoadIdentity( );
116 gluOrtho2D(0,SCREEN_WIDTH,0,SCREEN_HEIGHT);
117
118 SDL_EnableKeyRepeat(10,10); // enable key repeat and change repeat delays
119
120 draw(); // draw the scene even if there are no events
121
122 // events
123
124 while(SDL_WaitEvent(&event)) // Waiting for an event
125 {
126 switch(event.type) // Function used to determine type of event
127 {
128 case SDL_QUIT: // Type = Quit
129 exit(0);
130 break;
131 case SDL_KEYDOWN: // Type = key pressed
132 switch (event.key.keysym.sym) // Enable detection of key
133 {
134
135
136 // Classical switch with conditions to limit chain length and angles
137
138 case SDLK_UP:
139 chain_length --;
140 if (chain_length < 10)
141 chain_length = 10;
142 break;
143 case SDLK_DOWN:
144 chain_length ++;
145 if (chain_length > 100)
146 chain_length = 100;
147 break;
148 case SDLK_LEFT:
149 angle1++;
150 if (angle1 > 90)
151 angle1 = 90;
152 break;
153 case SDLK_a:
154 angle2++;
155 if (angle2 > 90)
156 angle2 = 90;
157 break;
158 case SDLK_RIGHT:
159 angle1--;
160 if (angle1 < 10)
161 angle1 = 10;
162 break;
163 case SDLK_q:
164 angle2--;
165 if (angle2 < -90)
166 angle2 = -90;
167 break;
168 }
169 break;
170 }
171 draw();
172 }
173
174
175 return 0;
176 }
177