Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ATerrain.cpp File Reference


Detailed Description

implements the 'terrain_' functions in AEngine.h

Definition in file ATerrain.cpp.

#include "AEngine.h"
#include "AState.h"
#include "AUtil.h"
#include "ATGAImage.h"

Include dependency graph for ATerrain.cpp:

Include dependency graph

Go to the source code of this file.

Defines

#define ADD(x, y, value)   if( x>=0 && y>=0 && x<TERR_COLS && y<TERR_ROWS ) { sum[y][x]+=value; count[y][x]++; }

Functions

void createZMap (TerrainEntry &e, UBYTE *pImg)
 create heightmap

void createNMap (TerrainEntry &e)
 create the normal given height map

void createBMap (TerrainEntry &e, UBYTE *pImg)
void createVIB (TerrainEntry &e)
 vertex&index buffer

ATerrain terrain_create (string filename, FLOAT sizeX, FLOAT sizeY, FLOAT sizeZ, FLOAT offsetZ)
void terrain_render (ATerrain terrain, ATexture texLow, ATexture texHigh, ATexture texNormal)
void terrain_flush ()
void terrain_processRenderRequest ()
FLOAT triArea (Vec2D &p0, Vec2D &p1, Vec2D &p2)
FLOAT terrain_getHeight (ATerrain terrain, FLOAT x, FLOAT y)


Define Documentation

#define ADD x,
y,
value       if( x>=0 && y>=0 && x<TERR_COLS && y<TERR_ROWS ) { sum[y][x]+=value; count[y][x]++; }
 


Function Documentation

void createBMap TerrainEntry   e,
UBYTE   pImg
 

Definition at line 96 of file ATerrain.cpp.

References TerrainEntry::BMap, TERR_COLS, and TERR_ROWS.

Referenced by terrain_create().

00097 {
00098         for( int j=0; j<TERR_ROWS; j++ )                        // get blend factor from channel G
00099                 for( int i=0; i<TERR_COLS; i++ )
00100                         e.BMap[j][i] = pImg[ (j*TERR_COLS+i)*3 +1] / 255.0f;
00101 }

void createNMap TerrainEntry   e
 

create the normal given height map

Definition at line 68 of file ATerrain.cpp.

References TERR_COLS, TERR_ROWS, and Vec3D.

Referenced by terrain_create().

00069 {
00070         // 2x distance between 2 adjacent tiles
00071         FLOAT deltaX = 2.0f/TERR_COLS * e.sizeX;
00072         FLOAT deltaY = 2.0f/TERR_ROWS * e.sizeY;                
00073 
00074         for( int j=0; j<TERR_ROWS; j++ )
00075                 for( int i=0; i<TERR_COLS; i++ )
00076                 {
00077                         if( i==0 || i==TERR_COLS-1 || j==0 || j==TERR_ROWS-1 )          // if border case, normal points up
00078                         {
00079                                 e.NMap[j][i] = Vec3D( 0.0f, 0.0f, 1.0f );
00080                         }
00081                         else
00082                         {
00083                                 FLOAT dzdx = e.zMap[j-1][i+1] + e.zMap[j  ][i+1] + e.zMap[j+1][i+1]
00084                                                    - e.zMap[j-1][i-1] - e.zMap[j  ][i-1] - e.zMap[j+1][i-1];
00085                                 FLOAT dzdy = e.zMap[j+1][i-1] + e.zMap[j+1][i  ] + e.zMap[j+1][i+1]
00086                                                    - e.zMap[j-1][i-1] - e.zMap[j-1][i  ] - e.zMap[j-1][i+1];
00087                                 
00088                            dzdx *= 1.0f / 3.0f / deltaX;
00089                            dzdy *= 1.0f / 3.0f / deltaY;
00090                            FLOAT denom = 1.0f / sqrtf( dzdx*dzdx + dzdy*dzdy + 1.0f );          // normalize it
00091                            e.NMap[j][i] = Vec3D( dzdx*denom, dzdy*denom, denom );
00092                         }
00093                 }
00094 }

void createVIB TerrainEntry   e
 

vertex&index buffer

Definition at line 104 of file ATerrain.cpp.

References TERR_COLS, TERR_ROWS, and Vec3D.

Referenced by terrain_create().

00105 {
00106         int vbByteSize = TERR_ROWS * TERR_COLS * sizeof(ColoredTerrainVertex);
00107         int ibByteSize = ((TERR_ROWS-1)*2*TERR_COLS + (TERR_ROWS-2)*2) * sizeof(USHORT);
00108         ColoredTerrainVertex *pVertex;
00109         USHORT                           *pIndex;
00110 
00111         AS.pDevice->CreateVertexBuffer( vbByteSize, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &e.vb );
00112         AS.pDevice->CreateIndexBuffer(  ibByteSize, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &e.ib );
00113         if( FAILED( e.vb->Lock(0,0, (BYTE**)&pVertex, 0) )) throw Error("Can't Lock terrVB");
00114         if( FAILED( e.ib->Lock(0,0, (BYTE**)&pIndex,  0) )) throw Error("Can't Lock terrIB");
00115 
00116         int writeIndex = 0;
00117         for( int j=0; j<TERR_ROWS; j++ )
00118                 for( int i=0; i<TERR_COLS; i++ )
00119                 {
00120                         pVertex[writeIndex].pos = Vec3D( e.sizeX * (i*1.0f/TERR_COLS -0.5f),
00121                                                                                          e.sizeY * (j*1.0f/TERR_ROWS -0.5f),
00122                                                                                          e.zMap[j][i] );
00123                         pVertex[writeIndex].normal = e.NMap[j][i];
00124                         pVertex[writeIndex].blendFactor = e.BMap[j][i];                 
00125                         writeIndex++;
00126                 }
00127 
00128         writeIndex = 0;
00129         for( int j=0; j<TERR_ROWS-1; j++ )                              // fill indices
00130         {
00131                 for( int i=0; i<TERR_COLS; i++ )                                                // create tri strips
00132                 {
00133                         pIndex[writeIndex++] = j*TERR_COLS +i;
00134                         pIndex[writeIndex++] = (j+1)*TERR_COLS +i;
00135                 }
00136                 if( j<TERR_ROWS-2 )                                                                     // join strips
00137                 {
00138                         pIndex[writeIndex++] = (j+2)*TERR_COLS -1;
00139                         pIndex[writeIndex++] = (j+1)*TERR_COLS;
00140                 }
00141         }
00142 
00143     e.vb->Unlock();
00144         e.ib->Unlock();
00145 }

void createZMap TerrainEntry   e,
UBYTE   pImg
 

create heightmap

Definition at line 30 of file ATerrain.cpp.

References TERR_COLS, and TERR_ROWS.

Referenced by terrain_create().

00031 {
00032         for( int j=0; j<TERR_ROWS; j++ )                        // get height from channel R
00033                 for( int i=0; i<TERR_COLS; i++ )
00034                         e.zMap[j][i] = e.sizeZ * pImg[ (j*TERR_COLS+i)*3 ] / 255.0f + e.offsetZ;
00035 
00036 
00037         // blur Z
00038         FLOAT sum[TERR_ROWS][TERR_COLS];
00039         int   count[TERR_ROWS][TERR_COLS];
00040 
00041 #define ADD( x, y, value )   if( x>=0 && y>=0 && x<TERR_COLS && y<TERR_ROWS ) { sum[y][x]+=value; count[y][x]++; }
00042 
00043         for( int blurCount=0; blurCount<2; blurCount++ )
00044         {
00045                 ZeroMemory( sum, sizeof(sum) );
00046                 ZeroMemory( count, sizeof(count) );
00047                 for( int j=0; j<TERR_ROWS; j++ )
00048                         for( int i=0; i<TERR_COLS; i++ )
00049                         {
00050                                 FLOAT value = e.zMap[j][i];
00051                                 ADD( i-1, j-1, value )
00052                                 ADD( i  , j-1, value )
00053                                 ADD( i+1, j-1, value )
00054                                 ADD( i-1, j  , value )
00055                                 ADD( i+1, j  , value )
00056                                 ADD( i-1, j+1, value )
00057                                 ADD( i  , j+1, value )
00058                                 ADD( i+1, j+1, value )
00059                         }
00060 
00061                 for( int j=0; j<TERR_ROWS; j++ )
00062                         for( int i=0; i<TERR_COLS; i++ )
00063                                 e.zMap[j][i] = sum[j][i] / count[j][i];
00064         }
00065 }

ATerrain terrain_create string    filename,
FLOAT    sizeX,
FLOAT    sizeY,
FLOAT    sizeZ,
FLOAT    offsetZ
 

Definition at line 147 of file ATerrain.cpp.

References ATerrain, createBMap(), createNMap(), createVIB(), createZMap(), TerrainEntry::doRender, CImage::GetHeight(), CImage::GetImageData(), CImage::GetWidth(), CImage::LoadTga(), TerrainEntry::offsetZ, TerrainEntry::sizeX, TerrainEntry::sizeY, TerrainEntry::sizeZ, TERR_COLS, TERR_ROWS, TerrainEntry::texHigh, TerrainEntry::texLow, TerrainEntry::texNormal, UBYTE, util_loadPixelShader(), and util_loadVertexShader().

Referenced by load_terrain().

00148 {
00149         CImage img;
00150         img.LoadTga(filename);
00151         assert(img.GetWidth()==TERR_COLS && img.GetHeight()==TERR_ROWS);
00152         UBYTE *imgData  = img.GetImageData();
00153 
00154         TerrainEntry e;
00155         e.doRender = false;
00156         e.texLow    = (DWORD) -1;
00157         e.texHigh   = (DWORD) -1;
00158         e.texNormal = (DWORD) -1;
00159         e.sizeX = sizeX;
00160         e.sizeY = sizeY;
00161         e.sizeZ = sizeZ;
00162         e.offsetZ = offsetZ;
00163 
00164         createZMap(e,imgData);
00165         createNMap(e);
00166         createBMap(e,imgData);
00167         createVIB(e);
00168 
00169         AS.res_terrains.push_back(e);
00170 
00171         // create V&P shaders
00172         if(AS.vshader_terrain==0)
00173         {
00174                 AS.vshader_terrain = util_loadVertexShader( "shaders\\terrain.vso", dwColoredTerrainVertexDecl );
00175                 AS.pshader_terrain = util_loadPixelShader(  "shaders\\terrain.pso" );   
00176         }
00177         
00178         return (ATerrain)AS.res_terrains.size()-1;
00179 }

void terrain_flush  
 

Definition at line 190 of file ATerrain.cpp.

References UINT.

Referenced by flushRenderRequests().

00191 {
00192         for( UINT i=0; i<AS.res_terrains.size(); i++ )
00193                 AS.res_terrains[i].doRender = false;
00194 }

FLOAT terrain_getHeight ATerrain    terrain,
FLOAT    x,
FLOAT    y
 

Definition at line 268 of file ATerrain.cpp.

References TerrainEntry::sizeX, TerrainEntry::sizeY, sys_console(), TERR_COLS, TERR_ROWS, triArea(), Vec2D, and TerrainEntry::zMap.

Referenced by Globals::ArtWork::ArtWork(), BattleGroup::destroyUnit(), BattleGroup::drawOutlineBox(), BattleGroup::fire(), BattleGroup::fireAntiAir(), BattleJets::flyTo(), BattleEntry::inputIssueJetsCommand(), BattleGroup::isContain2DPoint(), MilitaryUnit::move(), BattleJets::orderToBomb(), BattleGroup::render(), BattleEntry::renderGroups(), City::update(), and BattleEntry::updateDebris().

00269 {
00270         // idea : return the weighted average height of the closest 4 pts
00271         // weight = area of triangle formed
00272         assert(terrain>=0 && terrain<(int)AS.res_terrains.size());
00273         TerrainEntry &t = AS.res_terrains[terrain];
00274 
00275         FLOAT gridSizeX = t.sizeX / (TERR_COLS);
00276         FLOAT gridSizeY = t.sizeY / (TERR_ROWS);
00277         int i = (int)( (x+t.sizeX/2) / gridSizeX );
00278         int j = (int)( (y+t.sizeY/2) / gridSizeY );
00279         if( !(i>=0 && j>=0 && i<TERR_COLS-1 && j<TERR_ROWS-1) )
00280         {
00281                 sys_console() << "Warning : terrain_getHeight out of terrain area" << endl;
00282                 return 0;
00283         }
00284 
00285         Vec2D pMid(x,y);
00286         Vec2D p0( t.sizeX*(    i*1.0f/TERR_COLS -0.5f), t.sizeY*(    j*1.0f/TERR_ROWS -0.5f) );
00287         Vec2D p1( t.sizeX*((i+1)*1.0f/TERR_COLS -0.5f), t.sizeY*(    j*1.0f/TERR_ROWS -0.5f) );
00288         Vec2D p2( t.sizeX*((i+1)*1.0f/TERR_COLS -0.5f), t.sizeY*((j+1)*1.0f/TERR_ROWS -0.5f) );
00289         Vec2D p3( t.sizeX*(    i*1.0f/TERR_COLS -0.5f), t.sizeY*((j+1)*1.0f/TERR_ROWS -0.5f) );
00290 
00291         FLOAT tri0 = triArea( p0, p1, pMid );
00292         FLOAT tri1 = triArea( p1, p2, pMid );
00293         FLOAT tri2 = triArea( p2, p3, pMid );
00294         FLOAT tri3 = triArea( p3, p0, pMid );
00295 
00296         FLOAT weight0 = tri1*tri2,              weight1=tri2*tri3,
00297                   weight2 = tri3*tri0,          weight3=tri0*tri1;
00298         FLOAT sum = t.zMap[j][i]    *weight0 + t.zMap[j][i+1]*weight1
00299                       + t.zMap[j+1][i+1]*weight2 + t.zMap[j+1][i]*weight3;
00300         FLOAT height = sum/(weight0+weight1+weight2+weight3);   
00301         //return ((int)(height*10))/10.0f;
00302         return height;
00303 }

void terrain_processRenderRequest  
 

Definition at line 196 of file ATerrain.cpp.

References device_setIndexSource(), device_setPixelShader(), device_setRenderState(), device_setRenderStateBlendMode(), device_setStreamSource(), device_setTexture(), device_setTextureStageState(), device_setVertexShader(), DWORD, TerrainEntry::ib, Matx, TerrainEntry::sizeX, TerrainEntry::sizeY, TERR_COLS, TERR_ROWS, TerrainEntry::texHigh, TerrainEntry::texLow, TerrainEntry::texNormal, UINT, and TerrainEntry::vb.

Referenced by processRenderRequests().

00197 {       
00198         UINT i;
00199         for( i=0; i<AS.res_terrains.size(); i++ )               // find the one that needs rendering, if any
00200                 if( AS.res_terrains[i].doRender ) break;
00201         if( i>=AS.res_terrains.size() ) return;
00202         TerrainEntry &e = AS.res_terrains[i];   
00203 
00204         device_setVertexShader( AS.vshader_terrain );
00205         device_setPixelShader(  AS.pshader_terrain );
00206 
00207         device_setTexture( 0, AS.res_textures[e.texLow] );
00208         device_setTexture( 1, AS.res_textures[e.texHigh] );
00209         device_setTexture( 2, AS.res_textures[e.texNormal] );
00210 
00211         device_setStreamSource( 0, e.vb, sizeof(ColoredTerrainVertex) );
00212         device_setIndexSource( e.ib );
00213 
00214         // rendering flags
00215         device_setRenderState( D3DRS_ZENABLE,  TRUE );
00216         device_setRenderState( D3DRS_ZWRITEENABLE,  TRUE );
00217         for( DWORD stage=0; stage<4; stage++ )
00218         {
00219                 device_setTextureStageState( stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
00220                 device_setTextureStageState( stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
00221                 device_setTextureStageState( stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
00222         }       
00223         device_setRenderState( D3DRS_CULLMODE, D3DCULL_CW );
00224         device_setRenderStateBlendMode( BlendModes::NONE );
00225         device_setRenderState( D3DRS_SPECULARENABLE, TRUE );
00226 
00227         // set projXview matrix
00228         Matx mat;       
00229         D3DXMatrixTranspose( &mat, &AS.camera_world2projMatrix);
00230         AS.pDevice->SetVertexShaderConstant( 0, &mat, 4 );
00231 
00232         // set UV const
00233         FLOAT uvScale[4] = { 10.0f/e.sizeX, 10.0f/e.sizeY, 0.0f, 0.0f };
00234         FLOAT uvShift[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
00235         FLOAT nScale[4]  = { 25.0f/e.sizeX, 25.0f/e.sizeY, 0.0f, 0.0f };
00236         AS.pDevice->SetVertexShaderConstant( 4, &uvScale, 1 );
00237         AS.pDevice->SetVertexShaderConstant( 5, &uvShift, 1 );
00238         AS.pDevice->SetVertexShaderConstant( 8, &nScale, 1 );
00239 
00240         // set ATM const
00241         FLOAT lightVec[4] = { 0.5882f, 0.1961f, 0.7843f, 0.0f };  //lightVec = c6
00242         FLOAT lightAmbient[4] = { 0.24f, 0.24f, 0.2f };
00243         AS.pDevice->SetVertexShaderConstant( 6, &lightVec, 1 );
00244         AS.pDevice->SetVertexShaderConstant( 7, &lightAmbient, 1 );
00245         
00246         FLOAT normalVec[4] = { 0.3882f, 0.1961f, 0.1843f, 0.0f };  // PS c0
00247         FLOAT atmColor[4]  = { 0.6f, 0.8f, 1.0f, 0.0f };
00248         FLOAT zScale[4]    = { 0.0025f };
00249         AS.pDevice->SetPixelShaderConstant( 0, &normalVec, 1 );         // PS c1 = atm color
00250         AS.pDevice->SetPixelShaderConstant( 1, &atmColor, 1 );
00251         AS.pDevice->SetVertexShaderConstant( 9, &zScale, 1 );
00252         
00253         // render strip
00254         int numVertex = TERR_ROWS * TERR_COLS;
00255         int primCount = (TERR_ROWS-1)*2*TERR_COLS + (TERR_ROWS-2)*2 - 2;
00256         AS.pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, numVertex, 0, primCount );
00257 }

void terrain_render ATerrain    terrain,
ATexture    texLow,
ATexture    texHigh,
ATexture    texNormal
 

Definition at line 181 of file ATerrain.cpp.

Referenced by Overhead::overheadRender(), and BattleEntry::renderEnvironment().

00182 {
00183         assert(terrain>=0 && terrain<(int)AS.res_terrains.size());
00184         AS.res_terrains[terrain].doRender = true;
00185         AS.res_terrains[terrain].texLow    = texLow;
00186         AS.res_terrains[terrain].texHigh   = texHigh;
00187         AS.res_terrains[terrain].texNormal = texNormal;
00188 }

FLOAT triArea Vec2D   p0,
Vec2D   p1,
Vec2D   p2
 

Definition at line 259 of file ATerrain.cpp.

References Vec2D.

Referenced by BattleGroup::isContain2DPoint(), and terrain_getHeight().

00260 {
00261         Vec2D side1 = p0 - p2;
00262         Vec2D side2 = p1 - p2;
00263         FLOAT area = D3DXVec2CCW( &side1, &side2) / 2.0f;               // size of the cross product/2
00264         if( area>0 ) return  area;
00265                 else     return -area;
00266 }


Generated on Wed Apr 23 05:50:36 2003 for Modern Warfare by doxygen1.3-rc2