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. | |
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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.
|
|
||||||||||||||||
|
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 }
|
1.3.6