#ifndef __D3DTEXTURE_H #define __D3DTEXTURE_H class D3DDataFormat { public: virtual void GetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD& dwValue) { assert(0); }; virtual void SetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD dwValue) { assert(0); }; virtual void GetColors(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& fRed, float& fGreen, float& fBlue, float& fAlpha) { assert(0); }; virtual void SetColors(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float fRed, float fGreen, float fBlue, float fAlpha) { assert(0); }; virtual void GetLuminance(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& Luminance) { assert(0); }; virtual void SetLuminance(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float Luminance) { assert(0); }; virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& inVector) { assert(0); }; virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { assert(0); }; }; class D3DDataFormat_32Bit : public D3DDataFormat { public: virtual void GetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD& dwValue) { dwValue = (*(DWORD*) (((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(DWORD))) ); } virtual void SetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD dwValue) { *(DWORD*)(((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(DWORD))) = dwValue; } }; class D3DDataFormat_16Bit : public D3DDataFormat { public: virtual void GetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD& dwValue) { dwValue = ((DWORD)*(WORD*)(((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(WORD))) ); } virtual void SetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD dwValue) { *(WORD*)(((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(WORD))) = (WORD)dwValue; } }; class D3DDataFormat_8Bit : public D3DDataFormat { public: virtual void GetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD& dwValue) { dwValue = ((DWORD)*(BYTE*)(((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(BYTE))) ); } virtual void SetData(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, DWORD dwValue) { *(BYTE*)(((BYTE*)LockData.pBits) + (j * LockData.Pitch) + (i * sizeof(WORD))) = (BYTE)dwValue; } }; class D3DDataFormat_A8R8G8B8 : public D3DDataFormat_32Bit { public: virtual void GetColors(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& fRed, float& fGreen, float& fBlue, float& fAlpha) { DWORD dwValue; GetData(LockData, i, j, dwValue); fBlue = ((float)(dwValue & 0xFF))/ 255.0f; fGreen = ((float)((dwValue >> 8) & 0xFF)) / 255.0f; fRed = ((float)((dwValue >> 16) & 0xFF)) / 255.0f; fAlpha = ((float)((dwValue >> 24) & 0xFF)) / 255.0f; } virtual void GetLuminance(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& Luminance) { float fRed, fGreen, fBlue, fAlpha; GetColors(LockData, i, j, fRed, fGreen, fBlue, fAlpha); Luminance = ((fRed * 0.3f) + (fGreen * 0.59f) + (fBlue * 0.11f)); } virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { D3DXVECTOR3 vecScaled = (inVector + D3DXVECTOR3(1.0f, 1.0f, 1.0f)) * 127.5f; BYTE red = (BYTE)vecScaled.x; BYTE green = (BYTE)vecScaled.y; BYTE blue = (BYTE)vecScaled.z; BYTE alpha = 0xFF; DWORD dwData = (DWORD)( ( (DWORD)alpha << 24 ) | ( (DWORD)red << 16 ) | ( (DWORD)green << 8 ) | ( (DWORD)blue << 0) ); SetData(LockData, i, j, dwData); } virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& outVector) { DWORD dwData; GetData(LockData, i, j, dwData); outVector.x = (float)((dwData >> 16) & 0xFF); outVector.y = (float)((dwData >> 8) & 0xFF); outVector.z = (float)((dwData) & 0xFF); outVector /= 127.5f; outVector -= D3DXVECTOR3(1.0f, 1.0f, 1.0f); } }; class D3DDataFormat_X8R8G8B8 : public D3DDataFormat_32Bit { public: virtual void GetColors(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& fRed, float& fGreen, float& fBlue, float& fAlpha) { DWORD dwValue; GetData(LockData, i, j, dwValue); fBlue = ((float)(dwValue & 0xFF))/ 255.0f; fGreen = ((float)((dwValue >> 8) & 0xFF)) / 255.0f; fRed = ((float)((dwValue >> 16) & 0xFF)) / 255.0f; fAlpha = 1.0f; } virtual void GetLuminance(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, float& Luminance) { float fRed, fGreen, fBlue, fAlpha; GetColors(LockData, i, j, fRed, fGreen, fBlue, fAlpha); Luminance = ((fRed * 0.3f) + (fGreen * 0.59f) + (fBlue * 0.11f)); } virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { D3DXVECTOR3 vecScaled = (inVector + D3DXVECTOR3(1.0f, 1.0f, 1.0f)) * 127.5f; BYTE red = (BYTE)vecScaled.x; BYTE green = (BYTE)vecScaled.y; BYTE blue = (BYTE)vecScaled.z; BYTE alpha = 0xFF; DWORD dwData = (DWORD)( ( (DWORD)alpha << 24 ) | ( (DWORD)red << 16 ) | ( (DWORD)green << 8 ) | ( (DWORD)blue << 0) ); SetData(LockData, i, j, dwData); } virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& outVector) { DWORD dwData; GetData(LockData, i, j, dwData); outVector.x = (float)((dwData >> 16) & 0xFF); outVector.y = (float)((dwData >> 8) & 0xFF); outVector.z = (float)((dwData) & 0xFF); outVector /= 127.5f; outVector -= D3DXVECTOR3(1.0f, 1.0f, 1.0f); } }; class D3DDataFormat_Q8W8V8U8 : public D3DDataFormat_32Bit { virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { D3DXVECTOR3 vecScaled = inVector * 127.5f; signed char red = (signed char)vecScaled.x; signed char green = (signed char)vecScaled.y; signed char blue = (signed char)vecScaled.z; signed char alpha = 0; DWORD dwData = (DWORD)( ( (DWORD)(unsigned char)alpha << 24 ) | ( (DWORD)(unsigned char)blue << 16 ) | ( (DWORD)(unsigned char)green << 8 ) | ( (DWORD)(unsigned char)red << 0) ); SetData(LockData, i, j, dwData); } virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& outVector) { DWORD dwData; GetData(LockData, i, j, dwData); outVector.x = (float)(signed char)((dwData) & 0xFF); outVector.y = (float)(signed char)((dwData >> 8) & 0xFF); outVector.z = (float)(signed char)((dwData >> 16) & 0xFF); outVector /= 127.5f; } }; class D3DDataFormat_X8L8V8U8 : public D3DDataFormat_32Bit { virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { D3DXVECTOR3 vecScaled = inVector * 127.5f; signed char red = (signed char)vecScaled.x; signed char green = (signed char)vecScaled.y; signed char blue = (signed char)vecScaled.z; signed char alpha = 0; DWORD dwData = (DWORD)( ( (DWORD)(unsigned char)alpha << 24 ) | ( (DWORD)(unsigned char)blue << 16 ) | ( (DWORD)(unsigned char)green << 8 ) | ( (DWORD)(unsigned char)red << 0) ); SetData(LockData, i, j, dwData); } virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& outVector) { DWORD dwData; GetData(LockData, i, j, dwData); outVector.x = (float)(signed char)((dwData) & 0xFF); outVector.y = (float)(signed char)((dwData >> 8) & 0xFF); outVector.z = (float)(signed char)((dwData >> 16) & 0xFF); outVector /= 127.5f; } }; class D3DDataFormat_D3DHS : public D3DDataFormat_32Bit { virtual void SetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { D3DXVECTOR3 vecScaled = inVector * 32767.0f; signed short h = (signed short)vecScaled.x; signed short l = (signed short)vecScaled.y; DWORD dwData = ( ( (DWORD)(unsigned short)h << 16 ) | ( (DWORD)(unsigned short)l << 0 ) ); SetData(LockData, i, j, dwData); } virtual void GetVector(const D3DLOCKED_RECT& LockData, DWORD i, DWORD j, D3DXVECTOR3& outVector) { DWORD dwData; GetData(LockData, i, j, dwData); outVector.x = (float)(unsigned short)((dwData >> 16) & 0xFFFF); outVector.y = (float)(unsigned short)((dwData) & 0xFFFF); outVector.z = 1.0f; outVector /= 32767.0f; } }; class D3D2DTextureLocker { public: enum { MAX_LOCK_LEVELS = 12 }; D3D2DTextureLocker(LPDIRECT3DTEXTURE9 pTexture) : m_pTexture(pTexture), m_pDataFormat(NULL) { m_pTexture->AddRef(); for (DWORD i=0; i < MAX_LOCK_LEVELS; i++) { m_bLocked[i] = false; } m_dwLevels = m_pTexture->GetLevelCount(); D3DSURFACE_DESC LevelDesc; m_pTexture->GetLevelDesc(0, &LevelDesc); switch(LevelDesc.Format) { case D3DFMT_UNKNOWN: case D3DFMT_VERTEXDATA: case D3DFMT_INDEX16: #ifndef _XBOX case D3DFMT_INDEX32: #endif case D3DFMT_DXT1: case D3DFMT_DXT2: #ifndef _XBOX case D3DFMT_DXT3: #endif case D3DFMT_DXT4: #ifndef _XBOX case D3DFMT_DXT5: default: assert(!"Don't understand surface format"); break; case D3DFMT_R8G8B8: assert(!"Don't handle 24 bit surfaces"); break; case D3DFMT_X8L8V8U8: m_pDataFormat = new D3DDataFormat_X8L8V8U8; break; #endif case D3DFMT_A8R8G8B8: m_pDataFormat = new D3DDataFormat_A8R8G8B8; break; case D3DFMT_X8R8G8B8: m_pDataFormat = new D3DDataFormat_X8R8G8B8; break; case D3DFMT_Q8W8V8U8: m_pDataFormat = new D3DDataFormat_Q8W8V8U8; break; case MAKEFOURCC('N', 'V', 'H', 'S'): m_pDataFormat = new D3DDataFormat_D3DHS; break; } assert(m_pDataFormat); } virtual ~D3D2DTextureLocker() { for (DWORD i = 0; i < MAX_LOCK_LEVELS; i++) { if (m_bLocked[i]) { Unlock(i); } } SAFE_RELEASE(m_pTexture); SAFE_DELETE(m_pDataFormat); } bool Lock(DWORD dwLevel) { HRESULT hr; assert(dwLevel < m_dwLevels); assert(!m_bLocked[dwLevel]); m_bLocked[dwLevel] = true; hr = m_pTexture->LockRect(dwLevel, &m_LockData[dwLevel], NULL, 0); m_pTexture->GetLevelDesc(dwLevel, &m_LevelDesc[dwLevel]); if (FAILED(hr)) return false; return true; } bool Unlock(DWORD dwLevel) { HRESULT hr; assert(dwLevel < m_dwLevels); assert(m_bLocked[dwLevel]); m_bLocked[dwLevel] = false; hr = m_pTexture->UnlockRect(dwLevel); if (FAILED(hr)) return false; return true; } void WrapAddress(DWORD dwLevel, DWORD& i, DWORD& j) { if (i >= 0) { i = (i % m_LevelDesc[dwLevel].Width); } else { i = (m_LevelDesc[dwLevel].Width - 1) + (i % m_LevelDesc[dwLevel].Width); } if (j >= 0) { j = (j % m_LevelDesc[dwLevel].Height); } else { j = (m_LevelDesc[dwLevel].Height - 1) + (j % m_LevelDesc[dwLevel].Height); } assert(i >= 0); assert(j >= 0); assert(i < m_LevelDesc[dwLevel].Width); assert(j < m_LevelDesc[dwLevel].Height); } void GetMapData(DWORD dwLevel, DWORD i, DWORD j, DWORD& dwValue) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->GetData(m_LockData[dwLevel], i, j, dwValue); } void SetMapData(DWORD dwLevel, DWORD i, DWORD j, DWORD dwValue) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->SetData(m_LockData[dwLevel], i, j, dwValue); } void GetMapColors(DWORD dwLevel, DWORD i, DWORD j, float& fRed, float& fGreen, float& fBlue, float& fAlpha) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->GetColors(m_LockData[dwLevel], i, j, fRed, fGreen, fBlue, fAlpha); } void GetMapLuminance(DWORD dwLevel, DWORD i, DWORD j, float& Luminance) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->GetLuminance(m_LockData[dwLevel], i, j, Luminance); } void SetMapVector(DWORD dwLevel, DWORD i, DWORD j, const D3DXVECTOR3& inVector) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->SetVector(m_LockData[dwLevel], i, j, inVector); } void GetMapVector(DWORD dwLevel, DWORD i, DWORD j, D3DXVECTOR3& inVector) { assert(m_bLocked[dwLevel]); WrapAddress(dwLevel, i, j); m_pDataFormat->GetVector(m_LockData[dwLevel], i, j, inVector); } private: D3DDataFormat* m_pDataFormat; DWORD m_dwLevels; bool m_bLocked[MAX_LOCK_LEVELS]; D3DLOCKED_RECT m_LockData[MAX_LOCK_LEVELS]; D3DSURFACE_DESC m_LevelDesc[MAX_LOCK_LEVELS]; LPDIRECT3DTEXTURE9 m_pTexture; }; class D3D2DSurfaceLocker { public: D3D2DSurfaceLocker(LPDIRECT3DSURFACE9 pSurface) : m_pSurface(pSurface), m_pDataFormat(NULL) { m_pSurface->AddRef(); m_bLocked = false; m_pSurface->GetDesc(&m_LevelDesc); switch(m_LevelDesc.Format) { case D3DFMT_UNKNOWN: case D3DFMT_VERTEXDATA: case D3DFMT_INDEX16: #ifndef _XBOX case D3DFMT_INDEX32: #endif #ifndef _XBOX case D3DFMT_DXT1: case D3DFMT_DXT2: case D3DFMT_DXT3: case D3DFMT_DXT4: case D3DFMT_DXT5: default: assert(!"Don't understand surface format"); break; case D3DFMT_R8G8B8: assert(!"Don't handle 24 bit surfaces"); break; case D3DFMT_X8L8V8U8: m_pDataFormat = new D3DDataFormat_X8L8V8U8; break; #endif case D3DFMT_A8R8G8B8: m_pDataFormat = new D3DDataFormat_A8R8G8B8; break; case D3DFMT_X8R8G8B8: m_pDataFormat = new D3DDataFormat_X8R8G8B8; break; case D3DFMT_Q8W8V8U8: m_pDataFormat = new D3DDataFormat_Q8W8V8U8; break; case MAKEFOURCC('N', 'V', 'H', 'S'): m_pDataFormat = new D3DDataFormat_D3DHS; break; } assert(m_pDataFormat); } virtual ~D3D2DSurfaceLocker() { if (m_bLocked) { Unlock(); } SAFE_RELEASE(m_pSurface); SAFE_DELETE(m_pDataFormat); } bool Lock() { HRESULT hr; assert(!m_bLocked); m_bLocked = true; hr = m_pSurface->LockRect(&m_LockData, NULL, 0); if (FAILED(hr)) return false; return true; } bool Unlock() { HRESULT hr; assert(m_bLocked); m_bLocked = false; hr = m_pSurface->UnlockRect(); if (FAILED(hr)) return false; return true; } void WrapAddress(DWORD& i, DWORD& j) { if (i >= 0) { i = (i % m_LevelDesc.Width); } else { i = (m_LevelDesc.Width - 1) + (i % m_LevelDesc.Width); } if (j >= 0) { j = (j % m_LevelDesc.Height); } else { j = (m_LevelDesc.Height - 1) + (j % m_LevelDesc.Height); } assert(i >= 0); assert(j >= 0); assert(i < m_LevelDesc.Width); assert(j < m_LevelDesc.Height); } void GetMapData(DWORD i, DWORD j, DWORD& dwValue) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->GetData(m_LockData, i, j, dwValue); } void SetMapData(DWORD i, DWORD j, DWORD dwValue) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->SetData(m_LockData, i, j, dwValue); } void GetMapColors(DWORD i, DWORD j, float& fRed, float& fGreen, float& fBlue, float& fAlpha) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->GetColors(m_LockData, i, j, fRed, fGreen, fBlue, fAlpha); } void GetMapLuminance(DWORD i, DWORD j, float& Luminance) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->GetLuminance(m_LockData, i, j, Luminance); } void SetMapVector(DWORD i, DWORD j, const D3DXVECTOR3& inVector) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->SetVector(m_LockData, i, j, inVector); } void GetMapVector(DWORD i, DWORD j, D3DXVECTOR3& inVector) { assert(m_bLocked); WrapAddress(i, j); m_pDataFormat->GetVector(m_LockData, i, j, inVector); } private: D3DDataFormat* m_pDataFormat; bool m_bLocked; D3DSURFACE_DESC m_LevelDesc; D3DLOCKED_RECT m_LockData; LPDIRECT3DSURFACE9 m_pSurface; }; class CD3DTexture { public: // Gets height from luminance value static LPDIRECT3DTEXTURE9 CreateNormalMap(LPDIRECT3DDEVICE9 pD3DDev, LPDIRECT3DTEXTURE9 pSource, STexPic *ti, bool bMips, D3DXVECTOR3 Scale, D3DFORMAT Format = D3DFMT_Q8W8V8U8, D3DPOOL Pool = D3DPOOL_MANAGED) { LPDIRECT3DTEXTURE9 pNormalMap = NULL; D3DSURFACE_DESC ddsdDescDest; D3DSURFACE_DESC ddsdDescSource; D3DXVECTOR3 Normal; HRESULT hr; DWORD i, j; LPDIRECT3DTEXTURE9 pNewTex = NULL; assert(pSource && pSource->GetType() == D3DRTYPE_TEXTURE); if (!pSource) return NULL; (pSource)->GetLevelDesc(0, &ddsdDescSource); // Handle conversion from compressed to specified format switch(ddsdDescSource.Format) { default: break; case D3DFMT_DXT1: case D3DFMT_DXT3: case D3DFMT_DXT5: { hr = D3DXCreateTexture(pD3DDev, ddsdDescSource.Width, ddsdDescSource.Height, bMips ? D3DX_DEFAULT : 1, 0, Format, D3DPOOL_SYSTEMMEM, &pNewTex); if (FAILED(hr)) return NULL; // Copy the levels to RGB textures for (i = 0; i < 1; i++) { LPDIRECT3DSURFACE9 pDestSurf; LPDIRECT3DSURFACE9 pSourceSurf; pNewTex->GetSurfaceLevel(i, &pDestSurf); pSource->GetSurfaceLevel(i, &pSourceSurf); D3DXLoadSurfaceFromSurface(pDestSurf, NULL, NULL, pSourceSurf, NULL, NULL, D3DX_FILTER_NONE, 0); SAFE_RELEASE(pDestSurf); SAFE_RELEASE(pSourceSurf); } pSource = pNewTex; } break; } hr = D3DXCreateTexture(pD3DDev, ddsdDescSource.Width, ddsdDescSource.Height, bMips ? D3DX_DEFAULT : 1, 0, Format, Pool, &pNormalMap ); if (FAILED(hr)) { SAFE_RELEASE(pNewTex); return NULL; } D3D2DTextureLocker SourceLocker(pSource); D3D2DTextureLocker DestLocker(pNormalMap); for (DWORD Level = 0; Level < 1; Level++) { pNormalMap->GetLevelDesc(Level, &ddsdDescDest); DWORD dwWidth = ddsdDescDest.Width; DWORD dwHeight = ddsdDescDest.Height; SourceLocker.Lock(Level); DestLocker.Lock(Level); for(i=0; i < dwWidth; i++) { for(j = 0; j < dwHeight; j++) { float fRight, fLeft, fUp, fDown; SourceLocker.GetMapLuminance(Level, i + 1, j, fRight); SourceLocker.GetMapLuminance(Level, i - 1, j, fLeft); SourceLocker.GetMapLuminance(Level, i, j - 1, fUp); SourceLocker.GetMapLuminance(Level, i, j + 1, fDown); D3DXVECTOR3 dfdi(2.f, 0.f, fRight - fLeft); D3DXVECTOR3 dfdj(0.f, 2.f, fDown - fUp); D3DXVec3Cross(&Normal, &dfdi, &dfdj); Normal[0] *= Scale[0]; Normal[1] *= Scale[1]; Normal[2] *= Scale[2]; D3DXVec3Normalize(&Normal, &Normal); if (ti->m_eTT == eTT_DSDTBump) Normal[2] = 0.5f; DestLocker.SetMapVector(Level, i, j, Normal); } } SourceLocker.Unlock(Level); DestLocker.Unlock(Level); } SAFE_RELEASE(pNewTex); return pNormalMap; } static void FilterNormalMap(LPDIRECT3DDEVICE9 pD3DDev, LPDIRECT3DTEXTURE9 pNormalMap) { D3DSURFACE_DESC ddsdDescSource; D3DXVECTOR3 Normal; DWORD i, j; D3D2DTextureLocker SurfaceLocker(pNormalMap); for (DWORD Level = 0; Level < pNormalMap->GetLevelCount() - 1; Level++) { SurfaceLocker.Lock(Level); SurfaceLocker.Lock(Level + 1); pNormalMap->GetLevelDesc(Level, &ddsdDescSource); for(i=0; i < ddsdDescSource.Width; i+=2) { for(j = 0; j < ddsdDescSource.Height; j+=2) { D3DXVECTOR3 Vectors[4]; SurfaceLocker.GetMapVector(Level, i, j, Vectors[0]); SurfaceLocker.GetMapVector(Level, i+1, j, Vectors[1]); SurfaceLocker.GetMapVector(Level, i+1, j+1, Vectors[2]); SurfaceLocker.GetMapVector(Level, i+1, j+1, Vectors[3]); D3DXVECTOR3 Normal = Vectors[0] + Vectors[1] + Vectors[2] + Vectors[3]; D3DXVec3Normalize(&Normal, &Normal); SurfaceLocker.SetMapVector(Level + 1, i / 2, j / 2, Normal); } } SurfaceLocker.Unlock(Level); SurfaceLocker.Unlock(Level + 1); } } static LPDIRECT3DCUBETEXTURE9 CreateNormalizationCubeMap(LPDIRECT3DDEVICE9 pD3DDev, DWORD dwWidth, DWORD dwMipmaps = 0, D3DPOOL Pool = D3DPOOL_MANAGED) { HRESULT hr; LPDIRECT3DCUBETEXTURE9 pCubeTexture; hr = D3DXCreateCubeTexture(pD3DDev, dwWidth, dwMipmaps, 0, D3DFMT_X8R8G8B8, Pool, &pCubeTexture); if(FAILED(hr)) { return NULL; } if (dwMipmaps == 0) dwMipmaps = pCubeTexture->GetLevelCount(); for (DWORD dwLevel = 0; dwLevel < dwMipmaps; dwLevel++) { for (int i = 0; i < 6; i++) { D3DLOCKED_RECT Locked; D3DXVECTOR3 Normal; float w,h; D3DSURFACE_DESC ddsdDesc; pCubeTexture->GetLevelDesc(dwLevel, &ddsdDesc); pCubeTexture->LockRect((D3DCUBEMAP_FACES)i, dwLevel, &Locked, NULL, 0); for (unsigned int y = 0; y < ddsdDesc.Height; y++) { h = (float)y / ((float)(ddsdDesc.Height - 1)); h *= 2.0f; h -= 1.0f; for (unsigned int x = 0; x < ddsdDesc.Width; x++) { w = (float)x / ((float)(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: Normal = D3DXVECTOR3(1.0f, -h, -w); break; case D3DCUBEMAP_FACE_NEGATIVE_X: Normal = D3DXVECTOR3(-1.0f, -h, w); break; case D3DCUBEMAP_FACE_POSITIVE_Y: Normal = D3DXVECTOR3(w, 1.0f, h); break; case D3DCUBEMAP_FACE_NEGATIVE_Y: Normal = D3DXVECTOR3(w, -1.0f, -h); break; case D3DCUBEMAP_FACE_POSITIVE_Z: Normal = D3DXVECTOR3(w, -h, 1.0f); break; case D3DCUBEMAP_FACE_NEGATIVE_Z: Normal = D3DXVECTOR3(-w, -h, -1.0f); break; default: assert(0); break; } D3DXVec3Normalize(&Normal, &Normal); // Scale to be a color from 0 to 255 (127 is 0) Normal += D3DXVECTOR3(1.0f, 1.0f, 1.0f); Normal *= 127.0f; // Store the color *pBits = (DWORD)(((DWORD)Normal.x << 16) | ((DWORD)Normal.y << 8) | ((DWORD)Normal.z << 0)); } } pCubeTexture->UnlockRect((D3DCUBEMAP_FACES)i, 0); } } return pCubeTexture; } }; //vlad123 #endif __D3DTEXTURE_H