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; }
HRESULT D3DXMeshCreateAttributeEnumer(LPD3DXMESH pMesh, D3DXMeshAttributeEnumer& enumer ) { _ASSERTE(! enumer.IsValid()); ZeroMemory(&enumer, sizeof(D3DXMeshAttributeEnumer)); //因为外部传入的enumer是可能重用的,这里绝对要重新清空一次 _ASSERTE(NULL != pMesh); KG_PROCESS_ERROR(NULL != pMesh); { HRESULT hr = pMesh->LockAttributeBuffer(0, reinterpret_cast<DWORD**>(&enumer.m_pBuffer)); KG_COM_PROCESS_ERROR(hr); _ASSERTE(1 == sizeof(BYTE) && 2 == sizeof(WORD) && 4 == sizeof(DWORD)); enumer.m_pMesh = pMesh; enumer.m_pMesh->AddRef(); enumer.m_dwNumFaceCount = pMesh->GetNumFaces(); return S_OK; } Exit0: return E_FAIL; }
//------------------------------------------------------ // 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; }
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; }
void CreateBox( const float &w, const float &h, const float &d, const bool ¢erWidth, const bool ¢erHeight, const bool ¢erDepth, 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 ); }