void CRenderPrimitive::SetGraphicSphere(float radius) { ID3DXMesh *pMesh; D3DXCreateSphere( g_pD3dDevice, radius, 8, 8, &pMesh, NULL); mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1); pMesh->Release(); }
void CRenderPrimitive::SetGraphicCylinder(float radius, float length) { ID3DXMesh *pMesh; D3DXCreateCylinder( g_pD3dDevice, radius, radius, length, 8, 1, &pMesh, NULL); mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1); pMesh->Release(); mIsCylinder = 1; }
void CRenderPrimitive::SetGraphicBox(float Width, float Height, float Depth) { //create the render mesh ID3DXMesh *pMesh; D3DXCreateBox( g_pD3dDevice, Width, Height, Depth, &pMesh, NULL); mMesh.Create(g_pD3dDevice, pMesh, &mMaterial, 1); pMesh->Release(); }
// Creates a sphere. Returns true on success, false otherwise bool CreateSphere(float radius, int color, ID3DXMesh **mesh) { assert(g3D->mDevice != NULL); assert(mesh != NULL); const unsigned int kSlices = 16; const unsigned int kStacks = 16; ID3DXMesh *tempMesh; // Temp D3D mesh object // Create the sphere if(D3DXCreateSphere(g3D->mDevice, radius, kSlices, kStacks, &tempMesh, NULL) != D3D_OK) return false; // Flag for how to create the D3D mesh. We want the vertex buffer and index // buffer memory to be managed by DirectX DWORD flag = D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED; // Copy the sphere, converting to our FVF if(tempMesh->CloneMeshFVF(flag, SVertexType, g3D->mDevice, mesh) != D3D_OK) return false; SVertex *v; // Lock the vertex data of our sphere if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK) { (*mesh)->Release(); return false; } // Set the sphere's color for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i) v[i].color = color; // Unlock the vertex data (*mesh)->UnlockVertexBuffer(); tempMesh->Release(); // Free up the temporary mesh return true; }
void MeshManager::CreateSphereMesh(){ // Create MeshComponents for Sphere mesh MeshComponents* meshComp = new MeshComponents(); meshComp->numMaterials = 1; meshComp->bufMeshMaterial = NULL; meshComp->material = NULL; meshComp->texture = NULL; //Create main sphere to be used to draw spheres place by user //Create a temporary sphere first ID3DXMesh* tempSphere; D3DXCreateSphere(m_Device, 1.0f, 10, 16, &tempSphere, 0); //Clone temp sphere to the main sphere and give its vertices a color value tempSphere->CloneMeshFVF( D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_DIFFUSE, m_Device, &meshComp->mesh ); //Release the temp sphere tempSphere->Release(); // Add sphere to meshCollection/List m_mMeshCollection.insert( make_pair("sphere", meshComp) ); m_vMeshList.push_back( meshComp ); }
/** * 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) ); } }
// Create a torus with the parameters specified // Returns true for success, false otherwise bool CreateTorus(float innerRad, float outerRad, int color, ID3DXMesh **mesh) { assert(g3D->mDevice != NULL); assert(mesh != NULL); const unsigned int kSides = 16; // Number of divisions looking at the torus form the side const unsigned int kRings = 16; // Number of divisions looking at the torus from the top // so you can see the hole in the middle ID3DXMesh *temp = NULL; // Temp D3D mesh object // Create the torus // By paramter: // g3D->mDevice -- Pointer to the Direct3D device to be associated with the torus // innerRad -- Inner radius of the torus // outerRad -- Outside radius of the torus // kSides -- Number of sides in a cross-section of the torus // kRings -- Number of rings in a cross-section of the torus // &temp -- A pointer to a ID3DXMesh*, it will get filled with the // the created mesh // NULL -- Optional pointer to a ID3DXBuffer, if a valid pointer was passed // it would be filled with the adjacency information for each face in // the mesh. By passing NULL, we say we don't want this information if(D3DXCreateTorus(g3D->mDevice, innerRad, outerRad, kSides, kRings, &temp, NULL) != D3D_OK) return false; // Next we clone the mesh. This does two things. First, it allows us to // specify the vertex format we want on the cloned mesh. Second, it copies the // current mesh data into the ID3DXMesh we passed to this function. // By parameter: // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED -- Flags specifying how we want the mesh to be // cloned. This particular flag combo says // "Have the vertex buffer and index buffer // associated with this mesh be in pooled memory // that DirectX manages for us." // SVertexType -- Flexible vertex format that we want the cloned mesh to be converted to // g3D->mDevice -- IDirect3DDevice9 to associate this mesh with // mesh -- A pointer to a ID3DXMesh* that will get filled with the cloned mesh if(temp->CloneMeshFVF(D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED, SVertexType, g3D->mDevice, mesh) != D3D_OK) { return false; } // Okay so up to this point we've created a stock D3D torus, then converted // it a torus with the FVF that we want. Now were going to loop through each // vertex and set it to the color that we want it to be. SVertex *v; // Lock the vertex buffer if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK) { (*mesh)->Release(); return false; } // Loop through all the verts in the mesh, setting each one's // color to the color passed into the function for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i) v[i].color = color; // We're done with the vertex buffer, so unlock it so it may be used // by others (*mesh)->UnlockVertexBuffer(); temp->Release(); // Last but not least, free up the temporary mesh return true; }
// This functions creates a sphere of "radius" and vertex color "color" bool CreateSphere(float radius, int color, ID3DXMesh **mesh) { assert(g3D->mDevice != NULL); assert(mesh != NULL); // This is the number of divisions the sphere will have vertically and // horizontally const unsigned int kSlices = 16; // Vertical divisions const unsigned int kStacks = 16; // Horizontal divisions ID3DXMesh *temp = NULL; // Temp D3D mesh object // Create the sphere // By parameter: // g3D->mDevice -- Pointer to the Direct3D device to be associated with the sphere // radius -- Radius of the sphere // kSlices -- Number of vertical divisions in the sphere // kStacks -- Number of horizontal divisions in the sphere // &temp -- A pointer to a ID3DXMesh*, it will get filled with the // the created mesh // NULL -- Optional pointer to a ID3DXBuffer, if a valid pointer was passed // it would be filled with the adjacency information for each face in // the mesh. By passing NULL, we say we don't want this information if(D3DXCreateSphere(g3D->mDevice, radius, kSlices, kStacks, &temp, NULL) != D3D_OK) return false; // Next we clone the mesh. This does two things. First, it allows us to // specify the vertex format we want on the cloned mesh. Second, it copies the // current mesh data into the ID3DXMesh we passed to this function. // By parameter: // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED -- Flags specifying how we want the mesh to be // cloned. This particular flag combo says // "Have the vertex buffer and index buffer // associated with this mesh be in pooled memory // that DirectX manages for us." // SVertexType -- Flexible vertex format that we want the cloned mesh to be converted to // g3D->mDevice -- IDirect3DDevice9 to associate this mesh with // mesh -- A pointer to a ID3DXMesh* that will get filled with the cloned mesh if(temp->CloneMeshFVF(D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED, SVertexType, g3D->mDevice, mesh) != D3D_OK) { return false; } // Okay so up to this point we've created a stock D3D sphere, then converted // it a sphere with the FVF that we want. Now were going to // loop through each vertex and set it to the color that we want it to be SVertex *v; // Lock the vertex buffer if((*mesh)->LockVertexBuffer(0, (void**)&v) != D3D_OK) { (*mesh)->Release(); return false; } // Loop through all the verts in the mesh, setting each one's // color to the color passed into the function for(unsigned int i = 0; i < (*mesh)->GetNumVertices(); ++i) v[i].color = color; // Don't be stingy, unlock the vertex buffer so others can use it (*mesh)->UnlockVertexBuffer(); temp->Release(); // Last but not least, free up the temporary mesh return true; }
HRESULT HelloShadowVolume::RestoreDeviceObjects() { HRESULT hr; IDirect3DDevice8* device; hr = m_spD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_dpps, &device); if (FAILED(hr)) { MessageBox(0, L"CreateDevice failed", 0, 0); return E_FAIL; } m_spDevice.reset(device, [](IDirect3DDevice8* device) { device->Release(); }); m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); D3DVIEWPORT8 viewport = { 0, 0, m_iWidth, m_iHeight }; m_spDevice->SetViewport(&viewport); D3DXVECTOR3 eye(0.0f, 0.0f, 30.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&m_mtView, &eye, &target, &up); D3DXMatrixPerspectiveFovLH(&m_mtProj, 0.2*D3DX_PI, (float)m_iWidth / (float)m_iHeight, 1.0f, 100.f); m_cPlaneTint = { 0.7f, 0.6f, 0.4f, 1.0f }; ID3DXMesh* plane; //D3DXCreatePolygon(m_spDevice.get(), 2.0f, 4, &plane, NULL); CreatePlane(m_spDevice.get(), 15.0f, 10, &plane); //D3DXCreateSphere(m_spDevice.get(), 1.0f,20,20, &plane, NULL); IDirect3DVertexBuffer8* vb; IDirect3DIndexBuffer8* ib; plane->GetVertexBuffer(&vb); plane->GetIndexBuffer(&ib); m_spPlaneVB.reset(vb, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spPlaneIB.reset(ib, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwPlaneNumVertices = plane->GetNumVertices(); m_dwPlaneNumFaces = plane->GetNumFaces(); plane->Release(); DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(0, D3DVSDT_FLOAT3), D3DVSD_REG(3, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"plane.vso", &m_dwPlaneVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"plane.pso", &m_dwPlanePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } D3DXMATRIX Rx, Tz; D3DXMatrixRotationX(&Rx, D3DX_PI*0.5f); D3DXMatrixTranslation(&Tz, 0.0f, -3.0f, 0.0f); m_mtPlaneWorld = Rx * Tz; ID3DXMesh* occluder; CreateOccluder(m_spDevice.get(), &occluder); IDirect3DVertexBuffer8* vbOccluder; IDirect3DIndexBuffer8* ibOccluder; occluder->GetVertexBuffer(&vbOccluder); occluder->GetIndexBuffer(&ibOccluder); m_spOccluderVB.reset(vbOccluder, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spOccluderIB.reset(ibOccluder, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwOccluderNumVertices = occluder->GetNumVertices(); m_dwOccluderNumFaces = occluder->GetNumFaces(); occluder->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"occluder.vso", &m_dwOccluderVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"occluder.pso", &m_dwOccluderPSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cOccluderTint = { 0.3f, 0.0f, 0.8f, 1.0f }; D3DXMATRIX Rz, T; D3DXMatrixTranslation(&T, 5.1f * cosf(0.5), 0.0f, 5.1f * sinf(0.5)); D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtOccluderWorld = T * Rz; ID3DXMesh* volume; CreateVolume(m_spDevice.get(), &volume); IDirect3DVertexBuffer8* vbVolume; IDirect3DIndexBuffer8* ibVolume; volume->GetVertexBuffer(&vbVolume); volume->GetIndexBuffer(&ibVolume); m_spVolumeVB.reset(vbVolume, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spVolumeIB.reset(ibVolume, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwVolumeNumVertices = volume->GetNumVertices(); m_dwVolumeNumFaces = volume->GetNumFaces(); volume->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"volume.vso", &m_dwVolumeVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"volume.pso", &m_dwVolumePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cVolumeTint = { 0.7f, 0.0f, 0.0f, 1.0f }; D3DXMATRIX Sx; D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixScaling(&Sx, 6.0f, 1.0f, 1.0f); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtVolumeWorld = Sx * Rz; return S_OK; }
void CMeshConverter::OptimiseGraphicsObject(void) { int i; int j; ID3DXMesh* pXMesh; CGraphicsPrimitive* pcPrimitive; CVertexBufferExtended* psVertexBuffer; void* pvDestIndexBuffer; void* pvDestVertexBuffer; void* pvSrcIndexBuffer; void* pvSrcVertexBuffer; int iVertSize; DWORD* pvAdjacency; int iPrimitiveStart; int iOldVertSize; int iNumIndices; int iOldVertexBufferIndex; int iNumTriangles; void* pvDestBaseIndexBuffer; SIndexBuffer* psIndexBuffer; DWORD iMeshOptions; mpcGraphicsObject->SortPrimitives(); mpcGraphicsObject->Lock(); psIndexBuffer = mpcGraphicsObject->GetIndexBuffer(); iVertSize = 0; iNumIndices = 0; iOldVertexBufferIndex = 0; iNumTriangles = 0; iOldVertSize = 0; iMeshOptions = D3DXMESH_SYSTEMMEM; SetFlag((int*)&iMeshOptions, D3DXMESH_32BIT, psIndexBuffer->iIndexSize == 4); for (i = 0; i < mpcGraphicsObject->GetNumPrimitives(); i++) { pcPrimitive = mpcGraphicsObject->GetPrimitive(i); psVertexBuffer = mpcGraphicsObject->GetVertexBufferForIndex(pcPrimitive->miVertexBufferIndex); if (iOldVertSize != psVertexBuffer->iVertexSize) { if (iNumIndices != 0) { gcD3D.CreateMesh(iNumTriangles, iNumIndices, iMeshOptions, psVertexBuffer->iVertexFormat, &pXMesh); iVertSize = pXMesh->GetNumBytesPerVertex(); pXMesh->LockIndexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestBaseIndexBuffer); pXMesh->LockVertexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestVertexBuffer); psVertexBuffer = mpcGraphicsObject->GetVertexBufferForIndex(iOldVertexBufferIndex); pvSrcVertexBuffer = psVertexBuffer->pvLockedBuffer; if (iVertSize != psVertexBuffer->iVertexSize) { gcLogger.Error("D3DX vertex size differs from expected size"); break; } memcpy(pvDestVertexBuffer, pvSrcVertexBuffer, psVertexBuffer->iVertexSize * psVertexBuffer->iNumVerticies); pvDestIndexBuffer = pvDestBaseIndexBuffer; for (j = iPrimitiveStart; j < i; j++) { pcPrimitive = mpcGraphicsObject->GetPrimitive(j); pvSrcIndexBuffer = RemapSinglePointer(psIndexBuffer->pvLockedBuffer, 2 * pcPrimitive->miStartIndex); memcpy(pvDestIndexBuffer, pvSrcIndexBuffer, psIndexBuffer->iIndexSize * pcPrimitive->miNumVertices); pvDestIndexBuffer = RemapSinglePointer(pvDestIndexBuffer, pcPrimitive->miNumVertices); } pvAdjacency = (DWORD*)malloc(pcPrimitive->miNumPrimitives * 3 * sizeof(DWORD)); pXMesh->GenerateAdjacency(0.0f, pvAdjacency); pXMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DONOTSPLIT, pvAdjacency, NULL, NULL, NULL); free(pvAdjacency); pvDestIndexBuffer = pvDestBaseIndexBuffer; for (j = iPrimitiveStart; j < i; j++) { pcPrimitive = mpcGraphicsObject->GetPrimitive(j); pvSrcIndexBuffer = RemapSinglePointer(psIndexBuffer->pvLockedBuffer, 2 * pcPrimitive->miStartIndex); memcpy(pvSrcIndexBuffer, pvDestIndexBuffer, psIndexBuffer->iIndexSize * pcPrimitive->miNumVertices); pvDestIndexBuffer = RemapSinglePointer(pvDestIndexBuffer, pcPrimitive->miNumVertices); } memcpy(pvSrcVertexBuffer, pvDestVertexBuffer, psVertexBuffer->iVertexSize * psVertexBuffer->iNumVerticies); pXMesh->UnlockIndexBuffer(); pXMesh->UnlockVertexBuffer(); pXMesh->Release(); } iPrimitiveStart = i; iNumIndices = 0; iOldVertexBufferIndex = pcPrimitive->miVertexBufferIndex; } else { iNumIndices += pcPrimitive->miNumVertices; iNumTriangles += pcPrimitive->miNumPrimitives; if (iOldVertexBufferIndex != pcPrimitive->miVertexBufferIndex) { gcUserError.Set("Primitive vertex buffer index is F****D!"); break; } } } mpcGraphicsObject->Unlock(); }
ID3DXMesh* CMesh::createD3DXMesh() const { HRESULT hr; ID3DXMesh* dxMesh = 0; DWORD meshOpts = D3DXMESH_MANAGED; if( getIndexStride() == 4 ) meshOpts |= D3DXMESH_32BIT; // get declaration D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; UINT numElements; getVertexDecl().getObject()->GetDeclaration( decl, &numElements ); // create mesh hr = D3DXCreateMesh( getIndexCount()/3, getVertexCount(), meshOpts, decl, &CD3DDevice::getInstance().getDevice(), &dxMesh ); if( FAILED(hr) ) return NULL; // copy VB { const void* srcVB = lockVBRead(); void* dxVB = 0; hr = dxMesh->LockVertexBuffer( 0, &dxVB ); if( FAILED(hr) ) { dxMesh->Release(); return NULL; } memcpy( dxVB, srcVB, getVertexCount() * getVertexStride() ); hr = dxMesh->UnlockVertexBuffer(); unlockVBRead(); } // copy IB { const void* srcIB = lockIBRead(); void* dxIB = 0; hr = dxMesh->LockIndexBuffer( 0, &dxIB ); if( FAILED(hr) ) { dxMesh->Release(); return NULL; } memcpy( dxIB, srcIB, getIndexCount() * getIndexStride() ); hr = dxMesh->UnlockIndexBuffer(); unlockIBRead(); } // copy groups { int ngroups = getGroupCount(); D3DXATTRIBUTERANGE* attrs = new D3DXATTRIBUTERANGE[ngroups]; DWORD* attrBuf = 0; hr = dxMesh->LockAttributeBuffer( 0, &attrBuf ); if( FAILED(hr) ) { dxMesh->Release(); return NULL; } for( int g = 0; g < ngroups; ++g ) { attrs[g].AttribId = g; const CMesh::CGroup& group = getGroup(g); attrs[g].VertexStart = group.getFirstVertex(); attrs[g].VertexCount = group.getVertexCount(); attrs[g].FaceStart = group.getFirstPrim(); attrs[g].FaceCount = group.getPrimCount(); for( int f = 0; f < group.getPrimCount(); ++f ) *attrBuf++ = g; } dxMesh->UnlockAttributeBuffer(); hr = dxMesh->SetAttributeTable( attrs, ngroups ); delete[] attrs; } return dxMesh; }
bool CMeshBundle::loadMesh( const CResourceId& id, const CResourceId& fullName, CMesh& mesh ) const { // try to load with D3DX // obsolete case: .X files if( CStringHelper::endsWith( fullName.getUniqueName(), ".x" ) || CStringHelper::endsWith( fullName.getUniqueName(), ".X" ) ) { ID3DXBuffer* adjancency = NULL; ID3DXBuffer* material = NULL; ID3DXBuffer* effects = NULL; DWORD matCount; ID3DXMesh* dxmesh = NULL; HRESULT hres = D3DXLoadMeshFromX( fullName.getUniqueName().c_str(), D3DXMESH_SYSTEMMEM, &CD3DDevice::getInstance().getDevice(), &adjancency, &material, &effects, &matCount, &dxmesh ); if( !SUCCEEDED( hres ) ) return false; assert( dxmesh ); if( adjancency ) adjancency->Release(); if( material ) material->Release(); if( effects ) effects->Release(); // // init our mesh assert( !mesh.isCreated() ); // HACK - very limited int formatFlags = 0; DWORD dxFormat = dxmesh->GetFVF(); if( dxFormat & D3DFVF_XYZ ) formatFlags |= CVertexFormat::V_POSITION; if( dxFormat & D3DFVF_NORMAL ) formatFlags |= CVertexFormat::V_NORMAL; if( dxFormat & D3DFVF_TEX1 ) formatFlags |= CVertexFormat::V_UV0_2D; CVertexFormat vertFormat( formatFlags ); // HACK int indexStride = 2; CD3DVertexDecl* vertDecl = RGET_VDECL( CVertexDesc( vertFormat ) ); mesh.createResource( dxmesh->GetNumVertices(), dxmesh->GetNumFaces()*3, vertFormat, indexStride, *vertDecl, CMesh::BUF_STATIC ); // // now, copy data into our mesh void *dxvb, *dxib; dxmesh->LockVertexBuffer( 0, &dxvb ); dxmesh->LockIndexBuffer( 0, &dxib ); void* myvb = mesh.lockVBWrite(); void* myib = mesh.lockIBWrite(); memcpy( myvb, dxvb, mesh.getVertexCount() * mesh.getVertexStride() ); memcpy( myib, dxib, mesh.getIndexCount() * mesh.getIndexStride() ); dxmesh->UnlockVertexBuffer(); dxmesh->UnlockIndexBuffer(); mesh.unlockVBWrite(); mesh.unlockIBWrite(); // // create groups int ngroups; dxmesh->GetAttributeTable( 0, (DWORD*)&ngroups ); D3DXATTRIBUTERANGE *attrs = new D3DXATTRIBUTERANGE[ngroups]; dxmesh->GetAttributeTable( attrs, (DWORD*)&ngroups ); for( int i = 0; i < ngroups; ++i ) { const D3DXATTRIBUTERANGE& a = attrs[i]; mesh.addGroup( CMesh::CGroup( a.VertexStart, a.VertexCount, a.FaceStart, a.FaceCount ) ); } delete[] attrs; // release d3dx mesh dxmesh->Release(); } else { // our own format assert( !mesh.isCreated() ); bool ok = CMeshSerializer::loadMeshFromFile( fullName.getUniqueName().c_str(), mesh ); if( !ok ) return false; } mesh.computeAABBs(); CONSOLE.write( "mesh loaded '" + id.getUniqueName() + "'" ); return true; }