示例#1
0
//------------------------------------------------------------------------
// 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();
    }
}
示例#2
0
//------------------------------------------------------------------------
// 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;
}
示例#3
0
//------------------------------------------------------------------------
// 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 );
    }
}
示例#4
0
//------------------------------------------------------------------------
// 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 );
}
示例#5
0
//------------------------------------------------------------------------
// 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;
}
示例#6
0
//------------------------------------------------------------------------
// 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;
}
示例#7
0
//------------------------------------------------------------------------
// 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 );
    }
}
示例#8
0
//------------------------------------------------------------------------
// 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;
}
示例#9
0
//------------------------------------------------------------------------
// 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 );
}
示例#10
0
//------------------------------------------------------------------------
// 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();
}
示例#11
0
//------------------------------------------------------------------------
// 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() );
    }
}
示例#12
0
//------------------------------------------------------------------------
// 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++;
}
示例#13
0
//------------------------------------------------------------------------
// Destructor of the class.
//------------------------------------------------------------------------
etTileRenderable::~etTileRenderable(void)
{
    FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager();
    pResMgr->DeleteMaterial( m_pMaterial );
}
示例#14
0
//------------------------------------------------------------------------
// 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;
}
示例#15
0
//------------------------------------------------------------------------
// 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;
}
示例#16
0
//------------------------------------------------------------------------
// 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;
}