1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/* Simple program: Create a blank window, wait for keypress, quit.
Please see the SDL documentation for details on using the SDL API:
/Developer/Documentation/SDL/docs.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "SDL.h"
extern void Atlantis_Init ();
extern void Atlantis_Reshape (int w, int h);
extern void Atlantis_Animate ();
extern void Atlantis_Display ();
static SDL_Surface *gScreen;
static void initAttributes ()
{
// Setup attributes we want for the OpenGL context
int value;
// Don't set color bit sizes (SDL_GL_RED_SIZE, etc)
// Mac OS X will always use 8-8-8-8 ARGB for 32-bit screens and
// 5-5-5 RGB for 16-bit screens
// Request a 16-bit depth buffer (without this, there is no depth buffer)
value = 16;
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, value);
// Request double-buffered OpenGL
// The fact that windows are double-buffered on Mac OS X has no effect
// on OpenGL double buffering.
value = 1;
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, value);
}
static void printAttributes ()
{
// Print out attributes of the context we created
int nAttr;
int i;
int attr[] = { SDL_GL_RED_SIZE, SDL_GL_BLUE_SIZE, SDL_GL_GREEN_SIZE,
SDL_GL_ALPHA_SIZE, SDL_GL_BUFFER_SIZE, SDL_GL_DEPTH_SIZE };
char *desc[] = { "Red size: %d bits\n", "Blue size: %d bits\n", "Green size: %d bits\n",
"Alpha size: %d bits\n", "Color buffer size: %d bits\n",
"Depth bufer size: %d bits\n" };
nAttr = sizeof(attr) / sizeof(int);
for (i = 0; i < nAttr; i++) {
int value;
SDL_GL_GetAttribute (attr[i], &value);
printf (desc[i], value);
}
}
static void createSurface (int fullscreen)
{
Uint32 flags = 0;
flags = SDL_OPENGL;
if (fullscreen)
flags |= SDL_FULLSCREEN;
// Create window
gScreen = SDL_SetVideoMode (640, 480, 0, flags);
if (gScreen == NULL) {
fprintf (stderr, "Couldn't set 640x480 OpenGL video mode: %s\n",
SDL_GetError());
SDL_Quit();
exit(2);
}
}
static void initGL ()
{
Atlantis_Init ();
Atlantis_Reshape (gScreen->w, gScreen->h);
}
static void drawGL ()
{
Atlantis_Animate ();
Atlantis_Display ();
}
static void mainLoop ()
{
SDL_Event event;
int done = 0;
int fps = 24;
int delay = 1000/fps;
int thenTicks = -1;
int nowTicks;
while ( !done ) {
/* Check for events */
while ( SDL_PollEvent (&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
break;
case SDL_MOUSEBUTTONDOWN:
break;
case SDL_KEYDOWN:
/* Any keypress quits the app... */
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
// Draw at 24 hz
// This approach is not normally recommended - it is better to
// use time-based animation and run as fast as possible
drawGL ();
SDL_GL_SwapBuffers ();
// Time how long each draw-swap-delay cycle takes
// and adjust delay to get closer to target framerate
if (thenTicks > 0) {
nowTicks = SDL_GetTicks ();
delay += (1000/fps - (nowTicks-thenTicks));
thenTicks = nowTicks;
if (delay < 0)
delay = 1000/fps;
}
else {
thenTicks = SDL_GetTicks ();
}
SDL_Delay (delay);
}
}
int main(int argc, char *argv[])
{
// Init SDL video subsystem
if ( SDL_Init (SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",
SDL_GetError());
exit(1);
}
// Set GL context attributes
initAttributes ();
// Create GL context
createSurface (0);
// Get GL context attributes
printAttributes ();
// Init GL state
initGL ();
// Draw, get events...
mainLoop ();
// Cleanup
SDL_Quit();
return 0;
}
|