Mercurial > sdl-ios-xcode
comparison android/testproject/jni/lesson05.c @ 4708:f3f65cb6a382
Added egl headers so we can use eglMakeCurrent()
author | Paul Hunkin <paul@bieh.net> |
---|---|
date | Fri, 18 Jun 2010 01:28:39 +1200 |
parents | |
children | aeac51289991 |
comparison
equal
deleted
inserted
replaced
4707:8b109f0dcd2f | 4708:f3f65cb6a382 |
---|---|
1 /* | |
2 * This code was created by Jeff Molofee '99 | |
3 * (ported to Linux/SDL by Ti Leggett '01) | |
4 * | |
5 * If you've found this code useful, please let me know. | |
6 * | |
7 * Visit Jeff at http://nehe.gamedev.net/ | |
8 * | |
9 * or for port-specific comments, questions, bugreports etc. | |
10 * email to leggett@eecs.tulane.edu | |
11 */ | |
12 | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 #include <math.h> | |
16 | |
17 #include <android/log.h> | |
18 | |
19 | |
20 #ifdef ANDROID | |
21 #include <GLES/gl.h> | |
22 #else | |
23 #include <GL/gl.h> | |
24 #include <GL/glu.h> | |
25 #endif | |
26 #include "SDL.h" | |
27 | |
28 /* screen width, height, and bit depth */ | |
29 #define SCREEN_WIDTH 320 | |
30 #define SCREEN_HEIGHT 480 | |
31 #define SCREEN_BPP 16 | |
32 | |
33 /* Define our booleans */ | |
34 #define TRUE 1 | |
35 #define FALSE 0 | |
36 | |
37 /* This is our SDL surface */ | |
38 SDL_Surface *surface; | |
39 | |
40 | |
41 /************************************** | |
42 gluperspective implementation | |
43 **************************************/ | |
44 void gluPerspective(double fovy, double aspect, double zNear, double zFar){ | |
45 glMatrixMode(GL_PROJECTION); | |
46 glLoadIdentity(); | |
47 double xmin, xmax, ymin, ymax; | |
48 ymax = zNear * tan(fovy * M_PI / 360.0); | |
49 ymin = -ymax; | |
50 xmin = ymin * aspect; | |
51 xmax = ymax * aspect; | |
52 glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar); | |
53 } | |
54 | |
55 | |
56 /************************************** | |
57 glulookat implementation | |
58 **************************************/ | |
59 void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, | |
60 GLfloat centerx, GLfloat centery, GLfloat centerz, | |
61 GLfloat upx, GLfloat upy, GLfloat upz) | |
62 { | |
63 GLfloat m[16]; | |
64 GLfloat x[3], y[3], z[3]; | |
65 GLfloat mag; | |
66 | |
67 /* Make rotation matrix */ | |
68 | |
69 /* Z vector */ | |
70 z[0] = eyex - centerx; | |
71 z[1] = eyey - centery; | |
72 z[2] = eyez - centerz; | |
73 mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); | |
74 if (mag) { /* mpichler, 19950515 */ | |
75 z[0] /= mag; | |
76 z[1] /= mag; | |
77 z[2] /= mag; | |
78 } | |
79 | |
80 /* Y vector */ | |
81 y[0] = upx; | |
82 y[1] = upy; | |
83 y[2] = upz; | |
84 | |
85 /* X vector = Y cross Z */ | |
86 x[0] = y[1] * z[2] - y[2] * z[1]; | |
87 x[1] = -y[0] * z[2] + y[2] * z[0]; | |
88 x[2] = y[0] * z[1] - y[1] * z[0]; | |
89 | |
90 /* Recompute Y = Z cross X */ | |
91 y[0] = z[1] * x[2] - z[2] * x[1]; | |
92 y[1] = -z[0] * x[2] + z[2] * x[0]; | |
93 y[2] = z[0] * x[1] - z[1] * x[0]; | |
94 | |
95 /* mpichler, 19950515 */ | |
96 /* cross product gives area of parallelogram, which is < 1.0 for | |
97 * non-perpendicular unit-length vectors; so normalize x, y here | |
98 */ | |
99 | |
100 mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); | |
101 if (mag) { | |
102 x[0] /= mag; | |
103 x[1] /= mag; | |
104 x[2] /= mag; | |
105 } | |
106 | |
107 mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); | |
108 if (mag) { | |
109 y[0] /= mag; | |
110 y[1] /= mag; | |
111 y[2] /= mag; | |
112 } | |
113 | |
114 #define M(row,col) m[col*4+row] | |
115 M(0, 0) = x[0]; | |
116 M(0, 1) = x[1]; | |
117 M(0, 2) = x[2]; | |
118 M(0, 3) = 0.0; | |
119 M(1, 0) = y[0]; | |
120 M(1, 1) = y[1]; | |
121 M(1, 2) = y[2]; | |
122 M(1, 3) = 0.0; | |
123 M(2, 0) = z[0]; | |
124 M(2, 1) = z[1]; | |
125 M(2, 2) = z[2]; | |
126 M(2, 3) = 0.0; | |
127 M(3, 0) = 0.0; | |
128 M(3, 1) = 0.0; | |
129 M(3, 2) = 0.0; | |
130 M(3, 3) = 1.0; | |
131 #undef M | |
132 glMultMatrixf(m); | |
133 | |
134 /* Translate Eye to Origin */ | |
135 glTranslatef(-eyex, -eyey, -eyez); | |
136 | |
137 } | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 /* function to release/destroy our resources and restoring the old desktop */ | |
144 void Quit( int returnCode ) | |
145 { | |
146 /* clean up the window */ | |
147 SDL_Quit( ); | |
148 | |
149 /* and exit appropriately */ | |
150 exit( returnCode ); | |
151 } | |
152 | |
153 /* function to reset our viewport after a window resize */ | |
154 int resizeWindow( int width, int height ) | |
155 { | |
156 /* Height / width ration */ | |
157 GLfloat ratio; | |
158 | |
159 /* Protect against a divide by zero */ | |
160 if ( height == 0 ) | |
161 height = 1; | |
162 | |
163 ratio = ( GLfloat )width / ( GLfloat )height; | |
164 | |
165 /* Setup our viewport. */ | |
166 glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height ); | |
167 | |
168 /* change to the projection matrix and set our viewing volume. */ | |
169 glMatrixMode( GL_PROJECTION ); | |
170 glLoadIdentity( ); | |
171 | |
172 /* Set our perspective */ | |
173 gluPerspective( 45.0f, ratio, 0.1f, 100.0f ); | |
174 | |
175 /* Make sure we're chaning the model view and not the projection */ | |
176 glMatrixMode( GL_MODELVIEW ); | |
177 | |
178 /* Reset The View */ | |
179 glLoadIdentity( ); | |
180 | |
181 return( TRUE ); | |
182 } | |
183 | |
184 /* function to handle key press events */ | |
185 void handleKeyPress( SDL_keysym *keysym ) | |
186 { | |
187 switch ( keysym->sym ) | |
188 { | |
189 case SDLK_ESCAPE: | |
190 /* ESC key was pressed */ | |
191 Quit( 0 ); | |
192 break; | |
193 case SDLK_F1: | |
194 /* F1 key was pressed | |
195 * this toggles fullscreen mode | |
196 */ | |
197 SDL_WM_ToggleFullScreen( surface ); | |
198 break; | |
199 default: | |
200 break; | |
201 } | |
202 | |
203 return; | |
204 } | |
205 | |
206 /* general OpenGL initialization function */ | |
207 int initGL( GLvoid ) | |
208 { | |
209 | |
210 /* Enable smooth shading */ | |
211 glShadeModel( GL_SMOOTH ); | |
212 | |
213 /* Set the background black */ | |
214 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); | |
215 | |
216 /* Depth buffer setup */ | |
217 //glClearDepth( 1.0f ); | |
218 | |
219 /* Enables Depth Testing */ | |
220 glEnable( GL_DEPTH_TEST ); | |
221 | |
222 /* The Type Of Depth Test To Do */ | |
223 glDepthFunc( GL_LEQUAL ); | |
224 | |
225 /* Really Nice Perspective Calculations */ | |
226 glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); | |
227 | |
228 return( TRUE ); | |
229 } | |
230 | |
231 /* Here goes our drawing code */ | |
232 int drawGLScene( GLvoid ) | |
233 { | |
234 static int Frames = 0; | |
235 static int T0 = 0; | |
236 | |
237 glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); | |
238 | |
239 glClearColorx(0,0,Frames,255); | |
240 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); | |
241 | |
242 glMatrixMode(GL_PROJECTION); | |
243 glLoadIdentity(); | |
244 gluPerspective(45, (float)SCREEN_WIDTH / SCREEN_HEIGHT, 0.5f, 150); | |
245 | |
246 glMatrixMode(GL_MODELVIEW); | |
247 | |
248 glLoadIdentity(); | |
249 | |
250 //Camera | |
251 gluLookAt(0,0,5, 0,0,0, 0,1,0); | |
252 | |
253 //Draw a triangle | |
254 //glRotatef(iRot, 0, 1, 0); | |
255 | |
256 glRotatef( Frames % 360, 0.0f, 1.0f, 0.0f ); | |
257 | |
258 | |
259 glEnableClientState (GL_VERTEX_ARRAY); | |
260 glEnableClientState (GL_COLOR_ARRAY); | |
261 | |
262 /* Rotate The Triangle On The Y axis ( NEW ) */ | |
263 glRotatef( Frames % 360, 0.0f, 1.0f, 0.0f ); | |
264 | |
265 /* GLES variant of drawing a triangle */ | |
266 const GLfloat triVertices[][9] = { | |
267 { /* Front Triangle */ | |
268 0.0f, 1.0f, 0.0f, /* Top Of Triangle */ | |
269 -1.0f, -1.0f, 1.0f, /* Left Of Triangle */ | |
270 1.0f, -1.0f, 1.0f /* Right Of Triangle */ | |
271 }, { /* Right Triangle */ | |
272 0.0f, 1.0f, 0.0f, /* Top Of Triangle */ | |
273 1.0f, -1.0f, 1.0f, /* Left Of Triangle */ | |
274 1.0f, -1.0f, -1.0f /* Right Of Triangle */ | |
275 }, { /* Back Triangle */ | |
276 0.0f, 1.0f, 0.0f, /* Top Of Triangle */ | |
277 1.0f, -1.0f, -1.0f, /* Left Of Triangle */ | |
278 -1.0f, -1.0f, -1.0f /* Right Of Triangle */ | |
279 }, { /* Left Triangle */ | |
280 0.0f, 1.0f, 0.0f, /* Top Of Triangle */ | |
281 -1.0f, -1.0f, -1.0f, /* Left Of Triangle */ | |
282 -1.0f, -1.0f, 1.0f /* Right Of Triangle */ | |
283 } | |
284 }; | |
285 | |
286 /* unlike GL, GLES does not support RGB. We have to use RGBA instead */ | |
287 const GLfloat triColors[][12] = { | |
288 { /* Front triangle */ | |
289 1.0f, 0.0f, 0.0f, 1.0f, /* Red */ | |
290 0.0f, 1.0f, 0.0f, 1.0f, /* Green */ | |
291 0.0f, 0.0f, 1.0f, 1.0f /* Blue */ | |
292 }, { /* Right triangle */ | |
293 1.0f, 0.0f, 0.0f, 1.0f, /* Red */ | |
294 0.0f, 0.0f, 1.0f, 1.0f, /* Blue */ | |
295 0.0f, 1.0f, 0.0f, 1.0f /* Green */ | |
296 }, { /* Back triangle */ | |
297 1.0f, 0.0f, 0.0f, 1.0f, /* Red */ | |
298 0.0f, 1.0f, 0.0f, 1.0f, /* Green */ | |
299 0.0f, 0.0f, 1.0f, 1.0f /* Blue */ | |
300 }, { /* Left triangle */ | |
301 1.0f, 0.0f, 0.0f, 1.0f, /* Red */ | |
302 0.0f, 0.0f, 1.0f, 1.0f, /* Blue */ | |
303 0.0f, 1.0f, 0.0f, 1.0f /* Green */ | |
304 } | |
305 }; | |
306 | |
307 glEnableClientState(GL_COLOR_ARRAY); | |
308 | |
309 int tri=0; | |
310 | |
311 /* Loop through all Triangles */ | |
312 for(tri=0;tri<sizeof(triVertices)/(9*sizeof(GLfloat));tri++) | |
313 { | |
314 glVertexPointer(3, GL_FLOAT, 0, triVertices[tri]); | |
315 glColorPointer(4, GL_FLOAT, 0, triColors[tri]); | |
316 | |
317 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); | |
318 } | |
319 | |
320 //__android_log_print(ANDROID_LOG_INFO, "SDL", "render %d", Frames++); | |
321 | |
322 /* Draw it to the screen */ | |
323 SDL_GL_SwapBuffers( ); | |
324 | |
325 /* Gather our frames per second */ | |
326 Frames++; | |
327 { | |
328 GLint t = SDL_GetTicks(); | |
329 if (t - T0 >= 5000) { | |
330 GLfloat seconds = (t - T0) / 1000.0; | |
331 GLfloat fps = Frames / seconds; | |
332 __android_log_print(ANDROID_LOG_INFO, "SDL","%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); | |
333 T0 = t; | |
334 Frames = 0; | |
335 } | |
336 } | |
337 | |
338 return( TRUE ); | |
339 } | |
340 | |
341 int SDL_main( int argc, char **argv ) | |
342 { | |
343 | |
344 __android_log_print(ANDROID_LOG_INFO, "SDL","entry\n"); | |
345 | |
346 /* Flags to pass to SDL_SetVideoMode */ | |
347 int videoFlags; | |
348 /* main loop variable */ | |
349 int done = FALSE; | |
350 /* used to collect events */ | |
351 SDL_Event event; | |
352 /* this holds some info about our display */ | |
353 const SDL_VideoInfo *videoInfo; | |
354 /* whether or not the window is active */ | |
355 int isActive = TRUE; | |
356 | |
357 /* initialize SDL */ | |
358 if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) | |
359 { | |
360 __android_log_print(ANDROID_LOG_INFO, "SDL", "Video initialization failed: %s\n", | |
361 SDL_GetError( ) ); | |
362 Quit( 1 ); | |
363 } | |
364 | |
365 /* Fetch the video info */ | |
366 videoInfo = SDL_GetVideoInfo( ); | |
367 | |
368 if ( !videoInfo ) | |
369 { | |
370 __android_log_print(ANDROID_LOG_INFO, "SDL", "Video query failed: %s\n", | |
371 SDL_GetError( ) ); | |
372 Quit( 1 ); | |
373 } | |
374 | |
375 /* the flags to pass to SDL_SetVideoMode */ | |
376 videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */ | |
377 videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */ | |
378 videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */ | |
379 videoFlags |= SDL_RESIZABLE; /* Enable window resizing */ | |
380 | |
381 /* This checks to see if surfaces can be stored in memory */ | |
382 if ( videoInfo->hw_available ) | |
383 videoFlags |= SDL_HWSURFACE; | |
384 else | |
385 videoFlags |= SDL_SWSURFACE; | |
386 | |
387 /* This checks if hardware blits can be done */ | |
388 if ( videoInfo->blit_hw ) | |
389 videoFlags |= SDL_HWACCEL; | |
390 | |
391 /* Sets up OpenGL double buffering */ | |
392 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); | |
393 | |
394 /* get a SDL surface */ | |
395 surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, | |
396 videoFlags ); | |
397 | |
398 /* Verify there is a surface */ | |
399 if ( !surface ) | |
400 { | |
401 __android_log_print(ANDROID_LOG_INFO, "SDL", "Video mode set failed: %s\n", SDL_GetError( ) ); | |
402 Quit( 1 ); | |
403 } | |
404 | |
405 __android_log_print(ANDROID_LOG_INFO, "SDL","Made a video mode!\n"); | |
406 | |
407 /* initialize OpenGL */ | |
408 initGL( ); | |
409 | |
410 /* resize the initial window */ | |
411 resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT ); | |
412 | |
413 /* wait for events */ | |
414 while ( !done ) | |
415 { | |
416 /* handle the events in the queue */ | |
417 | |
418 while ( SDL_PollEvent( &event ) ) | |
419 { | |
420 switch( event.type ) | |
421 { | |
422 case SDL_ACTIVEEVENT: | |
423 /* Something's happend with our focus | |
424 * If we lost focus or we are iconified, we | |
425 * shouldn't draw the screen | |
426 */ | |
427 if ( event.active.gain == 0 ) | |
428 isActive = FALSE; | |
429 else | |
430 isActive = TRUE; | |
431 break; | |
432 case SDL_VIDEORESIZE: | |
433 /* handle resize event */ | |
434 surface = SDL_SetVideoMode( event.resize.w, | |
435 event.resize.h, | |
436 16, videoFlags ); | |
437 if ( !surface ) | |
438 { | |
439 __android_log_print(ANDROID_LOG_INFO, "SDL","Could not get a surface after resize: %s\n", SDL_GetError( ) ); | |
440 Quit( 1 ); | |
441 } | |
442 resizeWindow( event.resize.w, event.resize.h ); | |
443 break; | |
444 case SDL_KEYDOWN: | |
445 /* handle key presses */ | |
446 handleKeyPress( &event.key.keysym ); | |
447 break; | |
448 case SDL_QUIT: | |
449 /* handle quit requests */ | |
450 done = TRUE; | |
451 break; | |
452 default: | |
453 break; | |
454 } | |
455 } | |
456 | |
457 /* draw the scene */ | |
458 if ( isActive ) | |
459 drawGLScene( ); | |
460 } | |
461 | |
462 /* clean ourselves up and exit */ | |
463 Quit( 0 ); | |
464 | |
465 /* Should never get here */ | |
466 return( 0 ); | |
467 } | |
468 | |
469 |