HRESULT LoadMesh(IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh) { ID3DXMesh* pMesh = NULL; WCHAR str[MAX_PATH]; HRESULT hr; V_RETURN(DXUTFindDXSDKMediaFileCch(str, MAX_PATH, strFileName)); V_RETURN(D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh)); DWORD* rgdwAdjacency = NULL; if(!(pMesh->GetFVF() & D3DFVF_NORMAL)) { ID3DXMesh* pTempMesh; V(pMesh->CloneMeshFVF(pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pd3dDevice, &pTempMesh)); V(D3DXComputeNormals(pTempMesh, NULL)); SAFE_RELEASE(pMesh); pMesh = pTempMesh; } rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3]; if(rgdwAdjacency == NULL) return E_OUTOFMEMORY; V(pMesh->GenerateAdjacency(1e-6f, rgdwAdjacency)); V(pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL)); delete []rgdwAdjacency; *ppMesh = pMesh; return S_OK; }
void DebugBox::CreateBox(float width, float height, float depth, uint8_t r, uint8_t g, uint8_t b, D3DVECTOR origin) { IDirect3DDevice9 *pDirect3DDevice = eae6320::Graphics::Context::getDirect3DDevice(); // Create the sphere mesh ID3DXMesh *pTempBoxMesh; ID3DXBuffer *pBoxBuffer; HRESULT result = D3DXCreateBox(pDirect3DDevice, width, height, depth, &pTempBoxMesh, &pBoxBuffer); assert(SUCCEEDED(result)); // Clone the mesh to allow color pTempBoxMesh->CloneMeshFVF(0, D3DFVF_XYZ | D3DFVF_DIFFUSE, pDirect3DDevice, &m_boxMesh); if (SUCCEEDED(m_boxMesh->GetVertexBuffer(&m_boxVertexBuffer))) { int nNumVerts = m_boxMesh->GetNumVertices(); sDebugVertex *pVertices = NULL; m_boxVertexBuffer->Lock(0, 0, (void**)&pVertices, 0); { for (int i = 0; i < nNumVerts; ++i) { pVertices[i].r = r; pVertices[i].g = g; pVertices[i].b = b; pVertices[i].a = 255; pVertices[i].x += origin.x; pVertices[i].y += origin.y; pVertices[i].z += origin.z; } } m_boxVertexBuffer->Unlock(); } }
MeshManager::MeshManager() { //Create main sphere to be used to draw spheres place by user //Create a temporary sphere first ID3DXMesh* tempSphere; HR(D3DXCreateSphere(gD3DDev, 1.0f, 10, 16, &tempSphere, 0)); //Clone temp sphere to the main sphere and give its vertices a color value HR(tempSphere->CloneMeshFVF( D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_DIFFUSE, gD3DDev, &m_mSphere )); //Release the temp sphere ReleaseCOM(tempSphere); }
//-------------------------------------------------------------------------------------- // This function loads the mesh and ensures the mesh has normals; it also optimizes the // mesh for the graphics card's vertex cache, which improves performance by organizing // the internal triangle list for less cache misses. //-------------------------------------------------------------------------------------- HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh ) { ID3DXMesh* pMesh = NULL; WCHAR str[MAX_PATH]; HRESULT hr; // Load the mesh with D3DX and get back a ID3DXMesh*. For this // sample we'll ignore the X file's embedded materials since we know // exactly the model we're loading. See the mesh samples such as // "OptimizedMesh" for a more generic mesh loading example. V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) ); V_RETURN( D3DXLoadMeshFromX( str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh ) ); DWORD* rgdwAdjacency = NULL; // Make sure there are normals which are required for lighting if( !( pMesh->GetFVF() & D3DFVF_NORMAL ) ) { ID3DXMesh* pTempMesh; V( pMesh->CloneMeshFVF( pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pd3dDevice, &pTempMesh ) ); V( D3DXComputeNormals( pTempMesh, NULL ) ); SAFE_RELEASE( pMesh ); pMesh = pTempMesh; } // Optimize the mesh for this graphics card's vertex cache // so when rendering the mesh's triangle list the vertices will // cache hit more often so it won't have to re-execute the vertex shader // on those vertices so it will improve perf. rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3]; if( rgdwAdjacency == NULL ) return E_OUTOFMEMORY; V( pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) ); V( pMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL ) ); delete []rgdwAdjacency; *ppMesh = pMesh; return S_OK; }
//-------------------------------------------------------------------------------------- //메쉬 불러오는 함수 //-------------------------------------------------------------------------------------- HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh ) { ID3DXMesh* pMesh = NULL; WCHAR str[MAX_PATH]; HRESULT hr; V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) ); V_RETURN( D3DXLoadMeshFromX( str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh ) ); DWORD* rgdwAdjacency = NULL; // mesh에 노말벡터 생성하는 코드 if( !( pMesh->GetFVF() & D3DFVF_NORMAL ) ) { ID3DXMesh* pTempMesh; V( pMesh->CloneMeshFVF( pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pd3dDevice, &pTempMesh ) ); V( D3DXComputeNormals( pTempMesh, NULL ) ); SAFE_RELEASE( pMesh ); pMesh = pTempMesh; } //성능 향상을 도모하고자 인접 정보를 기록 //각 mesh(삼각형) 정보 테이블을 가지는 형태 //해당 정보는 pMesh가 가지고 있음 //각 mesh 정보는 인접할 수 있는 점의 최대 개수가 3개 이내임을 활용해 효율적으로 vertex 운영 rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3]; if( rgdwAdjacency == NULL ) return E_OUTOFMEMORY; V( pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) ); //버텍스 캐쉬를 활용하는 것 V( pMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL ) ); delete []rgdwAdjacency; //callback out 변수에 최종 값 저장 *ppMesh = pMesh; return S_OK; }
// 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; }
HRESULT FaceHierarchyLoader::CreateMeshContainer(LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer) { ID3DXMesh* pSrcMesh = pMeshData->pMesh; D3DXMESHCONTAINER* pContainer = new D3DXMESHCONTAINER(); memset(pContainer, 0, sizeof(D3DXMESHCONTAINER)); pSrcMesh->CloneMeshFVF(pSrcMesh->GetOptions(), pSrcMesh->GetFVF(), g_pDevice, &pContainer->MeshData.pMesh); *ppNewMeshContainer = pContainer; return S_OK; }
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 ); }
// 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; }