//------------------------------------------------------------- // Name: RestoreDeviceObjects() // Desc: 화면크기가 변했을때 호출됨 // 확보한 메모리는 InvalidateDeviceObjects()에서 해제 //------------------------------------------------------------- HRESULT CMyD3DApplication::RestoreDeviceObjects() { // 이펙트 if(m_pEffect) m_pEffect->OnResetDevice(); // 메시 m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice ); //--------------------------------------------------------- // FVF로 처리하지 않은 정점선언은 직접 처리 //--------------------------------------------------------- if( m_pMesh && m_pMesh->GetSysMemMesh() ){ LPD3DXMESH pMesh; m_pMesh->GetSysMemMesh()->CloneMesh( m_pMesh->GetSysMemMesh()->GetOptions(), decl, m_pd3dDevice, &pMesh ); D3DXComputeNormals( pMesh, NULL ); D3DXComputeTangent( pMesh, 0, 0, 0, TRUE, NULL ); SAFE_RELEASE(m_pMesh->m_pLocalMesh); m_pMesh->m_pLocalMesh = pMesh; } // 렌더링 상태설정 RS( D3DRS_ZENABLE, TRUE ); RS( D3DRS_LIGHTING, FALSE ); SAMP( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); SAMP( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); SAMP( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); SAMP( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); // 뷰행렬 D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f ); D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec ); // 투영행렬 FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height; D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f ); // 폰트 m_pFont->RestoreDeviceObjects(); return S_OK; }
HRESULT RacorX8::LoadXFile(const LPSTR name) { HRESULT hr; LPD3DXMESH pMesh, pClone; if (FAILED(D3DXLoadMeshFromX(name, D3DXMESH_SYSTEMMEM, m_spDevice.get(), NULL, NULL, NULL, &pMesh))) { MessageBox(m_hWnd, L"D3DXLoadMeshFromX failed!", L"Error", 0); return E_FAIL; } hr = pMesh->CloneMeshFVF(D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE3(1), m_spDevice.get(), &pClone); if (FAILED(hr)) { MessageBox(m_hWnd, L"CloneMeshFVF failed!", L"Error", 0); return E_FAIL; } hr = D3DXComputeTangent(pMesh, 0, pClone, 1, D3DX_COMP_TANGENT_NONE, TRUE, NULL); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXComputeTangent failed!", L"Error", 0); return E_FAIL; } IDirect3DIndexBuffer8* ib; hr = pClone->GetIndexBuffer(&ib); m_spIB.reset(ib, [](IDirect3DIndexBuffer8* ib){ib->Release(); }); IDirect3DVertexBuffer8* vb; hr = pClone->GetVertexBuffer(&vb); m_spVB.reset(vb, [](IDirect3DVertexBuffer8* vb){vb->Release(); }); m_iNumTriangles = pClone->GetNumFaces(); m_iNumVertices = pClone->GetNumVertices(); pMesh->Release(); pClone->Release(); return S_OK; }
//------------------------------------------------------------- // Name: RestoreDeviceObjects() // Desc: ȭ��ũ�Ⱑ �������� ȣ��� // Ȯ���� �� InvalidateDeviceObjects()���� ���� //------------------------------------------------------------- HRESULT CMyD3DApplication::RestoreDeviceObjects() { HRESULT hr; //--------------------------------------------------------- // ����� ������ HDR ���� ������Ÿ�� //--------------------------------------------------------- hr = m_pd3dDevice->CreateTexture( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_pTexScene, NULL); if( FAILED(hr) ) return hr; hr = m_pTexScene->GetSurfaceLevel( 0, &m_pSurfScene ); if( FAILED(hr) ) return hr; //--------------------------------------------------------- // ��ҹ��� //--------------------------------------------------------- // ��ҹ����� �⺻ũ��(4�� ���) m_dwCropWidth = m_d3dsdBackBuffer.Width - m_d3dsdBackBuffer.Width % 4; m_dwCropHeight = m_d3dsdBackBuffer.Height - m_d3dsdBackBuffer.Height % 4; hr = m_pd3dDevice->CreateTexture( m_dwCropWidth / 4, m_dwCropHeight / 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_pTexSceneScaled, NULL); if( FAILED(hr) ) return hr; hr = m_pTexSceneScaled->GetSurfaceLevel( 0, &m_pSurfSceneScaled ); if( FAILED(hr) ) return hr; //--------------------------------------------------------- // �ֵ����� //--------------------------------------------------------- hr = m_pd3dDevice->CreateTexture( m_dwCropWidth / 4 + 2, m_dwCropHeight / 4 + 2, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTexBrightPass, NULL); if( FAILED(hr) ) return hr; hr = m_pTexBrightPass->GetSurfaceLevel( 0, &m_pSurfBrightPass ); if( FAILED(hr) ) return hr; // �ֺ��θ� �˰�ĥ�Ѵ� m_pd3dDevice->ColorFill( m_pSurfBrightPass, NULL , D3DCOLOR_ARGB(0, 0, 0, 0) ); //--------------------------------------------------------- // ������ �ʵ��� �帴�ϰ� ������ �ؽ�ó //--------------------------------------------------------- hr = m_pd3dDevice->CreateTexture( m_dwCropWidth / 4 + 2, m_dwCropHeight / 4 + 2, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTexStarSource, NULL); if( FAILED(hr) ) return hr; hr = m_pTexStarSource->GetSurfaceLevel( 0, &m_pSurfStarSource ); if( FAILED(hr) ) return hr; // �ֺ��θ� �˰�ĥ�Ѵ� m_pd3dDevice->ColorFill( m_pSurfStarSource, NULL , D3DCOLOR_ARGB(0, 0, 0, 0) ); //--------------------------------------------------------- // �����ؽ�ó //--------------------------------------------------------- for(int i=0; i < NUM_STAR_TEXTURES; i++ ) { hr = m_pd3dDevice->CreateTexture( m_dwCropWidth /4, m_dwCropHeight / 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_apTexStar[i], NULL ); if( FAILED(hr) ) return hr; hr = m_apTexStar[i]->GetSurfaceLevel( 0, &m_apSurfStar[i] ); if( FAILED(hr) ) return hr; } // ����Ʈ if(m_pEffect) m_pEffect->OnResetDevice(); // �� m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice ); //--------------------------------------------------------- // ������ ó�� //--------------------------------------------------------- if( m_pMesh && m_pMesh->GetSysMemMesh() ){ LPD3DXMESH pMesh; m_pMesh->GetSysMemMesh()->CloneMesh( m_pMesh->GetSysMemMesh()->GetOptions(), decl, m_pd3dDevice, &pMesh ); D3DXComputeNormals( pMesh, NULL ); D3DXComputeTangent( pMesh, 0, 0, 0, TRUE, NULL ); SAFE_RELEASE(m_pMesh->m_pLocalMesh); m_pMesh->m_pLocalMesh = pMesh; } // ������ ���¼��� RS( D3DRS_ZENABLE, TRUE ); RS( D3DRS_LIGHTING, FALSE ); // ����� D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f ); D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec ); // ������� FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height; D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f ); // ��Ʈ m_pFont->RestoreDeviceObjects(); return S_OK; }
//**関数*************************************************************************** // メッシュ初期化 //********************************************************************************* bool CMesh::Initialize(LPCTSTR pszFName) { TCHAR szMsg[MAX_PATH + 32]; TCHAR szDir[_MAX_DIR]; TCHAR szCurrentDir[_MAX_PATH]; LPD3DXBUFFER pD3DXMtrlBuffer = NULL; // フォルダ名を抽出 _tsplitpath(pszFName, NULL, szDir, NULL, NULL); // Xファイルからメッシュデータを読み込む HRESULT hr = D3DXLoadMeshFromX(pszFName, D3DXMESH_SYSTEMMEM, CGraphics::GetDevice(), NULL, &pD3DXMtrlBuffer, NULL, &m_dwNumMaterial, &m_pD3DMesh); if (FAILED(hr)) { _stprintf(szMsg, _T("Xファイル(%s)の読み込みに失敗しました。"), pszFName); MessageBox(NULL, szMsg, NULL, MB_OK); return false; } // FVF形式を補正(頂点フォーマットを変換) LPD3DXMESH pMeshTmp; DWORD dwFVF = m_pD3DMesh->GetFVF(); if (dwFVF != FVF_BVERTEX) { hr = m_pD3DMesh->CloneMeshFVF(m_pD3DMesh->GetOptions(), FVF_BVERTEX, CGraphics::GetDevice(), &pMeshTmp); SAFE_RELEASE(m_pD3DMesh); if (FAILED(hr)) { SAFE_RELEASE(pD3DXMtrlBuffer); return false; } // 法線が無い場合は強制的に追加 if ((dwFVF & D3DFVF_NORMAL) == 0) { D3DXComputeNormals(pMeshTmp, NULL); } m_pD3DMesh = pMeshTmp; } // 接ベクトルがない場合は強制的に追加 D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]; D3DVERTEXELEMENT9 End = D3DDECL_END(); int iElem; m_pD3DMesh->GetDeclaration(Declaration); BOOL bHasTangents = FALSE; for (iElem = 0; Declaration[iElem].Stream != End.Stream; iElem++) { if (Declaration[iElem].Usage == D3DDECLUSAGE_TANGENT) { bHasTangents = TRUE; break; } } // Update Mesh Semantics if changed if (!bHasTangents) { Declaration[iElem].Stream = 0; Declaration[iElem].Offset = (WORD)m_pD3DMesh->GetNumBytesPerVertex(); Declaration[iElem].Type = D3DDECLTYPE_FLOAT3; Declaration[iElem].Method = D3DDECLMETHOD_DEFAULT; Declaration[iElem].Usage = D3DDECLUSAGE_TANGENT; Declaration[iElem].UsageIndex = 0; Declaration[iElem+1] = End; LPD3DXMESH pTempMesh; hr = m_pD3DMesh->CloneMesh(D3DXMESH_MANAGED, Declaration, CGraphics::GetDevice() , &pTempMesh); if (SUCCEEDED(hr)) { SAFE_RELEASE(m_pD3DMesh); m_pD3DMesh = pTempMesh; //hr = D3DXComputeTangent(m_pMesh, 0, 0, D3DX_DEFAULT, TRUE, NULL); hr = D3DXComputeTangent(m_pD3DMesh , 0, 0, D3DX_DEFAULT, FALSE, NULL); } } // 属性テーブルを生成するための最適化 hr = m_pD3DMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshTmp); if (SUCCEEDED(hr)) { m_pD3DMesh->Release(); m_pD3DMesh = pMeshTmp; } else { SAFE_RELEASE(pD3DXMtrlBuffer); return false; } // 属性テーブル取得 hr = m_pD3DMesh->GetAttributeTable(NULL, &m_dwAttr); if (FAILED(hr)) { SAFE_RELEASE(pD3DXMtrlBuffer); SAFE_RELEASE(m_pD3DMesh); return false; } m_pAttr = new D3DXATTRIBUTERANGE[m_dwAttr]; hr = m_pD3DMesh->GetAttributeTable(m_pAttr, &m_dwAttr); // 頂点バッファ/インデックスバッファ固定 LPVOID pVtx; m_pD3DMesh->LockVertexBuffer(D3DLOCK_READONLY, &pVtx); LPVOID pIdx; m_pD3DMesh->LockIndexBuffer(D3DLOCK_READONLY, &pIdx); // 抽出場所の確保 m_dwVtx = m_pD3DMesh->GetNumVertices(); m_pVtx = new BVERTEX[m_dwVtx]; m_dwFace = m_pD3DMesh->GetNumFaces(); m_dwIdx = m_dwFace * 3; m_pIdx = new WORD[m_dwIdx]; m_pPiece = new PARTICLE[m_dwFace]; m_pPieceVtx = new BVERTEX[m_dwIdx]; // コピー CopyMemory(m_pVtx, pVtx, sizeof(BVERTEX) * m_dwVtx); CopyMemory(m_pIdx, pIdx, sizeof(WORD) * m_dwIdx); // 頂点バッファ/インデックスバッファ解放 m_pD3DMesh->UnlockVertexBuffer(); m_pD3DMesh->UnlockIndexBuffer(); // カレントディレクトリを変更 if (szDir[0]) { GetCurrentDirectory(_MAX_PATH, szCurrentDir); SetCurrentDirectory(szDir); } // マテリアル読み込み D3DXMATERIAL* pD3DMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); m_pMaterial = new D3DMATERIAL9[m_dwNumMaterial]; m_ppTexture = new LPDIRECT3DTEXTURE9[m_dwNumMaterial]; for (DWORD i = 0; i < m_dwNumMaterial; i++) { m_pMaterial[i] = pD3DMaterials[i].MatD3D; m_pMaterial[i].Ambient = m_pMaterial[i].Diffuse; m_ppTexture[i] = NULL; if (pD3DMaterials[i].pTextureFilename && pD3DMaterials[i].pTextureFilename[0]) { // テクスチャファイルを読み込む if (FAILED(D3DXCreateTextureFromFileA(CGraphics::GetDevice(), pD3DMaterials[i].pTextureFilename, &m_ppTexture[i]))) { _stprintf(szMsg, _T("テクスチャ(%hs)の読み込みに失敗しました。"), pD3DMaterials[i].pTextureFilename); MessageBox(NULL, szMsg, NULL, MB_OK); } } } // カレントディレクトリを元に戻す if (szDir[0]) SetCurrentDirectory(szCurrentDir); pD3DXMtrlBuffer->Release(); // 境界ボックス生成 D3DXVECTOR3 vMin = m_pVtx[0].pos; D3DXVECTOR3 vMax = vMin; BVERTEX* pBVtx = m_pVtx + 1; for (DWORD i = 1; i < m_dwVtx; i++, pBVtx++) { if (vMin.x > pBVtx->pos.x) vMin.x = pBVtx->pos.x; if (vMin.y > pBVtx->pos.y) vMin.y = pBVtx->pos.y; if (vMin.z > pBVtx->pos.z) vMin.z = pBVtx->pos.z; if (vMax.x < pBVtx->pos.x) vMax.x = pBVtx->pos.x; if (vMax.y < pBVtx->pos.y) vMax.y = pBVtx->pos.y; if (vMax.z < pBVtx->pos.z) vMax.z = pBVtx->pos.z; } m_vHalf = (vMax - vMin) / 2.0f; m_vCenter = (vMax + vMin) / 2.0f; // 境界球の生成 m_fRadius = 0.0f; float fR; for (DWORD i = 0; i < m_dwVtx; i++) { fR = D3DXVec3Length(&(m_pVtx[i].pos - m_vCenter)); if (m_fRadius < fR) m_fRadius = fR; } // 境界球イメージの生成 D3DXCreateSphere(CGraphics::GetDevice(), m_fRadius, 32, 16, &m_pSphere, NULL); // OBB生成 float fWidth = vMax.x - vMin.x; float fHeight = vMax.y - vMin.y; float fDepth = vMax.z - vMin.z; m_vOBBHalf.x = fWidth / 2.0f; m_vOBBHalf.y = fHeight / 2.0f; m_vOBBHalf.z = fDepth / 2.0f; // OBBイメージの生成 D3DXCreateBox(CGraphics::GetDevice() , fWidth , fHeight , fDepth , &m_pBox , NULL); return true; }
/** * \brief callback called when a mesh data is encountered during the .x file load * \param Name - name of the Mesh (const char*) * \param meshData - the mesh data * \param materials - material array * \param effectInstances - effect files / settings for the mesh * \param numMaterials - number of materials in the mesh * \param adjacency - adjacency array * \param pSkinInfo - skin info. * \param retNewMeshContainer - output pointer to assign our newly created mesh container * \return success code * \author Keith Ditchburn \date 17 July 2005 */ HRESULT CMeshHierarchy::CreateMeshContainer( LPCSTR Name, CONST D3DXMESHDATA *meshData, CONST D3DXMATERIAL *materials, CONST D3DXEFFECTINSTANCE *effectInstances, DWORD numMaterials, CONST DWORD *adjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER* retNewMeshContainer) { // Create a mesh container structure to fill and initilaise to zero values // Note: I use my extended version of the structure (D3DXMESHCONTAINER_EXTENDED) defined in MeshStructures.h D3DXMESHCONTAINER_EXTENDED *newMeshContainer=new D3DXMESHCONTAINER_EXTENDED; ZeroMemory(newMeshContainer, sizeof(D3DXMESHCONTAINER_EXTENDED)); // Always a good idea to initialise return pointer before proceeding *retNewMeshContainer = 0; // The mesh name (may be 0) needs copying over if (Name && strlen(Name)) { newMeshContainer->Name=CUtility::DuplicateCharString(Name); CUtility::DebugString("Added mesh: "+ToString(Name)+"\n"); } else { CUtility::DebugString("Added Mesh: no name given\n"); } // The mesh type (D3DXMESHTYPE_MESH, D3DXMESHTYPE_PMESH or D3DXMESHTYPE_PATCHMESH) if (meshData->Type!=D3DXMESHTYPE_MESH) { // This demo does not handle mesh types other than the standard // Other types are D3DXMESHTYPE_PMESH (progressive mesh) and D3DXMESHTYPE_PATCHMESH (patch mesh) DestroyMeshContainer(newMeshContainer); return E_FAIL; } newMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH; // Adjacency data - holds information about triangle adjacency, required by the ID3DMESH object DWORD dwFaces = meshData->pMesh->GetNumFaces(); newMeshContainer->pAdjacency = new DWORD[dwFaces*3]; memcpy(newMeshContainer->pAdjacency, adjacency, sizeof(DWORD) * dwFaces*3); // Get the Direct3D device, luckily this is held in the mesh itself (Note: must release it when done with it) LPDIRECT3DDEVICE9 pd3dDevice = 0; meshData->pMesh->GetDevice(&pd3dDevice); D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; meshData->pMesh->GetDeclaration(decl); HRESULT res; DWORD dwVertexStride = meshData->pMesh->GetNumBytesPerVertex (); DWORD dwNumDeclarations = 0; bool haveNormals = false; for (int i=0; (i < MAX_FVF_DECL_SIZE) && (decl[i].Stream != 0xFF); i++) { if (decl[dwNumDeclarations].Usage == D3DDECLUSAGE_NORMAL) haveNormals = true; if (decl[dwNumDeclarations].Usage == D3DDECLUSAGE_TANGENT) { dwNumDeclarations = 0; break; } dwNumDeclarations++; } if (dwNumDeclarations) { if (!haveNormals) { // normals decl[dwNumDeclarations].Stream = 0; decl[dwNumDeclarations].Offset = (WORD)dwVertexStride; decl[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3; decl[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT; decl[dwNumDeclarations].Usage = D3DDECLUSAGE_NORMAL; decl[dwNumDeclarations].UsageIndex = 0; dwVertexStride += sizeof(float)*3; dwNumDeclarations++; } // tangent decl[dwNumDeclarations].Stream = 0; decl[dwNumDeclarations].Offset = (WORD)dwVertexStride; decl[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3; decl[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT; decl[dwNumDeclarations].Usage = D3DDECLUSAGE_TANGENT; decl[dwNumDeclarations].UsageIndex = 0; dwNumDeclarations++; // ending element memset (&decl[dwNumDeclarations], 0, sizeof(D3DVERTEXELEMENT9)); decl[dwNumDeclarations].Stream = 0xFF; decl[dwNumDeclarations].Type = D3DDECLTYPE_UNUSED; } res = meshData->pMesh->CloneMesh(meshData->pMesh->GetOptions(),decl,pd3dDevice,&newMeshContainer->MeshData.pMesh); assert(res == D3D_OK); if (!haveNormals) { res = D3DXComputeNormals(newMeshContainer->MeshData.pMesh,newMeshContainer->pAdjacency); // compute normals assert(res == D3D_OK); } res = D3DXComputeTangent(newMeshContainer->MeshData.pMesh,0,0,1,TRUE,NULL); // compute tangent(u) assert(res == D3D_OK); //newMeshContainer->MeshData.pMesh=meshData->pMesh; newMeshContainer->MeshData.pMesh->AddRef(); // Create material and texture arrays. Note that I always want to have at least one newMeshContainer->NumMaterials = max(numMaterials,1); newMeshContainer->exMaterials = new D3DMATERIAL9[newMeshContainer->NumMaterials]; newMeshContainer->exTextures = new LPDIRECT3DTEXTURE9[newMeshContainer->NumMaterials]; ZeroMemory(newMeshContainer->exTextures, sizeof(LPDIRECT3DTEXTURE9) * newMeshContainer->NumMaterials); if (numMaterials>0) { // Load all the textures and copy the materials over for(DWORD i = 0; i < numMaterials; ++i) { newMeshContainer->exTextures[i] = 0; newMeshContainer->exMaterials[i]=materials[i].MatD3D; if(materials[i].pTextureFilename) { std::string texturePath(materials[i].pTextureFilename); if (CUtility::FindFile(&texturePath)) { // Use the D3DX function to load the texture if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, texturePath.c_str(), &newMeshContainer->exTextures[i]))) { CUtility::DebugString("Could not load texture: "+texturePath+"\n"); } } else { CUtility::DebugString("Could not find texture: "+ToString(materials[i].pTextureFilename)+"\n"); } } } } else // make a default material in the case where the mesh did not provide one { ZeroMemory(&newMeshContainer->exMaterials[0], sizeof( D3DMATERIAL9 ) ); newMeshContainer->exMaterials[0].Diffuse.r = 0.5f; newMeshContainer->exMaterials[0].Diffuse.g = 0.5f; newMeshContainer->exMaterials[0].Diffuse.b = 0.5f; newMeshContainer->exMaterials[0].Specular = newMeshContainer->exMaterials[0].Diffuse; newMeshContainer->exTextures[0]=0; } // If there is skin data associated with the mesh copy it over if (pSkinInfo) { // save off the SkinInfo newMeshContainer->pSkinInfo = pSkinInfo; pSkinInfo->AddRef(); // Need an array of offset matrices to move the vertices from the figure space to the bone's space UINT numBones = pSkinInfo->GetNumBones(); newMeshContainer->exBoneOffsets = new D3DXMATRIX[numBones]; // Create the arrays for the bones and the frame matrices newMeshContainer->exFrameCombinedMatrixPointer = new D3DXMATRIX*[numBones]; // get each of the bone offset matrices so that we don't need to get them later for (UINT i = 0; i < numBones; i++) newMeshContainer->exBoneOffsets[i] = *(newMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i)); CUtility::DebugString("Mesh has skinning info.\n Number of bones is: "+ToString(numBones)+"\n"); // Note: in the Microsoft samples a GenerateSkinnedMesh function is called here in order to prepare // the skinned mesh data for optimial hardware acceleration. As mentioned in the notes this sample // does not do hardware skinning but instead uses software skinning. } else { // No skin info so 0 all the pointers newMeshContainer->pSkinInfo = 0; newMeshContainer->exBoneOffsets = 0; newMeshContainer->exSkinMesh = 0; newMeshContainer->exFrameCombinedMatrixPointer = 0; } // When we got the device we caused an internal reference count to be incremented // So we now need to release it pd3dDevice->Release(); // The mesh may contain a reference to an effect file if (effectInstances) { if (effectInstances->pEffectFilename) CUtility::DebugString("This .x file references an effect file. Effect files are not handled by this demo\n"); } // Set the output mesh container pointer to our newly created one *retNewMeshContainer = newMeshContainer; return S_OK; }