//------------------------------------------------------------------------ // Initialize the vegetation object. // ---------------------------------------------------------------------- // Param -> IN: // VEGETATIONTYPE: Vegetation object type. // const char*: Name of the mesh resource. (Mesh vegetation) // float: Width of the polygon. (Polygon vegetation) // float: Height of the polygon. (Polygon vegetation) // const etFloatRect&: Texture coord rect. // const char*: Path to the texture. // UINT: Count of the polygons. //------------------------------------------------------------------------ HRESULT etVegetationObject::Initialize( VEGETATIONTYPE Type,const char* cMeshName, float fWidth,float fHeight,const etFloatRect& texRect, const char* cTexture,UINT nNumPolygons ) { m_Type = Type; FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); FlyMeshManager* pMeshMgr = FlyKernel::Instance().GetMeshManager(); if( Type == VGT_POLYGON ) { // Load the texture from file. m_pTexture = pResMgr->Load2DTexture( cTexture,0 ); // Build the renderable object. return BuildPolygonRenderable( fWidth,fHeight,nNumPolygons,texRect ); } else { m_pMesh = pMeshMgr->GetMeshByName( cMeshName ); pMeshMgr->AddResourceRef( cMeshName ); m_nDirtyState = m_pMesh->GetDirtyState(); // Build the mesh object. return BuildMeshRenderable(); } }
//------------------------------------------------------------------------ // Initialize the detail layer. // ---------------------------------------------------------------------- // Param -> IN: // UINT: Size of the alphamap. //------------------------------------------------------------------------ HRESULT etDetailLayer::Initialize( UINT nMapSize ) { HRESULT hr; void* pBits; int nPitch; // Clean the old data. DestroyLayer(); // Create the temp buffer. m_pTempData = new UCHAR[nMapSize*nMapSize*4]; if( !m_pTempData ) return FLY_OUTOFMEMORY; m_nMapSize = nMapSize; memset( m_pTempData,0,nMapSize*nMapSize*4 ); // Get the resourceManager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); m_pTexture = pResMgr->AddNullTexture( "et-DetailLayer" ); if( !m_pTexture ) return FLY_OUTOFMEMORY; // Create the texture for detail layer. hr = m_pTexture->Create2DTexture( nMapSize,nMapSize,TU_DEFAULT,PFT_A8R8G8B8,1 ); if( FAILED(hr) ) return hr; m_pTexture->Access2DMap( 0,TMA_WRITEONLY,&pBits,&nPitch ); memcpy( pBits,m_pTempData,nMapSize*nMapSize*4 ); m_pTexture->Unaccess2DMap( 0 ); return FLY_OK; }
//------------------------------------------------------------------------ // Constructor of the class. //------------------------------------------------------------------------ etTileSelected::etTileSelected( etTile* pParent ) { m_pParent = pParent; m_RenderType = RT_LINESTRIP; m_nPriority = PRIORITY_HIGH; m_nNumVerts = 25; m_nNumIndis = 0; m_nNumPrims = 24; // Get the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); m_pVB = pResMgr->MakeVertexBuffer( 25*sizeof(VERTEXL),BU_WRITEONLY,MM_MANAGED ); VERTEXL* pContent = (VERTEXL*)m_pVB->Lock( LOCK_NORMAL ); for( int i=0;i<25;i++ ) { pContent->x = 0.0f; pContent->y = 0.0f; pContent->z = 0.0f; pContent->color = FLYCOLOR::Blue().GetRGBAValue(); pContent->tu = 0.0f; pContent->tv = 0.0f; pContent++; } m_pVB->Unlock(); m_pMaterial = pResMgr->GetMaterialByName( "et-Brush" ); if( !m_pMaterial ) { m_pMaterial = pResMgr->CreateMaterial( "et-Brush" ); m_pMaterial->SetDepthMode( 0,DEPTH_NONE ); } }
//------------------------------------------------------------------------ // Destructor of the class. //------------------------------------------------------------------------ etDetailLayer::~etDetailLayer(void) { SAFE_DELETE_ARRAY( m_pTempData ); // Get the resourceManager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); if( m_pTexture ) pResMgr->DeleteTexture( m_pTexture ); }
//------------------------------------------------------------------------ // Build the mesh renderable object. //------------------------------------------------------------------------ HRESULT etVegetationObject::BuildMeshRenderable(void) { std::string sMatName; // Get the pointer to the resouceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // 1. Create the render materials. for( UINT i=0;i<m_pMesh->GetNumMaterials();i++ ) { char cTemp[20]; FlyRenderMaterial* pMaterial; sprintf( cTemp,"_%d",i ); sMatName = "vegetation_" + m_sName + cTemp; pMaterial = pResMgr->CreateMaterial( sMatName.c_str() ); if( !pMaterial ) return FLY_OUTOFMEMORY; FlyRenderEffect* pEffect = etCoreManager::Instance().GetVegetationFX(); pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(1) ); pMaterial->SetActiveTechnique( 0 ); FlyRenderEffectInstance* pInstance = pMaterial->GetActiveRenderEffectInstance(); *pInstance->GetParameterByIndex(2) = m_pMesh->GetMaterial(i)->pTexture; m_Materials.push_back( pMaterial ); } // 2. Create the renderable objects. for( i=0;i<m_pMesh->GetNumSubMeshes();i++ ) { FlySubMesh* pSubMesh = m_pMesh->GetSubMesh( i ); // Create a new renderable. etVegetationRenderable* pObject = new etVegetationRenderable( this ); if( !pObject ) return FLY_OUTOFMEMORY; pObject->m_nNumVerts = pSubMesh->GetNumVerts(); pObject->m_nNumIndis = pSubMesh->GetNumIndis(); pObject->m_nNumPrims = pSubMesh->GetNumPrims(); pObject->m_pVB = pSubMesh->GetVertexBuffer(); pObject->m_pIB = pSubMesh->GetIndexBuffer(); pObject->SetRenderMaterial( m_Materials[pSubMesh->GetRenderMaterial()] ); pObject->m_BBox = pSubMesh->GetBoundingBox(); // Add the new object to list. m_Renderables.push_back( pObject ); } // Set the local boundingBox. m_Bounds = m_pMesh->GetBoundingBox(); return FLY_OK; }
//------------------------------------------------------------------------ // Destroy the detail layer, clean the memory. //------------------------------------------------------------------------ void etDetailLayer::DestroyLayer(void) { SAFE_DELETE_ARRAY( m_pTempData ); // Get the resourceManager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); if( m_pTexture ) pResMgr->DeleteTexture( m_pTexture ); m_nMapSize = 0; m_pTexture = NULL; }
//------------------------------------------------------------------------ // Destructor of the class. //------------------------------------------------------------------------ etVegetationRenderable::~etVegetationRenderable(void) { FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); if( m_pParent->GetVegetationType() == VGT_POLYGON ) { SAFE_DELETE( m_pVB ); SAFE_DELETE( m_pIB ); pResMgr->DeleteMaterial( m_pMaterial ); } }
//------------------------------------------------------------------------ // Build the animation renderable units to render. //------------------------------------------------------------------------ HRESULT FlyAnimation::BuildMaterials(void) { std::string sMatName; // Get the resource Manager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); // Build the material datas. for( UINT i=0;i<m_sHeader.nNumMaterials;i++ ) { FLYMATERIAL mat; FlyTexture* pTexture; // Create the render material. char cTemp[20]; sprintf( cTemp,"_%d",i ); sMatName = "anim_" + m_sName + cTemp; FlyRenderMaterial* pMaterial = pResMgr->CreateMaterial( sMatName.c_str() ); if( !pMaterial ) return FLY_OUTOFMEMORY; memcpy( &mat,&m_pMaterials[i],sizeof(FLYMATERIAL) ); pMaterial->SetStdMaterial( 0,&mat ); // Load the texture A. if( m_pMaterials[i].sTexture_A != "" ) { pTexture = pResMgr->Load2DTexture( m_pMaterials[i].sTexture_A.c_str(),0 ); if( pTexture ) { pMaterial->SetTexture( 0,0,pTexture ); if( pTexture->HasAlphaChannel() ) { pMaterial->SetSceneAlphaMode( 0,true,false ); pMaterial->SetAlphaBlendMode( 0,SBM_SRCALPHA,SBM_INVSRCALPHA ); } } } // Load the texture B. if( m_pMaterials[i].sTexture_B != "" ) { pTexture = pResMgr->Load2DTexture( m_pMaterials[i].sTexture_B.c_str(),0 ); if( pTexture ) pMaterial->SetTexture( 0,1,pTexture ); } // Add the material to list. m_RMaterials.push_back( pMaterial ); } return FLY_OK; }
//------------------------------------------------------------------------ // Constructor of the class. //------------------------------------------------------------------------ etTileRenderable::etTileRenderable( etTile* pParent ) { m_pParent = pParent; m_nNumVerts = 0; m_nNumIndis = 0; m_nNumPrims = 0; m_pVB = NULL; m_pIB = NULL; memset( &m_BBox,0,sizeof(FlyAabb) ); // Get the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // Create the material if needed. char cMatName[80]; sprintf( cMatName,"et-%s",m_pParent->GetName() ); m_pMaterial = pResMgr->CreateMaterial( cMatName ); }
//------------------------------------------------------------------------ // Reinitialize the vegetation object. (Only for Mesh type) //------------------------------------------------------------------------ HRESULT etVegetationObject::Reinitialize(void) { // Get the pointer to the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // Destroy the old renderables. RenderableList::iterator obj; for( obj=m_Renderables.begin();obj!=m_Renderables.end();obj++ ) SAFE_DELETE( *obj ); m_Renderables.clear(); // Destroy the render materials. MaterialList::iterator mat; for( mat=m_Materials.begin();mat!=m_Materials.end();mat++ ) pResMgr->DeleteMaterial( *mat ); m_Materials.clear(); // Update the dirty state. m_nDirtyState = m_pMesh->GetDirtyState(); return BuildMeshRenderable(); }
//------------------------------------------------------------------------ // Destructor of the class. //------------------------------------------------------------------------ etVegetationObject::~etVegetationObject(void) { RenderableList::iterator itr; for( itr=m_Renderables.begin();itr!=m_Renderables.end();itr++ ) SAFE_DELETE( *itr ); // Get the pointer to the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // Get the pointer to the meshManager. FlyMeshManager* pMeshMgr = FlyKernel::Instance().GetMeshManager(); if( m_Type == VGT_POLYGON ) pResMgr->DeleteTexture( m_pTexture ); else { MaterialList::iterator mat; for( mat=m_Materials.begin();mat!=m_Materials.end();mat++ ) pResMgr->DeleteMaterial( *mat ); pMeshMgr->DecResourceRef( m_pMesh->GetName() ); } }
//------------------------------------------------------------------------ // Destroy the animation, clean all the memory. //------------------------------------------------------------------------ void FlyAnimation::Destroy(void) { FlyTexture* pTexture; // Get the resource manager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); // Clear all the anim node. for( size_t i=0;i<m_AnimGroup.size();i++ ) SAFE_DELETE_ARRAY( m_AnimGroup[i].pJoints ); m_AnimGroup.clear(); // Clear the materials. for( size_t i=0;i<m_RMaterials.size();i++ ) { pTexture = m_RMaterials[i]->GetTexture( 0,0 ); if( pTexture ) pResMgr->DeleteTexture( pTexture ); pTexture = m_RMaterials[i]->GetTexture( 0,1 ); if( pTexture ) pResMgr->DeleteTexture( pTexture ); pResMgr->DeleteMaterial( m_RMaterials[i] ); } m_RMaterials.clear(); // Clear the geometry datas. SAFE_DELETE_ARRAY( m_pVertices ); SAFE_DELETE_ARRAY( m_pVertices_Orig ); SAFE_DELETE_ARRAY( m_pFaces ); SAFE_DELETE_ARRAY( m_pMeshes ); SAFE_DELETE_ARRAY( m_pMaterials ); memset( &m_sHeader,0,sizeof(sModelHeader) ); memset( &m_BBox,0,sizeof(sModelHeader) ); // Update the dirty state. m_nDirtyState++; }
//------------------------------------------------------------------------ // Destructor of the class. //------------------------------------------------------------------------ etTileRenderable::~etTileRenderable(void) { FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); pResMgr->DeleteMaterial( m_pMaterial ); }
//------------------------------------------------------------------------ // Initialize the terrain tile. // ---------------------------------------------------------------------- // Param -> IN: // int,int: Position where we start to read the height data. // const float*: Pointer to the height data. //------------------------------------------------------------------------ HRESULT etTile::Initialize( int startx,int startz,const float* pHeightData ) { m_nStartX = startx; m_nStartZ = startz; // Get the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // Create the shared vertex buffer. UINT nTileSize = m_pLevel->GetTileSize(); m_pVB = pResMgr->MakeVertexBuffer( (nTileSize+1)*(nTileSize+1)*sizeof(VERTEX2T), BU_WRITEONLY,MM_MANAGED ); if( !m_pVB ) return FLY_CREATEBUFFER; float fMinHeight = 0.0f; float fMaxHeight = 0.0f; int endx = startx + nTileSize + 1; int endz = startz + nTileSize + 1; VERTEX2T* pVerts = (VERTEX2T*)m_pVB->Lock( 0,(nTileSize+1)*(nTileSize+1)*sizeof(VERTEX2T),LOCK_NORMAL ); for( int j=startz;j<endz;j++ ) { for( int i=startx;i<endx;i++ ) { float fHeight = pHeightData[j*(m_pLevel->GetTerrainSize()+1)+i]; fHeight *= m_pLevel->GetHeightScale(); pVerts->x = (float)i * m_pLevel->GetLengthPerUnit(); pVerts->y = fHeight; pVerts->z = (float)j * m_pLevel->GetLengthPerUnit(); pVerts->vN[0] = 0.0f; pVerts->vN[1] = 1.0f; pVerts->vN[2] = 0.0f; pVerts->tu0 = ((float)i / (float)nTileSize); pVerts->tv0 = ((float)j / (float)nTileSize); pVerts->tu1 = ((float)i / (float)m_pLevel->GetTerrainSize()); pVerts->tv1 = ((float)j / (float)m_pLevel->GetTerrainSize()); pVerts++; if( fHeight < fMinHeight ) fMinHeight = fHeight; if( fHeight > fMaxHeight ) fMaxHeight = fHeight; } } m_pVB->Unlock(); // Set the boundingBox. m_Bounds.vcMin.x = (float)startx * m_pLevel->GetLengthPerUnit(); m_Bounds.vcMin.y = fMinHeight - 1.0f; m_Bounds.vcMin.z = (float)startz * m_pLevel->GetLengthPerUnit(); m_Bounds.vcMax.x = (float)(endx-1) * m_pLevel->GetLengthPerUnit(); m_Bounds.vcMax.y = fMaxHeight + 1.0f; m_Bounds.vcMax.z = (float)(endz-1) * m_pLevel->GetLengthPerUnit(); // Set the boundingRect. m_BRect.SetMinPoint( m_Bounds.vcMin.x,m_Bounds.vcMin.z ); m_BRect.SetMaxPoint( m_Bounds.vcMax.x,m_Bounds.vcMax.z ); // Create the renderable object for the tile. m_pRenderable = new etTileRenderable( this ); m_pRenderable->m_BBox = m_Bounds; m_pRenderable->m_pVB = m_pVB; m_pRenderable->m_nNumVerts = (nTileSize+1)*(nTileSize+1); // Create the renderable object when tile is selected. m_pSelected = new etTileSelected( this ); m_pSelected->BuildGeometry(); FlyRenderEffect* pEffect = etCoreManager::Instance().GetTerrainFX(); m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(0) ); m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(1) ); m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(2) ); m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(3) ); m_pRenderable->m_pMaterial->SetActiveTechnique( 0 ); // Initialize the default GPU parameters. FlyRenderEffectInstance* pGPUProgram; FlyVector vLightDir = m_pManager->GetLightDirection(); vLightDir.Normalize(); for( int i=0;i<4;i++ ) { pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i); *pGPUProgram->GetParameterByIndex(0) = m_pMainTexture; *pGPUProgram->GetParameterByIndex(1) = m_pLevel->GetDetailLayer()->GetTexture(); *pGPUProgram->GetParameterByIndex(2) = m_pDetails[0]; *pGPUProgram->GetParameterByIndex(3) = m_pDetails[1]; *pGPUProgram->GetParameterByIndex(4) = m_pDetails[2]; *pGPUProgram->GetParameterByIndex(5) = m_pDetails[3]; *pGPUProgram->GetParameterByIndex(6) = m_fMainScale; *pGPUProgram->GetParameterByIndex(7) = m_fDetailScale[0]; *pGPUProgram->GetParameterByIndex(8) = m_fDetailScale[1]; *pGPUProgram->GetParameterByIndex(9) = m_fDetailScale[2]; *pGPUProgram->GetParameterByIndex(10) = m_fDetailScale[3]; *pGPUProgram->GetParameterByIndex(11) = m_pManager->GetLightingMode(); *pGPUProgram->GetParameterByIndex(12) = vLightDir; *pGPUProgram->GetParameterByIndex(13) = *((FlyVector*)&m_pManager->GetLightAmbient()); *pGPUProgram->GetParameterByIndex(14) = *((FlyVector*)&m_pManager->GetLightDiffuse()); *pGPUProgram->GetParameterByIndex(16) = *((FlyVector*)&m_pManager->GetWireColor()); } return FLY_OK; }
//------------------------------------------------------------------------ // Generate the triangle list indices for the tile. // ---------------------------------------------------------------------- // Param -> IN: // UINT: Flags when generating the buffer. // FlyGraphicBuffer**: To store the index buffer. // UINT*: To store the count of indices. //------------------------------------------------------------------------ void etTile::GenerateListIndexData( UINT nStitchFlags,FlyGraphicBuffer** ppIB, UINT* pNumIndices ) { UINT nNumIndices = 0; int step = 1 << m_nLodLevel; int east = nStitchFlags & STITCH_EAST ? step : 0; int west = nStitchFlags & STITCH_WEST ? step : 0; int south = nStitchFlags & STITCH_SOUTH ? step : 0; int north = nStitchFlags & STITCH_NORTH ? step : 0; UINT nTileSize = m_pLevel->GetTileSize(); UINT nBufferLength = (nTileSize/step) * (nTileSize/step) * 6; // Get the resourceManager. FlyResourceManager* pResMgr = FlyKernel::Instance().GetResourceManager(); // Create the index buffer. FlyGraphicBuffer* pIB = pResMgr->MakeIndexBuffer( nBufferLength*sizeof(WORD), BU_WRITEONLY,MM_MANAGED,IF_INDEX16 ); if( !pIB ) return; WORD* pIndices = (WORD*)pIB->Lock( 0,nBufferLength*sizeof(WORD),LOCK_NORMAL ); if( !pIndices ) { SAFE_DELETE( pIB ); return; } #define _Index(a,b) ((b)*(nTileSize+1)+(a)) for( int j=south;j<nTileSize-north;j+=step ) { for( int i=west;i<nTileSize-east;i+=step ) { *pIndices++ = _Index( i,j ); *pIndices++ = _Index( i,j+step ); *pIndices++ = _Index( i+step,j ); *pIndices++ = _Index( i,j+step ); *pIndices++ = _Index( i+step,j+step ); *pIndices++ = _Index( i+step,j ); nNumIndices += 6; } } #undef _Index if( north > 0 ) { nNumIndices += StitchEdge( NB_NORTH,m_nLodLevel,m_pNeighbors[NB_NORTH]->m_nLodLevel, east>0,west>0,&pIndices ); } if( east > 0 ) { nNumIndices += StitchEdge( NB_EAST,m_nLodLevel,m_pNeighbors[NB_EAST]->m_nLodLevel, south>0,north>0,&pIndices ); } if( south > 0 ) { nNumIndices += StitchEdge( NB_SOUTH,m_nLodLevel,m_pNeighbors[NB_SOUTH]->m_nLodLevel, west>0,east>0,&pIndices ); } if( west > 0 ) { nNumIndices += StitchEdge( NB_WEST,m_nLodLevel,m_pNeighbors[NB_WEST]->m_nLodLevel, north>0,south>0,&pIndices ); } pIB->Unlock(); *ppIB = pIB; *pNumIndices = nNumIndices; }
//------------------------------------------------------------------------ // Build the polygon renderable object. //------------------------------------------------------------------------ HRESULT etVegetationObject::BuildPolygonRenderable( float fWidth,float fHeight,UINT nNumPolygons, const etFloatRect& texRect ) { std::string sMatName; // Get the pointer to the sceneManager. etSceneManager* pManager = (etSceneManager*)etCoreManager::Instance().GetSceneManager(); // Create the renderable object. etVegetationRenderable* pRenderable = new etVegetationRenderable( this ); if( !pRenderable ) return FLY_OUTOFMEMORY; pRenderable->m_nNumVerts = nNumPolygons * 4; pRenderable->m_nNumIndis = nNumPolygons * 6; pRenderable->m_nNumPrims = nNumPolygons * 2; // Get the pointer to the resourceManager. FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager(); // Create the vertex buffer. pRenderable->m_pVB = pResMgr->MakeVertexBuffer( sizeof(VERTEXL)*pRenderable->m_nNumVerts, BU_WRITEONLY,MM_MANAGED ); if( !pRenderable->m_pVB ) return FLY_CREATEBUFFER; VERTEXL* pVerts = (VERTEXL*)pRenderable->m_pVB->Lock( LOCK_NORMAL ); // Create the index buffer. pRenderable->m_pIB = pResMgr->MakeIndexBuffer( sizeof(WORD)*pRenderable->m_nNumIndis, BU_WRITEONLY,MM_MANAGED,IF_INDEX16 ); if( !pRenderable->m_pIB ) return FLY_CREATEBUFFER; WORD* pIndis = (WORD*)pRenderable->m_pIB->Lock( LOCK_NORMAL ); float fAngle = FLY_PI / nNumPolygons; float fRadius = fWidth / 2.0f; UINT nVertOffset = 0; for( int i=0;i<nNumPolygons;i++ ) { float fX1 = -fRadius * cosf( fAngle*i ); float fZ1 = fRadius * sinf( fAngle*i ); float fX2 = -fRadius * cosf( fAngle*i+FLY_PI ); float fZ2 = fRadius * sinf( fAngle*i+FLY_PI ); pVerts->x = fX1; pVerts->y = -fHeight / 2.0f; pVerts->z = fZ1; pVerts->color = 0xffffffff; pVerts->tu = texRect.GetMinPointX(); pVerts->tv = texRect.GetMaxPointZ(); pVerts++; pVerts->x = fX1; pVerts->y = fHeight / 2.0f; pVerts->z = fZ1; pVerts->color = 0xffffffff; pVerts->tu = texRect.GetMinPointX(); pVerts->tv = texRect.GetMinPointZ(); pVerts++; pVerts->x = fX2; pVerts->y = fHeight / 2.0f; pVerts->z = fZ2; pVerts->color = 0xffffffff; pVerts->tu = texRect.GetMaxPointX(); pVerts->tv = texRect.GetMinPointZ(); pVerts++; pVerts->x = fX2; pVerts->y = -fHeight / 2.0f; pVerts->z = fZ2; pVerts->color = 0xffffffff; pVerts->tu = texRect.GetMaxPointX(); pVerts->tv = texRect.GetMaxPointZ(); pVerts++; *pIndis++ = 0 + nVertOffset; *pIndis++ = 1 + nVertOffset; *pIndis++ = 2 + nVertOffset; *pIndis++ = 2 + nVertOffset; *pIndis++ = 3 + nVertOffset; *pIndis++ = 0 + nVertOffset; nVertOffset += 4; } pRenderable->m_pVB->Unlock(); pRenderable->m_pIB->Unlock(); // Calculate the boundingBox. pRenderable->m_BBox.vcMin.Set( -fRadius,-fHeight/2.0f,-fRadius ); pRenderable->m_BBox.vcMax.Set( fRadius, fHeight/2.0f, fRadius ); // Create the render material for the object. sMatName = "vegetation_" + m_sName; pRenderable->m_pMaterial = pResMgr->CreateMaterial( sMatName.c_str() ); FlyRenderEffect* pEffect = etCoreManager::Instance().GetVegetationFX(); pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(0) ); pRenderable->m_pMaterial->SetActiveTechnique( 0 ); FlyRenderEffectInstance* pInstance = pRenderable->m_pMaterial->GetActiveRenderEffectInstance(); *pInstance->GetParameterByIndex(2) = m_pTexture; // Set the local boundingBox. m_Bounds = pRenderable->m_BBox; m_Renderables.push_back( pRenderable ); return FLY_OK; }