[Tuxracer-checkins] CVS: tuxracer/src quadtree.cpp,1.8,1.9 quadtree.hpp,1.7,1.8
Status: Beta
Brought to you by:
jfpatry
From: Jasmin P. <jf...@us...> - 2000-09-09 05:54:53
|
Update of /cvsroot/tuxracer/tuxracer/src In directory slayer.i.sourceforge.net:/tmp/cvs-serv15311 Modified Files: quadtree.cpp quadtree.hpp Log Message: Added a "perfect_terrain_blending" mode, which blends triangles with three different terrain types correctly. Also added a first cut at environment mapping for ice. Eventually this will have to be made more controllable via Tcl. Index: quadtree.cpp =================================================================== RCS file: /cvsroot/tuxracer/tuxracer/src/quadtree.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** quadtree.cpp 2000/09/06 14:04:07 1.8 --- quadtree.cpp 2000/09/09 05:54:51 1.9 *************** *** 14,22 **** #include "textures.h" #include "course_load.h" - #include <GL/gl.h> - - #include <stdio.h> - #include <math.h> #include "quadtree.hpp" #include "quadgeom.hpp" --- 14,21 ---- #include "textures.h" #include "course_load.h" + #include "fog.h" + #include "gl_util.h" + #include "course_render.h" #include "quadtree.hpp" #include "quadgeom.hpp" *************** *** 37,40 **** --- 36,47 ---- #define ERROR_MAGNIFICATION_AMOUNT 3 + /* Environment map alpha value, integer from 0-255 */ + #define ENV_MAP_ALPHA 50 + + /* Useful macro for setting colors in the color array */ + #define colorval(j,ch) \ + VNCArray[j*STRIDE_GL_ARRAY+STRIDE_GL_ARRAY-4+(ch)] + + // // quadsquare functions. *************** *** 42,47 **** GLuint quadsquare::TexId[NumTerrains]; GLuint *quadsquare::VertexArrayIndices = NULL; ! int quadsquare::VertexArrayCounter; quadsquare::quadsquare(quadcornerdata* pcd) --- 49,57 ---- GLuint quadsquare::TexId[NumTerrains]; + GLuint quadsquare::EnvmapTexId; GLuint *quadsquare::VertexArrayIndices = NULL; ! GLuint quadsquare::VertexArrayCounter; ! GLuint quadsquare::VertexArrayMinIdx; ! GLuint quadsquare::VertexArrayMaxIdx; quadsquare::quadsquare(quadcornerdata* pcd) *************** *** 95,106 **** // Initialize texture data if (!get_texture_binding("snow", &(TexId[Snow]))) { ! TexId[Snow] = 0; } if (!get_texture_binding("ice", &TexId[Ice])) { ! TexId[Ice] = 0; } if (!get_texture_binding("rock", &TexId[Rock])) { ! TexId[Rock] = 0; } Terrain = get_course_terrain_data(); --- 105,119 ---- // Initialize texture data if (!get_texture_binding("snow", &(TexId[Snow]))) { ! TexId[Snow] = 0; } if (!get_texture_binding("ice", &TexId[Ice])) { ! TexId[Ice] = 0; } if (!get_texture_binding("rock", &TexId[Rock])) { ! TexId[Rock] = 0; } + if ( !get_texture_binding( "terrain_envmap", &EnvmapTexId ) ) { + EnvmapTexId = 0; + } Terrain = get_course_terrain_data(); *************** *** 761,770 **** /* We don't really want to delete nodes when they're disabled, do we? ! if (Child[index]->Static == false) { ! delete Child[index]; ! Child[index] = 0; ! BlockDeleteCount++;//xxxxx ! } */ } --- 774,783 ---- /* We don't really want to delete nodes when they're disabled, do we? ! if (Child[index]->Static == false) { ! delete Child[index]; ! Child[index] = 0; ! BlockDeleteCount++;//xxxxx ! } */ } *************** *** 978,1006 **** GLubyte *VNCArray; ! int quadsquare::Render(const quadcornerdata& cd, GLubyte *vnc_array) // Draws the heightfield represented by this tree. // Returns the number of triangles rendered. { VNCArray = vnc_array; - int TriCount = 0; - for (int i=0; i<NumTerrains; i++) { ! VertexArrayCounter = 0; ! RenderAux(cd, SomeClip, i); if ( VertexArrayCounter == 0 ) { continue; } - glBindTexture( GL_TEXTURE_2D, TexId[i] ); - glDrawElements( GL_TRIANGLES, VertexArrayCounter, - GL_UNSIGNED_INT, VertexArrayIndices ); - TriCount += VertexArrayCounter / 3; } ! return TriCount; } --- 991,1150 ---- GLubyte *VNCArray; + + void quadsquare::DrawTris() + { + if ( glLockArraysEXT && getparam_use_cva() ) { + glLockArraysEXT( VertexArrayMinIdx, + VertexArrayMaxIdx - VertexArrayMinIdx + 1 ); + } + + glDrawElements( GL_TRIANGLES, VertexArrayCounter, + GL_UNSIGNED_INT, VertexArrayIndices ); + + if ( glUnlockArraysEXT && getparam_use_cva() ) { + glUnlockArraysEXT(); + } + } + + void quadsquare::DrawEnvmapTris() + { + if ( VertexArrayCounter > 0 && EnvmapTexId != 0 ) { + + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); + + glBindTexture( GL_TEXTURE_2D, EnvmapTexId ); + + DrawTris(); + + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); ! } ! } ! ! void quadsquare::InitArrayCounters() ! { ! VertexArrayCounter = 0; ! VertexArrayMinIdx = INT_MAX; ! VertexArrayMaxIdx = 0; ! } ! ! void quadsquare::Render(const quadcornerdata& cd, GLubyte *vnc_array) // Draws the heightfield represented by this tree. // Returns the number of triangles rendered. { VNCArray = vnc_array; + bool_t fog_on; + unsigned int i, j; + int nx, ny; + get_course_divisions( &nx, &ny ); ! /* Save fog state */ ! fog_on = is_fog_on(); ! ! /* ! * Draw the "normal" blended triangles ( <= 2 terrains textures ) ! */ ! for (j=0; j<NumTerrains; j++) { ! InitArrayCounters(); ! ! RenderAux(cd, SomeClip, j); if ( VertexArrayCounter == 0 ) { continue; } + + glBindTexture( GL_TEXTURE_2D, TexId[j] ); + DrawTris(); + + if ( j == Ice && getparam_terrain_envmap() ) { + /* Render Ice with environment map */ + glDisableClientState( GL_COLOR_ARRAY ); + glColor4f( 1.0, 1.0, 1.0, ENV_MAP_ALPHA / 255.0 ); + + DrawEnvmapTris(); + + glEnableClientState( GL_COLOR_ARRAY ); + } } ! /* ! * Draw the "special" triangles that have different terrain types ! * at each of the corners ! */ ! if ( getparam_terrain_blending() && ! getparam_perfect_terrain_blending() ) { ! ! /* ! * Get the "special" three-terrain triangles ! */ ! InitArrayCounters(); ! RenderAux( cd, SomeClip, -1 ); ! ! if ( VertexArrayCounter != 0 ) { ! /* Render black triangles */ ! glDisable( GL_FOG ); ! ! /* Set triangle vertices to black */ ! for (i=0; i<VertexArrayCounter; i++) { ! colorval( VertexArrayIndices[i], 0 ) = 0; ! colorval( VertexArrayIndices[i], 1 ) = 0; ! colorval( VertexArrayIndices[i], 2 ) = 0; ! colorval( VertexArrayIndices[i], 3 ) = 255; ! } ! ! /* Draw the black triangles */ ! glBindTexture( GL_TEXTURE_2D, TexId[0] ); ! DrawTris(); ! ! /* Now we draw the triangle once for each texture */ ! if (fog_on) { ! glEnable( GL_FOG ); ! } ! ! /* Use additive blend function */ ! glBlendFunc( GL_SRC_ALPHA, GL_ONE ); ! ! /* First set triangle colours to white */ ! for (i=0; i<VertexArrayCounter; i++) { ! colorval( VertexArrayIndices[i], 0 ) = 255; ! colorval( VertexArrayIndices[i], 1 ) = 255; ! colorval( VertexArrayIndices[i], 2 ) = 255; ! } ! ! for (j=0; j<NumTerrains; j++) { ! glBindTexture( GL_TEXTURE_2D, TexId[j] ); ! ! /* Set alpha values */ ! for (i=0; i<VertexArrayCounter; i++) { ! colorval( VertexArrayIndices[i], 3 ) = ! (Terrain[VertexArrayIndices[i]] == (terrain_t)j ) ? ! 255 : 0; ! } ! ! DrawTris(); ! } ! ! ! /* Render Ice with environment map */ ! if ( getparam_terrain_envmap() ) { ! glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); ! ! /* Need to set alpha values for ice */ ! for (i=0; i<VertexArrayCounter; i++) { ! colorval( VertexArrayIndices[i], 3 ) = ! (Terrain[VertexArrayIndices[i]] == Ice) ? ! ENV_MAP_ALPHA : 0; ! } ! DrawEnvmapTris(); ! } ! } ! } ! ! glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } *************** *** 1056,1059 **** --- 1200,1274 ---- + typedef void (*make_tri_func_t)( int a, int b, int c, int terrain ); + + /* Local macro for setting alpha value based on terrain */ + #define setalphaval(i) colorval(VertexIndices[i], 3) = \ + ( terrain <= VertexTerrains[i] ) ? 255 : 0 + + #define update_min_max( idx ) \ + if ( idx > VertexArrayMaxIdx ) { \ + VertexArrayMaxIdx = idx; \ + } \ + else if ( idx < VertexArrayMinIdx ) { \ + VertexArrayMinIdx = idx; \ + } + + inline void quadsquare::MakeTri( int a, int b, int c, int terrain ) + { + if ( ( VertexTerrains[a] == terrain || + VertexTerrains[b] == terrain || + VertexTerrains[c] == terrain ) ) + { + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[a]; + setalphaval(a); + update_min_max( VertexIndices[a] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[b]; + setalphaval(b); + update_min_max( VertexIndices[b] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[c]; + setalphaval(c); + update_min_max( VertexIndices[c] ); + } + } + + + inline void quadsquare::MakeSpecialTri( int a, int b, int c, int terrain) + { + /* terrain should be -1 */ + + if ( VertexTerrains[a] != VertexTerrains[b] && + VertexTerrains[a] != VertexTerrains[c] && + VertexTerrains[b] != VertexTerrains[c] ) + { + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[a]; + update_min_max( VertexIndices[a] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[b]; + update_min_max( VertexIndices[b] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[c]; + update_min_max( VertexIndices[c] ); + } + } + + inline void quadsquare::MakeNoBlendTri( int a, int b, int c, int terrain ) + { + if ( ( VertexTerrains[a] == terrain || + VertexTerrains[b] == terrain || + VertexTerrains[c] == terrain ) && + ( VertexTerrains[a] >= terrain && + VertexTerrains[b] >= terrain && + VertexTerrains[c] >= terrain ) ) + { + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[a]; + setalphaval(a); + update_min_max( VertexIndices[a] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[b]; + setalphaval(b); + update_min_max( VertexIndices[b] ); + VertexArrayIndices[VertexArrayCounter++] = VertexIndices[c]; + setalphaval(c); + update_min_max( VertexIndices[c] ); + } + } + void quadsquare::RenderAux(const quadcornerdata& cd, clip_result_t vis, int terrain) *************** *** 1125,1172 **** - // Local macros to make the triangle logic shorter & hopefully clearer. - #define setalphaval(a) \ - VNCArray[VertexIndices[a]*STRIDE_GL_ARRAY+STRIDE_GL_ARRAY-1] = \ - (( terrain <= VertexTerrains[a] ) ? 255 : 0 ) - - #define tri(a,b,c) \ - if ( \ - VertexTerrains[a] == terrain || \ - VertexTerrains[b] == terrain || \ - VertexTerrains[c] == terrain ) \ - { \ - VertexArrayIndices[VertexArrayCounter++] = VertexIndices[a]; \ - setalphaval(a); \ - VertexArrayIndices[VertexArrayCounter++] = VertexIndices[b]; \ - setalphaval(b); \ - VertexArrayIndices[VertexArrayCounter++] = VertexIndices[c]; \ - setalphaval(c); \ - } - - // Make the list of triangles to draw. ! if ((EnabledFlags & 1) == 0 ) { ! tri(0, 2, 8); ! } else { ! if (flags & 8) tri(0, 1, 8); ! if (flags & 1) tri(0, 2, 1); ! } ! if ((EnabledFlags & 2) == 0 ) { ! tri(0, 4, 2); ! } else { ! if (flags & 1) tri(0, 3, 2); ! if (flags & 2) tri(0, 4, 3); ! } ! if ((EnabledFlags & 4) == 0 ) { ! tri(0, 6, 4); ! } else { ! if (flags & 2) tri(0, 5, 4); ! if (flags & 4) tri(0, 6, 5); ! } ! if ((EnabledFlags & 8) == 0 ) { ! tri(0, 8, 6); } else { ! if (flags & 4) tri(0, 7, 6); ! if (flags & 8) tri(0, 8, 7); } } --- 1340,1376 ---- // Make the list of triangles to draw. ! #define make_tri_list(tri_func) \ ! if ((EnabledFlags & 1) == 0 ) { \ ! tri_func(0, 2, 8, terrain); \ ! } else { \ ! if (flags & 8) tri_func(0, 1, 8, terrain); \ ! if (flags & 1) tri_func(0, 2, 1, terrain); \ ! } \ ! if ((EnabledFlags & 2) == 0 ) { \ ! tri_func(0, 4, 2, terrain); \ ! } else { \ ! if (flags & 1) tri_func(0, 3, 2, terrain); \ ! if (flags & 2) tri_func(0, 4, 3, terrain); \ ! } \ ! if ((EnabledFlags & 4) == 0 ) { \ ! tri_func(0, 6, 4, terrain); \ ! } else { \ ! if (flags & 2) tri_func(0, 5, 4, terrain); \ ! if (flags & 4) tri_func(0, 6, 5, terrain); \ ! } \ ! if ((EnabledFlags & 8) == 0 ) { \ ! tri_func(0, 8, 6, terrain); \ ! } else { \ ! if (flags & 4) tri_func(0, 7, 6, terrain); \ ! if (flags & 8) tri_func(0, 8, 7, terrain); \ ! } ! ! if ( terrain == -1 ) { ! make_tri_list(MakeSpecialTri); ! } else if ( getparam_terrain_blending() ) { ! make_tri_list(MakeTri); } else { ! make_tri_list(MakeNoBlendTri); } } Index: quadtree.hpp =================================================================== RCS file: /cvsroot/tuxracer/tuxracer/src/quadtree.hpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** quadtree.hpp 2000/09/06 14:04:07 1.7 --- quadtree.hpp 2000/09/09 05:54:51 1.8 *************** *** 80,88 **** static terrain_t *Terrain; static GLuint TexId[NumTerrains]; static GLuint *VertexArrayIndices; ! static int VertexArrayCounter; // public: quadsquare(quadcornerdata* pcd); --- 80,99 ---- static terrain_t *Terrain; static GLuint TexId[NumTerrains]; + static GLuint EnvmapTexId; static GLuint *VertexArrayIndices; ! static GLuint VertexArrayCounter; ! static GLuint VertexArrayMinIdx; ! static GLuint VertexArrayMaxIdx; + static void MakeTri( int a, int b, int c, int terrain ); + static void MakeSpecialTri( int a, int b, int c, int terrain ); + static void MakeNoBlendTri( int a, int b, int c, int terrain ); + static void DrawTris(); + static void DrawEnvmapTris(); + static void InitArrayCounters(); + + // public: quadsquare(quadcornerdata* pcd); *************** *** 95,99 **** void Update(const quadcornerdata& cd, const float ViewerLocation[3], float Detail); ! int Render(const quadcornerdata& cd, GLubyte *vnc_array); float GetHeight(const quadcornerdata& cd, float x, float z); --- 106,110 ---- void Update(const quadcornerdata& cd, const float ViewerLocation[3], float Detail); ! void Render(const quadcornerdata& cd, GLubyte *vnc_array); float GetHeight(const quadcornerdata& cd, float x, float z); |