📄 nvtexture.h
字号:
{
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:
NVDataFormat* 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];
LPDIRECT3DTEXTURE8 m_pTexture;
};
class NV2DSurfaceLocker
{
public:
NV2DSurfaceLocker(LPDIRECT3DSURFACE8 pSurface)
: m_pSurface(pSurface),
m_pDataFormat(NULL)
{
m_pSurface->AddRef();
m_bLocked = false;
CHECK_D3DAPI(m_pSurface->GetDesc(&m_LevelDesc));
switch(m_LevelDesc.Format)
{
case D3DFMT_UNKNOWN:
case D3DFMT_VERTEXDATA:
case D3DFMT_INDEX16:
case D3DFMT_INDEX32:
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_A8R8G8B8:
m_pDataFormat = new NVDataFormat_A8R8G8B8;
break;
case D3DFMT_X8R8G8B8:
m_pDataFormat = new NVDataFormat_X8R8G8B8;
break;
case D3DFMT_Q8W8V8U8:
m_pDataFormat = new NVDataFormat_Q8W8V8U8;
break;
case MAKEFOURCC('N', 'V', 'H', 'S'):
m_pDataFormat = new NVDataFormat_NVHS;
break;
}
assert(m_pDataFormat);
}
virtual ~NV2DSurfaceLocker()
{
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:
NVDataFormat* m_pDataFormat;
bool m_bLocked;
D3DSURFACE_DESC m_LevelDesc;
D3DLOCKED_RECT m_LockData;
LPDIRECT3DSURFACE8 m_pSurface;
};
class NVTexture2
{
public:
// Gets height from luminance value
static LPDIRECT3DTEXTURE8 CreateNormalMap(LPDIRECT3DDEVICE8 pD3DDev, LPDIRECT3DTEXTURE8 pSource, D3DFORMAT Format = D3DFMT_Q8W8V8U8, D3DPOOL Pool = D3DPOOL_MANAGED)
{
LPDIRECT3DTEXTURE8 pNormalMap = NULL;
D3DSURFACE_DESC ddsdDescDest;
D3DSURFACE_DESC ddsdDescSource;
D3DXVECTOR3 Normal;
HRESULT hr;
DWORD i, j;
assert(pSource && pSource->GetType() == D3DRTYPE_TEXTURE);
if (!pSource)
return NULL;
(pSource)->GetLevelDesc(0, &ddsdDescSource);
hr = pD3DDev->CreateTexture(ddsdDescSource.Width, ddsdDescSource.Height, pSource->GetLevelCount(), 0, Format, Pool, &pNormalMap);
if (FAILED(hr))
{
return NULL;
}
NV2DTextureLocker SourceLocker(pSource);
NV2DTextureLocker DestLocker(pNormalMap);
for (DWORD Level = 0; Level < pSource->GetLevelCount(); 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);
D3DXVec3Normalize(&Normal, &Normal);
DestLocker.SetMapVector(Level, i, j, Normal);
}
}
SourceLocker.Unlock(Level);
DestLocker.Unlock(Level);
}
return pNormalMap;
}
static void FilterNormalMap(LPDIRECT3DDEVICE8 pD3DDev, LPDIRECT3DTEXTURE8 pNormalMap)
{
D3DSURFACE_DESC ddsdDescSource;
D3DXVECTOR3 Normal;
DWORD i, j;
NV2DTextureLocker 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++)
{
for(j = 0; j < ddsdDescSource.Height; j++)
{
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);
j += 2;
}
i += 2;
}
SurfaceLocker.Unlock(Level);
SurfaceLocker.Unlock(Level + 1);
}
}
static LPDIRECT3DCUBETEXTURE8 CreateNormalizationCubeMap(LPDIRECT3DDEVICE8 pD3DDev, DWORD dwWidth, WORD dwMipmaps = 0, D3DPOOL Pool = D3DPOOL_MANAGED)
{
HRESULT hr;
LPDIRECT3DCUBETEXTURE8 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 (int y = 0; y < ddsdDesc.Height; y++)
{
h = (float)y / ((float)(ddsdDesc.Height - 1));
h *= 2.0f;
h -= 1.0f;
for (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;
}
};
}; //nv_objects
#endif __NVTEXTURE_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -