//------------------------------------------------------------------------ // Render the vegetation object. //------------------------------------------------------------------------ void etVegetationObject::RenderObject(void) { FlyRenderEffectInstance* pInstance; float fCamDist = sqrtf(m_fSqrDistToCamera) - m_WorldBBox.GetBoundingRadius(); if( m_Type == VGT_POLYGON ) { FlyRenderMaterial* pMaterial = m_Renderables[0]->GetRenderMaterial(); pInstance = pMaterial->GetActiveRenderEffectInstance(); *pInstance->GetParameterByIndex(0) = fCamDist; *pInstance->GetParameterByIndex(1) = m_fBeyondDist; m_Renderables[0]->AddToRenderQueue(); } else { MaterialList::iterator mat; for( mat=m_Materials.begin();mat!=m_Materials.end();mat++ ) { pInstance = (*mat)->GetActiveRenderEffectInstance(); *pInstance->GetParameterByIndex(0) = fCamDist; *pInstance->GetParameterByIndex(1) = m_fBeyondDist; } RenderableList::iterator itr; for( itr=m_Renderables.begin();itr!=m_Renderables.end();itr++ ) (*itr)->AddToRenderQueue(); } }
//------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------ // Set the scale for the main texture. // ---------------------------------------------------------------------- // Param -> IN: // float: Scale of the main texture. //------------------------------------------------------------------------ void etTile::SetMainScale( float fScale ) { m_fMainScale = fScale; FlyRenderEffectInstance* pGPUProgram; for( int i=0;i<4;i++ ) { pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i); *pGPUProgram->GetParameterByIndex(6) = fScale; } }
//------------------------------------------------------------------------ // Set the main texture for the terrain tile. // ---------------------------------------------------------------------- // Param -> IN: // FlyTexture*: Pointer to the main texture. //------------------------------------------------------------------------ void etTile::SetMainTexture( FlyTexture* pTexture ) { if( !pTexture ) pTexture = m_pLevel->GetDefaultTexture(); FlyRenderEffectInstance* pGPUProgram; for( int i=0;i<4;i++ ) { pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i); *pGPUProgram->GetParameterByIndex(0) = pTexture; } m_pMainTexture = pTexture; }
//------------------------------------------------------------------------ // Set the detail layer's scale for the tile. // ---------------------------------------------------------------------- // Param -> IN: // int: Index of the detail layer. // float: Scale of the detail layer. //------------------------------------------------------------------------ void etTile::SetDetailScale( int nIndex,float fScale ) { FlyRenderEffectInstance* pGPUProgram; if( nIndex >= 0 && nIndex < 4 ) { m_fDetailScale[nIndex] = fScale; for( int i=0;i<4;i++ ) { pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i); *pGPUProgram->GetParameterByIndex(7+nIndex) = fScale; } } }
//------------------------------------------------------------------------ // Set the detail texture for the tile. // ---------------------------------------------------------------------- // Param -> IN: // int: Index of the terrain tile. // FlyTexture*: Pointer to the texture. //------------------------------------------------------------------------ void etTile::SetDetailTexture( int nIndex,FlyTexture* pTexture ) { FlyRenderEffectInstance* pGPUProgram; if( nIndex >= 0 && nIndex < 4 ) { m_pDetails[nIndex] = pTexture; for( int i=0;i<4;i++ ) { pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i); *pGPUProgram->GetParameterByIndex(2+nIndex) = pTexture; } if( !pTexture ) SetDetailScale( nIndex,0.0f ); } }
//------------------------------------------------------------------------ // 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; }
//------------------------------------------------------------------------ // 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; }