Back to index

extremetuxracer  0.5beta
gl_util.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * Copyright (C) 1999-2001 Jasmin F. Patry
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 
00023 #include "SDL.h"
00024 
00025 
00026 #if defined( HAVE_GL_GLX_H )
00027 #   include <GL/glx.h>
00028 #endif /* defined( HAVE_GL_GLX_H ) */
00029 
00030 #include "gl_util.h"
00031 #include "game_config.h"
00032 
00033 void set_gl_options( const RenderMode mode ) 
00034 {
00035     /* Must set the following options:
00036          Enable/Disable:
00037           GL_TEXTURE_2D
00038           GL_DEPTH_TEST
00039           GL_CULL_FACE
00040           GL_LIGHTING
00041           GL_NORMALIZE
00042           GL_ALPHA_TEST
00043           GL_BLEND
00044           GL_STENCIL_TEST
00045           GL_TEXTURE_GEN_S
00046           GL_TEXTURE_GEN_T
00047           GL_COLOR_MATERIAL
00048            
00049         Other Functions:
00050           glDepthMask
00051           glShadeModel
00052           glDepthFunc
00053     */
00054 
00055     /*
00056      * Modify defaults based on rendering mode
00057      * 
00058      * This could could be improved if it stored state and avoided
00059      * redundant state changes, which are costly (or so I've heard)...  
00060      */
00061     switch( mode ) {
00062     case GUI:
00063         glEnable( GL_TEXTURE_2D );
00064         glDisable( GL_DEPTH_TEST );
00065         glDisable( GL_CULL_FACE );
00066               glDisable( GL_LIGHTING );
00067               glDisable( GL_NORMALIZE );
00068               glDisable( GL_ALPHA_TEST );
00069         glEnable( GL_BLEND );
00070               glDisable( GL_STENCIL_TEST );
00071               glDisable( GL_TEXTURE_GEN_S );
00072               glDisable( GL_TEXTURE_GEN_T );
00073               glDisable( GL_COLOR_MATERIAL );
00074               glDepthMask( GL_TRUE );
00075               glShadeModel( GL_SMOOTH );
00076               glDepthFunc( GL_LESS );
00077               glDisable( GL_FOG );
00078         break;
00079     case GAUGE_BARS:
00080         glEnable( GL_TEXTURE_2D );
00081         glDisable( GL_DEPTH_TEST );
00082         glDisable( GL_CULL_FACE );
00083               glDisable( GL_LIGHTING );
00084               glDisable( GL_NORMALIZE );
00085               glDisable( GL_ALPHA_TEST );
00086         glEnable( GL_BLEND );
00087               glDisable( GL_STENCIL_TEST );
00088               glEnable( GL_TEXTURE_GEN_S );
00089               glEnable( GL_TEXTURE_GEN_T );
00090               glDisable( GL_COLOR_MATERIAL );
00091               glDepthMask( GL_TRUE );
00092               glShadeModel( GL_SMOOTH );
00093               glDepthFunc( GL_LESS );
00094 
00095               glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
00096               glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
00097         break;
00098 
00099     case TEXFONT:
00100         glEnable( GL_TEXTURE_2D );
00101         glDisable( GL_DEPTH_TEST );
00102         glDisable( GL_CULL_FACE );
00103               glDisable( GL_LIGHTING );
00104               glDisable( GL_NORMALIZE );
00105               glDisable( GL_ALPHA_TEST );
00106         glEnable( GL_BLEND );
00107               glDisable( GL_STENCIL_TEST );
00108               glDisable( GL_TEXTURE_GEN_S );
00109               glDisable( GL_TEXTURE_GEN_T );
00110               glDisable( GL_COLOR_MATERIAL );
00111               glDepthMask( GL_TRUE );
00112               glShadeModel( GL_SMOOTH );
00113         glEnable( GL_LINE_SMOOTH );
00114               glDepthFunc( GL_LESS );
00115         break;
00116 
00117     case TEXT:
00118         glDisable( GL_TEXTURE_2D );
00119         glDisable( GL_DEPTH_TEST );
00120         glDisable( GL_CULL_FACE );
00121               glDisable( GL_LIGHTING );
00122               glDisable( GL_NORMALIZE );
00123               glDisable( GL_ALPHA_TEST );
00124         glEnable( GL_BLEND );
00125               glDisable( GL_STENCIL_TEST );
00126               glDisable( GL_TEXTURE_GEN_S );
00127               glDisable( GL_TEXTURE_GEN_T );
00128               glDisable( GL_COLOR_MATERIAL );
00129               glDepthMask( GL_TRUE );
00130               glShadeModel( GL_SMOOTH );
00131               glDepthFunc( GL_LESS );
00132         break;
00133 
00134     case SPLASH_SCREEN:
00135         glDisable( GL_TEXTURE_2D );
00136         glDisable( GL_DEPTH_TEST );
00137         glDisable( GL_CULL_FACE );
00138               glDisable( GL_LIGHTING );
00139               glDisable( GL_NORMALIZE );
00140               glDisable( GL_ALPHA_TEST );
00141         glEnable( GL_BLEND );
00142               glDisable( GL_STENCIL_TEST );
00143               glDisable( GL_TEXTURE_GEN_S );
00144               glDisable( GL_TEXTURE_GEN_T );
00145               glDisable( GL_COLOR_MATERIAL );
00146               glDepthMask( GL_TRUE );
00147               glShadeModel( GL_SMOOTH );
00148               glDepthFunc( GL_LESS );
00149         break;
00150 
00151     case COURSE:
00152               glEnable( GL_TEXTURE_2D );
00153               glEnable( GL_DEPTH_TEST );
00154               glEnable( GL_CULL_FACE );
00155               glEnable( GL_LIGHTING );
00156               glDisable( GL_NORMALIZE );
00157               glDisable( GL_ALPHA_TEST );
00158               glEnable( GL_BLEND );
00159               glDisable( GL_STENCIL_TEST );
00160               glEnable( GL_TEXTURE_GEN_S );
00161               glEnable( GL_TEXTURE_GEN_T );
00162               glEnable( GL_COLOR_MATERIAL );
00163               glDepthMask( GL_TRUE );
00164               glShadeModel( GL_SMOOTH );
00165               glDepthFunc( GL_LEQUAL );
00166 
00167               glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
00168               glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
00169               break;
00170 
00171     case TREES:
00172               glEnable( GL_TEXTURE_2D );
00173               glEnable( GL_DEPTH_TEST );
00174         glDisable( GL_CULL_FACE );
00175               glEnable( GL_LIGHTING );
00176               glDisable( GL_NORMALIZE );
00177         glEnable( GL_ALPHA_TEST );
00178               glEnable( GL_BLEND );
00179               glDisable( GL_STENCIL_TEST );
00180               glDisable( GL_TEXTURE_GEN_S );
00181               glDisable( GL_TEXTURE_GEN_T );
00182               glDisable( GL_COLOR_MATERIAL );
00183               glDepthMask( GL_TRUE );
00184               glShadeModel( GL_SMOOTH );
00185               glDepthFunc( GL_LESS );
00186 
00187         glAlphaFunc( GL_GEQUAL, 0.5 );
00188         break;
00189         
00190     case PARTICLES:
00191         glEnable( GL_TEXTURE_2D );
00192               glEnable( GL_DEPTH_TEST );
00193         glDisable( GL_CULL_FACE );
00194               glDisable( GL_LIGHTING );
00195               glDisable( GL_NORMALIZE );
00196               glEnable( GL_ALPHA_TEST );
00197         glEnable( GL_BLEND );
00198               glDisable( GL_STENCIL_TEST );
00199               glDisable( GL_TEXTURE_GEN_S );
00200               glDisable( GL_TEXTURE_GEN_T );
00201               glDisable( GL_COLOR_MATERIAL );
00202               glDepthMask( GL_TRUE );
00203               glShadeModel( GL_SMOOTH );
00204               glDepthFunc( GL_LESS );
00205 
00206         glAlphaFunc( GL_GEQUAL, 0.5 );
00207         break;    
00208         
00209     case PARTICLE_SHADOWS:
00210         glDisable( GL_TEXTURE_2D );
00211               glEnable( GL_DEPTH_TEST );
00212         glDisable( GL_CULL_FACE );
00213               glDisable( GL_LIGHTING );
00214               glDisable( GL_NORMALIZE );
00215               glDisable( GL_ALPHA_TEST );
00216         glEnable( GL_BLEND );
00217               glDisable( GL_STENCIL_TEST );
00218               glDisable( GL_TEXTURE_GEN_S );
00219               glDisable( GL_TEXTURE_GEN_T );
00220               glDisable( GL_COLOR_MATERIAL );
00221               glDepthMask( GL_TRUE );
00222               glShadeModel( GL_SMOOTH );
00223               glDepthFunc( GL_LESS );
00224         break;
00225 
00226     case SKY:
00227               glEnable( GL_TEXTURE_2D );
00228               glDisable( GL_DEPTH_TEST );
00229               glDisable( GL_CULL_FACE ); 
00230               glDisable( GL_LIGHTING );
00231               glDisable( GL_NORMALIZE );
00232               glDisable( GL_ALPHA_TEST );
00233               glDisable( GL_BLEND );
00234               glDisable( GL_STENCIL_TEST );
00235               glDisable( GL_TEXTURE_GEN_S );
00236               glDisable( GL_TEXTURE_GEN_T );
00237               glDisable( GL_COLOR_MATERIAL );
00238               glDepthMask( GL_FALSE );
00239               glShadeModel( GL_SMOOTH );
00240               glDepthFunc( GL_LESS );
00241               glDepthFunc( GL_ALWAYS );
00242               break;
00243        
00244     case FOG_PLANE:
00245               glDisable( GL_TEXTURE_2D );
00246               glEnable( GL_DEPTH_TEST );
00247               glDisable( GL_CULL_FACE ); 
00248               glDisable( GL_LIGHTING );
00249               glDisable( GL_NORMALIZE );
00250               glDisable( GL_ALPHA_TEST );
00251               glEnable( GL_BLEND );
00252               glDisable( GL_STENCIL_TEST );
00253               glDisable( GL_TEXTURE_GEN_S );
00254               glDisable( GL_TEXTURE_GEN_T );
00255               glDisable( GL_COLOR_MATERIAL );
00256               glDepthMask( GL_TRUE );
00257               glShadeModel( GL_SMOOTH );
00258               glDepthFunc( GL_LESS );
00259               break;
00260 
00261     case TUX:
00262         glDisable( GL_TEXTURE_2D );
00263               glEnable( GL_DEPTH_TEST );
00264               glEnable( GL_CULL_FACE );
00265         glEnable( GL_LIGHTING );
00266               glEnable( GL_NORMALIZE );
00267               glDisable( GL_ALPHA_TEST );
00268               glEnable( GL_BLEND );
00269               glDisable( GL_STENCIL_TEST );
00270               glDisable( GL_TEXTURE_GEN_S );
00271               glDisable( GL_TEXTURE_GEN_T );
00272               glDisable( GL_COLOR_MATERIAL );
00273               glDepthMask( GL_TRUE );
00274               glShadeModel( GL_SMOOTH );
00275               glDepthFunc( GL_LESS );
00276         break;
00277 
00278     case TUX_SHADOW:
00279               if(getparam_stencil_buffer()){
00280                      glDisable( GL_TEXTURE_2D );
00281                      glEnable( GL_DEPTH_TEST );
00282                      glDisable( GL_CULL_FACE );
00283                      glDisable( GL_LIGHTING );
00284                      glDisable( GL_NORMALIZE );
00285                      glDisable( GL_ALPHA_TEST );
00286                      glEnable( GL_BLEND );
00287                      glEnable( GL_STENCIL_TEST );
00288                      glDisable( GL_COLOR_MATERIAL );
00289                      glDepthMask( GL_FALSE );
00290                      glShadeModel( GL_SMOOTH );
00291                      glDepthFunc( GL_LESS );
00292                      glStencilFunc( GL_EQUAL, 0, ~0 );
00293                      glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
00294               }else{
00295                      glDisable( GL_TEXTURE_2D );
00296                      glEnable( GL_DEPTH_TEST );
00297                      glEnable( GL_CULL_FACE );
00298                      glDisable( GL_LIGHTING );
00299                      glDisable( GL_NORMALIZE );
00300                      glDisable( GL_ALPHA_TEST );
00301                      glEnable( GL_BLEND );
00302                      glDisable( GL_STENCIL_TEST );
00303                      glDisable( GL_COLOR_MATERIAL );
00304                      glDepthMask( GL_TRUE );
00305                      glShadeModel( GL_SMOOTH );
00306                      glDepthFunc( GL_LESS );
00307               }
00308               break;
00309 
00310     case TRACK_MARKS:
00311               glEnable( GL_TEXTURE_2D );
00312               glEnable( GL_DEPTH_TEST );
00313               glDisable( GL_CULL_FACE );
00314               glEnable( GL_LIGHTING );
00315               glDisable( GL_NORMALIZE );
00316               glDisable( GL_ALPHA_TEST );
00317               glEnable( GL_BLEND );
00318               glDisable( GL_STENCIL_TEST );
00319               glDisable( GL_COLOR_MATERIAL );
00320               glDisable( GL_TEXTURE_GEN_S );
00321               glDisable( GL_TEXTURE_GEN_T );
00322               glDepthMask( GL_FALSE );
00323               glShadeModel( GL_SMOOTH );
00324               glDepthFunc( GL_LEQUAL );
00325               break;
00326 
00327     case OVERLAYS:
00328         glEnable( GL_TEXTURE_2D );
00329         glDisable( GL_DEPTH_TEST );
00330         glDisable( GL_CULL_FACE );
00331               glDisable( GL_LIGHTING );
00332               glDisable( GL_NORMALIZE );
00333               glEnable( GL_ALPHA_TEST );
00334         glEnable( GL_BLEND );
00335               glDisable( GL_STENCIL_TEST );
00336               glDisable( GL_TEXTURE_GEN_S );
00337               glDisable( GL_TEXTURE_GEN_T );
00338               glDisable( GL_COLOR_MATERIAL );
00339               glDepthMask( GL_TRUE );
00340               glShadeModel( GL_SMOOTH );
00341               glDepthFunc( GL_LESS );
00342 
00343         glAlphaFunc( GL_GEQUAL, 0.5 );
00344         break;
00345 
00346     default:
00347        code_not_reached();
00348     } 
00349 } 
00350 
00351 /* Checking for GL errors is really just another type of assertion, so we
00352    turn off the check if TUXRACER_NO_ASSERT is defined */
00353 #if defined( TUXRACER_NO_ASSERT )
00354 void check_gl_error()
00355 {
00356 }
00357 #else 
00358 void check_gl_error()
00359 {
00360     GLenum error;
00361     error = glGetError();
00362     if ( error != GL_NO_ERROR ) {
00363        print_warning( CRITICAL_WARNING, 
00364                      "OpenGL Error: %s", gluErrorString( error ) );
00365        fflush( stderr );
00366     }
00367 }
00368 #endif /* defined( TUXRACER_NO_ASSERT ) */
00369 
00370 void copy_to_glfloat_array( GLfloat dest[], double src[], int n )
00371 {
00372     int i;
00373     for (i=0; i<n; i++) {
00374        dest[i] = src[i];
00375     }
00376 }
00377 
00378 void init_glfloat_array( int num, GLfloat arr[], ... )
00379 {
00380     int i;
00381     va_list args;
00382 
00383     va_start( args, arr );
00384 
00385     for (i=0; i<num; i++) {
00386        arr[i] = va_arg(args, double);
00387     }
00388 
00389     va_end( args );
00390 }
00391 
00392 /* Extension func ptrs *must* be initialized to NULL */
00393 #ifndef NO_FUNCTION_POINTERS 
00394 PFNGLLOCKARRAYSEXTPROC glLockArraysEXT_p = NULL;
00395 PFNGLUNLOCKARRAYSEXTPROC glUnlockArraysEXT_p = NULL;
00396 #endif
00397 
00398 typedef void (*(*get_gl_proc_fptr_t)(const GLubyte *))(); 
00399 
00400 void init_opengl_extensions()
00401 {
00402     get_gl_proc_fptr_t get_gl_proc;
00403 
00404     get_gl_proc = (get_gl_proc_fptr_t) SDL_GL_GetProcAddress;
00405 
00406     #ifndef NO_FUNCTION_POINTERS
00407     if ( get_gl_proc ) {
00408        glLockArraysEXT_p = (PFNGLLOCKARRAYSEXTPROC) 
00409            (*get_gl_proc)( (GLubyte*) "glLockArraysEXT" );
00410        glUnlockArraysEXT_p = (PFNGLUNLOCKARRAYSEXTPROC) 
00411            (*get_gl_proc)( (GLubyte*) "glUnlockArraysEXT" );
00412        
00413        if ( glLockArraysEXT_p != NULL && glUnlockArraysEXT_p != NULL ) {
00414            print_debug( DEBUG_GL_EXT, 
00415                       "GL_EXT_compiled_vertex_array extension "
00416                       "supported" );
00417        } else {
00418            print_debug( DEBUG_GL_EXT, 
00419                       "GL_EXT_compiled_vertex_array extension "
00420                       "NOT supported" );
00421            glLockArraysEXT_p = NULL;
00422            glUnlockArraysEXT_p = NULL;
00423        }
00424     } else {
00425        print_debug( DEBUG_GL_EXT, 
00426                    "No function available for obtaining GL proc addresses" );
00427     }
00428     #endif 
00429 }
00430 
00431 
00432 
00433 /*---------------------------------------------------------------------------*/
00440 typedef struct {
00441     char *name;
00442     GLenum value;
00443     GLenum type;
00444 } gl_value_t;
00445 
00446 /* Add more things here as needed */
00447 gl_value_t gl_values[] = {
00448     { "maximum lights", GL_MAX_LIGHTS, GL_INT },
00449     { "modelview stack depth", GL_MAX_MODELVIEW_STACK_DEPTH, GL_INT },
00450     { "projection stack depth", GL_MAX_PROJECTION_STACK_DEPTH, GL_INT },
00451     { "max texture size", GL_MAX_TEXTURE_SIZE, GL_INT },
00452     { "double buffering", GL_DOUBLEBUFFER, GL_UNSIGNED_BYTE },
00453     { "red bits", GL_RED_BITS, GL_INT },
00454     { "green bits", GL_GREEN_BITS, GL_INT },
00455     { "blue bits", GL_BLUE_BITS, GL_INT },
00456     { "alpha bits", GL_ALPHA_BITS, GL_INT },
00457     { "depth bits", GL_DEPTH_BITS, GL_INT },
00458     { "stencil bits", GL_STENCIL_BITS, GL_INT } };
00459 
00460 void print_gl_info()
00461 {
00462     char *extensions;
00463     char *p, *oldp;
00464     unsigned int i;
00465     GLint int_val;
00466     GLfloat float_val;
00467     GLboolean boolean_val;
00468 
00469     fprintf( stderr,
00470             "  vendor: %s\n", 
00471             glGetString( GL_VENDOR ) );
00472 
00473     fprintf( stderr,
00474             "  renderer: %s\n", 
00475             glGetString( GL_RENDERER ) );
00476 
00477     fprintf( stderr,
00478             "  version: %s\n", 
00479             glGetString( GL_VERSION ) );
00480 
00481        //extensions = string_copy( (char*) glGetString( GL_EXTENSIONS ) );
00482        //oldp = extensions;
00483        
00484        extensions = (char*) glGetString( GL_EXTENSIONS );
00485 
00486        oldp = new char[strlen(extensions)+1];
00487        extensions = oldp;
00488        strcpy(oldp, extensions);
00489 
00490     fprintf( stderr, "  extensions:\n" );
00491        
00492     while ( (p=strchr(oldp,' ')) ) {
00493               *p='\0';
00494               fprintf( stderr, "    %s\n", oldp );
00495               oldp = p+1;
00496     }
00497        
00498        if ( *oldp ) {
00499               fprintf( stderr, "    %s\n", oldp );
00500     }
00501        
00502        delete extensions;
00503        
00504     for ( i=0; i<sizeof(gl_values)/sizeof(gl_values[0]); i++) {
00505        fprintf( stderr, "  %s: ", gl_values[i].name );
00506 
00507        switch( gl_values[i].type ) {
00508        case GL_INT:
00509            glGetIntegerv( gl_values[i].value, &int_val );
00510            fprintf( stderr, "%d", int_val );
00511            break;
00512 
00513        case GL_FLOAT:
00514            glGetFloatv( gl_values[i].value, &float_val );
00515            fprintf( stderr, "%f", float_val );
00516            break;
00517 
00518        case GL_UNSIGNED_BYTE:
00519            glGetBooleanv( gl_values[i].value, &boolean_val );
00520            fprintf( stderr, "%d", boolean_val );
00521            break;
00522 
00523        default:
00524            code_not_reached();
00525        }
00526 
00527        fprintf( stderr, "\n" );
00528     }
00529 
00530 
00531     fprintf( stderr, "\n" );
00532 }