VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/OpenGL/test/tstOGLSphere.c@ 8760

Last change on this file since 8760 was 8387, checked in by vboxsync, 17 years ago

eol

  • Property svn:eol-style set to native
File size: 28.7 KB
Line 
1#include <math.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <time.h>
5
6#include <windows.h>
7#include <mmsystem.h>
8
9#include <gl/gl.h>
10
11#define PI_OVER_180 0.01745329F
12#define DEG2RAD( a ) ( (a) * PI_OVER_180 )
13
14#define ELEMENTS_PER_VERTEX 3
15#define ELEMENTS_PER_NORMAL 3
16#define BYTES_PER_CACHELINE 32
17
18/* struct used to manage color ramps */
19struct colorIndexState {
20 GLfloat amb[3]; /* ambient color / bottom of ramp */
21 GLfloat diff[3]; /* diffuse color / middle of ramp */
22 GLfloat spec[3]; /* specular color / top of ramp */
23 GLfloat ratio; /* ratio of diffuse to specular in ramp */
24 GLint indexes[3]; /* where ramp was placed in palette */
25};
26
27#define NUM_COLORS (sizeof(s_colors) / sizeof(s_colors[0]))
28struct colorIndexState s_colors[] = {
29 {
30 { 0.0F, 0.0F, 0.0F },
31 { 1.0F, 0.0F, 0.0F },
32 { 1.0F, 1.0F, 1.0F },
33 0.75F, { 0, 0, 0 },
34 },
35 {
36 { 0.0F, 0.05F, 0.05F },
37 { 0.9F, 0.0F, 1.0F },
38 { 1.0F, 1.0F, 1.0F },
39 1.0F, { 0, 0, 0 },
40 },
41 {
42 { 0.0F, 0.0F, 0.0F },
43 { 1.0F, 0.9F, 0.1F },
44 { 1.0F, 1.0F, 1.0F },
45 0.75F, { 0, 0, 0 },
46 },
47 {
48 { 0.0F, 0.0F, 0.0F },
49 { 0.1F, 1.0F, 0.9F },
50 { 1.0F, 1.0F, 1.0F },
51 0.75F, { 0, 0, 0 },
52 },
53};
54
55static void (APIENTRY *LockArraysSGI)(GLint first, GLsizei count);
56static void (APIENTRY *UnlockArraysSGI)(void);
57static void (APIENTRY *CullParameterfvSGI)( GLenum pname, GLfloat *params );
58
59static GLint s_lit_tex_indexes[3];
60
61static int s_num_rows = 16;
62static int s_num_cols = 16;
63
64static int s_winwidth = 320;
65static int s_winheight = 240;
66
67#define MS_TO_RENDER 5000
68
69#define DRAW_VERTEX3FV 0
70#define DRAW_DRAW_ELEMENTS 1
71#define DRAW_DRAW_ARRAYS 2
72#define DRAW_ARRAY_ELEMENT 3
73
74static const char *s_class_name = "GL Sphere";
75static const char *s_window_name = "GL Sphere";
76
77static BOOL s_rgba = TRUE;
78static BOOL s_lighting = TRUE;
79static BOOL s_benchmark = FALSE;
80static BOOL s_remote = FALSE;
81static BOOL s_lock_arrays = TRUE;
82static BOOL s_vcull = TRUE;
83
84static HPALETTE s_hPalette = NULL;
85static HWND s_hWnd = NULL;
86static HGLRC s_hglrc = NULL;
87static HDC s_hDC = NULL;
88static int s_bpp = 8;
89static int s_draw_method = DRAW_VERTEX3FV;
90
91static unsigned long s_vertices_processed = 0L;
92static unsigned long s_triangles_processed = 0L;
93static float s_elapsed_time;
94static unsigned long s_start, s_stop;
95
96/*
97** this maintains the data for drawing stuff via tristrips
98*/
99static float **s_sphere_points;
100static float **s_sphere_normals;
101
102/*
103** this maintains the data for drawing stuff via vertex arrays and array elements
104*/
105static float *s_sphere_point_array;
106static float *s_sphere_normal_array;
107
108/*
109** this stores the data for drawing stuff using interleaved arrays with
110** draw elements
111*/
112static float *s_sphere_interleaved_array;
113static unsigned int **s_sphere_elements;
114
115/*
116** this maintains the data for drawing stuff via vertex arrays and drawarrays
117*/
118static float **s_sphere_point_draw_array;
119static float **s_sphere_normal_draw_array;
120
121static BOOL SphereCreateGeometry( int rows, int cols, float scale );
122static BOOL InitSphere( HINSTANCE hInstance, LPSTR lpszCmdLine );
123static void ShutdownSphere( void );
124static void SphereSetDefaults( void );
125static void SphereNormalizeVector( float v[3] );
126static void SphereHelp( void );
127static void SphereSetupPalette( HDC hDC );
128
129static void *AllocAlignedX( int num_bytes, int byte_alignment );
130
131static void SphereRedraw( void );
132
133static BOOL SphereSetupPixelFormat( HDC hDC );
134
135static LRESULT APIENTRY WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
136
137
138int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
139 LPSTR lpszCmdLine,
140 int nCmdShow )
141{
142 MSG msg;
143
144 if ( InitSphere( hInstance, lpszCmdLine ) )
145 {
146 ShowWindow( s_hWnd, nCmdShow );
147 UpdateWindow( s_hWnd );
148
149 while ( 1 )
150 {
151 if ( s_benchmark )
152 {
153 int i;
154 int vertices_to_render = 1000000;
155 int frames_to_render = vertices_to_render / ( s_num_rows * ( s_num_cols * 2 + 2 ) );
156
157 if ( frames_to_render < 1 ) frames_to_render = 1;
158
159 s_start = timeGetTime();
160
161 for ( i = 0; i < frames_to_render; i++ )
162 {
163 SphereRedraw();
164 }
165 glFinish();
166 s_stop = timeGetTime();
167 s_elapsed_time = ( s_stop - s_start ) / 1000.0F;
168 ShutdownSphere();
169 return 0;
170 }
171 else
172 {
173 while ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) == FALSE )
174 {
175 SphereRedraw();
176 }
177 if ( GetMessage( &msg, NULL, 0, 0 ) != TRUE )
178 {
179 ShutdownSphere();
180 return msg.wParam;
181 }
182 TranslateMessage( &msg );
183 DispatchMessage( &msg );
184 }
185 }
186 }
187
188 return 0;
189}
190
191static LRESULT APIENTRY WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
192{
193 switch ( msg )
194 {
195 case WM_CREATE:
196 s_hDC = GetDC( hWnd );
197
198 if ( !SphereSetupPixelFormat( s_hDC ) )
199 exit( 1 );
200 SphereSetupPalette( s_hDC );
201 s_hglrc = wglCreateContext( s_hDC );
202 wglMakeCurrent( s_hDC, s_hglrc );
203 /*
204 ** see what kind of extensions are supported
205 */
206 if ( strstr( glGetString( GL_EXTENSIONS ), "GL_SGI_compiled_vertex_array " ) != 0 )
207 {
208 LockArraysSGI = ( void (APIENTRY *)(GLint, GLint) ) wglGetProcAddress( "glLockArraysSGI" );
209 UnlockArraysSGI = ( void (APIENTRY *)( void ) ) wglGetProcAddress( "glUnlockArraysSGI" );
210 }
211#ifdef GL_SGI_cull_vertex
212 if ( s_vcull )
213 {
214 if ( strstr( glGetString( GL_EXTENSIONS ), "GL_SGI_cull_vertex" ) )
215 {
216 if ( ( CullParameterfvSGI = ( void (APIENTRY *)(GLenum, GLfloat*) ) wglGetProcAddress( "glCullParameterfvSGI" ) ) == 0 )
217 {
218 MessageBox( 0, "-vcull specified but wglGetProcAddress failed", "Sphere Warning", MB_OK | MB_ICONINFORMATION );
219 s_vcull = FALSE;
220 }
221 }
222 else
223 {
224 s_vcull = FALSE;
225 MessageBox( 0, "-vcull specified but no vcull extension exists", "Sphere Warning", MB_OK | MB_ICONINFORMATION );
226 }
227 }
228#endif
229
230 SphereSetDefaults();
231
232 /*
233 ** set vertex and normal array pointers
234 */
235 if ( s_draw_method == DRAW_ARRAY_ELEMENT )
236 {
237 glEnableClientState( GL_VERTEX_ARRAY );
238 glEnableClientState( GL_NORMAL_ARRAY );
239 glVertexPointer( ELEMENTS_PER_VERTEX, GL_FLOAT, 0, ( const GLvoid * ) s_sphere_point_array );
240 glNormalPointer( GL_FLOAT, ELEMENTS_PER_NORMAL * sizeof( float ) , ( const GLfloat * ) s_sphere_normal_array );
241 }
242 else if ( s_draw_method == DRAW_DRAW_ARRAYS )
243 {
244 glEnableClientState( GL_VERTEX_ARRAY );
245 glEnableClientState( GL_NORMAL_ARRAY );
246 }
247 else if ( s_draw_method == DRAW_DRAW_ELEMENTS )
248 {
249 }
250
251 {
252 char buffer[1000], buf2[1000];
253 char *dummy;
254
255 SearchPath( NULL, "opengl32.dll", NULL, 1000, buffer, &dummy );
256 sprintf( buf2, "GL Sphere (%s)", buffer );
257 SetWindowText( hWnd, buf2 );
258 }
259 return 0;
260 case WM_DESTROY:
261 PostQuitMessage( 0 );
262 return 0;
263 case WM_CHAR:
264 switch ( wParam )
265 {
266 case 'd':
267 s_draw_method = DRAW_DRAW_ELEMENTS;
268 glDisableClientState( GL_VERTEX_ARRAY );
269 glDisableClientState( GL_NORMAL_ARRAY );
270 break;
271 case 'a':
272 s_draw_method = DRAW_DRAW_ARRAYS;
273 glEnableClientState( GL_VERTEX_ARRAY );
274 glEnableClientState( GL_NORMAL_ARRAY );
275 break;
276 case 'l':
277 s_lock_arrays = !s_lock_arrays;
278 break;
279 case 27:
280 PostQuitMessage( 0 );
281 return 0;
282 }
283 break;
284 case WM_SIZE:
285 if ( s_hglrc )
286 {
287 int winWidth = ( int ) LOWORD( lParam );
288 int winHeight = ( int ) HIWORD( lParam );
289
290 glViewport( 0, 0, winWidth, winHeight );
291 }
292 return 0;
293 case WM_PALETTECHANGED:
294 if (s_hPalette != NULL && (HWND) wParam != hWnd)
295 {
296 UnrealizeObject( s_hPalette );
297 SelectPalette( s_hDC, s_hPalette, FALSE );
298 RealizePalette( s_hDC );
299 return 0;
300 }
301 break;
302 case WM_QUERYNEWPALETTE:
303 if ( s_hPalette != NULL )
304 {
305 UnrealizeObject( s_hPalette );
306 SelectPalette( s_hDC, s_hPalette, FALSE );
307 RealizePalette( s_hDC );
308 return TRUE;
309 }
310 break;
311 case WM_COMMAND:
312 break;
313 }
314
315 return DefWindowProc( hWnd, msg, wParam, lParam);
316}
317
318static BOOL InitSphere( HINSTANCE hInstance, LPSTR lpszCmdLine )
319{
320 WNDCLASS wc;
321
322 wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
323 wc.lpfnWndProc = WndProc;
324 wc.cbClsExtra = 0;
325 wc.cbWndExtra = 0;
326 wc.hInstance = hInstance;
327 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
328 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
329 wc.hbrBackground = GetStockObject(WHITE_BRUSH);
330 wc.lpszMenuName = NULL;
331 wc.lpszClassName = s_class_name;
332
333 RegisterClass( &wc );
334
335 {
336 HDC hdc = GetDC( 0 );
337
338 s_bpp = GetDeviceCaps( hdc, BITSPIXEL );
339
340#if NOTYET
341 if ( ( s_bpp <= 8 ) && !strstr( lpszCmdLine, "-332" ) )
342 s_rgba = 0;
343 else
344#endif
345
346 s_rgba = 1;
347
348 ReleaseDC( 0, hdc );
349 }
350
351 /*
352 ** check to see how to draw the sphere
353 */
354 if ( strstr( lpszCmdLine, "-arrayelement" ) )
355 s_draw_method = DRAW_ARRAY_ELEMENT;
356 else if ( strstr( lpszCmdLine, "-drawarrays" ) )
357 s_draw_method = DRAW_DRAW_ARRAYS;
358 else if ( strstr( lpszCmdLine, "-drawelements" ) )
359 s_draw_method = DRAW_DRAW_ELEMENTS;
360 else
361 s_draw_method = DRAW_VERTEX3FV;
362
363 if ( strstr( lpszCmdLine, "-benchmark" ) )
364 s_benchmark = TRUE;
365 if ( strstr( lpszCmdLine, "-remote" ) )
366 s_remote = TRUE;
367
368 if ( strstr( lpszCmdLine, "-rows:" ) )
369 {
370 s_num_rows = atoi( strchr( strstr( lpszCmdLine, "-rows:" ), ':' ) + 1 );
371 }
372 if ( strstr( lpszCmdLine, "-cols:" ) )
373 {
374 s_num_cols = atoi( strchr( strstr( lpszCmdLine, "-cols:" ), ':' ) + 1 );
375 }
376
377 if ( strstr( lpszCmdLine, "-nolockarrays" ) )
378 s_lock_arrays = FALSE;
379
380 if ( strstr( lpszCmdLine, "-novcull" ) )
381 s_vcull = FALSE;
382
383 if ( strstr( lpszCmdLine, "-?" ) || strstr( lpszCmdLine, "/?" ) )
384 {
385 SphereHelp();
386 return FALSE;
387 }
388
389 if ( strstr( lpszCmdLine, "-width:" ) )
390 s_winwidth = atoi( strchr( strstr( lpszCmdLine, "-width:" ), ':' ) + 1 );
391 if ( strstr( lpszCmdLine, "-height:" ) )
392 s_winheight = atoi( strchr( strstr( lpszCmdLine, "-height:" ), ':' ) + 1 );
393
394 /*
395 ** create geometry
396 */
397 if ( !SphereCreateGeometry( s_num_rows, s_num_cols, 1.0F ) )
398 return FALSE;
399
400 /*
401 ** create a window of the previously defined class
402 */
403 s_hWnd = CreateWindow( s_class_name,
404 s_window_name,
405 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
406 10, 10,
407 s_winwidth, s_winheight,
408 NULL,
409 NULL,
410 hInstance,
411 NULL );
412
413 if ( s_hWnd != NULL )
414 return TRUE;
415 return FALSE;
416}
417
418void ShutdownSphere( void )
419{
420 if ( s_benchmark && !s_remote )
421 {
422 char buffer[1000]="";
423 char temp[100];
424
425 sprintf( temp, "Vendor: %s\n\n", glGetString( GL_VENDOR ) );
426 strcat( buffer, temp );
427
428 sprintf( temp, "%.2f vertices/second\n", s_vertices_processed / s_elapsed_time );
429 strcat( buffer, temp );
430
431 sprintf( temp, "%.2f triangles/second\n", s_triangles_processed / s_elapsed_time );
432 strcat( buffer, temp );
433
434 MessageBox( 0, buffer, "Performance", MB_OK | MB_ICONINFORMATION );
435 }
436
437 if ( s_hglrc )
438 {
439 wglMakeCurrent( NULL, NULL );
440 wglDeleteContext( s_hglrc );
441 }
442 ReleaseDC( s_hWnd, s_hDC );
443
444}
445
446static BOOL SphereSetupPixelFormat( HDC hDC )
447{
448 unsigned char pixelType = s_rgba ? PFD_TYPE_RGBA : PFD_TYPE_COLORINDEX;
449 PIXELFORMATDESCRIPTOR pfd =
450 {
451 sizeof( PIXELFORMATDESCRIPTOR ),
452 1,
453 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
454 pixelType,
455 s_bpp,
456 0, 0, 0, 0, 0, 0,
457 0,
458 0,
459 0,
460 0, 0, 0, 0,
461 16, // 16-bit depth buffer
462 0, // no stencil buffer
463 0, // no aux buffers
464 PFD_MAIN_PLANE, /* main layer */
465 0,
466 0, 0, 0
467 };
468 int selected_pf;
469
470 if ( ( selected_pf = ChoosePixelFormat( hDC, &pfd ) ) == 0 )
471 {
472 MessageBox( 0, "Failed to find acceptable pixel format", "GL Sphere Error", MB_ICONERROR | MB_OK );
473 return FALSE;
474 }
475
476 if ( !SetPixelFormat( hDC, selected_pf, &pfd) )
477 {
478 MessageBox( 0, "Failed to SetPixelFormat", "GL Sphere Error", MB_ICONERROR | MB_OK );
479 return FALSE;
480 }
481 return TRUE;
482}
483
484static void SphereSetDefaults( void )
485{
486 // setup a default color
487 glColor3f( 1.0F, 1.0F, 1.0F );
488 glClearColor( 0.0F, 0.0F, 1.0F, 1.0F );
489
490#if 0
491 glClearDepth( 1.0F );
492 glDepthFunc( GL_LEQUAL );
493 glEnable( GL_DEPTH_TEST );
494 glDepthMask( GL_TRUE );
495#endif
496
497 // setup perspective
498 glMatrixMode( GL_PROJECTION );
499 glFrustum( -0.5, 0.5, -0.5, 0.5, 1.0, 1000.0 );
500
501 // setup viewer
502 glMatrixMode( GL_MODELVIEW );
503 glLoadIdentity();
504 glTranslatef( 0.0F, 0.0F, -3.0F );
505
506 // setup Z-buffering
507 // setup shade model
508 glShadeModel( GL_SMOOTH );
509
510 // setup lighting
511 if ( !s_lighting )
512 {
513 glDisable( GL_LIGHTING );
514 glDisable( GL_LIGHT0 );
515 }
516 else
517 {
518 GLfloat light0Pos[4] = { 0.70F, 0.70F, 1.25F, 0.00F };
519 GLfloat matAmb[4] = { 0.01F, 0.01F, 0.01F, 1.00F };
520 GLfloat matDiff[4] = { 0.65F, 0.05F, 0.20F, 0.60F };
521 GLfloat matSpec[4] = { 0.50F, 0.50F, 0.50F, 1.00F };
522 GLfloat matShine = 20.00F;
523
524 glEnable( GL_LIGHTING );
525 glEnable( GL_LIGHT0 );
526 glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
527 glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
528 glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff);
529 glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
530 glMaterialf(GL_FRONT, GL_SHININESS, matShine);
531 }
532
533 // setup cull mode
534 glEnable( GL_CULL_FACE );
535
536#ifdef GL_SGI_cull_vertex
537 if ( s_vcull )
538 {
539 GLfloat eyeDir[] = { 0.0F, 0.0F, 1.0F, 0.0F };
540
541 glEnable(GL_CULL_VERTEX_SGI);
542
543 if ( CullParameterfvSGI )
544 CullParameterfvSGI( GL_CULL_VERTEX_EYE_POSITION_SGI, eyeDir );
545 }
546 else
547 {
548 glDisable(GL_CULL_VERTEX_SGI);
549 }
550#endif
551
552 // setup dither
553 glEnable( GL_DITHER );
554
555 glClear( GL_COLOR_BUFFER_BIT );
556 SwapBuffers( s_hDC );
557}
558
559static BOOL SphereCreateGeometry( int rows, int cols, float scale )
560{
561 float cap_offset = 10.0F;
562
563 float x_delta = ( 360.0F - 2.0f * cap_offset ) / cols;
564 float y_delta = ( 180.0F - 2.0f * cap_offset ) / rows;
565 int row, col;
566 int num_vertex_rows = rows + 1;
567 int num_vertex_cols = cols;
568
569 float *spa, *sna, *sia;
570
571 s_sphere_points = ( float ** ) AllocAlignedX( sizeof( float ) * num_vertex_rows, BYTES_PER_CACHELINE );
572 s_sphere_normals = ( float ** ) AllocAlignedX( sizeof( float ) * num_vertex_rows, BYTES_PER_CACHELINE );
573
574 spa = s_sphere_point_array = ( float * ) AllocAlignedX( sizeof( float ) * ELEMENTS_PER_VERTEX * num_vertex_rows * num_vertex_cols, BYTES_PER_CACHELINE );
575 sna = s_sphere_normal_array = ( float * ) AllocAlignedX( sizeof( float ) * ELEMENTS_PER_NORMAL * num_vertex_rows * num_vertex_cols, BYTES_PER_CACHELINE );
576
577 if ( !s_sphere_points || !s_sphere_normals || !s_sphere_point_array || !s_sphere_normal_array )
578 return FALSE;
579
580 for ( row = 0; row < num_vertex_rows; row++ )
581 {
582 s_sphere_points[row] = ( float * ) AllocAlignedX( sizeof( float ) * num_vertex_cols * ELEMENTS_PER_VERTEX, BYTES_PER_CACHELINE );
583 s_sphere_normals[row] = ( float * ) AllocAlignedX( sizeof( float ) * num_vertex_cols * ELEMENTS_PER_NORMAL, BYTES_PER_CACHELINE );
584 }
585
586 for ( row = 0; row < num_vertex_rows; row++ )
587 {
588 float rowangle;
589
590 rowangle = row*y_delta + cap_offset;
591
592 for ( col = 0; col < num_vertex_cols; col++ )
593 {
594 float colangle;
595
596 colangle = col*x_delta;
597
598 spa[0] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+0] = ( float ) ( sin( DEG2RAD( colangle ) ) * sin ( DEG2RAD( rowangle ) ) * scale );
599 spa[1] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+1] = ( float ) ( sin( DEG2RAD( rowangle + 270.0F ) ) * scale );
600 spa[2] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+2] = ( float ) ( sin( DEG2RAD( colangle + 270.0F ) ) * sin ( DEG2RAD( rowangle ) ) * scale );
601#if ( ELEMENTS_PER_VERTEX == 4 )
602 spa[3] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+3] = 1.0F;
603#endif
604
605 spa += ELEMENTS_PER_VERTEX;
606
607 sna[0] = s_sphere_normals[row][col*ELEMENTS_PER_NORMAL+0] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+0];
608 sna[1] = s_sphere_normals[row][col*ELEMENTS_PER_NORMAL+1] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+1];
609 sna[2] = s_sphere_normals[row][col*ELEMENTS_PER_NORMAL+2] = s_sphere_points[row][col*ELEMENTS_PER_VERTEX+2];
610#if ( ELEMENTS_PER_NORMAL == 4 )
611 sna[3] = s_sphere_normals[row][col*ELEMENTS_PER_NORMAL+3] = 1.0F;
612#endif
613
614 SphereNormalizeVector( &s_sphere_normals[row][col*ELEMENTS_PER_NORMAL] );
615 SphereNormalizeVector( sna );
616
617 sna += ELEMENTS_PER_NORMAL;
618 }
619 }
620
621 /*
622 ** create the draw arrays data
623 */
624 s_sphere_point_draw_array = ( float ** ) AllocAlignedX( sizeof( float * ) * s_num_rows, BYTES_PER_CACHELINE );
625 s_sphere_normal_draw_array = ( float ** ) AllocAlignedX( sizeof( float * ) * s_num_rows, BYTES_PER_CACHELINE );
626
627 for ( row = 0; row < s_num_rows; row++ )
628 {
629 s_sphere_point_draw_array[row] = ( float * ) AllocAlignedX( sizeof( float ) * ELEMENTS_PER_VERTEX * ( s_num_cols + 1 ) * 2, BYTES_PER_CACHELINE );
630 s_sphere_normal_draw_array[row] = ( float * ) AllocAlignedX( sizeof( float ) * ELEMENTS_PER_NORMAL * ( s_num_cols + 1 ) * 2, BYTES_PER_CACHELINE );
631 }
632 for ( row = 0; row < s_num_rows; row++ )
633 {
634 for ( col = 0; col < s_num_cols; col++ )
635 {
636 float *pdst, *psrc;
637
638 pdst = &s_sphere_point_draw_array[row][col*2*ELEMENTS_PER_VERTEX];
639 psrc = &s_sphere_points[row][col*ELEMENTS_PER_VERTEX];
640 memcpy( pdst, psrc, sizeof( float ) * ELEMENTS_PER_VERTEX );
641
642 pdst = &s_sphere_point_draw_array[row][(col*2+1)*ELEMENTS_PER_VERTEX];
643 psrc = &s_sphere_points[row+1][col*ELEMENTS_PER_VERTEX];
644 memcpy( pdst, psrc, sizeof( float ) * ELEMENTS_PER_VERTEX );
645
646 pdst = &s_sphere_normal_draw_array[row][col*2*ELEMENTS_PER_NORMAL];
647 psrc = &s_sphere_normals[row][col*ELEMENTS_PER_NORMAL];
648 memcpy( pdst, psrc, sizeof( float ) * ELEMENTS_PER_NORMAL );
649
650 pdst = &s_sphere_normal_draw_array[row][(col*2+1)*ELEMENTS_PER_NORMAL];
651 psrc = &s_sphere_normals[row+1][col*ELEMENTS_PER_NORMAL];
652 memcpy( pdst, psrc, sizeof( float ) * ELEMENTS_PER_NORMAL );
653 }
654 memcpy( &s_sphere_point_draw_array[row][s_num_cols*2*ELEMENTS_PER_VERTEX], &s_sphere_points[row][0], sizeof( float ) * ELEMENTS_PER_VERTEX );
655 memcpy( &s_sphere_point_draw_array[row][(s_num_cols*2+1)*ELEMENTS_PER_VERTEX], &s_sphere_points[row+1][0], sizeof( float ) * ELEMENTS_PER_VERTEX );
656 memcpy( &s_sphere_normal_draw_array[row][s_num_cols*2*ELEMENTS_PER_NORMAL], &s_sphere_normals[row][0], sizeof( float ) * ELEMENTS_PER_NORMAL );
657 memcpy( &s_sphere_normal_draw_array[row][(s_num_cols*2+1)*ELEMENTS_PER_NORMAL], &s_sphere_normals[row+1][0], sizeof( float ) * ELEMENTS_PER_NORMAL );
658 }
659
660 /*
661 ** create the draw elements data
662 */
663 s_sphere_elements = ( unsigned int ** ) malloc( sizeof( unsigned int * ) * s_num_rows );
664 for ( row = 0; row < s_num_rows; row++ )
665 {
666 s_sphere_elements[row] = ( unsigned int * ) malloc( sizeof( unsigned int ) * ( 2 * s_num_cols + 2 ) );
667 }
668 for ( row = 0; row < s_num_rows; row++ )
669 {
670 for ( col = 0; col < s_num_cols*2; col += 2 )
671 {
672 s_sphere_elements[row][col] = row * s_num_cols + col/2;
673 s_sphere_elements[row][col+1] = ( row + 1 ) * s_num_cols + col/2;
674 }
675
676 s_sphere_elements[row][s_num_cols*2] = row * s_num_cols;
677 s_sphere_elements[row][s_num_cols*2+1] = ( row + 1 ) * s_num_cols;
678 }
679 sia = s_sphere_interleaved_array = ( float * ) malloc( sizeof( float ) * ELEMENTS_PER_VERTEX * ELEMENTS_PER_NORMAL * ( s_num_rows + 1 ) * ( s_num_cols + 1 ) );
680 memset( s_sphere_interleaved_array, 0, sizeof( float ) * ELEMENTS_PER_VERTEX * ELEMENTS_PER_NORMAL * ( s_num_rows + 1 ) * ( s_num_cols + 1 ) );
681
682 for ( row = 0; row < num_vertex_rows; row++ )
683 {
684 for ( col = 0; col < s_num_cols; col++ )
685 {
686 memcpy( sia, &s_sphere_normals[row][col*ELEMENTS_PER_NORMAL], sizeof( float ) * ELEMENTS_PER_NORMAL );
687
688 sia += ELEMENTS_PER_NORMAL;
689
690 memcpy( sia, &s_sphere_points[row][col*ELEMENTS_PER_VERTEX], sizeof( float ) * ELEMENTS_PER_VERTEX );
691
692 sia += ELEMENTS_PER_VERTEX;
693 }
694 }
695
696 return TRUE;
697}
698
699static void SphereRedraw( void )
700{
701 int row, col;
702
703 if ( !s_benchmark )
704 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
705
706 glRotatef( 1.0f, 0.0F, 1.0F, 0.0F );
707 glRotatef( 1.0f, 1.0F, 0.0F, 0.0F );
708
709 if ( s_draw_method == DRAW_VERTEX3FV )
710 {
711 for ( row = 0; row < s_num_rows; row++ )
712 {
713 glBegin( GL_TRIANGLE_STRIP );
714 for ( col = 0; col < s_num_cols; col++ )
715 {
716 glNormal3fv( &s_sphere_normals[row][col*ELEMENTS_PER_NORMAL] );
717 glVertex3fv( &s_sphere_points[row][col*ELEMENTS_PER_VERTEX] );
718 glNormal3fv( &s_sphere_normals[row+1][col*ELEMENTS_PER_NORMAL] );
719 glVertex3fv( &s_sphere_points[row+1][col*ELEMENTS_PER_VERTEX] );
720 }
721 glNormal3fv( &s_sphere_normals[row][0] );
722 glVertex3fv( &s_sphere_points[row][0] );
723 glNormal3fv( &s_sphere_normals[row+1][0] );
724 glVertex3fv( &s_sphere_points[row+1][0] );
725
726 glEnd();
727 }
728 }
729 else if ( s_draw_method == DRAW_DRAW_ARRAYS )
730 {
731 for ( row = 0; row < s_num_rows; row++ )
732 {
733 glVertexPointer( ELEMENTS_PER_VERTEX, GL_FLOAT, ELEMENTS_PER_VERTEX * sizeof( float ), ( const GLvoid * ) s_sphere_point_draw_array[row] );
734 glNormalPointer( GL_FLOAT, ELEMENTS_PER_NORMAL * sizeof( float ), ( const GLfloat * ) s_sphere_normal_draw_array[row] );
735 glDrawArrays( GL_TRIANGLE_STRIP, 0, (s_num_cols+1)*2 );
736 }
737 }
738 else if ( s_draw_method == DRAW_ARRAY_ELEMENT )
739 {
740 for ( row = 0; row < s_num_rows; row++ )
741 {
742 glBegin( GL_TRIANGLE_STRIP );
743
744 for ( col = 0; col < s_num_cols; col++ )
745 {
746 glArrayElement( col + row*s_num_cols );
747 glArrayElement( col + (row+1)*s_num_cols );
748 }
749
750 glArrayElement( row*s_num_cols );
751 glArrayElement( (row+1)*s_num_cols );
752
753 glEnd();
754 }
755 }
756 else if ( s_draw_method == DRAW_DRAW_ELEMENTS )
757 {
758 glInterleavedArrays( GL_N3F_V3F, ( ELEMENTS_PER_VERTEX + ELEMENTS_PER_NORMAL ) * sizeof( float ), s_sphere_interleaved_array );
759
760 if ( LockArraysSGI && s_lock_arrays )
761 {
762 LockArraysSGI( 0, ( s_num_rows + 1 ) * ( s_num_cols + 1 ) );
763 }
764
765 for ( row = 0; row < s_num_rows; row++ )
766 {
767 glDrawElements( GL_TRIANGLE_STRIP, (s_num_cols+1)*2, GL_UNSIGNED_INT, s_sphere_elements[row] );
768 }
769
770 if ( UnlockArraysSGI && s_lock_arrays )
771 {
772 UnlockArraysSGI();
773 }
774 }
775
776 s_vertices_processed += ( ( s_num_rows + 1 ) * ( s_num_cols ) );
777 s_triangles_processed += ( s_num_rows * s_num_cols );
778
779 if ( !s_benchmark )
780 SwapBuffers( s_hDC );
781}
782
783static void SphereNormalizeVector( float v[3] )
784{
785 float m = 1.0F / ( float ) ( sqrt( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] ) );
786
787 v[0] *= m;
788 v[1] *= m;
789 v[2] *= m;
790}
791
792static void *AllocAlignedX( int num_bytes, int byte_alignment )
793{
794 void *buf = malloc( num_bytes + byte_alignment );
795 unsigned long q = ( unsigned long ) buf;
796
797 q += byte_alignment;
798
799 q &= ~( byte_alignment - 1 );
800
801 return ( void * ) q;
802}
803
804static void SphereHelp( void )
805{
806 char superbuffer[1000]=
807 "-?\t\tthis help screen\n"
808 "-arrayelements\tuse glArrayElement\n"
809 "-drawelements\tuse glDrawElements\n"
810 "-drawarrays\tuse glDrawArrays\n"
811 "-tristrip\t\tuse triangle strips w/ glVertex3fv\n"
812 "-vcull\t\tuse SGI's vertex culling extension\n"
813 "-lockarrays\tuse SGI's lock arrays extension when doing drawelements\n\n"
814 "-cols:val\t\tspecify number of vertical (longitudinal) bands in sphere\n"
815 "-rows:val\t\tspecify number of horizontal (latitudinal) bands in sphere\n\n"
816 "-width:val\t\twidth of window, in pixels (default is 320)\n"
817 "-height:val\t\theight of window, in pixels (default is 240)\n\n"
818 "-benchmark\trun as benchmark and immediately quit when done\n"
819 "-remote\t\tdon't print performance data\n";
820
821 MessageBox( 0, superbuffer, "Sphere, Copyright (C) 1997 Silicon Graphics, Inc.", MB_OK | MB_ICONINFORMATION );
822}
823
824static void SphereSetupPalette( HDC hDC )
825{
826 PIXELFORMATDESCRIPTOR pfd;
827 LOGPALETTE *pPal;
828 int paletteSize;
829 int pixelFormat = GetPixelFormat(hDC);
830
831 DescribePixelFormat( hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
832
833 if (!(pfd.dwFlags & PFD_NEED_PALETTE || pfd.iPixelType == PFD_TYPE_COLORINDEX))
834 return;
835
836 paletteSize = 1 << pfd.cColorBits;
837
838 pPal = (LOGPALETTE * ) malloc( sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY) );
839 pPal->palVersion = 0x300;
840 pPal->palNumEntries = paletteSize;
841
842 /* start with a copy of the current system palette */
843 GetSystemPaletteEntries( hDC, 0, paletteSize, &pPal->palPalEntry[0] );
844
845 if ( pfd.iPixelType == PFD_TYPE_RGBA )
846 {
847 /* fill in an RGBA color palette */
848 int redMask = (1 << pfd.cRedBits) - 1;
849 int greenMask = (1 << pfd.cGreenBits) - 1;
850 int blueMask = (1 << pfd.cBlueBits) - 1;
851 int i;
852
853 for (i=0; i<paletteSize; ++i)
854 {
855 pPal->palPalEntry[i].peRed =
856 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
857 pPal->palPalEntry[i].peGreen =
858 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
859 pPal->palPalEntry[i].peBlue =
860 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
861 pPal->palPalEntry[i].peFlags = 0;
862 }
863 }
864 else
865 {
866 /* fill in a Color Index ramp color palette */
867 int numRamps = NUM_COLORS;
868 int rampSize = (paletteSize - 20) / numRamps;
869 int extra = (paletteSize - 20) - (numRamps * rampSize);
870 int i, r;
871
872 for (r=0; r<numRamps; ++r)
873 {
874 int rampBase = r * rampSize + 10;
875 PALETTEENTRY *pe = &pPal->palPalEntry[rampBase];
876 int diffSize = (int) (rampSize * s_colors[r].ratio);
877 int specSize = rampSize - diffSize;
878
879 for (i=0; i<rampSize; ++i)
880 {
881 GLfloat *c0, *c1;
882 GLint a;
883
884 if (i < diffSize)
885 {
886 c0 = s_colors[r].amb;
887 c1 = s_colors[r].diff;
888 a = (i * 255) / (diffSize - 1);
889 }
890 else
891 {
892 c0 = s_colors[r].diff;
893 c1 = s_colors[r].spec;
894 a = ((i - diffSize) * 255) / (specSize - 1);
895 }
896
897 pe[i].peRed = (BYTE) (a * (c1[0] - c0[0]) + 255 * c0[0]);
898 pe[i].peGreen = (BYTE) (a * (c1[1] - c0[1]) + 255 * c0[1]);
899 pe[i].peBlue = (BYTE) (a * (c1[2] - c0[2]) + 255 * c0[2]);
900 pe[i].peFlags = PC_NOCOLLAPSE;
901 }
902
903 s_colors[r].indexes[0] = rampBase;
904 s_colors[r].indexes[1] = rampBase + (diffSize-1);
905 s_colors[r].indexes[2] = rampBase + (rampSize-1);
906 }
907 s_lit_tex_indexes[0] = 0;
908 s_lit_tex_indexes[1] = (GLint)(rampSize*s_colors[0].ratio)-1;
909 s_lit_tex_indexes[2] = rampSize-1;
910
911 for (i=0; i<extra; ++i)
912 {
913 int index = numRamps*rampSize+10+i;
914 PALETTEENTRY *pe = &pPal->palPalEntry[index];
915
916 pe->peRed = (BYTE) 0;
917 pe->peGreen = (BYTE) 0;
918 pe->peBlue = (BYTE) 0;
919 pe->peFlags = PC_NOCOLLAPSE;
920 }
921 }
922
923 s_hPalette = CreatePalette( pPal );
924 free( pPal );
925
926 if ( s_hPalette )
927 {
928 SelectPalette( hDC, s_hPalette, FALSE );
929 RealizePalette( hDC );
930 }
931}
932
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette