Esempio n. 1
0
void cMyASELoader::LoadMesh(){
#ifdef _DEBUG
	_ASSERT(m_bLoaded && "Data Not Loaded");
#endif
	int check = 0;
	for (size_t i = 0; i < m_vecASENode.size(); i++){
		if (m_vecASENode[i].nRef != INT_MAX){
			m_vecsubSet.push_back(m_vecASENode[i].nRef);
			LPD3DXMESH pMesh = NULL;
			HRESULT hr = D3DXCreateMeshFVF(m_vecASENode[i].vecVertex.size() / 3,
				m_vecASENode[i].vecVertex.size(),
				D3DXMESH_MANAGED,
				ST_PNT_VERTEX::FVF,
				g_pD3DDevice,
				&pMesh);

			ST_PNT_VERTEX* pV = NULL;
			pMesh->LockVertexBuffer(0, (LPVOID*)&pV);
			memcpy(pV, &m_vecASENode[i].vecVertex[0], m_vecASENode[i].vecVertex.size() * sizeof(ST_PNT_VERTEX));
			pMesh->UnlockVertexBuffer();

			WORD* pI = NULL;
			pMesh->LockIndexBuffer(0, (LPVOID*)&pI);
			for (size_t j = 0; j < pMesh->GetNumVertices(); ++j)
			{
				pI[j] = j;
			}
			pMesh->UnlockIndexBuffer();

			DWORD* pA = NULL;
			pMesh->LockAttributeBuffer(0, &pA);
			for (size_t j = 0; j < pMesh->GetNumFaces(); j++){
				pA[j] = m_vecASENode[i].nRef;
			}
			pMesh->UnlockAttributeBuffer();

			std::vector<DWORD> vecAdjBuffer(m_vecASENode[i].vecVertex.size());
			pMesh->GenerateAdjacency(0.0f, &vecAdjBuffer[0]);

			pMesh->OptimizeInplace(
				D3DXMESHOPT_ATTRSORT |
				D3DXMESHOPT_COMPACT |
				D3DXMESHOPT_VERTEXCACHE,
				&vecAdjBuffer[0], 0, 0, 0);

			m_vecMeshs.push_back(pMesh);
		}
	}
	m_bMeshed = true;
}
Esempio n. 2
0
//------------------------------------------------------
//		DirectXメッシュの作成
//------------------------------------------------------
LPD3DXMESH	iex3DObj::CreateMesh( LPIEMFILE lpIem )
{
	LPD3DXMESH	lpMesh;
	u8			*pVertex, *pFace;
	u32			*pData;
	
	if( lpIem->version < 4 )
	{
		u32	Declaration = D3DFVF_MESHVERTEX;
		//	メッシュ作成
		D3DXCreateMeshFVF( lpIem->NumFace, lpIem->NumVertex, D3DXMESH_MANAGED, Declaration, tdnSystem::GetDevice(), &lpMesh );
		//	頂点設定
		lpMesh->LockVertexBuffer( 0, (void**)&pVertex );
		CopyMemory( pVertex, lpIem->lpVertex, sizeof(MESHVERTEX)*lpIem->NumVertex );
	} else {
		u32	Declaration = D3DFVF_MESHVERTEX2;
		//	メッシュ作成
		D3DXCreateMeshFVF( lpIem->NumFace, lpIem->NumVertex, D3DXMESH_MANAGED, Declaration, tdnSystem::GetDevice(), &lpMesh );
		//	頂点設定
		lpMesh->LockVertexBuffer( 0, (void**)&pVertex );
		CopyMemory( pVertex, lpIem->lpVertex, sizeof(MESHVERTEX2)*lpIem->NumVertex );
	}

	lpMesh->UnlockVertexBuffer();


	//	面設定
	lpMesh->LockIndexBuffer( 0, (void**)&pFace );
	CopyMemory( pFace, lpIem->lpFace, sizeof(u16)*lpIem->NumFace*3 );
	lpMesh->UnlockIndexBuffer();

	//	属性設定
	lpMesh->LockAttributeBuffer( 0, &pData );
	CopyMemory( pData, lpIem->lpAtr, sizeof(u32)*lpIem->NumFace );
	lpMesh->UnlockAttributeBuffer();

	return lpMesh;
}
//------------------------------------------------------------------------------------------------
// Name:  CreateTerrainMesh
// Desc:  
//------------------------------------------------------------------------------------------------
bool CreateTerrainMesh(LPDIRECT3DDEVICE9 d3dDevice, LPD3DXMESH* terrainMesh)
{
    // Calculate the number of faces and vertices required
    const unsigned int faces = (TMS_COUNT + 3) * 2;
    const unsigned int vertices = (TMS_COUNT + 3) * 4;

    // The internal terrain mesh
    LPD3DXMESH internalTerrainMesh;

    // Create the mesh
    HRESULT hr = D3DXCreateMeshFVF(faces, vertices, D3DXMESH_MANAGED, D3DFVF_GEOMETRYVERTEX, d3dDevice, &internalTerrainMesh);
    if (APP_ERROR(FAILED(hr))("Unable to create the terrain mesh"))
        return false;

    // Lock the mesh buffers
    GeometryVertex* lockedVertices = 0;
    WORD* lockedIndices = 0;
    DWORD* lockedAttributes = 0;
    if (APP_ERROR(FAILED(internalTerrainMesh->LockAttributeBuffer(0, &lockedAttributes)) ||
                   FAILED(internalTerrainMesh->LockVertexBuffer(0, (VOID**)&lockedVertices)) ||
                   FAILED(internalTerrainMesh->LockIndexBuffer(0, (VOID**)&lockedIndices)))("Unable to lock terrain mesh"))
    {
        // Deallocate the mesh
        SAFE_RELEASE(internalTerrainMesh);

        // Exit the method
        return false;
    }

    // Vertices that will be rotated 4x about Y at
    // 90-degree intervals to produce the wall mesh
    GeometryVertex wallSide[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { -0.5f, -1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // The flat square with unit size
    GeometryVertex flat[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the high-corner meshes,
    // with the high corner in the north-west
    GeometryVertex highCorner[] = {
        { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-corner meshes,
    // with the low corner in the north-west
    GeometryVertex lowCorner[] = {
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the high-side meshes,
    // with the high side to the north
    GeometryVertex highSide[] = {
        { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-corner meshes,
    // with the low corner in the north-west
    GeometryVertex raisedLowCorner[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-side meshes,
    // with the low side to the north
    GeometryVertex lowSide[] = {
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // The subset that is currently being written
    unsigned int currentSubset = TMS_WALL_SIDES;

    // Copy the wall first--it does not have any texture rotations
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 0.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 1.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 2.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 3.0f * D3DX_PI / 2.0f);

    // Copy four sets of squares
    lockedIndices = PrintSquareIndices(lockedIndices, 0, 4);
    lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 4);

    // Move to the next subset
    currentSubset++;

    // Write the flat mesh first, since it only has texture rotations
    for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset)
    {
        SetTerrainTexcoords(flat, textureDirection);
        lockedVertices = CopyYRotatedGeometry(lockedVertices, flat, 4, 0.0f);
        lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1);
        lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1);
    }

    // Repeat for all combinations of texture direction and rotation for the remaining types
    for (int type = 0; type < 5; ++type)
    {
        GeometryVertex* sourceGeometry;
        switch(type)
        {
            case 0: sourceGeometry = highCorner; break;
            case 1: sourceGeometry = lowCorner;  break;
            case 2: sourceGeometry = highSide;   break;
            case 3: sourceGeometry = raisedLowCorner; break;
            case 4: sourceGeometry = lowSide;    break;
        }

        // Repeat for all rotations
        for (int rotation = 0; rotation < 4; ++rotation)
        {
            // Calculate the rotation angle
            float rotationAngle = D3DX_PI / 2.0f * rotation;

            // Repeat for all texture directions
            for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset)
            {
                // Reverse the rotation of the texture by the rotation of the element so that we get
                // consistent texture directions (i.e. north is texture-up on all tiles)
                SetTerrainTexcoords(sourceGeometry, (textureDirection - rotation + 4) % 4);
                lockedVertices = CopyYRotatedGeometry(lockedVertices, sourceGeometry, 4, rotationAngle);
                lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1);
                lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1);
            }
        }
    }

    // Unlock the buffers
    internalTerrainMesh->UnlockVertexBuffer();
    internalTerrainMesh->UnlockIndexBuffer();
    internalTerrainMesh->UnlockAttributeBuffer();

    // Normalize
    //CONFIRM(SUCCEEDED(D3DXComputeNormals(internalTerrainMesh, NULL)));

    // Assign the output mesh
    *terrainMesh = internalTerrainMesh;

    // Success
    return true;
}
Esempio n. 4
0
HRESULT KModelWater::LoadMesh(LPSTR pFileName)
{
	HRESULT hr = S_OK;

	m_dwNumPoly_X = 63;     //长方形网格的长,网格数
	m_dwNumPoly_Z = 63;     //长方形网格的宽,网格数

	LPD3DXMESH pMesh = m_pWaterUp;
	LPD3DXMESH pDMesh = m_pWaterDn;

	DWORD m_dNumPloy     = m_dwNumPoly_X * m_dwNumPoly_Z;
	DWORD m_dNumFaces    = m_dNumPloy * 2;
	DWORD m_dNumVertices = (m_dwNumPoly_X+1)*(m_dwNumPoly_Z+1);

	SAFE_RELEASE(pMesh);	
	SAFE_RELEASE(pDMesh);
	WORD *pwIndices;

	//建立水面网格 
	if(FAILED(hr = g_pd3dDevice->CreateIndexBuffer(m_dNumFaces * 3 * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
		D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibIndices, NULL)))
	{
		return hr;
	}

	if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT,
		D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pMesh)))
	{
		return hr;
	}	
	if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT,
		D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pDMesh)))
	{
		return hr;
	}




	VFormat::FACES_NORMAL_TEXTURE1 * pVers = NULL;
	DWORD* pIndex = NULL;
	DWORD * pAttrib = NULL;	

	VFormat::FACES_NORMAL_TEXTURE1 * pDVers = NULL;
	DWORD* pDIndex = NULL;
	DWORD * pDAttrib = NULL;	
	if(FAILED(hr = m_pibIndices->Lock(0, m_dNumFaces *3 * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD)))
		return E_FAIL;
	if (FAILED(pMesh->LockVertexBuffer(0,(void**)&pVers)))
		return E_FAIL;
	if (FAILED(pMesh->LockIndexBuffer (0,(void**)&pIndex)))
		return E_FAIL;
	if (FAILED(pMesh->LockAttributeBuffer(0,(DWORD**)&pAttrib)))
		return E_FAIL;

	if (FAILED(pDMesh->LockVertexBuffer(0,(void**)&pDVers)))
		return E_FAIL;
	if (FAILED(pDMesh->LockIndexBuffer (0,(void**)&pDIndex)))
		return E_FAIL;
	if (FAILED(pDMesh->LockAttributeBuffer(0,(DWORD**)&pDAttrib)))
		return E_FAIL;

	DWORD i = 0;
	float _X = 1.0f/m_dwNumPoly_X;
	float _Z = 1.0f/m_dwNumPoly_Z;

	float m_fPolyWidth  = 200;
	float m_fPolyHeight = 200;

	for(DWORD X =0;X<=m_dwNumPoly_X;X++)
	{
		for(DWORD Y =0;Y<=m_dwNumPoly_Z;Y++)
		{
			float PX = X * m_fPolyWidth;
			float PZ = Y * m_fPolyHeight;

			D3DXVECTOR2 Pos(PX,PZ);

			pVers[i].p = D3DXVECTOR3(PX,200,PZ);

			pVers[i].Normal = D3DXVECTOR3(0,1,0);

			pVers[i].tu1 = (X * _X);
			pVers[i].tv1 = (1 - Y *_Z);
			pDVers[i].p = D3DXVECTOR3(PX,0,PZ);
			pDVers[i].Normal = D3DXVECTOR3(0,1,0);
			pDVers[i].tu1 = (X * _X);
			pDVers[i].tv1 = (1 - Y *_Z);
			i++;
		}
	}

	DWORD  Weight = m_dwNumPoly_X + 1;

	for(X =0;X<m_dwNumPoly_X;X++)
	{
		for(DWORD Y =0;Y<m_dwNumPoly_Z;Y++)
		{
			DWORD PloyIndex = Y*m_dwNumPoly_X +X;

			DWORD PolyMaterialID = 0;

			DWORD Vertex_A = X    *Weight+ Y;
			DWORD Vertex_B = (X+1)*Weight+ Y;
			DWORD Vertex_C = (X+1)*Weight+(Y+1);
			DWORD Vertex_D = X    *Weight+(Y+1);

			DWORD Faces_A1 = (PloyIndex*2)*3;
			DWORD Faces_B1 = Faces_A1 + 1;
			DWORD Faces_C1 = Faces_B1 + 1;

			pIndex[Faces_A1] = Vertex_A;
			pIndex[Faces_B1] = Vertex_B;
			pIndex[Faces_C1] = Vertex_D;
			pAttrib[PloyIndex*2] = PolyMaterialID;
			pDIndex[Faces_A1] = Vertex_A;
			pDIndex[Faces_B1] = Vertex_B;
			pDIndex[Faces_C1] = Vertex_D;
			pDAttrib[PloyIndex*2] = PolyMaterialID;

			pwIndices[Faces_A1] = WORD(Vertex_A);
			pwIndices[Faces_B1] = WORD(Vertex_B);
			pwIndices[Faces_C1] = WORD(Vertex_D);

			DWORD Faces_A2 = (PloyIndex*2+1)*3;
			DWORD Faces_B2 = Faces_A2 + 1;
			DWORD Faces_C2 = Faces_B2 + 1;

			pIndex[Faces_A2] = Vertex_D;
			pIndex[Faces_B2] = Vertex_B;
			pIndex[Faces_C2] = Vertex_C;
			pAttrib[PloyIndex*2+1] = PolyMaterialID;
			pDIndex[Faces_A2] = Vertex_D;
			pDIndex[Faces_B2] = Vertex_B;
			pDIndex[Faces_C2] = Vertex_C;
			pDAttrib[PloyIndex*2+1] = PolyMaterialID;

			pwIndices[Faces_A2] = WORD(Vertex_D);
			pwIndices[Faces_B2] = WORD(Vertex_B);
			pwIndices[Faces_C2] = WORD(Vertex_C);

		}
	}	

	D3DXComputeBoundingBox((D3DXVECTOR3*)pVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1),
		&m_BBox_A,&m_BBox_B);
	D3DXComputeBoundingBox((D3DXVECTOR3*)pDVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1),
		&m_BBox_A,&m_BBox_B);

	if (FAILED(pMesh->UnlockVertexBuffer()))
		return E_FAIL;
	if (FAILED(pMesh->UnlockIndexBuffer()))
		return E_FAIL;
	if (FAILED(pMesh->UnlockAttributeBuffer()))
		return E_FAIL;

	if (FAILED(pDMesh->UnlockVertexBuffer()))
		return E_FAIL;
	if (FAILED(pDMesh->UnlockIndexBuffer()))
		return E_FAIL;
	if (FAILED(pDMesh->UnlockAttributeBuffer()))
		return E_FAIL;
	if (FAILED(m_pibIndices->Unlock()))
		return E_FAIL;
	m_pWaterUp = pMesh;		
	m_pWaterDn = pDMesh;	


	//水面网格的材质
	m_dNumMaterial = 1;
	m_lpMaterial = new MATERIAL[m_dNumMaterial];
	ZeroMemory(m_lpMaterial,sizeof(MATERIAL)*m_dNumMaterial);

	DWORD Def_Option = MATERIAL_OPTION_ZBUFFER_TRUE|
		MATERIAL_OPTION_FILL_SOLID|
		MATERIAL_OPTION_SHADE_GOURAUD|
		MATERIAL_OPTION_CULL_NONE|
		MATERIAL_OPTION_SPECULARENABLE;

	for(DWORD i=0;i<m_dNumMaterial;i++)
	{
		m_lpMaterial[i].m_sMaterial9.Diffuse.r = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.g = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.b = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.a = 1.0f ;
		m_lpMaterial[i].m_sMaterial9.Ambient = m_lpMaterial[i].m_sMaterial9.Diffuse;
		m_lpMaterial[i].m_sMaterial9.Specular = m_lpMaterial[i].m_sMaterial9.Diffuse;
		m_lpMaterial[i].m_sMaterial9.Power = 15;
		m_lpMaterial[i].m_dOption = Def_Option;
	} 

	TCHAR Name[256];
	wsprintf(Name,"%s\\Water.Mtl",g_Def_ModelDirectory);
	LoadMaterial(Name);  


	//天空盒的纹理
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\LobbyCube.dds");
	if( FAILED( hr = D3DXCreateCubeTextureFromFile( g_pd3dDevice,Name, &m_pSkyCubeTex ) ) )
		return hr; 
	//水面的纹理
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\Water.bmp");
	if( FAILED( hr = D3DXCreateTextureFromFileEx(g_pd3dDevice, Name, D3DX_DEFAULT, D3DX_DEFAULT, 
		D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, 
		D3DX_DEFAULT, 0, NULL, NULL, &m_pWaterTex) ))
		return hr;
	/*
	// Effect
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"water.fx");
	if(FAILED(hr = D3DXCreateEffectFromFile(g_pd3dDevice, Name, NULL, NULL, 0, NULL, &m_pEffect, NULL)))
	return hr;
	m_pEffect->OnResetDevice();
	m_pEffect->SetTexture("tFLR", m_pWaterTex);
	m_pEffect->SetTexture("tENV", m_pSkyCubeTex);
	*/

	//创建水面bump纹理
	if( FAILED( InitBumpMap() ) )
		return E_FAIL;
	//	m_pEffect->SetTexture("tBump", m_pBumpMapTexture);
	WSea.Initialize(m_dwNumPoly_X,m_dwNumPoly_Z);
	Water.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z);   //初始化水纹
	Water.Drop();                                               //产生水纹  
	Ripple.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z);  //初始化涟漪纹


	return S_OK;

}
Esempio n. 5
0
	void CreateBox( const float &w, const float &h, const float &d, const bool &centerWidth, const bool &centerHeight, const bool &centerDepth, LPD3DXMESH &mesh )
	{
		float offsetX = 0, offsetY = 0, offsetZ = 0;
		if( centerWidth )
			offsetX = -w / 2.f;
		if( centerHeight )
			offsetY = -h / 2.f;
		if( centerDepth )
			offsetZ = -d / 2.f;

		std::vector<DWORD> vIB;
		std::vector<VERTEX3> vVB;
		std::vector<DWORD> vAB;
		DWORD offset = 0;

		// fill in the front face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the front face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 1.f ) );

		vAB.push_back( 0 );
		vAB.push_back( 0 );

		offset += 4;

		// fill in the back face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the back face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 0.f ) );

		vAB.push_back( 1 );
		vAB.push_back( 1 );

		offset += 4;

		// fill in the top face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		//fill in the top face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 2 );
		vAB.push_back( 2 );

		offset += 4;

		// fill in the bottom face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the bottom face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 3 );
		vAB.push_back( 3 );

		offset += 4;

		// fill in the left face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the left face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 4 );
		vAB.push_back( 4 );

		offset += 4;

		// fill in the right face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the right face vertex data
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 5 );
		vAB.push_back( 5 );

		offset += 4;

		D3DXCreateMeshFVF( offset / 2, offset, D3DXMESH_MANAGED | D3DXMESH_32BIT, VERTEX3::FVF, g_pEngine->core->lpd3dd9, &mesh );

		VERTEX3 *pVB = nullptr;
		mesh->LockVertexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pVB ) );
		copy( vVB.begin(), vVB.end(), pVB );
		mesh->UnlockVertexBuffer();

		DWORD *pIB = nullptr;
		mesh->LockIndexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pIB ) );
		copy( vIB.begin(), vIB.end(), pIB );
		mesh->UnlockIndexBuffer();

		DWORD *pAB = nullptr;
		mesh->LockAttributeBuffer( D3DLOCK_DISCARD, &pAB );
		copy( vAB.begin(), vAB.end(), pAB );
		mesh->UnlockAttributeBuffer();

		std::vector<DWORD> adjacencyBuffer( mesh->GetNumFaces() * 3 );
		mesh->GenerateAdjacency( 0.f, &adjacencyBuffer[ 0 ] );
		mesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, &adjacencyBuffer[ 0 ], nullptr, nullptr, nullptr );
	}