MF_API void MFTexture_Unmap(MFTexture *pTexture, int element, int mipLevel) { switch(pTexture->type) { case MFTexType_1D: case MFTexType_2D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; pTex->UnlockRect(mipLevel); break; } case MFTexType_3D: { IDirect3DVolumeTexture9 *pTex = (IDirect3DVolumeTexture9*)pTexture->pInternalData; pTex->UnlockBox(mipLevel); break; } case MFTexType_Cubemap: { IDirect3DCubeTexture9 *pTex = (IDirect3DCubeTexture9*)pTexture->pInternalData; pTex->UnlockRect(gD3DCubeFaces[element], mipLevel); break; } } }
//----------------------------------------------------------------------------- HRESULT CDXUTMesh::CreateMaterials( LPCWSTR strPath, IDirect3DDevice9 *pd3dDevice, D3DXMATERIAL* d3dxMtrls, DWORD dwNumMaterials ) { // Get material info for the mesh // Get the array of materials out of the buffer m_dwNumMaterials = dwNumMaterials; if( d3dxMtrls && m_dwNumMaterials > 0 ) { // Allocate memory for the materials and textures m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials]; if( m_pMaterials == NULL ) return E_OUTOFMEMORY; m_pTextures = new LPDIRECT3DBASETEXTURE9[m_dwNumMaterials]; if( m_pTextures == NULL ) return E_OUTOFMEMORY; m_strMaterials = new CHAR[m_dwNumMaterials][MAX_PATH]; if( m_strMaterials == NULL ) return E_OUTOFMEMORY; // Copy each material and create its texture for( DWORD i=0; i<m_dwNumMaterials; i++ ) { // Copy the material m_pMaterials[i] = d3dxMtrls[i].MatD3D; m_pTextures[i] = NULL; // Create a texture if( d3dxMtrls[i].pTextureFilename ) { StringCchCopyA( m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename ); WCHAR strTexture[MAX_PATH]; WCHAR strTextureTemp[MAX_PATH]; D3DXIMAGE_INFO ImgInfo; // First attempt to look for texture in the same folder as the input folder. MultiByteToWideChar( CP_ACP, 0, d3dxMtrls[i].pTextureFilename, -1, strTextureTemp, MAX_PATH ); strTextureTemp[MAX_PATH-1] = 0; StringCchCopy( strTexture, MAX_PATH, strPath ); StringCchCat( strTexture, MAX_PATH, strTextureTemp ); // Inspect the texture file to determine the texture type. if( FAILED( D3DXGetImageInfoFromFile( strTexture, &ImgInfo ) ) ) { // Search the media folder if( FAILED( DXUTFindDXSDKMediaFileCch( strTexture, MAX_PATH, strTextureTemp ) ) ) continue; // Can't find. Skip. D3DXGetImageInfoFromFile( strTexture, &ImgInfo ); } // Call the appropriate loader according to the texture type. switch( ImgInfo.ResourceType ) { case D3DRTYPE_TEXTURE: { IDirect3DTexture9 *pTex; if( SUCCEEDED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) { // Obtain the base texture interface pTex->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i] ); // Release the specialized instance pTex->Release(); } break; } case D3DRTYPE_CUBETEXTURE: { IDirect3DCubeTexture9 *pTex; if( SUCCEEDED( D3DXCreateCubeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) { // Obtain the base texture interface pTex->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i] ); // Release the specialized instance pTex->Release(); } break; } case D3DRTYPE_VOLUMETEXTURE: { IDirect3DVolumeTexture9 *pTex; if( SUCCEEDED( D3DXCreateVolumeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) ) { // Obtain the base texture interface pTex->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i] ); // Release the specialized instance pTex->Release(); } break; } } } } } return S_OK; }
bool CAXModel::Load(const char* strFileName) { this->Unload(); m_strFile = strFileName; LPD3DXBUFFER pAdjacencyBuffer = NULL; LPD3DXBUFFER pMtrlBuffer = NULL; if (FAILED(D3DXLoadMeshFromXA(m_strFile.c_str(), D3DXMESH_MANAGED, APROJECT_WINDOW->GetD3DDevice(), &pAdjacencyBuffer, &pMtrlBuffer, NULL, &m_dwNumMaterials, &m_pMeshObject))) return false; // Optimize the mesh for performance if (FAILED(m_pMeshObject->OptimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL))) { SAFE_RELEASE(pAdjacencyBuffer); SAFE_RELEASE(pMtrlBuffer); return false; } D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer(); do { if (d3dxMtrls && m_dwNumMaterials > 0) { // Allocate memory for the materials and textures m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials]; if (m_pMaterials == NULL) break; m_pTextures = new LPDIRECT3DBASETEXTURE9[m_dwNumMaterials]; if (m_pTextures == NULL) break; m_strMaterials = new CHAR[m_dwNumMaterials][MAX_PATH]; if (m_strMaterials == NULL) break; // Copy each material and create its texture for (DWORD i = 0; i < m_dwNumMaterials; i++) { // Copy the material m_pMaterials[i] = d3dxMtrls[i].MatD3D; m_pTextures[i] = NULL; // Create a texture if (d3dxMtrls[i].pTextureFilename) { strcpy_s(m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename); CHAR strTexture[MAX_PATH]; D3DXIMAGE_INFO ImgInfo; // First attempt to look for texture in the same folder as the input folder. int p = 0; strcpy_s(strTexture, MAX_PATH, m_strFile.c_str()); for (DWORD j = 0; j < strlen(strTexture); j++) { if (strTexture[j] == '/') p = j; } strTexture[p + 1] = 0; strcat_s(strTexture, MAX_PATH, d3dxMtrls[i].pTextureFilename); // Inspect the texture file to determine the texture type. if (FAILED(D3DXGetImageInfoFromFileA(strTexture, &ImgInfo))) continue; // Call the appropriate loader according to the texture type. switch (ImgInfo.ResourceType) { case D3DRTYPE_TEXTURE: { IDirect3DTexture9* pTex; if (SUCCEEDED(D3DXCreateTextureFromFileA(APROJECT_WINDOW->GetD3DDevice(), strTexture, &pTex))) { pTex->QueryInterface(IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i]); pTex->Release(); } break; } case D3DRTYPE_CUBETEXTURE: { IDirect3DCubeTexture9* pTex; if (SUCCEEDED(D3DXCreateCubeTextureFromFileA(APROJECT_WINDOW->GetD3DDevice(), strTexture, &pTex))) { pTex->QueryInterface(IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i]); pTex->Release(); } break; } case D3DRTYPE_VOLUMETEXTURE: { IDirect3DVolumeTexture9* pTex; if (SUCCEEDED(D3DXCreateVolumeTextureFromFileA(APROJECT_WINDOW->GetD3DDevice(), strTexture, &pTex))) { pTex->QueryInterface(IID_IDirect3DBaseTexture9, (LPVOID*)&m_pTextures[i]); pTex->Release(); } break; } } } } } } while (0); // Extract data from m_pMesh for easy access D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; m_dwNumVertices = m_pMeshObject->GetNumVertices(); m_dwNumFaces = m_pMeshObject->GetNumFaces(); m_dwBytesPerVertex = m_pMeshObject->GetNumBytesPerVertex(); m_pMeshObject->GetIndexBuffer(&m_pIB); m_pMeshObject->GetVertexBuffer(&m_pVB); m_pMeshObject->GetDeclaration(decl); APROJECT_WINDOW->GetD3DDevice()->CreateVertexDeclaration(decl, &m_pDecl); SAFE_RELEASE(pAdjacencyBuffer); SAFE_RELEASE(pMtrlBuffer); return true; }
MF_API bool MFTexture_Map(MFTexture *pTexture, int element, int mipLevel, MFLockedTexture *pLock) { int numFaces = pTexture->type == MFTexType_Cubemap ? 6 : 1; MFDebug_Assert(element < numFaces, "Array textures not supported in D3D9!"); int s = mipLevel*pTexture->numElements + (element ? element : 0); MFTextureSurface &surface = pTexture->pSurfaces[s]; DWORD lockFlags = (pTexture->createFlags & MFTCF_TypeMask) == MFTCF_Scratch ? D3DLOCK_DISCARD : 0; switch(pTexture->type) { case MFTexType_1D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } case MFTexType_2D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } case MFTexType_3D: { IDirect3DVolumeTexture9 *pTex = (IDirect3DVolumeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DVOLUME_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height && (int)desc.Depth == surface.depth, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_BOX box; pTex->LockBox(mipLevel, &box, NULL, lockFlags); pLock->pData = box.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = box.RowPitch; pLock->sliceInBytes = box.SlicePitch; break; } case MFTexType_Cubemap: { IDirect3DCubeTexture9 *pTex = (IDirect3DCubeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(gD3DCubeFaces[element], mipLevel, &rect, NULL, lockFlags); pLock->pData = rect.pBits; pLock->width = surface.width; pLock->height = surface.height; pLock->depth = surface.depth; pLock->strideInBytes = rect.Pitch; pLock->sliceInBytes = rect.Pitch * surface.height; break; } } return true; }
MF_API bool MFTexture_Update(MFTexture *pTexture, int element, int mipLevel, const void *pData, size_t lineStride, size_t sliceStride) { int numFaces = pTexture->type == MFTexType_Cubemap ? 6 : 1; MFDebug_Assert(element < numFaces, "Array textures not supported in D3D9!"); int s = mipLevel*pTexture->numElements + (element > -1 ? element : 0); MFTextureSurface &surface = pTexture->pSurfaces[s]; DWORD lockFlags = (pTexture->createFlags & MFTCF_TypeMask) == MFTCF_Scratch ? D3DLOCK_DISCARD : 0; size_t lineBytes = (surface.bitsPerPixel * surface.width) / 8; if(lineStride == 0) lineStride = lineBytes; if(sliceStride == 0) sliceStride = lineStride * surface.width; switch(pTexture->type) { case MFTexType_1D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); MFCopyMemory(rect.pBits, pData, lineBytes); pTex->UnlockRect(mipLevel); break; } case MFTexType_2D: { IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(mipLevel, &rect, NULL, lockFlags); const char *pSrc = (const char*)pData; char *pDest = (char*)rect.pBits; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDest, pSrc, lineBytes); pDest += rect.Pitch; pSrc += lineStride; } pTex->UnlockRect(mipLevel); break; } case MFTexType_3D: { IDirect3DVolumeTexture9 *pTex = (IDirect3DVolumeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DVOLUME_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height && (int)desc.Depth == surface.depth, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_BOX box; pTex->LockBox(mipLevel, &box, NULL, lockFlags); MFCopyMemory(box.pBits, pData, surface.bufferLength); const char *pSrcSlice = (const char*)pData; char *pDestSlice = (char*)box.pBits; for(int d=0; d<surface.depth; ++d) { const char *pSrcLine = pSrcSlice; char *pDestLine = pDestSlice; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDestLine, pSrcLine, lineBytes); pDestLine += box.RowPitch; pSrcLine += lineStride; } pSrcSlice += sliceStride; pDestSlice += box.SlicePitch; } pTex->UnlockBox(mipLevel); break; } case MFTexType_Cubemap: { MFDebug_Assert(element != -1, "TODO: must handle setting all surfaces at once..."); IDirect3DCubeTexture9 *pTex = (IDirect3DCubeTexture9*)pTexture->pInternalData; #if defined(MF_DEBUG) D3DSURFACE_DESC desc; pTex->GetLevelDesc(mipLevel, &desc); MFDebug_Assert((int)desc.Width == surface.width && (int)desc.Height == surface.height, "D3D9 mip dimensions don't match the texture template data..."); #endif D3DLOCKED_RECT rect; pTex->LockRect(gD3DCubeFaces[element], mipLevel, &rect, NULL, lockFlags); const char *pSrc = (const char*)pData; char *pDest = (char*)rect.pBits; for(int i=0; i<surface.height; ++i) { MFCopyMemory(pDest, pSrc, lineBytes); pDest += rect.Pitch; pSrc += lineStride; } pTex->UnlockRect(gD3DCubeFaces[element], mipLevel); break; } } return true; }