// interface functions void MFTexture_CreatePlatformSpecific(MFTexture *pTexture, bool generateMipChain) { MFCALLSTACK; HRESULT hr; MFTextureTemplateData *pTemplate = pTexture->pTemplateData; // create texture D3DFORMAT platformFormat = (D3DFORMAT)MFTexture_GetPlatformFormatID(pTemplate->imageFormat, MFDD_D3D9); hr = D3DXCreateTexture(pd3dDevice, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, generateMipChain ? 0 : 1, 0, platformFormat, D3DPOOL_MANAGED, (IDirect3DTexture9**)&pTexture->pInternalData); MFDebug_Assert(hr != D3DERR_NOTAVAILABLE, MFStr("LoadTexture failed: D3DERR_NOTAVAILABLE, 0x%08X", hr)); MFDebug_Assert(hr != D3DERR_OUTOFVIDEOMEMORY, MFStr("LoadTexture failed: D3DERR_OUTOFVIDEOMEMORY, 0x%08X", hr)); MFDebug_Assert(hr != D3DERR_INVALIDCALL, MFStr("LoadTexture failed: D3DERR_INVALIDCALL, 0x%08X", hr)); MFDebug_Assert(hr != D3DXERR_INVALIDDATA, MFStr("LoadTexture failed: D3DXERR_INVALIDDATA, 0x%08X", hr)); MFDebug_Assert(hr == D3D_OK, MFStr("Failed to create texture '%s'.", pTexture->name)); IDirect3DTexture9 *pTex = (IDirect3DTexture9*)pTexture->pInternalData; // copy image data D3DLOCKED_RECT rect; pTex->LockRect(0, &rect, NULL, 0); MFCopyMemory(rect.pBits, pTemplate->pSurfaces[0].pImageData, pTemplate->pSurfaces[0].bufferLength); pTex->UnlockRect(0); // filter mip levels if(generateMipChain) D3DXFilterTexture(pTex, NULL, 0, D3DX_DEFAULT); }
virtual IDirect3DTexture9* createTexture() { IDirect3DTexture9* tex = CFixedTextureCreator::createTexture(); // create the offscreen surface HRESULT hr; CD3DDevice& dx = CD3DDevice::getInstance(); IDirect3DSurface9* srcSurf = 0; hr = dx.getDevice().CreateOffscreenPlainSurface( mGameMap->getCellsX(), mGameMap->getCellsY(), D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &srcSurf, NULL ); assert( SUCCEEDED(hr) ); D3DLOCKED_RECT lr; srcSurf->LockRect( &lr, NULL, D3DLOCK_DISCARD ); const char* linePtr = (const char*)lr.pBits; for( int y = 0; y < mGameMap->getCellsY(); ++y ) { D3DCOLOR* p = (D3DCOLOR*)linePtr; for( int x = 0; x < mGameMap->getCellsX(); ++x ) { const CGameMap::SCell& cell = mGameMap->getCell(x,y); *p = gColors.minimap[cell.color][cell.type]; ++p; } linePtr += lr.Pitch; } srcSurf->UnlockRect(); // now, filter this into the texture IDirect3DSurface9* dstSurf = 0; hr = tex->GetSurfaceLevel( 0, &dstSurf ); assert( SUCCEEDED(hr) ); hr = D3DXLoadSurfaceFromSurface( dstSurf, NULL, NULL, srcSurf, NULL, NULL, D3DX_FILTER_BOX, 0 ); dstSurf->Release(); srcSurf->Release(); D3DXFilterTexture( tex, NULL, 0, D3DX_FILTER_BOX ); return tex; }
///////////////////////////////////////////////////////////// /// Met à jour les pixels de la texture /// /// \param Rect : Rectangle à mettre à jour dans la texture /// //////////////////////////////////////////////////////////// void DX9Texture::Update(const CRectangle& Rect) { CA_ASSERT(CRectangle(0, 0, m_Size.x, m_Size.y).Intersects(Rect) == INT_IN, "DX9Texture::Update() : rectangle out of bounds"); // Si le format des pixels à copier est le même que celui de la texture on fait une simple copie, // sinon on effectue une conversion if (m_Format == m_Data.GetFormat()) { // Verrouillage de la texture D3DLOCKED_RECT LockedRect; RECT Lock = {Rect.Left(), Rect.Top(), Rect.Right(), Rect.Bottom()}; DXCheck(m_Texture->LockRect(0, &LockedRect, &Lock, 0)); // Copie des pixels UpdateSurface(LockedRect, Rect); // Déverrouillage de la texture m_Texture->UnlockRect(0); } else { // Récupération du device SmartPtr<IDirect3DDevice9, CResourceCOM> Device; m_Texture->GetDevice(&GetPtr(Device)); // Création d'une texture en mémoire système pour y copier les pixels SmartPtr<IDirect3DSurface9, CResourceCOM> Src; if (FAILED(Device->CreateOffscreenPlainSurface(Rect.Width(), Rect.Height(), DX9Enum::Get(m_Data.GetFormat()), D3DPOOL_SYSTEMMEM, &GetPtr(Src), nullptr))) throw DX9Exception("CreateOffscreenPlainSurface", "DX9Texture::Update"); // Verrouillage de la texture temporaire D3DLOCKED_RECT LockedRect; Src->LockRect(&LockedRect, nullptr, 0); // Copie des pixels UpdateSurface(LockedRect, Rect); // Déverrouillage de la texture temporaire Src->UnlockRect(); // Récupération de la surface de niveau 0 de la texture SmartPtr<IDirect3DSurface9, CResourceCOM> Dest; m_Texture->GetSurfaceLevel(0, &GetPtr(Dest)); // Copie de la surface Src sur la surface Dest (c'est ici qu'est effectuée la conversion de format) RECT DestRect = {Rect.Left(), Rect.Top(), Rect.Right(), Rect.Bottom()}; if (FAILED(D3DXLoadSurfaceFromSurface(Dest, nullptr, &DestRect, Src, nullptr, nullptr, D3DX_DEFAULT, 0))) throw DX9Exception("D3DXLoadSurfaceFromSurface", "DX9Texture::Update"); } // Génération des niveaux de mipmapping si nécessaire if (m_HasMipmaps) { if (m_AutoMipmaps) m_Texture->GenerateMipSubLevels(); else D3DXFilterTexture(m_Texture, nullptr, D3DX_DEFAULT, D3DX_DEFAULT); } }
void CD3D9Texture::Filter(int nSrcLevel, int nFilter) { D3DXFilterTexture( m_pd3dTexture, 0, // default palette 0, // use top level as source level D3DX_DEFAULT); // default filter }
//! Regenerates the mip map levels of the texture. Useful after locking and //! modifying the texture void CD3D8Texture::regenerateMipMapLevels(void* mipmapData) { if (mipmapData) { core::dimension2du size = TextureSize; u32 level=0; do { if (size.Width>1) size.Width /=2; if (size.Height>1) size.Height /=2; ++level; IDirect3DSurface8* mipSurface = 0; HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); if (FAILED(hr) || !mipSurface) { os::Printer::log("Could not get mipmap level", ELL_WARNING); return; } D3DSURFACE_DESC mipDesc; mipSurface->GetDesc(&mipDesc); D3DLOCKED_RECT miplr; // lock mipmap surface if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) { mipSurface->Release(); os::Printer::log("Could not lock texture", ELL_WARNING); return; } memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; // unlock mipSurface->UnlockRect(); // release mipSurface->Release(); } while (size.Width != 1 || size.Height != 1); } else if (HasMipMaps) { // create mip maps. #ifndef _IRR_USE_D3DXFilterTexture_ // The D3DXFilterTexture function seems to get linked wrong when // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. // So mipmapgeneration is replaced with my own bad generation in d3d 8 when // compiling with both D3D 8 and 9. HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); if (FAILED(hr)) #endif createMipMaps(); } }
static void test_D3DXFilterTexture(IDirect3DDevice9 *device) { IDirect3DTexture9 *tex; HRESULT hr; hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL); if (SUCCEEDED(hr)) { hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Last miplevel */ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 20, D3DX_FILTER_NONE); /* Invalid miplevel */ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); } else skip("Failed to create texture\n"); IDirect3DTexture9_Release(tex); hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE); ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); /* Test different pools */ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL); if (SUCCEEDED(hr)) { hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); IDirect3DTexture9_Release(tex); } else skip("Failed to create texture\n"); hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL); if (SUCCEEDED(hr)) { hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE); ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK); IDirect3DTexture9_Release(tex); } else skip("Failed to create texture\n"); }
// interface functions void MFTexture_CreatePlatformSpecific(MFTexture *pTexture, bool generateMipChain) { MFTextureTemplateData *pTemplate = pTexture->pTemplateData; // create texture D3DFORMAT platformFormat = (D3DFORMAT)MFTexture_GetPlatformFormatID(pTemplate->imageFormat, MFDD_XBOX); #if defined(XB_XGTEXTURES) pTexture->pTexture = &pTexture->texture; XGSetTextureHeader(pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, 1, 0, platformFormat, 0, pTexture->pTexture, 0, 0); pTexture->pTexture->Register(pTemplate->pSurfaces[0].pImageData); if(pTemplate->imageFormat >= TexFmt_XB_A8R8G8B8s && pTemplate->imageFormat <= TexFmt_XB_R4G4B4A4s) { XGSwizzleRect(pTemplate->pSurfaces[0].pImageData, 0, NULL, pTemplate->pSurfaces[0].pImageData, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, NULL, pTemplate->pSurfaces[0].bitsPerPixel/8); } #else HRESULT hr; hr = D3DXCreateTexture(pd3dDevice, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, generateMipChain ? 0 : 1, 0, platformFormat, 0, &pTexture->pTexture); MFDebug_Assert(hr != D3DERR_NOTAVAILABLE, MFStr("LoadTexture failed: D3DERR_NOTAVAILABLE, 0x%08X", hr)); MFDebug_Assert(hr != D3DERR_OUTOFVIDEOMEMORY, MFStr("LoadTexture failed: D3DERR_OUTOFVIDEOMEMORY, 0x%08X", hr)); MFDebug_Assert(hr != D3DERR_INVALIDCALL, MFStr("LoadTexture failed: D3DERR_INVALIDCALL, 0x%08X", hr)); MFDebug_Assert(hr != D3DXERR_INVALIDDATA, MFStr("LoadTexture failed: D3DXERR_INVALIDDATA, 0x%08X", hr)); MFDebug_Assert(hr == D3D_OK, MFStr("Failed to create texture '%s'.", pTexture->name)); // copy image data D3DLOCKED_RECT rect; pTexture->pTexture->LockRect(0, &rect, NULL, 0); if(pTemplate->imageFormat >= TexFmt_XB_A8R8G8B8s && pTemplate->imageFormat <= TexFmt_XB_R4G4B4A4s) { XGSwizzleRect(pTemplate->pSurfaces[0].pImageData, 0, NULL, rect.pBits, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, NULL, pTemplate->pSurfaces[0].bitsPerPixel/8); } else { MFCopyMemory(rect.pBits, pTemplate->pSurfaces[0].pImageData, pTemplate->pSurfaces[0].bufferLength); } pTexture->pTexture->UnlockRect(0); // filter mip levels if(generateMipChain) D3DXFilterTexture(pTexture->pTexture, NULL, 0, D3DX_DEFAULT); #endif }
/// <summary> /// Generates mipmaps if the specified texture has the levels to accommodate them. /// </summary> /// <param name="src">The DirectX texture to apply mipmaps to.</param> /// <param name="njs_texture">The Dremcast texture to receive the DirectX texture.</param> static void __fastcall GenerateMipmaps_c(IDirect3DTexture8* src, NJS_TEXMEMLIST* njs_texture) { if (src == nullptr || njs_texture == nullptr) return; if (blacklisted || src->GetLevelCount() > 1) goto ABORT; #ifndef PALLETIZED_MIPMAPS Uint32 format = njs_texture->texinfo.texsurface.PixelFormat; if (format == NJD_PIXELFORMAT_PALETTIZED_4BPP || format == NJD_PIXELFORMAT_PALETTIZED_8BPP) goto ABORT; #endif HRESULT result; D3DSURFACE_DESC info; result = src->GetLevelDesc(0, &info); if (!SUCCEEDED(result)) goto ABORT; IDirect3DTexture8* dest; result = Direct3D_Device->CreateTexture(info.Width, info.Height, 0, info.Usage, info.Format, info.Pool, &dest); if (!SUCCEEDED(result)) goto ABORT; result = CopyTexture(dest, src, info.Height); if (!SUCCEEDED(result)) goto ABORT; result = D3DXFilterTexture(dest, nullptr, D3DX_DEFAULT, D3DX_DEFAULT); if (!SUCCEEDED(result)) { PrintDebug("Mipmap generation failed with error code 0x%08X\n", result); dest->Release(); goto ABORT; } src->Release(); SetSurface(dest, &njs_texture->texinfo.texsurface); return; ABORT: SetSurface(src, &njs_texture->texinfo.texsurface); return; }
//! constructor CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, u32 flags, const char* name) : ITexture(name), Image(image), Texture(0), RTTSurface(0), Driver(driver), TextureSize(0,0), ImageSize(0,0), Pitch(0), HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) { #ifdef _DEBUG setDebugName("CD3D9Texture"); #endif const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); Device=driver->getExposedVideoData().D3D9.D3DDev9; if (Device) Device->AddRef(); if (Image) { Image->grab(); if (createTexture(flags)) { if (copyTexture() && generateMipLevels) { // create mip maps. #ifdef _IRR_USE_D3DXFilterTexture_ // The D3DXFilterTexture function seems to get linked wrong when // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. // So mipmapgeneration is replaced with my own bad generation HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT); if (FAILED(hr)) os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING); else HasMipMaps = true; #else createMipMaps(); HasMipMaps = true; #endif } } else os::Printer::log("Could not create DIRECT3D9 Texture.", ELL_WARNING); } }
LPDIRECT3DTEXTURE9 Viewer::loadTexture(const std::string& strFilename) { LPDIRECT3DTEXTURE9 pTex=NULL; if(strcmpi(strchr(strFilename.c_str(),'.'),".raw")==0) { std::ifstream file; file.open(strFilename.c_str(), std::ios::in | std::ios::binary); if(!file) { std::cout << "Texture file '" << strFilename << "' not found." << std::endl; return NULL; } // load the dimension of the texture int width; file.read((char *)&width, 4); int height; file.read((char *)&height, 4); int depth; file.read((char *)&depth, 4); // allocate a temporary buffer to load the texture to unsigned char *pBuffer; pBuffer = new unsigned char[2 * width * height * depth]; if(pBuffer == 0) { std::cout << "Memory allocation for texture '" << strFilename << "' failed." << std::endl; return 0; } // load the texture file.read((char *)pBuffer, width * height * depth); // explicitely close the file file.close(); // flip texture around y-axis (-> opengl/d3d-style) int y; for(y = 0; y < height; y++) { memcpy(&pBuffer[(height + y) * width * depth], &pBuffer[(height - y - 1) * width * depth], width * depth); } D3DXCreateTexture(g_pD3DDevice, width, height, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTex); D3DLOCKED_RECT Locked; pTex->LockRect(0, &Locked, NULL, 0); for (y = 0; y < height; y++) { for (int x = 0; x < width; x++) { DWORD* pBits = (DWORD*)((BYTE*)Locked.pBits + (y * Locked.Pitch)); pBits += x; DWORD p; p=pBuffer[height * width * depth + (y*width+x)*depth] << 16; p+=pBuffer[height * width * depth + (y*width+x)*depth+1] << 8; p+=pBuffer[height * width * depth + (y*width+x)*depth+2] ; if(depth==4) p+=pBuffer[height * width * depth + (y*width+x)*depth+3]<<24; *pBits = p; } } pTex->UnlockRect(0); D3DXFilterTexture(pTex, NULL, 0, D3DX_FILTER_LINEAR); delete [] pBuffer; } else D3DXCreateTextureFromFile(g_pD3DDevice,strFilename.c_str(),&pTex); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); return pTex; }
bool Terrain::genTexture(D3DXVECTOR3* directionToLight) { // Method fills the top surface of a texture procedurally. Then // lights the top surface. Finally, it fills the other mipmap // surfaces based on the top surface data using D3DXFilterTexture. HRESULT hr = 0; // texel for each quad cell int texWidth = _numCellsPerRow; int texHeight = _numCellsPerCol; // create an empty texture hr = D3DXCreateTexture( _device, texWidth, texHeight, 0, // create a complete mipmap chain 0, // usage D3DFMT_X8R8G8B8,// 32 bit XRGB format D3DPOOL_MANAGED, &_tex); if(FAILED(hr)) return false; D3DSURFACE_DESC textureDesc; _tex->GetLevelDesc(0 /*level*/, &textureDesc); // make sure we got the requested format because our code // that fills the texture is hard coded to a 32 bit pixel depth. if( textureDesc.Format != D3DFMT_X8R8G8B8 ) return false; D3DLOCKED_RECT lockedRect; _tex->LockRect(0/*lock top surface*/, &lockedRect, 0 /* lock entire tex*/, 0/*flags*/); DWORD* imageData = (DWORD*)lockedRect.pBits; for(int i = 0; i < texHeight; i++) { for(int j = 0; j < texWidth; j++) { D3DXCOLOR c; // get height of upper left vertex of quad. float height = (float)getHeightmapEntry(i, j) / _heightScale; if( (height) < 42.5f ) c = d3d::BEACH_SAND; else if( (height) < 85.0f ) c = d3d::LIGHT_YELLOW_GREEN; else if( (height) < 127.5f ) c = d3d::PUREGREEN; else if( (height) < 170.0f ) c = d3d::DARK_YELLOW_GREEN; else if( (height) < 212.5f ) c = d3d::DARKBROWN; else c = d3d::WHITE; // fill locked data, note we divide the pitch by four because the // pitch is given in bytes and there are 4 bytes per DWORD. imageData[i * lockedRect.Pitch / 4 + j] = (D3DCOLOR)c; } } _tex->UnlockRect(0); if(!lightTerrain(directionToLight)) { ::MessageBox(0, "lightTerrain() - FAILED", 0, 0); return false; } hr = D3DXFilterTexture( _tex, 0, // default palette 0, // use top level as source level D3DX_DEFAULT); // default filter if(FAILED(hr)) { ::MessageBox(0, "D3DXFilterTexture() - FAILED", 0, 0); return false; } return true; }
void CRenderLib::m_BuildNormalizationCubemap(int32 pixelDim, int32 mipmapLevels) { HRESULT hr; uint32 i, y, x; /*hr = p_Device->CreateCubeTexture(pixelDim, mipmapLevels, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &p_NormalizationCubeMapTexture);*/ hr=D3DXCreateCubeTexture(p_Device, pixelDim, mipmapLevels, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &p_NormalizationCubeMapTexture); if (hr != D3D_OK) m_D3DError(hr, "Normalization CubeMap can't be created!"); for (i=0; i<6; i++) { D3DLOCKED_RECT Locked; AD_Vect3D Normal; float4 w, h; D3DSURFACE_DESC ddsdDesc; p_NormalizationCubeMapTexture->GetLevelDesc(0, &ddsdDesc); p_NormalizationCubeMapTexture->LockRect((D3DCUBEMAP_FACES)i, 0, &Locked, NULL, 0); for (y=0; y<ddsdDesc.Height; y++) { h = (float4)y / ((float4)(ddsdDesc.Height - 1)); h *= 2.0f; h -= 1.0f; for (x=0; x<ddsdDesc.Width; x++) { w = (float4)x / ((float4)(ddsdDesc.Width - 1)); w *= 2.0f; w -= 1.0f; DWORD* pBits = (DWORD*)((BYTE*)Locked.pBits + (y * Locked.Pitch)); pBits += x; switch((D3DCUBEMAP_FACES)i) { case D3DCUBEMAP_FACE_POSITIVE_X: vect_set(&Normal, 1.0f, -h, -w); break; case D3DCUBEMAP_FACE_NEGATIVE_X: vect_set(&Normal, -1.0f, -h, w); break; case D3DCUBEMAP_FACE_POSITIVE_Y: vect_set(&Normal, w, 1.0f, h); break; case D3DCUBEMAP_FACE_NEGATIVE_Y: vect_set(&Normal, w, -1.0f, -h); break; case D3DCUBEMAP_FACE_POSITIVE_Z: vect_set(&Normal, w, -h, 1.0f); break; case D3DCUBEMAP_FACE_NEGATIVE_Z: vect_set(&Normal, -w, -h, -1.0f); break; } vect_auto_normalize(&Normal); // Scale to be a color from 0 to 255 (127 is 0) Normal.x=(Normal.x+1)*127.0f; Normal.y=(Normal.y+1)*127.0f; Normal.z=(Normal.z+1)*127.0f; *pBits = (DWORD)(((DWORD)Normal.x << 16) | ((DWORD)Normal.y << 8) | ((DWORD)Normal.z)); } } p_NormalizationCubeMapTexture->UnlockRect((D3DCUBEMAP_FACES)i, 0); if (mipmapLevels>1) hr=D3DXFilterTexture(p_NormalizationCubeMapTexture, NULL, 0, D3DX_FILTER_TRIANGLE); } }
void D3DTexture::SetImage(void *lpData) { traceInFast(D3DTexture::SetImage); assert(lpData); D3DLOCKED_RECT d3dRect; int i,j; HRESULT problemo = GetTex()->LockRect(0, &d3dRect, NULL, 0); if(!d3dRect.pBits) return; if(dwFormat <= GS_GRAYSCALE) // if dwFormat is GS_ALPHA or GS_GRAYSCALE { if(dwInternalFormat == D3DFMT_A8L8) { LPWORD lpBits = (LPWORD)d3dRect.pBits; LPBYTE lpInput = (LPBYTE)lpData; for(i=0; i<texHeight; i++) { for(j=0; j<texWidth; j++) { WORD val = ((lpInput[(i*texWidth)+j]) << 8) | 0xFF; lpBits[(i*(d3dRect.Pitch/2))+j] = val; } } } else { LPBYTE lpBits = (LPBYTE)d3dRect.pBits; LPBYTE lpInput = (LPBYTE)lpData; for(i=0; i<texHeight; i++) mcpy(lpBits+(i*(d3dRect.Pitch)), lpInput+(i*texWidth), texWidth); } } else if((dwFormat == GS_A8L8) || (dwFormat == GS_L16)) { LPWORD lpBits = (LPWORD)d3dRect.pBits; LPWORD lpInput = (LPWORD)lpData; DWORD widthX2 = texWidth*2; for(i=0; i<texHeight; i++) mcpy(lpBits+(i*d3dRect.Pitch), lpInput+(i*widthX2), widthX2); } else if(dwFormat == GS_RGB) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits, lpInput = (LPBYTE)lpData; //DWORD widthX3 = texWidth*3; for(i=0; i<texHeight; i++) { //mcpy(lpBits+(i*d3dRect.Pitch), lpInput+(i*widthX3), widthX3); DWORD curY = (i*texWidth*3); DWORD curD3DY = (i*d3dRect.Pitch); for(j=0; j<texWidth; j++) { DWORD curX = curY+(j*3); DWORD curD3DX = curD3DY+(j*4); lpBits[curD3DX] = lpInput[curX]; lpBits[curD3DX+1] = lpInput[curX+1]; lpBits[curD3DX+2] = lpInput[curX+2]; } } } else if(dwFormat == GS_DXT1) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits, lpInput = (LPBYTE)lpData; DWORD tempWidth = (texWidth+3)/4; DWORD tempHeight = (texHeight+3)/4; mcpy(lpBits, lpInput, tempWidth*tempHeight*8); } else if((dwFormat == GS_DXT3) || (dwFormat == GS_DXT5)) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits, lpInput = (LPBYTE)lpData; DWORD tempWidth = (texWidth+3)/4; DWORD tempHeight = (texHeight+3)/4; mcpy(lpBits, lpInput, tempWidth*tempHeight*16); } else if((dwFormat == GS_RGBA) || (dwFormat == GS_RG16F)) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits, lpInput = (LPBYTE)lpData; DWORD widthX4 = texWidth*4; for(i=0; i<texHeight; i++) { mcpy(lpBits+(i*d3dRect.Pitch), lpInput+(i*widthX4), widthX4); /*DWORD curY = (i*texWidth*4); DWORD curD3DY = (i*d3dRect.Pitch); for(j=0; j<texWidth; j++) { DWORD jx4 = (j*4); DWORD curX = curY+jx4; DWORD curD3DX = curD3DY+jx4; lpBits[curD3DX] = lpInput[curX+2]; lpBits[curD3DX+1] = lpInput[curX+1]; lpBits[curD3DX+2] = lpInput[curX]; lpBits[curD3DX+3] = lpInput[curX+3]; }*/ } } else if((dwFormat == GS_RGBA16) || (dwFormat == GS_RGBA16F) || (dwFormat == GS_RG32F)) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits; LPWORD lpInput = (LPWORD)lpData; DWORD widthX8 = texWidth*8; for(i=0; i<texHeight; i++) { mcpy(lpBits+(i*d3dRect.Pitch), lpInput+(i*widthX8), widthX8); /*DWORD yOffset = (i*(texWidth*8)); DWORD yTexOffset = (i*d3dRect.Pitch); for(j=0; j<texWidth; j++) { WORD *lpColors = (WORD*)&lpBits[yTexOffset+(j*8)]; DWORD offset = yOffset+(j*8); lpColors[3] = lpInput[offset+2]; lpColors[2] = lpInput[offset+1]; lpColors[1] = lpInput[offset]; lpColors[0] = lpInput[offset+3]; }*/ } } else if(dwFormat == GS_RGBA32F) { LPBYTE lpBits = (LPBYTE)d3dRect.pBits; LPDWORD lpInput = (LPDWORD)lpData; DWORD widthX16 = texWidth*16; for(i=0; i<texHeight; i++) { mcpy(lpBits+(i*d3dRect.Pitch), lpInput+(i*widthX16), widthX16); /*DWORD yOffset = (i*(texWidth*16)); DWORD yTexOffset = (i*d3dRect.Pitch); for(j=0; j<texWidth; j++) { LPDWORD lpColors = (LPDWORD)&lpBits[yTexOffset+(j*8)]; DWORD offset = yOffset+(j*16); lpColors[3] = lpInput[offset+2]; lpColors[2] = lpInput[offset+1]; lpColors[1] = lpInput[offset]; lpColors[0] = lpInput[offset+3]; }*/ } } else { GetTex()->UnlockRect(0); ErrOut(TEXT("eep-chi, this message is required because a texture format needs Texture::SetImage implementation.")); return; } GetTex()->UnlockRect(0); if(bHasMipMaps && (dwTexType == D3DTEXTURE_STANDARD_BUFFER)) D3DXFilterTexture(GetTex(), NULL, 0, D3DX_DEFAULT); if(bDynamic && (textureData != lpData)) { Free(textureData); textureData = (LPBYTE)lpData; } traceOutFast; }
void __cdecl GeneratePalletizedMipmaps_c(IDirect3DTexture8* src) { if (src->GetLevelCount() >= 2) D3DXFilterTexture(src, nullptr, 0, D3DX_DEFAULT); }
void CDxtexDoc::GenerateMipMaps() { LONG lwTempH; LONG lwTempW; LONG lwPowsW; LONG lwPowsH; LPDIRECT3DTEXTURE9 pddsNew = NULL; D3DFORMAT fmt; HRESULT hr; LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev(); LPDIRECT3DTEXTURE9 pmiptex = NULL; LPDIRECT3DCUBETEXTURE9 pcubetex = NULL; LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL; LPDIRECT3DTEXTURE9 pmiptexNew = NULL; LPDIRECT3DCUBETEXTURE9 pcubetexNew = NULL; LPDIRECT3DVOLUMETEXTURE9 pvoltexNew = NULL; LPDIRECT3DSURFACE9 psurfSrc; LPDIRECT3DSURFACE9 psurfDest; LPDIRECT3DVOLUME9 pvolSrc; LPDIRECT3DVOLUME9 pvolDest; if (IsVolumeMap()) pvoltex = (LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig; else if (IsCubeMap()) pcubetex = (LPDIRECT3DCUBETEXTURE9)m_ptexOrig; else pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig; if (pvoltex != NULL) { D3DVOLUME_DESC vd; pvoltex->GetLevelDesc(0, &vd); fmt = vd.Format; } else if (pcubetex != NULL) { D3DSURFACE_DESC sd; pcubetex->GetLevelDesc(0, &sd); fmt = sd.Format; } else { D3DSURFACE_DESC sd; pmiptex->GetLevelDesc(0, &sd); fmt = sd.Format; } lwTempW = m_dwWidth; lwTempH = m_dwHeight; lwPowsW = 0; lwPowsH = 0; while (lwTempW > 0) { lwPowsW++; lwTempW = lwTempW / 2; } while (lwTempH > 0) { lwPowsH++; lwTempH = lwTempH / 2; } m_numMips = lwPowsW > lwPowsH ? lwPowsW : lwPowsH; // Create destination mipmap surface - same format as source if (pvoltex != NULL) { if (FAILED(hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips, 0, fmt, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL))) { goto LFail; } hr = pvoltex->GetVolumeLevel(0, &pvolSrc); hr = pvoltexNew->GetVolumeLevel(0, &pvolDest); hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, pvolSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&pvolSrc); ReleasePpo(&pvolDest); hr = D3DXFilterVolumeTexture(pvoltexNew, NULL, 0, D3DX_DEFAULT); } else if (pmiptex != NULL) { if (FAILED(hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 0, fmt, D3DPOOL_MANAGED, &pmiptexNew, NULL))) { goto LFail; } hr = pmiptex->GetSurfaceLevel(0, &psurfSrc); hr = pmiptexNew->GetSurfaceLevel(0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = D3DXFilterTexture(pmiptexNew, NULL, 0, D3DX_DEFAULT); } else { if (FAILED(hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 0, fmt, D3DPOOL_MANAGED, &pcubetexNew, NULL))) { goto LFail; } hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfSrc); hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfDest); hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, D3DX_DEFAULT, 0); ReleasePpo(&psurfSrc); ReleasePpo(&psurfDest); hr = D3DXFilterCubeTexture(pcubetexNew, NULL, 0, D3DX_DEFAULT); } ReleasePpo(&m_ptexOrig); if (pvoltexNew != NULL) m_ptexOrig = pvoltexNew; else if (pcubetexNew != NULL) m_ptexOrig = pcubetexNew; else m_ptexOrig = pmiptexNew; if (m_ptexNew != NULL) { // Rather than filtering down the (probably-compressed) m_ptexNew // top level, compress each mip level from the (probably-uncompressed) // m_ptexOrig levels. if (pvoltexNew != NULL) { D3DVOLUME_DESC vd; ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetLevelDesc(0, &vd); fmt = vd.Format; } else if (pcubetexNew != NULL) { D3DSURFACE_DESC sd; ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd); fmt = sd.Format; } else { D3DSURFACE_DESC sd; ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd); fmt = sd.Format; } Compress(fmt, FALSE); } m_bTitleModsChanged = TRUE; // Generate title bar update UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers SetModifiedFlag(); return; LFail: ReleasePpo(&pddsNew); }