void CCubeTexture::Load() { IDirect3DCubeTexture9* tex; if(D3DXCreateCubeTextureFromFileA(((CD3DRenderer*)g_Renderer)->GetDevice(), mUrl.Name.c_str(), &tex) != S_OK) { LogErrorAlways("Failed to load cube texture data from %s", mUrl.Name.c_str()); throw ResourceException("Resource loading failed"); } mTexture = tex; // Reload params D3DSURFACE_DESC desc; memset(&desc, 0, sizeof(D3DSURFACE_DESC)); HR(tex->GetLevelDesc(0, &desc)); mSurfaceDesc.Width = desc.Width; mSurfaceDesc.Height = desc.Height; mSurfaceDesc.Format = FromDXFormat(desc.Format); mSurfaceDesc.Type = SFC_CUBETEXTURE; }
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; }