// // Loads mesh after device loss void DirectX::Mesh::onDeviceReset( ) { if( m_meshInfo ) { char* infoIter = (char*)m_meshInfo; unsigned long fvf = *(unsigned long*)infoIter; infoIter += sizeof(long); unsigned long stride = *(unsigned long*)infoIter; infoIter += sizeof(long); unsigned long options = *(unsigned long*)infoIter; infoIter += sizeof(long); unsigned int nVertices = *(unsigned int*)infoIter; infoIter += sizeof(int); unsigned int nIndices = *(unsigned int*)infoIter; infoIter += sizeof(int); unsigned int vbSize = *(unsigned int*)infoIter; infoIter += sizeof(int); unsigned int ibSize = *(unsigned int*)infoIter; infoIter += sizeof(int); // Create the mesh HRESULT hr = D3DXCreateMeshFVF( nIndices*3, nVertices, options, fvf, DirectX::Manager::instance( )->getD3DDev( ), &m_mesh ); if( hr ) MessageBox( NULL, L"Call to D3DXCreateMeshFVF has failed.", L"DirectX Engine", NULL ); void *vb, *ib; m_mesh->LockVertexBuffer( D3DLOCK_READONLY, &vb ); m_mesh->LockIndexBuffer( D3DLOCK_READONLY, &ib ); memcpy( vb, infoIter, vbSize ); infoIter += vbSize; memcpy( ib, infoIter, ibSize ); infoIter += ibSize; free(m_meshInfo); } }
// // Creates a DirectX mesh void DirectX::Mesh::create( unsigned int nFaces, unsigned int nVertices, unsigned long fvf, unsigned long options ) { // Create the mesh HRESULT hr = D3DXCreateMeshFVF( nFaces, nVertices, options, fvf, DirectX::Manager::instance( )->getD3DDev( ), &m_mesh ); if( hr ) MessageBox( NULL, L"Call to D3DXCreateMeshFVF has failed.", L"DirectX Engine", NULL ); // Register with the manager if( !(options&D3DXMESH_SYSTEMMEM) ) DirectX::Manager::instance( )->addResource( this ); }
void D3D9Mesh::Allocate(UINT VertexCount, UINT FaceCount) { FreeMemory(); if(VertexCount == 0 || FaceCount == 0) { return; } D3DXCreateMeshFVF(FaceCount, VertexCount, D3DMeshOptions, D3DMeshFVF, GetD3DDevice(), &_Mesh); //tell DirectX to allocate space for the _Mesh Lock(); //toggle the buffer locking just to clear things up Unlock(); //we want the buffers unlocked whenever possible }
//------------------------------------------------------ // 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; }
// 板ポリメッシュ作成関数 HRESULT D3DXPlus::CreateBoard(IDirect3DDevice* pDevice, float width, float height, LPD3DXMESH* ppMesh) { struct D3DVERTEX { D3DXVECTOR3 v; // 頂点 D3DXVECTOR3 n; // 法線 float tu, tv; // テクスチャUV enum { FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 }; }; HRESULT hr = D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, D3DVERTEX::FVF, pDevice, ppMesh); if (FAILED(hr)) { return hr; } D3DVERTEX* pVertex; WORD* pIndex; (*ppMesh)->LockVertexBuffer(D3DLOCK_DISCARD, (void**)&pVertex); (*ppMesh)->LockIndexBuffer(D3DLOCK_DISCARD, (void**)&pIndex); float hlen = width / 2.0f; float vlen = height/ 2.0f; pVertex[0].v = D3DXVECTOR3(-hlen, 0.0f, -vlen); pVertex[1].v = D3DXVECTOR3(-hlen, 0.0f, vlen); pVertex[2].v = D3DXVECTOR3( hlen, 0.0f, vlen); pVertex[3].v = D3DXVECTOR3( hlen, 0.0f, -vlen); pVertex[0].n = D3DXVECTOR3(0.0f, 1.0f, 0.0f); pVertex[1].n = D3DXVECTOR3(0.0f, 1.0f, 0.0f); pVertex[2].n = D3DXVECTOR3(0.0f, 1.0f, 0.0f); pVertex[3].n = D3DXVECTOR3(0.0f, 1.0f, 0.0f); pVertex[0].tu = 0.0f; pVertex[0].tv = 0.0f; pVertex[1].tu = 0.0f; pVertex[1].tv = 1.0f; pVertex[2].tu = 1.0f; pVertex[2].tv = 1.0f; pVertex[3].tu = 1.0f; pVertex[3].tv = 0.0f; pIndex[0] = 0; pIndex[1] = 1; pIndex[2] = 2; pIndex[3] = 2; pIndex[4] = 3; pIndex[5] = 0; (*ppMesh)->UnlockIndexBuffer(); (*ppMesh)->UnlockVertexBuffer(); return hr; }
PrimMesh::PrimMesh(IDirect3DDevice9 *device, LLVolumeFace *volumeFace) { int numVertices = volumeFace->mVertices.size(); int numIndices = volumeFace->mIndices.size(); HRESULT hr = D3DXCreateMeshFVF( numIndices/3, //NumFaces,三角形个数 numVertices, //NumVertices D3DXMESH_MANAGED, //Options FVF_VERTEX, //FVF device, &primMesh); //产出的mesh结果 //向空mesh填充点坐标 Vertex* v = 0; primMesh->LockVertexBuffer(0, (void**)&v); for(int j = 0; j<numVertices; j++) { float p0 = volumeFace->mVertices[j].mPosition.mV[0]; float p1 = volumeFace->mVertices[j].mPosition.mV[1]; float p2 = volumeFace->mVertices[j].mPosition.mV[2]; float n0 = volumeFace->mVertices[j].mNormal.mV[0]; float n1 = volumeFace->mVertices[j].mNormal.mV[1]; float n2 = volumeFace->mVertices[j].mNormal.mV[2]; float u1 = volumeFace->mVertices[j].mTexCoord.mV[0]; float u2 = volumeFace->mVertices[j].mTexCoord.mV[1]; v[j] = Vertex(p0, p1, p2, n0, n1, n2, u1, u2); } primMesh->UnlockVertexBuffer(); //填充index WORD* i = 0; primMesh->LockIndexBuffer(0, (void**)&i); for(U32 j=0; j<numIndices; j++) { i[j] = volumeFace->mIndices[j]; } primMesh->UnlockIndexBuffer(); //指明哪些三角形属于哪个Subset,为贴纹理作准备,这里将所有三角形都归一个类了 DWORD* attributeBuffer = 0; primMesh->LockAttributeBuffer(0, &attributeBuffer); for(int j=0; j<numIndices/3; j++) { attributeBuffer[j] = 0; } primMesh->UnlockAttributeBuffer(); }
void LoadEffectResources(IDirect3DDevice9 *m_pDevice) { //Calculate sight mesh (a simple quad) D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, SimpleVertex::FVF, m_pDevice, &billboardMesh); //Create 4 vertices SimpleVertex* v = 0; billboardMesh->LockVertexBuffer(0,(void**)&v); v[0] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 0)); v[1] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 0)); v[2] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 1)); v[3] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 1)); billboardMesh->UnlockVertexBuffer(); //Create 2 faces WORD* indices = 0; billboardMesh->LockIndexBuffer(0,(void**)&indices); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 1; indices[4] = 3; indices[5] = 2; billboardMesh->UnlockIndexBuffer(); //Set Attributes for the 2 faces DWORD *att = 0; billboardMesh->LockAttributeBuffer(0,&att); att[0] = 0; att[1] = 0; billboardMesh->UnlockAttributeBuffer(); //Sight MTRL memset(&whiteMtrl, 0, sizeof(D3DMATERIAL9)); whiteMtrl.Diffuse = whiteMtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); //Load Shaders effectVertexShader.Init(m_pDevice, "shaders/effect.vs", VERTEX_SHADER); effectPixelShader.Init(m_pDevice, "shaders/effect.ps", PIXEL_SHADER); //Get constants effectMatW = effectVertexShader.GetConstant("matW"); effectMatVP = effectVertexShader.GetConstant("matVP"); effectVCol = effectVertexShader.GetConstant("vertexColor"); //Create Sprite D3DXCreateSprite(m_pDevice, &sprite); //Load textures D3DXCreateTextureFromFile(m_pDevice, "textures/runes.dds", &runesTexture); D3DXCreateTextureFromFile(m_pDevice, "textures/cloud.dds", &cloudTexture); D3DXCreateTextureFromFile(m_pDevice, "textures/fireball.dds", &fireballTexture); D3DXCreateTextureFromFile(m_pDevice, "textures/lensflare.dds", &lensflareTexture); }
/*-----------------------------------------------------------------------------------------* | <<< メッシュ作成 >>> *-----------------------------------------------------------------------------------------*/ static void CreateMeshFromMetaseq(void) { if(meta->iPolyCount == 0){ return;} // Xファイルから読み込む場合は // 立方体の場合 インデックスは 40 個 // 頂点情報 24 個 となっていた。 D3DXCreateMeshFVF(meta->iPolyCount, // 表面数 数は適当 meta->uiVtxCount, // 頂点数 数は適当 D3DXMESH_MANAGED, // メッシュのオプション D3_FVF_DEFAULT, // 頂点フォーマット d3.dev, // デバイス &meta->lpMesh); // 作成されたメッシュ //--- 頂点情報を書き込む ---------------------------------------- D3_VTX_DEFAULT *pvtxBuf; // 頂点バッファ WORD *pwIndex; // インデックスバッファ DWORD *pdwMaterial; // マテリアルバッファ meta->lpMesh->LockVertexBuffer( D3DLOCK_DISCARD, (void **)&pvtxBuf); meta->lpMesh->LockIndexBuffer( D3DLOCK_DISCARD, (void **)&pwIndex); meta->lpMesh->LockAttributeBuffer(D3DLOCK_DISCARD, &pdwMaterial); // 頂点バッファ転送 for(uint i = 0; i < meta->uiVtxCount; i++) { pvtxBuf[i].p = meta->avtx[i].p; pvtxBuf[i].n = meta->avtx[i].n; pvtxBuf[i].uv = meta->avtx[i].uv; } // インデックスバッファ転送 for(int i = 0; i < meta->iPolyCount * 3; i++) { pwIndex[i] = meta->auiIndex[i]; } // マテリアルバッファ転送 for(int i = 0; i < meta->iPolyCount; i++) { pdwMaterial[i] = meta->aucMat[i]; } //--- 頂点バッファ閉じる ---------------------------------------- meta->lpMesh->UnlockAttributeBuffer(); meta->lpMesh->UnlockIndexBuffer(); meta->lpMesh->UnlockVertexBuffer(); }
void cAllignedQuad::Init() { #pragma region CreateRenderToSurface D3DXCreateTexture( g_pEngine->core->lpd3dd9, 1920, 1080, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pDynamicTexture_1 ); m_pDynamicTexture_1->GetSurfaceLevel( 0, &m_pTextureSurface_1 ); D3DXCreateTexture( g_pEngine->core->lpd3dd9, 1920, 1080, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pDynamicTexture_2 ); m_pDynamicTexture_2->GetSurfaceLevel( 0, &m_pTextureSurface_2 ); D3DXCreateRenderToSurface( g_pEngine->core->lpd3dd9, 1920, 1080, D3DFMT_A8R8G8B8, TRUE, D3DFMT_D16, &m_pRenderToSurface ); #pragma endregion #pragma region CreateAllignedQuad VERTEX3 VertexAllignedQuad[] = { VERTEX3( -1, 1, 0, 1, 0, 0, 0, 0 ), VERTEX3( 1, 1, 0, 1, 0, 0, 1, 0 ), VERTEX3( 1, -1, 0, 1, 0, 0, 1, 1 ), VERTEX3( -1, -1, 0, 1, 0, 0, 0, 1 ) }; short IndexAllignedQuad[] = { 0, 1, 2, 2, 3, 0 }; D3DXCreateMeshFVF( 2, 6, D3DXMESH_MANAGED, VERTEX3::FVF, g_pEngine->core->lpd3dd9, &m_meshAllignedQuad ); VERTEX3 *pVD; m_meshAllignedQuad->LockVertexBuffer( NULL, reinterpret_cast< void** >( &pVD ) ); memcpy( pVD, VertexAllignedQuad, sizeof( VertexAllignedQuad ) ); m_meshAllignedQuad->UnlockVertexBuffer(); short *pID; m_meshAllignedQuad->LockIndexBuffer( NULL, reinterpret_cast< void** >( &pID ) ); memcpy( pID, IndexAllignedQuad, sizeof( IndexAllignedQuad ) ); m_meshAllignedQuad->UnlockIndexBuffer(); DWORD *pAB; m_meshAllignedQuad->LockAttributeBuffer( NULL, static_cast< DWORD** >( &pAB ) ); memset( pAB, 0, 2 ); m_meshAllignedQuad->UnlockAttributeBuffer(); #pragma endregion m_allignedQuadEffect = new AllignedQuadEffect(); m_allignedQuadEffect->Init(); }
bool XFileUtils::LoadMesh( ID3DXFileData* pFileData, IDirect3DDevice9* pDevice, ID3DXMesh** pNewMesh, ID3DXBuffer** pMaterial, DWORD* pNumAttribute, GSkinInfo** pNewSkininfo) { //检查类型 _XCheckType(pFileData, "Mesh", false); DWORD nVertices = 0; DWORD nFaces = 0; _XCheckExcute(ParseBasemesh(pFileData, &nVertices, &nFaces, nullptr, nullptr, sizeof(XVertex_p3_n3_t1))); ID3DXMesh* pMesh = nullptr; if (FAILED(D3DXCreateMeshFVF(nFaces, nVertices, D3DXMESH_32BIT | D3DXMESH_MANAGED, XVertex_p3_n3_t1::fvf, pDevice, &pMesh))) return false; void* pVertices = nullptr; DWORD* pIndices = nullptr; DWORD* pAttribtues = nullptr; pMesh->LockVertexBuffer(0, &pVertices); pMesh->LockIndexBuffer(0, (void**)&pIndices); pMesh->LockAttributeBuffer(0, &pAttribtues); _XCheckExcute(ParseBasemesh(pFileData, &nVertices, &nFaces, pVertices, pIndices, sizeof(XVertex_p3_n3_t1))); _XCheckExcute(ParseNormals(pFileData, nVertices, pVertices, pIndices, sizeof(XVertex_p3_n3_t1), sizeof(D3DXVECTOR3))); _XCheckExcute(ParseTexcoord(pFileData, pVertices, sizeof(XVertex_p3_n3_t1), sizeof(D3DXVECTOR3) * 2)); _XCheckExcute(ParseMaterial(pFileData, pAttribtues, nFaces, pNumAttribute, pMaterial)); pMesh->UnlockAttributeBuffer(); pMesh->UnlockIndexBuffer(); pMesh->UnlockVertexBuffer(); *pNewMesh = pMesh; ParseSkinInfo(pFileData, pNewSkininfo); return true; }
// // Creates a DirectX mesh void DirectX::Mesh::create( void* vertexBuffer, void* indexBuffer, unsigned long FVF, unsigned int nVertices, unsigned int nFaces, unsigned long options ) { // Calculate vertex stride int vertexStride = ((FVF|D3DFVF_XYZ) == FVF) * 12 + ((FVF|D3DFVF_XYZRHW) == FVF) * 12 + ((FVF|D3DFVF_XYZB1) == FVF) * 12 + ((FVF|D3DFVF_XYZB2) == FVF) * 12 + ((FVF|D3DFVF_XYZB3) == FVF) * 12 + ((FVF|D3DFVF_XYZB4) == FVF) * 12 + ((FVF|D3DFVF_XYZB5) == FVF) * 12 + ((FVF|D3DFVF_XYZW) == FVF) * 12 + ((FVF|D3DFVF_NORMAL) == FVF) * 12 + ((FVF|D3DFVF_DIFFUSE) == FVF) * 4 + ((FVF|D3DFVF_SPECULAR) == FVF) * 4 + ((FVF|D3DFVF_TEX1) == FVF) * 8 + ((FVF|D3DFVF_TEX2) == FVF) * 8 + ((FVF|D3DFVF_TEX3) == FVF) * 8 + ((FVF|D3DFVF_TEX4) == FVF) * 8 + ((FVF|D3DFVF_TEX5) == FVF) * 8 + ((FVF|D3DFVF_TEX6) == FVF) * 8 + ((FVF|D3DFVF_TEX7) == FVF) * 8 + ((FVF|D3DFVF_TEX8) == FVF) * 8; // Create mesh of sufficient size to store vertex/index buffer data HRESULT hr = D3DXCreateMeshFVF( nFaces, nVertices, options, FVF, DirectX::Manager::instance( )->getD3DDev( ), &m_mesh ); if( hr ) MessageBox( NULL, L"Call to D3DXCreateMeshFVF has failed.", L"DirectX Engine", NULL ); LPDIRECT3DVERTEXBUFFER9 vb; LPDIRECT3DINDEXBUFFER9 ib; m_mesh->GetVertexBuffer( &vb ); m_mesh->GetIndexBuffer( &ib ); // Lock the ibuffer and load the indices char* pVertices; vb->Lock( NULL, NULL, (void**)&pVertices, D3DLOCK_DISCARD ); memcpy( pVertices, vertexBuffer, nVertices*vertexStride ); vb->Unlock( ); // Lock the vbuffer and load the vertices char* pIndices; ib->Lock( NULL, NULL, (void**)&pIndices, D3DLOCK_DISCARD ); memcpy( pIndices, indexBuffer, nFaces*3*sizeof(short) ); ib->Unlock( ); // Register with the manager if( !(options&D3DXMESH_SYSTEMMEM) ) DirectX::Manager::instance( )->addResource( this ); }
HRESULT AiPathReader::CreateMesh(LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH &pMesh) { //Todo: ID3DXMesh::SetAttributeTable (set materials how they are defined in the face struct) DWORD dwFVF = (D3DFVF_XYZ | D3DFVF_NORMAL); struct D3DVERTEX { D3DXVECTOR3 p; D3DXVECTOR3 n; }; HRESULT r = D3DXCreateMeshFVF(3 * nodes.size(), 3 * nodes.size(), D3DXMESH_MANAGED, dwFVF, pD3DDevice, &pMesh); if(FAILED(r)) { return r; } D3DVERTEX *vertexBuffer; WORD *indexBuffer = nullptr; unsigned long *pAdjacency = new unsigned long[nodes.size() * 3]; pMesh->LockIndexBuffer(0, reinterpret_cast<void **>(&indexBuffer)); pMesh->LockVertexBuffer(0, reinterpret_cast<void **>(&vertexBuffer)); for(int i = 0; i < nodes.size(); i++) { auto face = nodes[i]; for(int j = 0; j < 3; j++) { D3DVERTEX &vert = vertexBuffer[3 * i + j]; vert.p.x = face.triangle[j].x; vert.p.y = face.triangle[j].y; vert.p.z = face.triangle[j].z; indexBuffer[3 * i + j] = 3 * i + j; pAdjacency[3 * i + j] = (face.adjacency[j] == 0xffff) ? 0xffffffffUL : face.adjacency[j]; } } //D3DXWeldVertices(pMesh, D3DXWELDEPSILONS_WELDALL, nullptr, pAdjacency, nullptr, nullptr, nullptr); //pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_IGNOREVERTS | D3DXMESHOPT_STRIPREORDER, newAdjacency, pAdjacency, nullptr, nullptr); delete[] pAdjacency; HRESULT hr = D3DXComputeNormals(pMesh, nullptr); D3DXMATERIAL *m_pMaterials = nullptr; DWORD m_dwNumMaterials = 0; hr = D3DXSaveMeshToX("NavMesh.x", pMesh, nullptr, m_pMaterials, nullptr, m_dwNumMaterials, D3DXF_FILEFORMAT_BINARY); pMesh->UnlockVertexBuffer(); pMesh->UnlockIndexBuffer(); return S_OK; }
//------------------------------------------------- // Name: Create // Desc: //------------------------------------------------- HRESULT cprimitive::Create(int iID, LPDIRECT3DDEVICE9 pd3dDevice, float length, D3DXVECTOR2 angle, float width, D3DXVECTOR2 restrAngX, D3DXVECTOR2 restrAngY, D3DXVECTOR3 ivOffset, float displace, float direction, float coefficient, float mass, BOOL ibTilt, BOOL ibPressure, BOOL ibLaser ) { HRESULT hr; int i; //store id = iID; vAngle = angle; rAngle = angle; fLength = length; fWidth = width; restrictAngleX = restrAngX; restrictAngleY = restrAngY; fDisplace = displace; fDirection = direction; fCoefficient = coefficient; vOffset = ivOffset; fMass = mass; bTilt = ibTilt; bPressure = ibPressure; bLaser = ibLaser; // VERTEX BUFFER // Initialize three vertices for rendering a triangle CUSTOMVERTEX vertices[] = { { -width, 0.0f, -width, 0.f, 0.f,}, { width, 0.0f, -width, 1.f, 0.f,}, { width, length, -width, 1.f, 1.f,}, { -width, length, -width, 0.f, 1.f, }, { -width, 0.0f, width, 0.f, 0.f,}, { width, 0.0f, width, 1.f, 0.f,}, { width, length, width, 1.f, 1.f,}, { -width, length, width, 0.f, 1.f,}, }; WORD indices[] = { 0,3,2, 0,2,1, 4,7,6, 4,6,5, 3,7,4, 3,4,0, 2,6,5, 2,5,1, 0,4,5, 0,5,1, 3,6,7, 3,2,6 }; m_numVertices = sizeof(vertices)/sizeof(CUSTOMVERTEX); m_numIndices = sizeof(indices)/sizeof(WORD); // CREATE MESH hr = D3DXCreateMeshFVF( m_numIndices / 3, m_numVertices, D3DXMESH_MANAGED, D3DFVF_CUSTOMVERTEX, pd3dDevice, &pMesh ); if(FAILED(hr)) return NULL; // Create the vertex buffer CUSTOMVERTEX* pVertices; pMesh->LockVertexBuffer(D3DLOCK_DISCARD, (void**)&pVertices); memcpy( pVertices, vertices, sizeof(vertices) ); pMesh->UnlockVertexBuffer(); // INDEX BUFFER WORD* pBI; pMesh->LockIndexBuffer(D3DLOCK_DISCARD,(void**)&pBI); memcpy( pBI, indices, m_numIndices*sizeof(WORD) ); for(i=0;i<m_numIndices;i++) { HTMLLog("index %d ", (int)pBI[i]); } pMesh->UnlockIndexBuffer(); // TEXTURE if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, L"./data/tex000.jpg", &tex ) ) ) return E_FAIL; 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 ); }
HRESULT D3DXMeshCreateDiamond( LPDIRECT3DDEVICE9 pDevice, DWORD dwFVF, DWORD dwOption, UINT uSlice , FLOAT fRadius, FLOAT fUpperConeHeight, FLOAT fLowerConeHeight, LPD3DXMESH* pRet ) { //创建上下各一棱锥的钻石型 _ASSERTE(fRadius > 0 && fUpperConeHeight >= 0 && fLowerConeHeight >= 0 && uSlice >= 3); HRESULT hr = E_FAIL; LPD3DXMESH pMesh = NULL; KG_PROCESS_ERROR(NULL != pRet); KG_PROCESS_ERROR(fRadius > 0 && fUpperConeHeight >= 0 && fLowerConeHeight >= 0 && uSlice >= 3); { UINT uNumVertices = uSlice + 2; //2是上下两个点 UINT uNumFaces = uSlice * 2; _ASSERTE(IsMeshValidToBeCreated(dwOption, uNumVertices, uNumFaces * 3)); hr = D3DXCreateMeshFVF(uNumFaces, uNumVertices, dwOption, dwFVF, pDevice, &pMesh); KG_COM_CHECK_ERROR(hr); //点的分布是先填圆周的一圈,然后填上下两个点 { D3DXMeshVertexEnumer vertexEnumer; hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(vertexEnumer.IsValid() && vertexEnumer.GetVertexCount() == uNumVertices); float fAnglePerVertex = 2 * D3DX_PI /static_cast<FLOAT>(uSlice); float fAngleRotate = D3DX_PI / 4.f; //把所有顶点旋转45度,这样子好些 //注意Angle是不可能超过cos和sin的值域的,不用检查了 for (UINT i = 0; i < vertexEnumer.GetVertexCount() - 2; ++i) { FLOAT fAngle = fAnglePerVertex * i; D3DXVECTOR3 vTemp; vTemp.x = fRadius * cosf(fAngle + fAngleRotate); //单位圆锥,最后再放缩,所以这里用1 vTemp.y = 0; vTemp.z = fRadius * sinf(fAngle + fAngleRotate); vertexEnumer.SetPos(i, vTemp); } _ASSERTE(vertexEnumer.GetVertexCount() > 2); //填上上下两个点 UINT uTopPoint = vertexEnumer.GetVertexCount() - 2; vertexEnumer.SetPos(uTopPoint, D3DXVECTOR3(0, fUpperConeHeight, 0)); UINT uBottomPoint = vertexEnumer.GetVertexCount() - 1; vertexEnumer.SetPos(uBottomPoint, D3DXVECTOR3(0, -fLowerConeHeight, 0)); } { D3DXMeshIndexEnumer indexEnumer; hr = D3DXMeshCreateIndexEnumer(pMesh, indexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(indexEnumer.IsValid()&& indexEnumer.GetIndexCount() == 2 * uSlice * 3); UINT uVertexCountInCircle = pMesh->GetNumVertices() - 2; { UINT uUpperFaceCount = uVertexCountInCircle; DWORD uTopPointIndex = pMesh->GetNumVertices() - 2; for (UINT uIt = 0, uIndexIndex = 0; uIt < uUpperFaceCount; ++uIt, uIndexIndex += 3) { indexEnumer.SetIndex(uIndexIndex, uIt); indexEnumer.SetIndex(uIndexIndex + 1, uTopPointIndex); indexEnumer.SetIndex(uIndexIndex + 2, (uIt + 1) % uVertexCountInCircle); } } { UINT uBottomFaceCount = uVertexCountInCircle; UINT uUpperFaceCount = uVertexCountInCircle; DWORD uBottomPointIndex = pMesh->GetNumVertices() - 1; for (UINT uIt = 0, uIndexIndex = uUpperFaceCount * 3 ; uIt < uBottomFaceCount; ++uIt, uIndexIndex += 3) { indexEnumer.SetIndex(uIndexIndex, uIt); indexEnumer.SetIndex(uIndexIndex + 1, (uIt + 1) % uVertexCountInCircle); indexEnumer.SetIndex(uIndexIndex + 2, uBottomPointIndex); } } } hr = D3DXMeshZeroMeshAttributes(pMesh); } _ASSERTE(NULL != pRet); *pRet = pMesh; return S_OK; Exit0: SAFE_RELEASE(pMesh); return E_FAIL; }
HRESULT D3DXMeshCreatePlane( LPDIRECT3DDEVICE9 pDevice, DWORD dwFVF, DWORD dwOption, UINT uXSlice, UINT uZSlice , FLOAT fXLength, FLOAT fZLength, LPD3DXMESH* pRet ) { HRESULT hr = E_FAIL; LPD3DXMESH pMesh = NULL; KG_PROCESS_ERROR(D3DFVF_XYZ & dwFVF);//不是XYZ型的Mesh无法自动处理 KG_PROCESS_ERROR(NULL != pRet); KG_PROCESS_ERROR(uXSlice < 2048 && uZSlice < 2048 && _T("不能创建太大的Plane")); { DWORD dwVertexCountInXAxis = (uXSlice + 1); DWORD dwVertexCountInZAxis = (uZSlice + 1); DWORD dwVertexCount = dwVertexCountInXAxis * dwVertexCountInZAxis; DWORD dwNumFaces = uXSlice * uZSlice; _ASSERTE(IsMeshValidToBeCreated(dwOption, dwVertexCount, dwNumFaces * 3)); hr = D3DXCreateMeshFVF(dwNumFaces, dwVertexCount, dwOption, dwFVF, pDevice, &pMesh); KG_COM_PROCESS_ERROR(hr); _ASSERTE(sizeof(BYTE) == 1); ////填点,D3DXMeshVertexEnumer生命域 { D3DXMeshVertexEnumer vertexEnumer; hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer); KG_COM_PROCESS_ERROR(hr); FLOAT XSliceGap = fXLength / static_cast<FLOAT>(uXSlice); FLOAT ZSliceGap = fZLength / static_cast<FLOAT>(uZSlice); _ASSERTE(vertexEnumer.GetVertexCount() == dwVertexCount); for (UINT i = 0; i < dwVertexCountInXAxis; ++i) { for (UINT j = 0; j < dwVertexCountInZAxis; ++j) { FLOAT xPos = i * XSliceGap; FLOAT zPos = i * ZSliceGap; UINT uIndex = i * dwVertexCountInXAxis + j; vertexEnumer.SetPos(uIndex, D3DXVECTOR3(xPos, 0, zPos)); } } //把坐标填上 if (D3DFVF_TEX1 & dwFVF) //这个默认就是UV两个浮点的。如果用了D3DFVF_TEXCOORDn的话,位会变 { D3DXMeshVertexTexCoordEnumer texEnumer; hr = D3DXMeshCreateVertexTexCoordEnumer(vertexEnumer, texEnumer); FLOAT xUGap = 1.f / static_cast<FLOAT>(uXSlice); FLOAT zVGap = 1.f / static_cast<FLOAT>(uZSlice); if (SUCCEEDED(hr)) { _ASSERTE(2 == texEnumer.GetTexCoordSize()); for (UINT i = 0; i < dwVertexCountInXAxis; ++i) { for (UINT j = 0; j < dwVertexCountInZAxis; ++j) { UINT uIndex = i * dwVertexCountInXAxis + j; texEnumer.GetTexCoord2(uIndex) = D3DXVECTOR2(xUGap * i, zVGap * j); } } } } }////填点,D3DXMeshVertexEnumer生命域 //填Index { D3DXMeshIndexEnumer indexEnumer; hr = D3DXMeshCreateIndexEnumer(pMesh, indexEnumer); KG_COM_PROCESS_ERROR(hr); if (! indexEnumer.Is32Bit()) { KG_PROCESS_ERROR((pMesh->GetNumVertices() < SHRT_MAX) && _T("顶点数超过IndexBuffer的最大数")); } for (UINT i = 0; i < uXSlice; ++i) { for (UINT j = 0; j < uZSlice; ++j) { DWORD uLowerLeftVertexIndex = i * (uXSlice + 1) + j; DWORD uLowerRightVertexIndex = uLowerLeftVertexIndex + 1; DWORD uUpperLeftVertexIndex = uLowerLeftVertexIndex + (uXSlice + 1); DWORD uUpperRightVertexIndex = uUpperLeftVertexIndex + 1; UINT uRegionIndexBegin = (i * uXSlice + j) * 6; indexEnumer.SetIndex(uRegionIndexBegin, uLowerLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 1, uUpperLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 2, uLowerRightVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 3, uLowerLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 4, uUpperLeftVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 5, uUpperRightVertexIndex); indexEnumer.SetIndex(uRegionIndexBegin + 6, uLowerRightVertexIndex); } } } //填Attribute hr = D3DXMeshZeroMeshAttributes(pMesh); _ASSERTE(NULL != pRet); *pRet = pMesh; return S_OK; } Exit0: SAFE_RELEASE(pMesh); return NULL; return E_FAIL; }
HRESULT D3DXMeshCreateByVerticesPos( DWORD dwFVF, D3DVECTOR* pPosArray, DWORD dwVertexCount , DWORD* pIndexArray, DWORD dwNumIndexCount , LPDIRECT3DDEVICE9 pDevice, DWORD dwOption, LPD3DXMESH* pRet ) { HRESULT hr = E_FAIL; LPD3DXMESH pMesh = NULL; KG_PROCESS_ERROR((dwFVF & D3DFVF_XYZ)); KG_PROCESS_ERROR(NULL != pPosArray && NULL != pIndexArray && NULL != pDevice && NULL != pRet); _ASSERTE(IsMeshValidToBeCreated(dwOption, dwVertexCount, dwNumIndexCount)); { DWORD dwNumFaces = dwNumIndexCount / 3; hr = D3DXCreateMeshFVF(dwNumFaces, dwVertexCount, dwOption, dwFVF, pDevice, &pMesh); KG_COM_PROCESS_ERROR(hr); #if defined(DEBUG) | defined(_DEBUG) ULONG uRefSave = KGGetRef(pMesh); #endif { BOOL bValidity = pMesh->GetNumVertices() == dwVertexCount && pMesh->GetNumFaces() == dwNumFaces; KG_PROCESS_ERROR(bValidity); } _ASSERTE(sizeof(BYTE) == 1); { D3DXMeshVertexEnumer vertexEnumer; hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(vertexEnumer.IsValid() && vertexEnumer.GetVertexCount() == dwVertexCount); for (UINT i = 0; i < vertexEnumer.GetVertexCount(); ++i) { vertexEnumer.SetPos(i, pPosArray[i]); } } { D3DXMeshIndexEnumer indexEnumer; hr = D3DXMeshCreateIndexEnumer(pMesh, indexEnumer); KG_COM_PROCESS_ERROR(hr); _ASSERTE(indexEnumer.IsValid() && indexEnumer.GetIndexCount() <= dwNumIndexCount); for (UINT i = 0; i < indexEnumer.GetIndexCount(); ++i) { indexEnumer.SetIndex(i, pIndexArray[i]); } } D3DXMeshZeroMeshAttributes(pMesh); _ASSERTE(uRefSave == KGGetRef(pMesh)); } *pRet = pMesh; return S_OK; Exit0: SAFE_RELEASE(pMesh); return E_FAIL; }
Mesh* GenerateCylinder(IDirect3DDevice9* device, float radius, float height, UINT sectors) { if (!device) { return 0; } const DWORD numVertexes = 2 * (sectors + 1); const DWORD numFaces = 2 * sectors; ID3DXMesh* mesh = 0; HRESULT hr = D3DXCreateMeshFVF(numFaces, numVertexes, D3DXMESH_32BIT | D3DXMESH_VB_WRITEONLY | D3DXMESH_IB_WRITEONLY, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1, device, &mesh); if (FAILED(hr)) { MessageBox(0, L"Unable to generate sphere", L"Application error", MB_ICONSTOP); return 0; } SphereVertex* vertexes = 0; DWORD* indexes = 0; mesh->LockVertexBuffer(0, (void**)&vertexes); mesh->LockIndexBuffer(0, (void**)&indexes); const UINT rings = 1; // for (UINT ring = 0; ring < rings + 1; ring++) { for (UINT sector = 0; sector < sectors + 1; sector++) { const float z = sinf(sector * D3DX_PI * 2.f / sectors) * radius; const float x = cosf(sector * D3DX_PI * 2.f / sectors) * radius ; const float y = height * (1.0f - (ring / rings)); SphereVertex* vertex = vertexes++; vertex->pos = Vec3(x, y, z); vertex->normal = Vec3(x, 0, z); vertex->tex = Vec2((FLOAT)sector / (sectors - 1), (FLOAT)ring / rings ); } } // for (UINT ring = 0; ring < rings; ++ring) { for (UINT sector = 0; sector < sectors; ++sector) { DWORD v0 = (ring * (sectors + 1) + sector); DWORD v1 = (ring * (sectors + 1) + sector + 1); DWORD v2 = ((ring + 1) * (sectors + 1) + sector); DWORD v3 = ((ring + 1) * (sectors + 1) + sector + 1); *indexes++ = v0; *indexes++ = v1; *indexes++ = v2; *indexes++ = v2; *indexes++ = v1; *indexes++ = v3; } } mesh->UnlockIndexBuffer(); mesh->UnlockVertexBuffer(); return mesh; }
HRESULT PATCH::CreateMesh(HEIGHTMAP &hm, RECT source, IDirect3DDevice9* Dev, int index) { if(m_pMesh != NULL) { m_pMesh->Release(); m_pMesh = NULL; } try { m_pDevice = Dev; int width = source.right - source.left; int height = source.bottom - source.top; int nrVert = (width + 1) * (height + 1); int nrTri = width * height * 2; if(FAILED(D3DXCreateMeshFVF(nrTri, nrVert, D3DXMESH_MANAGED, TERRAINVertex::FVF, m_pDevice, &m_pMesh))) { debug.Print("Couldn't create mesh for PATCH"); return E_FAIL; } //Create vertices TERRAINVertex* ver = 0; m_pMesh->LockVertexBuffer(0,(void**)&ver); for(int z=source.top, z0 = 0;z<=source.bottom;z++, z0++) for(int x=source.left, x0 = 0;x<=source.right;x++, x0++) { //Calculate vertex color float prc = hm.m_pHeightMap[x + z * hm.m_size.x] / hm.m_maxHeight; int red = (int)(255 * prc); int green = (int)(255 * (1.0f - prc)); D3DCOLOR col; if(index % 2 == 0) //Invert color depending on what patch it is... col = D3DCOLOR_ARGB(255, red, green, 0); else col = D3DCOLOR_ARGB(255, green, red, 0); //Extract height (and position) from heightmap D3DXVECTOR3 pos = D3DXVECTOR3((float)x, hm.m_pHeightMap[x + z * hm.m_size.x], (float)-z); //Set new vertex ver[z0 * (width + 1) + x0] = TERRAINVertex(pos, col); } m_pMesh->UnlockVertexBuffer(); //Calculate Indices WORD* ind = 0; m_pMesh->LockIndexBuffer(0,(void**)&ind); int index = 0; for(int z=source.top, z0 = 0;z<source.bottom;z++, z0++) for(int x=source.left, x0 = 0;x<source.right;x++, x0++) { //Triangle 1 ind[index++] = z0 * (width + 1) + x0; ind[index++] = z0 * (width + 1) + x0 + 1; ind[index++] = (z0+1) * (width + 1) + x0; //Triangle 2 ind[index++] = (z0+1) * (width + 1) + x0; ind[index++] = z0 * (width + 1) + x0 + 1; ind[index++] = (z0+1) * (width + 1) + x0 + 1; } m_pMesh->UnlockIndexBuffer(); //Set Attributes DWORD *att = 0; m_pMesh->LockAttributeBuffer(0,&att); memset(att, 0, sizeof(DWORD)*nrTri); m_pMesh->UnlockAttributeBuffer(); //Compute normals D3DXComputeNormals(m_pMesh, NULL); } catch(...) { debug.Print("Error in PATCH::CreateMesh()"); return E_FAIL; } return S_OK; }
// // Framework functions // bool Setup() { HRESULT hr = 0; // // We are going to fill the empty mesh with the geometry of a box, // so we need 12 triangles and 24 vetices. // hr = D3DXCreateMeshFVF( 12, 24, D3DXMESH_MANAGED, Vertex::FVF, Device, &Mesh); if(FAILED(hr)) { ::MessageBox(0, "D3DXCreateMeshFVF() - FAILED", 0, 0); return false; } // // Fill in vertices of a box // Vertex* v = 0; Mesh->LockVertexBuffer(0, (void**)&v); // fill in the front face vertex data v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f); v[1] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f); v[2] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f); v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); // fill in the back face vertex data v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); v[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f); v[6] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); v[7] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); // fill in the top face vertex data v[8] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f); v[9] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f); v[10] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f); v[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); // fill in the bottom face vertex data v[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f); v[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f); v[14] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f); v[15] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); // fill in the left face vertex data v[16] = Vertex(-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[17] = Vertex(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[18] = Vertex(-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f); // fill in the right face vertex data v[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f); v[21] = Vertex( 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); v[22] = Vertex( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f); v[23] = Vertex( 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); Mesh->UnlockVertexBuffer(); // // Define the triangles of the box // WORD* i = 0; Mesh->LockIndexBuffer(0, (void**)&i); // fill in the front face index data i[0] = 0; i[1] = 1; i[2] = 2; i[3] = 0; i[4] = 2; i[5] = 3; // fill in the back face index data i[6] = 4; i[7] = 5; i[8] = 6; i[9] = 4; i[10] = 6; i[11] = 7; // fill in the top face index data i[12] = 8; i[13] = 9; i[14] = 10; i[15] = 8; i[16] = 10; i[17] = 11; // fill in the bottom face index data i[18] = 12; i[19] = 13; i[20] = 14; i[21] = 12; i[22] = 14; i[23] = 15; // fill in the left face index data i[24] = 16; i[25] = 17; i[26] = 18; i[27] = 16; i[28] = 18; i[29] = 19; // fill in the right face index data i[30] = 20; i[31] = 21; i[32] = 22; i[33] = 20; i[34] = 22; i[35] = 23; Mesh->UnlockIndexBuffer(); // // Specify the subset each triangle belongs to, in this example // we will use three subsets, the first two faces of the cube specified // will be in subset 0, the next two faces will be in subset 1 and // the the last two faces will be in subset 2. // DWORD* attributeBuffer = 0; Mesh->LockAttributeBuffer(0, &attributeBuffer); for(int a = 0; a < 4; a++) attributeBuffer[a] = 0; for(int b = 4; b < 8; b++) attributeBuffer[b] = 1; for(int c = 8; c < 12; c++) attributeBuffer[c] = 2; Mesh->UnlockAttributeBuffer(); // // Optimize the mesh to generate an attribute table. // std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3); Mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]); hr = Mesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, &adjacencyBuffer[0], 0, 0, 0); // // Dump the Mesh Data to file. // OutFile.open("Mesh Dump.txt"); dumpVertices(OutFile, Mesh); dumpIndices(OutFile, Mesh); dumpAttributeTable(OutFile, Mesh); dumpAttributeBuffer(OutFile, Mesh); dumpAdjacencyBuffer(OutFile, Mesh); OutFile.close(); // // Load the textures and set filters. // D3DXCreateTextureFromFile( Device, "brick0.jpg", &Textures[0]); D3DXCreateTextureFromFile( Device, "brick1.jpg", &Textures[1]); D3DXCreateTextureFromFile( Device, "checker.jpg", &Textures[2]); Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); // // Disable lighting. // Device->SetRenderState(D3DRS_LIGHTING, false); // // Set camera. // D3DXVECTOR3 pos(0.0f, 0.f, -4.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V; D3DXMatrixLookAtLH( &V, &pos, &target, &up); Device->SetTransform(D3DTS_VIEW, &V); // // Set projection matrix. // D3DXMATRIX proj; D3DXMatrixPerspectiveFovLH( &proj, D3DX_PI * 0.5f, // 90 - degree (float)Width / (float)Height, 1.0f, 1000.0f); Device->SetTransform(D3DTS_PROJECTION, &proj); return true; }
void GWater::recreateGraphInfo() { HRESULT hr = S_FALSE; SeaVertex *pVertextBuffer = NULL; //Mesh的顶点缓冲区 DWORD *pIndexBuffer = NULL; //Mesh的索引缓冲区 ID3DXMesh* mesh = 0; hr = D3DXCreateMeshFVF ( mCellCount * mCellCount * 2, ( mCellCount + 1 ) * ( mCellCount + 1 ), D3DXMESH_32BIT | D3DXMESH_MANAGED, FVFSea, Content::Device.getD9Device(), &mesh ); dDebugMsgBox ( hr, "创建海面Mesh失败!" ); DWORD dwIndex = 0; mesh->LockVertexBuffer ( D3DLOCK_DISCARD, ( void** ) &pVertextBuffer ); for ( int i = 0; i < mCellCount + 1; i++ ) { for ( int j = 0; j < mCellCount + 1; j++ ) { dwIndex = i * ( mCellCount + 1 ) + j; pVertextBuffer[dwIndex].vertex.x = ( j - mCellCount / 2.0f ) * mCellWidth; pVertextBuffer[dwIndex].vertex.y = 0; pVertextBuffer[dwIndex].vertex.z = ( i - mCellCount / 2.0f ) * mCellWidth; pVertextBuffer[dwIndex].u = j / 10.0f; pVertextBuffer[dwIndex].v = ( mCellCount - i ) / 10.0f; } } mesh->UnlockVertexBuffer(); mesh->LockIndexBuffer ( D3DLOCK_DISCARD, ( void** ) &pIndexBuffer ); DWORD dwBaseIndex = 0; for ( int i = 0; i < mCellCount; i++ ) { for ( int j = 0; j < mCellCount; j++ ) { pIndexBuffer[dwBaseIndex + 0] = i * ( mCellCount + 1 ) + j; pIndexBuffer[dwBaseIndex + 1] = ( i + 1 ) * ( mCellCount + 1 ) + j; pIndexBuffer[dwBaseIndex + 2] = ( i + 1 ) * ( mCellCount + 1 ) + j + 1; pIndexBuffer[dwBaseIndex + 3] = i * ( mCellCount + 1 ) + j; pIndexBuffer[dwBaseIndex + 4] = ( i + 1 ) * ( mCellCount + 1 ) + j + 1;; pIndexBuffer[dwBaseIndex + 5] = i * ( mCellCount + 1 ) + j + 1; dwBaseIndex += 6; } } mesh->UnlockIndexBuffer(); mMeshBufferNode->setMesh ( mesh ); mMeshBufferNode->setSubCount ( 1 ); DWORD *pAdj = new DWORD[mesh->GetNumFaces() * 3]; mesh->GenerateAdjacency ( 1.0f, pAdj ); delete []pAdj ; }
bool GraphicalPlane::GenerateBoard(const std::string& path, const int &width, const int &height, const TextureSP &texture) { // キーネーム設定 std::stringstream nameBuffer(""); // ファイルパス→生成番号→幅高さの順で追加 nameBuffer << path << ++_createCount << width << height; std::string name = nameBuffer.str(); // メッシュインスタンスの生成 _mesh = Mesh::CreateEmpty(name); // サイズを記録 _size.x = (float)width ; _size.y = (float)height ; //_size.z = 0 ; // テクスチャ指定がある場合そのサイズを取得 if(texture != NULL) { while(UINT(_textureSize.x) < _texture->GetImageInfo().Width) { _textureSize.x *= 2; } while(UINT(_textureSize.y) < _texture->GetImageInfo().Height) { _textureSize.y *= 2; } } // シェーダー設定 _shader = ShaderNormal::Create(); // メッシュを生成する LPD3DXMESH mesh; if (FAILED(D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, Vertex::FVF, GraphicsManager::_device, &mesh))) return false; //頂点データの作成 Vertex* vertex; mesh->LockVertexBuffer(0, (void**)&vertex); for (int y = 0 ; y < 2 ; y++) { for (int x = 0 ; x < 2 ; x++) { float x1 = (float)(x * width - ((float)width / 2)); float y1 = (float)(y * height - ((float)height / 2)); int index = y * 2 + x; vertex[index]._position.x = x1; vertex[index]._position.y = y1; vertex[index]._position.z = 0; vertex[index]._normal.x = 0; vertex[index]._normal.y = 0; vertex[index]._normal.z = 1; if( texture == NULL ) { vertex[index]._uv.x = (float)x * 1.0f; vertex[index]._uv.y = 1.0f - ((float)y * 1.0f); } } } if(texture) { vertex[0]._uv.x = (float)_rects[_number].left / _texture->GetImageInfo().Width; vertex[0]._uv.y = (float)_rects[_number].bottom / _texture->GetImageInfo().Height; vertex[1]._uv.x = (float)_rects[_number].right / _texture->GetImageInfo().Width; vertex[1]._uv.y = (float)_rects[_number].bottom / _texture->GetImageInfo().Height; vertex[2]._uv.x = (float)_rects[_number].left / _texture->GetImageInfo().Width; vertex[2]._uv.y = (float)_rects[_number].top / _texture->GetImageInfo().Height; vertex[3]._uv.x = (float)_rects[_number].right / _texture->GetImageInfo().Width; vertex[3]._uv.y = (float)_rects[_number].top / _texture->GetImageInfo().Height; } mesh->UnlockVertexBuffer(); //インデックスデータの作成 WORD *index; mesh->LockIndexBuffer(0, (void **)&index); index[0] = 0; index[1] = 2; index[2] = 1; index[3] = 1; index[4] = 2; index[5] = 3; mesh->UnlockIndexBuffer(); _mesh->SetMesh(mesh); return true; }
void ObjParser::Load(LPCSTR Filename, LPDIRECT3DDEVICE9 pDevice) { FILE* fileHandle = fopen(Filename, "r+"); if( fileHandle == NULL ) return; char line[256]; D3DXVECTOR3 vec; while( !feof(fileHandle) )//Foreach Line { fgets(line, 256, fileHandle); #pragma region Line Read switch(line[0]) { case 'm': { LPCSTR name = new CHAR[256]; sscanf_s(line, "mtllib %s", name, 255); ParseMaterial(name); } break; case 'v'://Vertex Item { switch(line[1]) { case ' '://Vertex { sscanf_s(line, "v %f %f %f", &vec.x, &vec.y, &vec.z ); Vertexs.push_back(vec); mVertexsHT.push_back(NULL);//expand HashTable } break; case 't'://Texture Coordinates { D3DXVECTOR3 tex; sscanf_s(line, "vt %f %f %f", &vec.x, &vec.y, &vec.z); Textures.push_back(vec); } break; case 'n'://Normal { D3DXVECTOR3 nor; sscanf_s(line, "vn %f %f %f", &vec.x, &vec.y, &vec.z ); Normals.push_back(vec); } break; default:// Not supposed to happen assert( false ); } } break; case 'f'://Face Item { DWORD quadP[4];//Position Index quad DWORD quadT[4];//Texture Index quad DWORD quadN[4];//Normal Index quad memset(quadP, -1, sizeof(DWORD)*4); memset(quadT, -1, sizeof(DWORD)*4); memset(quadN, -1, sizeof(DWORD)*4); int size = strlen(line); int barCount = std::count(line, line+size, '/'); int readed = 0; //By default .obj file puts faces with CW winding switch( barCount ) { case 0:// tri/quad pos { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d %d %d %d", &quadP[3], &quadP[2], &quadP[1], &quadP[0] ); else readed = sscanf_s(line, "f %d %d %d %d", &quadP[0], &quadP[1], &quadP[2], &quadP[3] ); assert( readed == 3 || readed == 4 ); } break; case 3:// tri pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[0], quadT[0], &quadP[1], quadT[1], &quadP[2], quadT[2] ); assert( readed == 6 ); readed /= 2; } break; case 4:// quad pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[3], &quadT[3], &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[0], &quadT[0], &quadP[1], &quadT[1], &quadP[2], &quadT[2], &quadP[3], &quadT[3] ); assert( readed == 8 ); readed /= 2; } break; case 6:// tri pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2] ); assert( readed == 9 ); readed /= 3; } break; case 8:// quad pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[3], &quadT[3], &quadN[3], &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2], &quadP[3], &quadT[3], &quadN[3] ); assert( readed == 12 ); readed /= 3; } break; default:// Not supposed to happen assert( false ); } //The indexs are in 1 Base, we transform to 0 Base for( int i=0; i < 4 ; ++i ) { quadP[i]--; quadT[i]--; quadN[i]--; } for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } if( readed == 4 )// quad readed { quadP[1] = quadP[2]; quadT[1] = quadT[2]; quadN[1] = quadN[2]; quadP[2] = quadP[3]; quadT[2] = quadT[3]; quadN[1] = quadN[2]; for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } } } break; } #pragma endregion } fclose(fileHandle); DWORD FVF = NULL; D3DVERTEXELEMENT9* pMeshVDeclaration = NULL; int code = 0; IdentifieLoadedFormat(FVF, pMeshVDeclaration, code); if( code == 0 ) return; //Setup Mesh with VertexDeclaration corresponding to the loaded data LPD3DXMESH pMesh = NULL; HRESULT hr = NULL; int FacesCount = mIndexs.size()/3; switch( m_VertexMetaFormat ) { case VertexMetaFormat::VertexDeclaration: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); else hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); } break; case VertexMetaFormat::FVF: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); else hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); } break; default: assert( false ); } assert( !FAILED(hr) ); //Puts vertex data inside loadedData in the smallest format needed //(not nesesarily VertexTextureNormal) void* loadedData = NULL; void* loadedIndex = NULL; size_t size = 0; //Pass to our vertex format PutLoadedDataInVertexDeclarationFormat(loadedData,loadedIndex,size,code, FacesCount); //Free Auxiliary Arrays Vertexs.clear(); Textures.clear(); Normals.clear(); mVertexsHT.clear(); void* data = NULL; //Loads the Vertex Buffer if( FAILED(pMesh->LockVertexBuffer(NULL, &data)) ) return; memcpy(data, loadedData, size*mVertexs.size()); pMesh->UnlockVertexBuffer(); //Loads the Index Buffer if( FAILED(pMesh->LockIndexBuffer(NULL, &data)) ) return; if( FacesCount > 65535 ) memcpy(data, loadedIndex, sizeof(DWORD)*mIndexs.size()); else memcpy(data, loadedIndex, sizeof(WORD)*mIndexs.size()); pMesh->UnlockIndexBuffer(); //Free main Arrays mVertexs.clear(); mIndexs.clear(); //Mesh data ready m_RootMeshContainer = new D3DXMESHCONTAINER; m_RootMeshContainer->MeshData.pMesh = pMesh; return; }
//------------------------------------------------------ // IMO読み込み //------------------------------------------------------ BOOL iexMesh::LoadIMO( LPSTR filename ) { IMOOBJ imo; DWORD i; // ファイル読み込み HANDLE hfile; DWORD dum; int version = 1; hfile = CreateFile( filename, GENERIC_READ, FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL ); if( hfile == INVALID_HANDLE_VALUE ) return FALSE; ReadFile( hfile, &imo, sizeof(IMOOBJ), &dum, NULL ); if( imo.id == '2OMI' ) version = 2; // メッシュ作成 BYTE *pVertex, *pFace; DWORD *pData; LVERTEX* workV = new LVERTEX[imo.NumVertex]; MESHVERTEX2* workV2 = new MESHVERTEX2[imo.NumVertex]; WORD* workF = new WORD[imo.NumFace*3]; if( version == 1 ) { // 頂点読み込み ReadFile( hfile, workV, sizeof(LVERTEX)*imo.NumVertex, &dum, NULL ); // インデックス読み込み ReadFile( hfile, workF, sizeof(WORD)*imo.NumFace*3, &dum, NULL ); for (DWORD i = 0; i < imo.NumVertex; i++) { workV2[i].x = workV[i].x; workV2[i].y = workV[i].y; workV2[i].z = workV[i].z; workV2[i].tu = workV[i].tu; workV2[i].tv = workV[i].tv; workV2[i].color = workV[i].color; workV2[i].nx = .0f; workV2[i].ny = .0f; workV2[i].nz = .0f; } for (DWORD i = 0; i < imo.NumFace; i++) { // 法線計算 Vector3 v1, v2, n; v1.x = workV[workF[i * 3 + 0]].x - workV[workF[i * 3 + 1]].x; v1.y = workV[workF[i * 3 + 0]].y - workV[workF[i * 3 + 1]].y; v1.z = workV[workF[i * 3 + 0]].z - workV[workF[i * 3 + 1]].z; v2.x = workV[workF[i * 3 + 1]].x - workV[workF[i * 3 + 2]].x; v2.y = workV[workF[i * 3 + 1]].y - workV[workF[i * 3 + 2]].y; v2.z = workV[workF[i * 3 + 1]].z - workV[workF[i * 3 + 2]].z; n.x = (v1.y*v2.z - v1.z*v2.y); n.y = (v1.z*v2.x - v1.x*v2.z); n.z = (v1.x*v2.y - v1.y*v2.x); float d = sqrtf( n.x*n.x + n.y*n.y + n.z*n.z ); n.x /= d; n.y /= d; n.z /= d; workV2[workF[i * 3 + 0]].nx += n.x; workV2[workF[i * 3 + 0]].ny += n.y; workV2[workF[i * 3 + 0]].nz += n.z; workV2[workF[i * 3 + 1]].nx += n.x; workV2[workF[i * 3 + 1]].ny += n.y; workV2[workF[i * 3 + 1]].nz += n.z; workV2[workF[i * 3 + 2]].nx += n.x; workV2[workF[i * 3 + 2]].ny += n.y; workV2[workF[i * 3 + 2]].nz += n.z; } for (DWORD i = 0; i < imo.NumVertex; i++) { float d = sqrtf( workV2[i].nx*workV2[i].nx + workV2[i].ny*workV2[i].ny + workV2[i].nz*workV2[i].nz ); workV2[i].nx /= d; workV2[i].ny /= d; workV2[i].nz /= d; } } else { // 頂点読み込み ReadFile( hfile, workV2, sizeof(MESHVERTEX2)*imo.NumVertex, &dum, NULL ); // インデックス読み込み ReadFile( hfile, workF, sizeof(WORD)*imo.NumFace*3, &dum, NULL ); } DWORD Declaration = D3DFVF_MESHVERTEX2; D3DXCreateMeshFVF( imo.NumFace, imo.NumVertex, D3DXMESH_MANAGED, Declaration, tdnSystem::GetDevice(), &lpMesh ); // 頂点設定 lpMesh->LockVertexBuffer( 0, (void**)&pVertex ); memcpy( pVertex, workV2, sizeof(MESHVERTEX2)*imo.NumVertex ); lpMesh->UnlockVertexBuffer(); // 面設定 lpMesh->LockIndexBuffer( 0, (void**)&pFace ); memcpy( pFace, workF, sizeof(WORD)*imo.NumFace*3 ); lpMesh->UnlockIndexBuffer(); // 属性設定 lpMesh->LockAttributeBuffer( 0, &pData ); ReadFile( hfile, pData, sizeof(DWORD)*imo.NumFace, &dum, NULL ); lpMesh->UnlockAttributeBuffer(); // パス分割 char workpath[MAX_PATH]; CopyMemory( workpath, filename, lstrlen(filename)+1 ); for( i=lstrlen(filename) ; i>0 ; i-- ){ if( IsDBCSLeadByte(workpath[i-2]) ){ i--; continue; } if( workpath[i-1] == '\\' || workpath[i-1] == '/' ){ workpath[i] = '\0'; break; } } // マテリアル設定 MaterialCount = imo.NumMaterial; lpMaterial = new D3DMATERIAL9[ MaterialCount ]; CopyMemory( lpMaterial, imo.Material, sizeof(D3DMATERIAL9)*imo.NumMaterial ); // テクスチャ設定 lpTexture = new Texture2D* [ imo.NumMaterial ]; lpNormal = new Texture2D* [ imo.NumMaterial ]; lpSpecular = new Texture2D* [ imo.NumMaterial ]; lpHeight = new Texture2D* [ imo.NumMaterial ]; char temp[256]; for( i=0 ; i<MaterialCount ; i++ ){ lpTexture[i] = NULL; lpNormal[i] = NULL; lpSpecular[i] = NULL; lpHeight[i] = NULL; if( imo.Texture[i][0] == '\0' ) continue; // テクスチャ読み込み sprintf( temp, "%s%s", workpath, imo.Texture[i] ); lpTexture[i] = tdnTexture::Load( temp ); sprintf( temp, "%sN%s", workpath, imo.Texture[i] ); lpNormal[i] = tdnTexture::Load( temp ); sprintf( temp, "%sS%s", workpath, imo.Texture[i] ); lpSpecular[i] = tdnTexture::Load( temp ); sprintf( temp, "%sH%s", workpath, imo.Texture[i] ); lpHeight[i] = tdnTexture::Load( temp, 1 ); } CloseHandle(hfile); delete[] workV; delete[] workV2; delete[] workF; // 初期設定 SetPos(0,0,0); SetAngle(0.0f); SetScale(1.0f); dwFlags = 0; bLoad = TRUE; 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; }
HRESULT KG3DMeshBone::_CreateMesh() { HRESULT hResult = E_FAIL; HRESULT hRetCode = E_FAIL; DWORD dwNumFaces = (DWORD)m_vecSubMeshInfo.size() * 8; DWORD dwNumVertices = (DWORD)m_vecSubMeshInfo.size() * 6; VFormat::FACES_NORMAL_DIFFUSE_TEXTURE0* pVBuffer = NULL; WORD* pIBuffer = NULL; DWORD* pABuffer = NULL; hRetCode = D3DXCreateMeshFVF( dwNumFaces, dwNumVertices, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE, g_pd3dDevice, &m_pSysMesh ); KG_COM_PROCESS_ERROR(hRetCode); // vertex hRetCode = m_pSysMesh->LockVertexBuffer(0, (void**)&pVBuffer); KG_COM_PROCESS_ERROR(hRetCode); for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++) { pVBuffer[i * 6].p = m_vecSubMeshInfo[i].vPosition[0]; pVBuffer[i * 6].diffuse = 0xFFFFFFFF; pVBuffer[i * 6 + 1].p = m_vecSubMeshInfo[i].vPosition[1]; pVBuffer[i * 6 + 1].diffuse = 0xFFFF0000; pVBuffer[i * 6 + 2].p = m_vecSubMeshInfo[i].vPosition[2]; pVBuffer[i * 6 + 2].diffuse = 0xFF0000FF; pVBuffer[i * 6 + 3].p = m_vecSubMeshInfo[i].vPosition[3]; pVBuffer[i * 6 + 3].diffuse = 0xFF00FF00; pVBuffer[i * 6 + 4].p = m_vecSubMeshInfo[i].vPosition[4]; pVBuffer[i * 6 + 4].diffuse = 0xFFFFFF00; pVBuffer[i * 6 + 5].p = m_vecSubMeshInfo[i].vPosition[5]; pVBuffer[i * 6 + 5].diffuse = 0xFFFFFFFF; } hRetCode = m_pSysMesh->UnlockVertexBuffer(); KG_COM_PROCESS_ERROR(hRetCode); // index hRetCode = m_pSysMesh->LockIndexBuffer(0, (void**)&pIBuffer); KG_COM_PROCESS_ERROR(hRetCode); for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++) { for (DWORD j = 0; j < 24; j++) { pIBuffer[i * 24 + j] = (WORD)(m_vecSubMeshInfo[i].dwIndex[j] + 6 * i); } } hRetCode = m_pSysMesh->UnlockIndexBuffer(); KG_COM_PROCESS_ERROR(hRetCode); // index hRetCode = m_pSysMesh->LockAttributeBuffer(0, (DWORD**)&pABuffer); KG_COM_PROCESS_ERROR(hRetCode); for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++) { for (DWORD j = 0; j < 8; j++) { pABuffer[i * 8 + j] = i; } } hRetCode = m_pSysMesh->UnlockAttributeBuffer(); KG_COM_PROCESS_ERROR(hRetCode); D3DXComputeNormals(m_pSysMesh, NULL); hResult = S_OK; Exit0: return hResult; }
/** * Exports all geometry into a D3D .x file into the current working folder. * @param Filename Desired filename (may include path) * @param bShow Whether the D3D .x file viewer should be invoked. If shown, we'll block until it has been closed. */ void F3DVisualizer::Export( const TCHAR* Filename, bool bShow/*=false*/ ) { ID3DXMesh* Mesh; Mesh = NULL; int32 NumPrimitives = NumTriangles() + NumLines()*2; int32 NumVertices = NumTriangles()*3 + NumLines()*4; HRESULT Result = D3DXCreateMeshFVF( NumPrimitives, NumVertices, D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_SPECULAR, D3D->D3DDevice, &Mesh ); void* VertexBuffer = NULL; void* IndexBuffer = NULL; Result = Mesh->LockVertexBuffer(D3DLOCK_DISCARD, &VertexBuffer); Result = Mesh->LockIndexBuffer(D3DLOCK_DISCARD, &IndexBuffer); D3DXVertex* Vertices = (D3DXVertex*)VertexBuffer; uint32* Indices = (uint32*) IndexBuffer; int32 NumVerticesStored = 0; int32 NumIndicesStored = 0; // Add the triangles to the vertexbuffer and indexbuffer. for ( int32 TriangleIndex=0; TriangleIndex < NumTriangles(); ++TriangleIndex ) { const FVector4& P1 = Triangles[TriangleIndex].Vertices[0]; const FVector4& P2 = Triangles[TriangleIndex].Vertices[1]; const FVector4& P3 = Triangles[TriangleIndex].Vertices[2]; const FColor& Color = Triangles[TriangleIndex].Color; Vertices[NumVerticesStored+0].Pos[0] = P1[0]; Vertices[NumVerticesStored+0].Pos[1] = P1[1]; Vertices[NumVerticesStored+0].Pos[2] = P1[2]; Vertices[NumVerticesStored+0].Color1 = Color.DWColor(); Vertices[NumVerticesStored+0].Color2 = 0; Vertices[NumVerticesStored+1].Pos[0] = P2[0]; Vertices[NumVerticesStored+1].Pos[1] = P2[1]; Vertices[NumVerticesStored+1].Pos[2] = P2[2]; Vertices[NumVerticesStored+1].Color1 = Color.DWColor(); Vertices[NumVerticesStored+1].Color2 = 0; Vertices[NumVerticesStored+2].Pos[0] = P3[0]; Vertices[NumVerticesStored+2].Pos[1] = P3[1]; Vertices[NumVerticesStored+2].Pos[2] = P3[2]; Vertices[NumVerticesStored+2].Color1 = Color.DWColor(); Vertices[NumVerticesStored+2].Color2 = 0; // Reverse triangle winding order for the .x file. Indices[NumIndicesStored+0] = NumVerticesStored + 0; Indices[NumIndicesStored+1] = NumVerticesStored + 2; Indices[NumIndicesStored+2] = NumVerticesStored + 1; NumVerticesStored += 3; NumIndicesStored += 3; } // Add the lines to the vertexbuffer and indexbuffer. for ( int32 LineIndex=0; LineIndex < NumLines(); ++LineIndex ) { const FVector4& P1 = Lines[LineIndex].Vertices[0]; const FVector4& P2 = Lines[LineIndex].Vertices[1]; const FColor& Color = Lines[LineIndex].Color; Vertices[NumVerticesStored+0].Pos[0] = P1[0]; Vertices[NumVerticesStored+0].Pos[1] = P1[1] - 5.0f; Vertices[NumVerticesStored+0].Pos[2] = P1[2]; Vertices[NumVerticesStored+0].Color1 = 0; Vertices[NumVerticesStored+0].Color2 = Color.DWColor(); Vertices[NumVerticesStored+1].Pos[0] = P1[0]; Vertices[NumVerticesStored+1].Pos[1] = P1[1] + 5.0f; Vertices[NumVerticesStored+1].Pos[2] = P1[2]; Vertices[NumVerticesStored+1].Color1 = 0; Vertices[NumVerticesStored+1].Color2 = Color.DWColor(); Vertices[NumVerticesStored+2].Pos[0] = P2[0]; Vertices[NumVerticesStored+2].Pos[1] = P2[1] - 5.0f; Vertices[NumVerticesStored+2].Pos[2] = P2[2]; Vertices[NumVerticesStored+2].Color1 = 0; Vertices[NumVerticesStored+2].Color2 = Color.DWColor(); Vertices[NumVerticesStored+3].Pos[0] = P2[0]; Vertices[NumVerticesStored+3].Pos[1] = P2[1] + 5.0f; Vertices[NumVerticesStored+3].Pos[2] = P2[2]; Vertices[NumVerticesStored+3].Color1 = 0; Vertices[NumVerticesStored+3].Color2 = Color.DWColor(); Indices[NumIndicesStored+0] = NumVerticesStored+0; Indices[NumIndicesStored+1] = NumVerticesStored+2; Indices[NumIndicesStored+2] = NumVerticesStored+1; Indices[NumIndicesStored+3] = NumVerticesStored+2; Indices[NumIndicesStored+4] = NumVerticesStored+3; Indices[NumIndicesStored+5] = NumVerticesStored+1; NumVerticesStored += 4; NumIndicesStored += 6; } Mesh->UnlockVertexBuffer(); Mesh->UnlockIndexBuffer(); Result = D3DXComputeNormals( Mesh, NULL ); D3DXMATERIAL MeshMaterial; MeshMaterial.MatD3D.Ambient.r = 0.1f; MeshMaterial.MatD3D.Ambient.g = 0.1f; MeshMaterial.MatD3D.Ambient.b = 0.1f; MeshMaterial.MatD3D.Ambient.a = 0.0f; MeshMaterial.MatD3D.Diffuse.r = 1.0f; MeshMaterial.MatD3D.Diffuse.g = 1.0f; MeshMaterial.MatD3D.Diffuse.b = 1.0f; MeshMaterial.MatD3D.Diffuse.a = 1.0f; MeshMaterial.MatD3D.Emissive.r = 1.0f; MeshMaterial.MatD3D.Emissive.g = 1.0f; MeshMaterial.MatD3D.Emissive.b = 1.0f; MeshMaterial.MatD3D.Emissive.a = 1.0f; MeshMaterial.MatD3D.Specular.r = 1.0f; MeshMaterial.MatD3D.Specular.g = 1.0f; MeshMaterial.MatD3D.Specular.b = 1.0f; MeshMaterial.MatD3D.Specular.a = 1.0f; MeshMaterial.MatD3D.Power = 16.0f; MeshMaterial.pTextureFilename = NULL; D3DXEFFECTINSTANCE EffectInstance; EffectInstance.pEffectFilename = "D3DExport.fx"; EffectInstance.NumDefaults = 0; EffectInstance.pDefaults = NULL; // Write out the .x file. D3DXSaveMeshToX( Filename, Mesh, NULL, &MeshMaterial, &EffectInstance, 1, D3DXF_FILEFORMAT_BINARY ); Mesh->Release(); // Write out the .fx file, if it doesn't always exist. HANDLE ShaderFile = CreateFile( TEXT("D3DExport.fx"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (ShaderFile != INVALID_HANDLE_VALUE) { ::DWORD BytesWritten; WriteFile(ShaderFile, ShaderFxFile, (uint32)FCStringAnsi::Strlen(ShaderFxFile), &BytesWritten, NULL); CloseHandle( ShaderFile ); } // If specified, run the default viewer for .x files and block until it's closed. if ( bShow ) { system( TCHAR_TO_ANSI(Filename) ); } }
//================================================================================================= void Terrain::Build(bool smooth) { assert(state == 1); HRESULT hr = D3DXCreateMeshFVF(n_tris, n_verts, D3DXMESH_MANAGED | D3DXMESH_32BIT, VTerrain::fvf, device, &mesh); if(FAILED(hr)) throw Format("Failed to create new terrain mesh (%d)!", hr); VTerrain* v; //word* idx; uint* idx; uint n = 0; //uint index = 0; V(mesh->LockVertexBuffer(0, (void**)&v)); V(mesh->LockIndexBuffer(0, (void**)&idx)); #define TRI(xx,zz,uu,vv) v[n++] = VTerrain((x+xx)*tile_size, h[x+xx+(z+zz)*hszer], (z+zz)*tile_size, float(uu)/uv_mod, float(vv)/uv_mod,\ ((float)(x+xx)) / n_tiles, ((float)(z+zz)) / n_tiles) for(uint z = 0; z < n_tiles; ++z) { for(uint x = 0; x < n_tiles; ++x) { int u1 = (x%uv_mod); int u2 = ((x + 1) % uv_mod); if(u2 == 0) u2 = uv_mod; int v1 = (z%uv_mod); int v2 = ((z + 1) % uv_mod); if(v2 == 0) v2 = uv_mod; TRI(0, 0, u1, v1); TRI(0, 1, u1, v2); TRI(1, 0, u2, v1); CalculateNormal(v[n - 3], v[n - 2], v[n - 1]); TRI(0, 1, u1, v2); TRI(1, 1, u2, v2); TRI(1, 0, u2, v1); CalculateNormal(v[n - 3], v[n - 2], v[n - 1]); } } #undef TRI for(uint z = 0; z < n_parts; ++z) { for(uint x = 0; x < n_parts; ++x) { const uint z_start = z*tiles_per_part, z_end = z_start + tiles_per_part, x_start = x*tiles_per_part, x_end = x_start + tiles_per_part; for(uint zz = z_start; zz < z_end; ++zz) { for(uint xx = x_start; xx < x_end; ++xx) { for(uint j = 0; j < 6; ++j) { *idx = (xx + zz*n_tiles) * 6 + j; ++idx; } } } } } V(mesh->UnlockIndexBuffer()); state = 2; if(smooth) SmoothNormals(v); V(mesh->UnlockVertexBuffer()); }
//------------------------------------------------------------------------------------------------ // 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; }
void cASEObject::setup(stASENode& nodeinfo, D3DXMATRIXA16* pmatParentWorld/* = NULL*/){ m_stNodeInfo = nodeinfo; m_matWorldTM = nodeinfo.LocalMat; m_matOriginalWorld = nodeinfo.LocalMat; m_stNodeAni = nodeinfo.AnimationInfo; if (pmatParentWorld){ D3DXMATRIXA16 mtPrnI; D3DXMatrixInverse(&mtPrnI, NULL, pmatParentWorld); m_matLocalMat = m_matWorldTM * mtPrnI; } else { D3DXMatrixIdentity(&m_matLocalMat); } D3DXMATRIXA16 matInverse; D3DXMatrixInverse(&matInverse, NULL, &m_matWorldTM); for (size_t i = 0; i < m_stNodeInfo.vecVertex.size(); i++){ D3DXVec3TransformCoord( &m_stNodeInfo.vecVertex[i].p, &m_stNodeInfo.vecVertex[i].p, &matInverse); D3DXVec3TransformNormal( &m_stNodeInfo.vecVertex[i].n, &m_stNodeInfo.vecVertex[i].n, &matInverse ); } D3DXCreateSphere(g_pD3DDevice, 0.025f, 10, 10, &m_pNodeMesh, NULL); if (m_stNodeInfo.nRef != INT_MAX){ m_pMesh = NULL; HRESULT hr = D3DXCreateMeshFVF(m_stNodeInfo.vecVertex.size() / 3, m_stNodeInfo.vecVertex.size(), D3DXMESH_MANAGED, ST_PNT_VERTEX::FVF, g_pD3DDevice, &m_pMesh); #ifdef _DEBUG _ASSERT(hr == S_OK && "Mesh Not Created"); #endif ST_PNT_VERTEX* pV = NULL; m_pMesh->LockVertexBuffer(0, (LPVOID*)&pV); memcpy(pV, &m_stNodeInfo.vecVertex[0], m_stNodeInfo.vecVertex.size() * sizeof(ST_PNT_VERTEX)); m_pMesh->UnlockVertexBuffer(); WORD* pI = NULL; m_pMesh->LockIndexBuffer(0, (LPVOID*)&pI); for (size_t j = 0; j < m_pMesh->GetNumVertices(); ++j) { pI[j] = j; } m_pMesh->UnlockIndexBuffer(); DWORD* pA = NULL; m_pMesh->LockAttributeBuffer(0, &pA); for (size_t j = 0; j < m_pMesh->GetNumFaces(); j++){ pA[j] = m_stNodeInfo.nRef; } m_pMesh->UnlockAttributeBuffer(); std::vector<DWORD> vecAdjBuffer(m_stNodeInfo.vecVertex.size()); m_pMesh->GenerateAdjacency(0.0f, &vecAdjBuffer[0]); m_pMesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE, &vecAdjBuffer[0], 0, 0, 0); } }