Main Page | Namespace List | Class List | File List | Class Members | File Members

heightfield.h File Reference

Go to the source code of this file.

Functions

void initHeightField (int W, int H, const char *file)
 Initialize the height field.

void drawHeightField (float x, float y, int w, int h)
 Draw the height field.

float gethf (int, int)
 Get value of the height field at certain coordinate.


Function Documentation

void drawHeightField float  x,
float  y,
int  w,
int  h
 

Draw the height field.

The field is placed in the XY plane centered in (0,0,0). The height field position (x,y) lies in the origin, and w x h tiles around this position are drawn. Each tile covers 1 square unit in OpenGL coordinates.

Definition at line 363 of file heightfield.cpp.

References averageHeight(), _S_VertexData::bShadow, _S_VertexData::bWater, drawMultipassQuad(), drawWaterQuads(), g_bBlending, gethfVertexData(), hftexture(), initGLState(), _S_VertexData::nTex, streamVertex(), TEX_N, texture(), TEXTURE, _S_VertexData::x, _S_WaterQuad::x, _S_WaterQuad::xp, _S_WaterQuad::y, _S_WaterQuad::yp, and _S_VertexData::z.

Referenced by renderScene().

00364 {
00365   // List of the water quads (rendered after field)
00366   vector<_S_WaterQuad> water;
00367 
00368   initGLState();
00369   int xi = int(x);
00370   int yi = int(y);   
00371   for (int xc=xi-w; xc <= xi+w; xc++ ) {
00372     TEXTURE nCurrentTexture = TEX_N;
00373     _S_VertexData v1, v2;
00374     gethfVertexData( x,y, xc+1, yi-h, v1 );
00375     gethfVertexData( x,y, xc,   yi-h, v2 );
00376     for ( int yc=yi-h; yc <= yi+h; yc++ ) {
00377       _S_VertexData v3, v4;
00378       gethfVertexData( x,y, xc,   yc+1, v3 );
00379       gethfVertexData( x,y, xc+1, yc+1, v4 );
00380       
00381       // Get correct textures for all four vertices of the next quad
00382       TEXTURE t1 = v1.nTex;
00383       TEXTURE t2 = v2.nTex;
00384       TEXTURE t3 = v3.nTex;
00385       TEXTURE t4 = v4.nTex;
00386       // Check if all are equal
00387       bool bAllEqual = false;
00388       if (t1==t2 && t2==t3 && t3==t4) {
00389         bAllEqual = true;
00390       }
00391       // Check if shadow quad
00392       bool bShadow = false;
00393       if (v1.bShadow || v2.bShadow || v3.bShadow || v4.bShadow) {
00394         bShadow = true;
00395       }
00396 
00397       bool bWater = false;
00398       if (v1.bWater || v2.bWater || v3.bWater || v4.bWater) {
00399         bWater = true;
00400       }
00401       
00402       if (bAllEqual && t1==nCurrentTexture && !bShadow && !bWater) {
00403         // Continue current triangle strip
00404         assert( t1 != TEX_N );
00405         streamVertex( v1 );
00406         streamVertex( v2 );
00407       }
00408       else {
00409         // The current texture changes. Stop the triangle strip,
00410         // if one is currently active.
00411         if ( nCurrentTexture != TEX_N ) {
00412           streamVertex( v1 );
00413           streamVertex( v2 );
00414           nCurrentTexture = TEX_N;
00415           glEnd();
00416         }
00417 
00418         if (bAllEqual && !bShadow && !bWater) {
00419           // Only one pass is required. Start a new active
00420           // triangle strip.
00421           glBindTexture( GL_TEXTURE_2D, texture(t1) );
00422           glBegin( GL_TRIANGLE_STRIP );
00423           nCurrentTexture = t1;
00424           streamVertex( v1 );
00425           streamVertex( v2 );
00426         }
00427         else {
00428           if ( g_bBlending && !bAllEqual ) {
00429             // Draw the current quad using multiple passes.
00430             // Get coordinates for next vertices in the strip
00431               drawMultipassQuad( v1,v2,v3,v4 );
00432           }
00433           else {
00434             // Just use the texture for the average height
00435             TEXTURE tex = hftexture( averageHeight( xc,yc ));
00436             glBindTexture( GL_TEXTURE_2D, texture(tex) );
00437             glBegin( GL_QUADS );
00438             streamVertex( v1 );
00439             streamVertex( v2 );
00440             streamVertex( v3 );
00441             streamVertex( v4 );
00442             glEnd();
00443           }
00444 
00445           if (bWater) {
00446             _S_WaterQuad W;
00447             W.x = xc; W.y = yc;
00448             W.xp = v2.x; W.yp = v2.z;
00449             water.push_back( W );
00450           }
00451         }
00452       }
00453       v1 = v4; v2 = v3;
00454     }
00455     
00456     glEnd();
00457   }
00458   glDisable( GL_TEXTURE_2D );
00459 
00460   drawWaterQuads( water );
00461   glEnable( GL_LIGHTING );
00462 }

float gethf int  ,
int 
 

Get value of the height field at certain coordinate.

Definition at line 52 of file heightfield.cpp.

References g_H, g_hf, and g_W.

00052                             {
00053   // Not exactly as in the previous assignment, but looks 
00054   // better than modulo.
00055      x = abs(x); y=abs(y);
00056 //    while (x<0) x += g_hfW;
00057 //    while (y<0) y += g_hfH;
00058     
00059   // Tile HF over full plane
00060   return g_hf[ (x%g_W) + (y%g_H)*g_W ];
00061 }

void initHeightField int  W,
int  H,
const char *  file
 

Initialize the height field.

The field data is loaded as W*H continuous raw floats from the file.

Definition at line 124 of file heightfield.cpp.

References computeNormal(), g_cellsize, g_fHeightScale, g_H, g_hf, g_hfData, g_strResourceDir, g_texcoord, g_tpt, g_W, gethf(), hftexture(), _S_VertexData::nTex, _S_VertexData::nx, _S_VertexData::ny, _S_VertexData::nz, _S_VertexData::tx, _S_VertexData::ty, _S_VertexData::x, _S_VertexData::y, and _S_VertexData::z.

Referenced by initGL().

00125 {
00126   // Validate params
00127   assert( W>0 && W*H > 0 );
00128   // Clear old data
00129   if (g_hf != NULL) {
00130     delete[] g_hf;
00131   }
00132   if (g_hfData != NULL) {
00133     delete[] g_hfData;
00134   }
00135 
00136   // Init new data
00137   g_W = W;
00138   g_H = H;
00139   g_hf = new float[W*H];
00140   g_hfData = new _S_VertexData[W*H];
00141 
00142   // Read data from file
00143   if (filename != NULL) {
00144     int L = strlen( filename ) + strlen( g_strResourceDir );
00145     char fn[L+1];
00146     strcpy( fn, g_strResourceDir );
00147     strcat( fn, filename );
00148 
00149     FILE *file = fopen( fn, "rb" );
00150     assert( file != NULL );
00151     int n;
00152     if ( (n=fread( g_hf, sizeof(float), W*H, file )) != W*H) {
00153       printf( "Error loading height field, only %i floats read.", n ); 
00154     }
00155     else {
00156       printf( "read %i floats ... ", n );
00157     }
00158   }
00159 
00160   // Init texture coords
00161   for ( int i=0; i<=g_tpt; i++) {
00162     g_texcoord[i] = float(i) / float(g_tpt);
00163   }
00164   for ( int i=0; i<g_tpt; i++) {
00165     g_texcoord[i + g_tpt] = 1.0f - float(i) / float(g_tpt);
00166   }
00167 
00168   // Init height field
00169   for (int x=0; x<g_W; x++) {
00170     for (int y=0; y<g_H; y++) {
00171       g_hf[ x+y*g_W ] *= g_fHeightScale;
00172     }
00173   }
00174 
00175   // Init per vertex height field data
00176   for (int x=0; x<g_W; x++) {
00177     for (int y=0; y<g_H; y++) {
00178 
00179         _S_VertexData &V = g_hfData[ x+y*g_W ];
00180         V.x = x * g_cellsize;
00181         V.y = gethf( x,y );
00182         V.z = y * g_cellsize;
00183         computeNormal( x,y, V.nx, V.ny, V.nz );
00184         V.tx = g_texcoord[ abs(x) % (2*g_tpt) ];
00185         V.ty = g_texcoord[ abs(y) % (2*g_tpt) ];
00186         V.nTex = hftexture( V.y );
00187 
00188     }
00189   }
00190 }


Generated on Thu Jan 20 02:46:58 2005 for Main_Demo by doxygen 1.3.6