testgl.c revision 9682c8870b8ff5e4ac2e4c70b759f791c6f38c1f
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <math.h>
5
6#include "SDL.h"
7
8#ifdef __MACOS__
9#define HAVE_OPENGL
10#endif
11
12#ifdef HAVE_OPENGL
13
14#include "SDL_opengl.h"
15
16/* Undefine this if you want a flat cube instead of a rainbow cube */
17#define SHADED_CUBE
18
19/* Define this to be the name of the logo image to use with -logo */
20#define LOGO_FILE	"icon.bmp"
21
22/* The SDL_OPENGLBLIT interface is deprecated.
23   The code is still available for benchmark purposes though.
24*/
25
26static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
27
28static SDL_Surface *global_image = NULL;
29static GLuint global_texture = 0;
30static GLuint cursor_texture = 0;
31
32/**********************************************************************/
33
34void HotKey_ToggleFullScreen(void)
35{
36	SDL_Surface *screen;
37
38	screen = SDL_GetVideoSurface();
39	if ( SDL_WM_ToggleFullScreen(screen) ) {
40		printf("Toggled fullscreen mode - now %s\n",
41		    (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
42	} else {
43		printf("Unable to toggle fullscreen mode\n");
44	}
45}
46
47void HotKey_ToggleGrab(void)
48{
49	SDL_GrabMode mode;
50
51	printf("Ctrl-G: toggling input grab!\n");
52	mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
53	if ( mode == SDL_GRAB_ON ) {
54		printf("Grab was on\n");
55	} else {
56		printf("Grab was off\n");
57	}
58	mode = SDL_WM_GrabInput(!mode);
59	if ( mode == SDL_GRAB_ON ) {
60		printf("Grab is now on\n");
61	} else {
62		printf("Grab is now off\n");
63	}
64}
65
66void HotKey_Iconify(void)
67{
68	printf("Ctrl-Z: iconifying window!\n");
69	SDL_WM_IconifyWindow();
70}
71
72int HandleEvent(SDL_Event *event)
73{
74	int done;
75
76	done = 0;
77	switch( event->type ) {
78	    case SDL_ACTIVEEVENT:
79		/* See what happened */
80		printf( "app %s ", event->active.gain ? "gained" : "lost" );
81		if ( event->active.state & SDL_APPACTIVE ) {
82			printf( "active " );
83		} else if ( event->active.state & SDL_APPMOUSEFOCUS ) {
84			printf( "mouse " );
85		} else if ( event->active.state & SDL_APPINPUTFOCUS ) {
86			printf( "input " );
87		}
88		printf( "focus\n" );
89		break;
90
91
92	    case SDL_KEYDOWN:
93		if ( event->key.keysym.sym == SDLK_ESCAPE ) {
94			done = 1;
95		}
96		if ( (event->key.keysym.sym == SDLK_g) &&
97		     (event->key.keysym.mod & KMOD_CTRL) ) {
98			HotKey_ToggleGrab();
99		}
100		if ( (event->key.keysym.sym == SDLK_z) &&
101		     (event->key.keysym.mod & KMOD_CTRL) ) {
102			HotKey_Iconify();
103		}
104		if ( (event->key.keysym.sym == SDLK_RETURN) &&
105		     (event->key.keysym.mod & KMOD_ALT) ) {
106			HotKey_ToggleFullScreen();
107		}
108		printf("key '%s' pressed\n",
109			SDL_GetKeyName(event->key.keysym.sym));
110		break;
111	    case SDL_QUIT:
112		done = 1;
113		break;
114	}
115	return(done);
116}
117
118void SDL_GL_Enter2DMode()
119{
120	SDL_Surface *screen = SDL_GetVideoSurface();
121
122	/* Note, there may be other things you need to change,
123	   depending on how you have your OpenGL state set up.
124	*/
125	glPushAttrib(GL_ENABLE_BIT);
126	glDisable(GL_DEPTH_TEST);
127	glDisable(GL_CULL_FACE);
128	glEnable(GL_TEXTURE_2D);
129
130	/* This allows alpha blending of 2D textures with the scene */
131	glEnable(GL_BLEND);
132	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133
134	glViewport(0, 0, screen->w, screen->h);
135
136	glMatrixMode(GL_PROJECTION);
137	glPushMatrix();
138	glLoadIdentity();
139
140	glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
141
142	glMatrixMode(GL_MODELVIEW);
143	glPushMatrix();
144	glLoadIdentity();
145
146	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
147}
148
149void SDL_GL_Leave2DMode()
150{
151	glMatrixMode(GL_MODELVIEW);
152	glPopMatrix();
153
154	glMatrixMode(GL_PROJECTION);
155	glPopMatrix();
156
157	glPopAttrib();
158}
159
160/* Quick utility function for texture creation */
161static int power_of_two(int input)
162{
163	int value = 1;
164
165	while ( value < input ) {
166		value <<= 1;
167	}
168	return value;
169}
170
171GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
172{
173	GLuint texture;
174	int w, h;
175	SDL_Surface *image;
176	SDL_Rect area;
177	Uint32 saved_flags;
178	Uint8  saved_alpha;
179
180	/* Use the surface width and height expanded to powers of 2 */
181	w = power_of_two(surface->w);
182	h = power_of_two(surface->h);
183	texcoord[0] = 0.0f;			/* Min X */
184	texcoord[1] = 0.0f;			/* Min Y */
185	texcoord[2] = (GLfloat)surface->w / w;	/* Max X */
186	texcoord[3] = (GLfloat)surface->h / h;	/* Max Y */
187
188	image = SDL_CreateRGBSurface(
189			SDL_SWSURFACE,
190			w, h,
191			32,
192#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
193			0x000000FF,
194			0x0000FF00,
195			0x00FF0000,
196			0xFF000000
197#else
198			0xFF000000,
199			0x00FF0000,
200			0x0000FF00,
201			0x000000FF
202#endif
203		       );
204	if ( image == NULL ) {
205		return 0;
206	}
207
208	/* Save the alpha blending attributes */
209	saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
210	saved_alpha = surface->format->alpha;
211	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
212		SDL_SetAlpha(surface, 0, 0);
213	}
214
215	/* Copy the surface into the GL texture image */
216	area.x = 0;
217	area.y = 0;
218	area.w = surface->w;
219	area.h = surface->h;
220	SDL_BlitSurface(surface, &area, image, &area);
221
222	/* Restore the alpha blending attributes */
223	if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
224		SDL_SetAlpha(surface, saved_flags, saved_alpha);
225	}
226
227	/* Create an OpenGL texture for the image */
228	glGenTextures(1, &texture);
229	glBindTexture(GL_TEXTURE_2D, texture);
230	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
231	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
232	glTexImage2D(GL_TEXTURE_2D,
233		     0,
234		     GL_RGBA,
235		     w, h,
236		     0,
237		     GL_RGBA,
238		     GL_UNSIGNED_BYTE,
239		     image->pixels);
240	SDL_FreeSurface(image); /* No longer needed */
241
242	return texture;
243}
244
245void DrawLogoCursor(void)
246{
247	static GLfloat texMinX, texMinY;
248	static GLfloat texMaxX, texMaxY;
249	static int w, h;
250	int x, y;
251
252	if ( ! cursor_texture ) {
253		SDL_Surface *image;
254		GLfloat texcoord[4];
255
256		/* Load the image (could use SDL_image library here) */
257		image = SDL_LoadBMP(LOGO_FILE);
258		if ( image == NULL ) {
259			return;
260		}
261		w = image->w;
262		h = image->h;
263
264		/* Convert the image into an OpenGL texture */
265		cursor_texture = SDL_GL_LoadTexture(image, texcoord);
266
267		/* Make texture coordinates easy to understand */
268		texMinX = texcoord[0];
269		texMinY = texcoord[1];
270		texMaxX = texcoord[2];
271		texMaxY = texcoord[3];
272
273		/* We don't need the original image anymore */
274		SDL_FreeSurface(image);
275
276		/* Make sure that the texture conversion is okay */
277		if ( ! cursor_texture ) {
278			return;
279		}
280	}
281
282	/* Move the image around */
283	SDL_GetMouseState(&x, &y);
284	x -= w/2;
285	y -= h/2;
286
287	/* Show the image on the screen */
288	SDL_GL_Enter2DMode();
289	glBindTexture(GL_TEXTURE_2D, cursor_texture);
290	glBegin(GL_TRIANGLE_STRIP);
291	glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
292	glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
293	glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
294	glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
295	glEnd();
296	SDL_GL_Leave2DMode();
297}
298
299void DrawLogoTexture(void)
300{
301	static GLfloat texMinX, texMinY;
302	static GLfloat texMaxX, texMaxY;
303	static int x = 0;
304	static int y = 0;
305	static int w, h;
306	static int delta_x = 1;
307	static int delta_y = 1;
308
309	SDL_Surface *screen = SDL_GetVideoSurface();
310
311	if ( ! global_texture ) {
312		SDL_Surface *image;
313		GLfloat texcoord[4];
314
315		/* Load the image (could use SDL_image library here) */
316		image = SDL_LoadBMP(LOGO_FILE);
317		if ( image == NULL ) {
318			return;
319		}
320		w = image->w;
321		h = image->h;
322
323		/* Convert the image into an OpenGL texture */
324		global_texture = SDL_GL_LoadTexture(image, texcoord);
325
326		/* Make texture coordinates easy to understand */
327		texMinX = texcoord[0];
328		texMinY = texcoord[1];
329		texMaxX = texcoord[2];
330		texMaxY = texcoord[3];
331
332		/* We don't need the original image anymore */
333		SDL_FreeSurface(image);
334
335		/* Make sure that the texture conversion is okay */
336		if ( ! global_texture ) {
337			return;
338		}
339	}
340
341	/* Move the image around */
342	x += delta_x;
343	if ( x < 0 ) {
344		x = 0;
345		delta_x = -delta_x;
346	} else
347	if ( (x+w) > screen->w ) {
348		x = screen->w-w;
349		delta_x = -delta_x;
350	}
351	y += delta_y;
352	if ( y < 0 ) {
353		y = 0;
354		delta_y = -delta_y;
355	} else
356	if ( (y+h) > screen->h ) {
357		y = screen->h-h;
358		delta_y = -delta_y;
359	}
360
361	/* Show the image on the screen */
362	SDL_GL_Enter2DMode();
363	glBindTexture(GL_TEXTURE_2D, global_texture);
364	glBegin(GL_TRIANGLE_STRIP);
365	glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
366	glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
367	glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
368	glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
369	glEnd();
370	SDL_GL_Leave2DMode();
371}
372
373/* This code is deprecated, but available for speed comparisons */
374void DrawLogoBlit(void)
375{
376	static int x = 0;
377	static int y = 0;
378	static int w, h;
379	static int delta_x = 1;
380	static int delta_y = 1;
381
382	SDL_Rect dst;
383	SDL_Surface *screen = SDL_GetVideoSurface();
384
385	if ( global_image == NULL ) {
386		SDL_Surface *temp;
387
388		/* Load the image (could use SDL_image library here) */
389		temp = SDL_LoadBMP(LOGO_FILE);
390		if ( temp == NULL ) {
391			return;
392		}
393		w = temp->w;
394		h = temp->h;
395
396		/* Convert the image into the screen format */
397		global_image = SDL_CreateRGBSurface(
398				SDL_SWSURFACE,
399				w, h,
400				screen->format->BitsPerPixel,
401				screen->format->Rmask,
402				screen->format->Gmask,
403				screen->format->Bmask,
404				screen->format->Amask);
405		if ( global_image ) {
406			SDL_BlitSurface(temp, NULL, global_image, NULL);
407		}
408		SDL_FreeSurface(temp);
409
410		/* Make sure that the texture conversion is okay */
411		if ( ! global_image ) {
412			return;
413		}
414	}
415
416	/* Move the image around
417           Note that we do not clear the old position.  This is because we
418           perform a glClear() which clears the framebuffer and then only
419           update the new area.
420           Note that you can also achieve interesting effects by modifying
421           the screen surface alpha channel.  It's set to 255 by default..
422         */
423	x += delta_x;
424	if ( x < 0 ) {
425		x = 0;
426		delta_x = -delta_x;
427	} else
428	if ( (x+w) > screen->w ) {
429		x = screen->w-w;
430		delta_x = -delta_x;
431	}
432	y += delta_y;
433	if ( y < 0 ) {
434		y = 0;
435		delta_y = -delta_y;
436	} else
437	if ( (y+h) > screen->h ) {
438		y = screen->h-h;
439		delta_y = -delta_y;
440	}
441	dst.x = x;
442	dst.y = y;
443	dst.w = w;
444	dst.h = h;
445	SDL_BlitSurface(global_image, NULL, screen, &dst);
446
447	/* Show the image on the screen */
448	SDL_UpdateRects(screen, 1, &dst);
449}
450
451int RunGLTest( int argc, char* argv[],
452               int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync, int accel )
453{
454	int i;
455	int rgb_size[3];
456	int w = 640;
457	int h = 480;
458	int done = 0;
459	int frames;
460	Uint32 start_time, this_time;
461        float color[8][3]= {{ 1.0,  1.0,  0.0},
462			    { 1.0,  0.0,  0.0},
463			    { 0.0,  0.0,  0.0},
464			    { 0.0,  1.0,  0.0},
465			    { 0.0,  1.0,  1.0},
466			    { 1.0,  1.0,  1.0},
467			    { 1.0,  0.0,  1.0},
468			    { 0.0,  0.0,  1.0}};
469	float cube[8][3]= {{ 0.5,  0.5, -0.5},
470			   { 0.5, -0.5, -0.5},
471			   {-0.5, -0.5, -0.5},
472			   {-0.5,  0.5, -0.5},
473			   {-0.5,  0.5,  0.5},
474			   { 0.5,  0.5,  0.5},
475			   { 0.5, -0.5,  0.5},
476			   {-0.5, -0.5,  0.5}};
477	Uint32 video_flags;
478	int value;
479
480	if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
481		fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
482		exit( 1 );
483	}
484
485	/* See if we should detect the display depth */
486	if ( bpp == 0 ) {
487		if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
488			bpp = 8;
489		} else {
490			bpp = 16;  /* More doesn't seem to work */
491		}
492	}
493
494	/* Set the flags we want to use for setting the video mode */
495	if ( logo && USE_DEPRECATED_OPENGLBLIT ) {
496		video_flags = SDL_OPENGLBLIT;
497	} else {
498		video_flags = SDL_OPENGL;
499	}
500	for ( i=1; argv[i]; ++i ) {
501		if ( strcmp(argv[i], "-fullscreen") == 0 ) {
502			video_flags |= SDL_FULLSCREEN;
503		}
504	}
505
506        if (noframe) {
507           video_flags |= SDL_NOFRAME;
508        }
509
510	/* Initialize the display */
511	switch (bpp) {
512	    case 8:
513		rgb_size[0] = 3;
514		rgb_size[1] = 3;
515		rgb_size[2] = 2;
516		break;
517	    case 15:
518	    case 16:
519		rgb_size[0] = 5;
520		rgb_size[1] = 5;
521		rgb_size[2] = 5;
522		break;
523            default:
524		rgb_size[0] = 8;
525		rgb_size[1] = 8;
526		rgb_size[2] = 8;
527		break;
528	}
529	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
530	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
531	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
532	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
533	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
534	if ( fsaa ) {
535		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
536		SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa );
537	}
538	if ( accel ) {
539		SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
540	}
541	if ( sync ) {
542		SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
543	} else {
544		SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
545	}
546	if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
547		fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
548		SDL_Quit();
549		exit(1);
550	}
551
552	printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
553	printf("\n");
554	printf( "Vendor     : %s\n", glGetString( GL_VENDOR ) );
555	printf( "Renderer   : %s\n", glGetString( GL_RENDERER ) );
556	printf( "Version    : %s\n", glGetString( GL_VERSION ) );
557	printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
558	printf("\n");
559
560	SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
561	printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
562	SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
563	printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
564	SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
565	printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
566	SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
567	printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
568	SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
569	printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
570	if ( fsaa ) {
571		SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &value );
572		printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value );
573		SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value );
574		printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value );
575	}
576	if ( accel ) {
577		SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &value );
578		printf( "SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value );
579	}
580	if ( sync ) {
581		SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL, &value );
582		printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value );
583	}
584
585	/* Set the window manager title bar */
586	SDL_WM_SetCaption( "SDL GL test", "testgl" );
587
588	/* Set the gamma for the window */
589	if ( gamma != 0.0 ) {
590		SDL_SetGamma(gamma, gamma, gamma);
591	}
592
593	glViewport( 0, 0, w, h );
594	glMatrixMode( GL_PROJECTION );
595	glLoadIdentity( );
596
597	glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
598
599	glMatrixMode( GL_MODELVIEW );
600	glLoadIdentity( );
601
602	glEnable(GL_DEPTH_TEST);
603
604	glDepthFunc(GL_LESS);
605
606	glShadeModel(GL_SMOOTH);
607
608	/* Loop until done. */
609	start_time = SDL_GetTicks();
610	frames = 0;
611	while( !done ) {
612		GLenum gl_error;
613		char* sdl_error;
614		SDL_Event event;
615
616		/* Do our drawing, too. */
617		glClearColor( 0.0, 0.0, 0.0, 1.0 );
618		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
619
620		glBegin( GL_QUADS );
621
622#ifdef SHADED_CUBE
623			glColor3fv(color[0]);
624			glVertex3fv(cube[0]);
625			glColor3fv(color[1]);
626			glVertex3fv(cube[1]);
627			glColor3fv(color[2]);
628			glVertex3fv(cube[2]);
629			glColor3fv(color[3]);
630			glVertex3fv(cube[3]);
631
632			glColor3fv(color[3]);
633			glVertex3fv(cube[3]);
634			glColor3fv(color[4]);
635			glVertex3fv(cube[4]);
636			glColor3fv(color[7]);
637			glVertex3fv(cube[7]);
638			glColor3fv(color[2]);
639			glVertex3fv(cube[2]);
640
641			glColor3fv(color[0]);
642			glVertex3fv(cube[0]);
643			glColor3fv(color[5]);
644			glVertex3fv(cube[5]);
645			glColor3fv(color[6]);
646			glVertex3fv(cube[6]);
647			glColor3fv(color[1]);
648			glVertex3fv(cube[1]);
649
650			glColor3fv(color[5]);
651			glVertex3fv(cube[5]);
652			glColor3fv(color[4]);
653			glVertex3fv(cube[4]);
654			glColor3fv(color[7]);
655			glVertex3fv(cube[7]);
656			glColor3fv(color[6]);
657			glVertex3fv(cube[6]);
658
659			glColor3fv(color[5]);
660			glVertex3fv(cube[5]);
661			glColor3fv(color[0]);
662			glVertex3fv(cube[0]);
663			glColor3fv(color[3]);
664			glVertex3fv(cube[3]);
665			glColor3fv(color[4]);
666			glVertex3fv(cube[4]);
667
668			glColor3fv(color[6]);
669			glVertex3fv(cube[6]);
670			glColor3fv(color[1]);
671			glVertex3fv(cube[1]);
672			glColor3fv(color[2]);
673			glVertex3fv(cube[2]);
674			glColor3fv(color[7]);
675			glVertex3fv(cube[7]);
676#else /* flat cube */
677			glColor3f(1.0, 0.0, 0.0);
678			glVertex3fv(cube[0]);
679			glVertex3fv(cube[1]);
680			glVertex3fv(cube[2]);
681			glVertex3fv(cube[3]);
682
683			glColor3f(0.0, 1.0, 0.0);
684			glVertex3fv(cube[3]);
685			glVertex3fv(cube[4]);
686			glVertex3fv(cube[7]);
687			glVertex3fv(cube[2]);
688
689			glColor3f(0.0, 0.0, 1.0);
690			glVertex3fv(cube[0]);
691			glVertex3fv(cube[5]);
692			glVertex3fv(cube[6]);
693			glVertex3fv(cube[1]);
694
695			glColor3f(0.0, 1.0, 1.0);
696			glVertex3fv(cube[5]);
697			glVertex3fv(cube[4]);
698			glVertex3fv(cube[7]);
699			glVertex3fv(cube[6]);
700
701			glColor3f(1.0, 1.0, 0.0);
702			glVertex3fv(cube[5]);
703			glVertex3fv(cube[0]);
704			glVertex3fv(cube[3]);
705			glVertex3fv(cube[4]);
706
707			glColor3f(1.0, 0.0, 1.0);
708			glVertex3fv(cube[6]);
709			glVertex3fv(cube[1]);
710			glVertex3fv(cube[2]);
711			glVertex3fv(cube[7]);
712#endif /* SHADED_CUBE */
713
714		glEnd( );
715
716		glMatrixMode(GL_MODELVIEW);
717		glRotatef(5.0, 1.0, 1.0, 1.0);
718
719		/* Draw 2D logo onto the 3D display */
720		if ( logo ) {
721			if ( USE_DEPRECATED_OPENGLBLIT ) {
722				DrawLogoBlit();
723			} else {
724				DrawLogoTexture();
725			}
726		}
727		if ( logocursor ) {
728			DrawLogoCursor();
729		}
730
731		SDL_GL_SwapBuffers( );
732
733		/* Check for error conditions. */
734		gl_error = glGetError( );
735
736		if( gl_error != GL_NO_ERROR ) {
737			fprintf( stderr, "testgl: OpenGL error: %d\n", gl_error );
738		}
739
740		sdl_error = SDL_GetError( );
741
742		if( sdl_error[0] != '\0' ) {
743			fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
744			SDL_ClearError();
745		}
746
747		/* Allow the user to see what's happening */
748		if ( slowly ) {
749			SDL_Delay( 20 );
750		}
751
752		/* Check if there's a pending event. */
753		while( SDL_PollEvent( &event ) ) {
754			done = HandleEvent(&event);
755		}
756		++frames;
757	}
758
759	/* Print out the frames per second */
760	this_time = SDL_GetTicks();
761	if ( this_time != start_time ) {
762		printf("%2.2f FPS\n",
763			((float)frames/(this_time-start_time))*1000.0);
764	}
765
766	if ( global_image ) {
767	   	SDL_FreeSurface(global_image);
768		global_image = NULL;
769	}
770	if ( global_texture ) {
771		glDeleteTextures( 1, &global_texture );
772		global_texture = 0;
773	}
774	if ( cursor_texture ) {
775		glDeleteTextures( 1, &cursor_texture );
776		cursor_texture = 0;
777	}
778
779	/* Destroy our GL context, etc. */
780	SDL_Quit( );
781	return(0);
782}
783
784int main(int argc, char *argv[])
785{
786	int i, logo, logocursor = 0;
787	int numtests;
788	int bpp = 0;
789	int slowly;
790	float gamma = 0.0;
791	int noframe = 0;
792	int fsaa = 0;
793	int accel = 0;
794	int sync = 0;
795
796	logo = 0;
797	slowly = 0;
798	numtests = 1;
799	for ( i=1; argv[i]; ++i ) {
800		if ( strcmp(argv[i], "-twice") == 0 ) {
801			++numtests;
802		}
803		if ( strcmp(argv[i], "-logo") == 0 ) {
804			logo = 1;
805			USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
806		}
807		if ( strcmp(argv[i], "-logoblit") == 0 ) {
808			logo = 1;
809			USE_DEPRECATED_OPENGLBLIT = SDL_TRUE;
810		}
811		if ( strcmp(argv[i], "-logocursor") == 0 ) {
812			logocursor = 1;
813		}
814		if ( strcmp(argv[i], "-slow") == 0 ) {
815			slowly = 1;
816		}
817		if ( strcmp(argv[i], "-bpp") == 0 ) {
818 		       bpp = atoi(argv[++i]);
819		}
820		if ( strcmp(argv[i], "-gamma") == 0 ) {
821 		       gamma = (float)atof(argv[++i]);
822		}
823		if ( strcmp(argv[i], "-noframe") == 0 ) {
824 		       noframe = 1;
825		}
826		if ( strcmp(argv[i], "-fsaa") == 0 ) {
827 		       ++fsaa;
828		}
829		if ( strcmp(argv[i], "-accel") == 0 ) {
830 		       ++accel;
831		}
832		if ( strcmp(argv[i], "-sync") == 0 ) {
833 		       ++sync;
834		}
835		if ( strncmp(argv[i], "-h", 2) == 0 ) {
836 		       printf(
837"Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel] [-sync] [-fullscreen]\n",
838 			      argv[0]);
839			exit(0);
840		}
841	}
842	for ( i=0; i<numtests; ++i ) {
843 		RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa, sync, accel);
844	}
845	return 0;
846}
847
848#else /* HAVE_OPENGL */
849
850int main(int argc, char *argv[])
851{
852	printf("No OpenGL support on this system\n");
853	return 1;
854}
855
856#endif /* HAVE_OPENGL */
857