Files
bluflame/evoke-64k/trunk/ev10/Texture.cpp
2026-04-18 22:31:51 +02:00

506 lines
11 KiB
C++

#include "intrin.h"
#include "defines.h"
#include "Texture.h"
#include "Random.h"
#include "globals.h"
#include "rotmat.h"
void Texture::Init()
{
m_iSizeX= -1;
m_iSizeY= -1;
m_iSizeZ= -1;
m_iMipLevel= -1;
m_pTexture= NULL;
m_d3dlb.pBits= NULL;
m_d3dlb.RowPitch= -1;
m_d3dlb.SlicePitch= -1;
}
void Texture::DeInit()
{
Release();
}
void Texture::Create( int iSizeX,
int iSizeY,
int iSizeZ,
int iMipLevel )
{
Release();
m_iSizeX= iSizeX;
m_iSizeY= iSizeY;
m_iSizeZ= iSizeZ;
m_iMipLevel= iMipLevel;
if(m_iSizeZ > 1)
{
g_d3d_device->CreateVolumeTexture(
m_iSizeX,
m_iSizeY,
m_iSizeZ,
m_iMipLevel,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
(IDirect3DVolumeTexture9**)&m_pTexture,
NULL );
}
else
{
m_iSizeZ = 1;
g_d3d_device->CreateTexture(
m_iSizeX,
m_iSizeY,
m_iMipLevel,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
(IDirect3DTexture9**)&m_pTexture,
NULL );
}
}
void Texture::Release()
{
Unlock();
if( m_pTexture != NULL )
{
m_pTexture->Release();
m_pTexture= NULL;
}
m_iSizeX= -1;
m_iSizeY= -1;
m_iSizeZ= -1;
m_iMipLevel= -1;
m_d3dlb.pBits= NULL;
m_d3dlb.RowPitch= -1;
m_d3dlb.SlicePitch= -1;
}
void Texture::Lock()
{
if(m_iSizeZ > 1)
{
((IDirect3DVolumeTexture9*)m_pTexture)->LockBox( 0, &m_d3dlb, 0, 0 );
}
else
{
D3DLOCKED_RECT d3dlr;
((IDirect3DTexture9*)m_pTexture)->LockRect( 0, &d3dlr, 0, 0 );
m_d3dlb.pBits = d3dlr.pBits;
m_d3dlb.RowPitch = d3dlr.Pitch;
m_d3dlb.SlicePitch = 0;
}
}
void Texture::Unlock()
{
if( m_d3dlb.pBits == NULL )
{
return;
}
if(m_iSizeZ > 1)
{
((IDirect3DVolumeTexture9*)m_pTexture)->UnlockBox( 0 );
}
else
{
((IDirect3DTexture9*)m_pTexture)->UnlockRect( 0 );
}
m_d3dlb.pBits= NULL;
m_d3dlb.RowPitch= -1;
m_d3dlb.SlicePitch= -1;
}
const D3DLOCKED_BOX& Texture::GetData() const
{
return m_d3dlb;
};
void Texture::PrepareRandomTexture()
{
RandomGenerator rg;
rg.setSeed( 1024 );
for( int i= 0; i < 1024; ++i )
{
rg.genFloat();
}
Lock();
for( int iZ= 0; iZ < m_iSizeZ; ++iZ )
{
for( int iY= 0; iY < m_iSizeY; ++iY )
{
DWORD* pData= (DWORD*)((BYTE*)m_d3dlb.pBits + iY * m_d3dlb.RowPitch + iZ * m_d3dlb.SlicePitch );
for( int iX= 0; iX < m_iSizeX; ++iX )
{
rg.genFloat();
*pData++ = rg.getLastTempValue();
}
}
}
Unlock();
// Generate mip maps
D3DXFilterTexture(m_pTexture, NULL, 0, D3DX_DEFAULT);
}
#ifdef EXTRACODE
#include <fstream>
#endif
void Texture::PrepareRotMatrixFromFile()
{
#ifdef EXTRACODE
Release();
D3DXCreateTextureFromFile(
g_d3d_device,
"64k_pre/rotationalMatrix32.png",
(IDirect3DTexture9**)&m_pTexture );
m_iSizeX= 32;
m_iSizeY= 32;
m_iSizeZ = 1;
m_iMipLevel= 1;
Lock();
std::ofstream ofs( "64k_pre/rotMat.txt" );
for( int iY= 0; iY < m_iSizeY; ++iY )
{
DWORD* pData= (DWORD*)((BYTE*)m_d3dlb.pBits + iY * m_d3dlb.RowPitch );
for( int iX= 0; iX < m_iSizeX; ++iX )
{
//rg.genFloat();
//*pData++ = rg.getLastTempValue();
DWORD dw= *pData++;
ofs << dw << "," << "\n";
}
}
Unlock();
#endif
}
void Texture::PrepareTexGenRenderStates(IDirect3DBaseTexture9 *pInputTexture)
{
g_d3d_device->SetRenderState( D3DRS_LIGHTING, FALSE );
g_d3d_device->SetRenderState( D3DRS_ZENABLE, FALSE );
g_d3d_device->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, FALSE );
g_d3d_device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
g_d3d_device->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
g_d3d_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_d3d_device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_d3d_device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
// sampler2D randomSampler : register(s0);
g_d3d_device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_d3d_device->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
g_d3d_device->SetTexture( 0, g_pTextures[ TI_Random ].GetPointer() );
// sampler2D randomCubeSampler : register(s1);
g_d3d_device->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_d3d_device->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
g_d3d_device->SetSamplerState( 1, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP );
g_d3d_device->SetTexture( 1, g_pTextures[ TI_RandomCube ].GetPointer() );
// sampler2D ditherSampler : register(s2);
g_d3d_device->SetSamplerState( 2, D3DSAMP_MINFILTER, D3DTEXF_POINT );
g_d3d_device->SetSamplerState( 2, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
g_d3d_device->SetSamplerState( 2, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
g_d3d_device->SetSamplerState( 2, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_d3d_device->SetSamplerState( 2, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
g_d3d_device->SetTexture( 2, g_pTextures[ TI_RotMatrix ].GetPointer() );
// sampler2D inputSampler : register(s3);
g_d3d_device->SetSamplerState( 3, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 3, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 3, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
g_d3d_device->SetSamplerState( 3, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
g_d3d_device->SetSamplerState( 3, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
g_d3d_device->SetTexture( 3, pInputTexture );
}
void Texture::PrepareShaderTexture(int iShader1, int iShader2, int iShader3, int iShader4)
{
const int iMaxShaderCount = 4;
int shaders[iMaxShaderCount] = { iShader1, iShader2, iShader3, iShader4 };
IDirect3DTexture9 *pIntermediate = NULL;
IDirect3DSurface9 *pIntermediateSurface = NULL;
IDirect3DSurface9 *pIntermediateData = NULL;
// Create intermediate texture target
g_d3d_device->CreateTexture( m_iSizeX,
m_iSizeY,
1,
D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&(pIntermediate),
NULL);
pIntermediate->GetSurfaceLevel(0, &pIntermediateSurface);
// Create system-memory surface
g_d3d_device->CreateOffscreenPlainSurface( m_iSizeX,
m_iSizeY,
D3DFMT_A8R8G8B8,
D3DPOOL_SYSTEMMEM,
&(pIntermediateData),
NULL);
IDirect3DSurface9 *pColorSurface = NULL;
IDirect3DSurface9 *pDepthStencilSurface = NULL;
g_d3d_device->BeginScene();
// Get targets
g_d3d_device->GetRenderTarget(0, &pColorSurface);
g_d3d_device->GetDepthStencilSurface(&pDepthStencilSurface);
for(int i = 0; i < iMaxShaderCount; i++)
{
int iShader = shaders[i];
if(iShader < 0)
continue;
// Set intermediate target & state
g_d3d_device->SetRenderTarget(0, pIntermediateSurface);
g_d3d_device->SetDepthStencilSurface(NULL);
PrepareTexGenRenderStates(m_pTexture);
Shader::SetResolution(m_iSizeX, m_iSizeY);
// Generate texture
g_FullScreenQuad.m_iUsedShader[0] = iShader;
g_FullScreenQuad.Render();
// Copy data
g_d3d_device->GetRenderTargetData(pIntermediateSurface, pIntermediateData);
D3DLOCKED_RECT intermediateRect;
// Lock surfaces
pIntermediateData->LockRect(&intermediateRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY);
Lock();
// Copy data to destination surface
mymemcpy(m_d3dlb.pBits, intermediateRect.pBits, m_d3dlb.RowPitch * m_iSizeY);
// Unlock surfaces
Unlock();
pIntermediateData->UnlockRect();
// Generate mip maps
D3DXFilterTexture(m_pTexture, NULL, 0, D3DX_DEFAULT);
}
// Reset targets
g_d3d_device->SetRenderTarget(0, pColorSurface);
g_d3d_device->SetDepthStencilSurface(pDepthStencilSurface);
g_d3d_device->EndScene();
g_d3d_device->Present(NULL, NULL, NULL, NULL);
// Release
if(pColorSurface)
pColorSurface->Release();
if(pDepthStencilSurface)
pDepthStencilSurface->Release();
pIntermediateSurface->Release();
pIntermediate->Release();
pIntermediateData->Release();
}
void Texture::PrepareRotMatrix()
{
Lock();
int iPos= 0;
for( int iY= 0; iY < m_iSizeY; ++iY )
{
DWORD* pData= (DWORD*)((BYTE*)m_d3dlb.pBits + iY * m_d3dlb.RowPitch );
for( int iX= 0; iX < m_iSizeX; ++iX )
{
*pData++ = dwRotMatData[ iPos++ ];
}
}
Unlock();
}
void Texture::PrepareSpecTexture()
{
g_pTextures[ TI_LightSpec1D ].Create( 256, 1, 1, 1 );
g_pTextures[ TI_LightSpec1D ].Lock();
float fVal= 255.0f;
for( int i= 0; i <= 255; ++i )
{
int iV= (int)fVal;
((DWORD*)(g_pTextures[ TI_LightSpec1D ].m_d3dlb.pBits))[ 255 - i ]=
0xff << 24 |
( iV & 0xff ) << 16 |
( iV & 0xff ) << 8 |
( iV & 0xff );
fVal*= 0.925f;
}
//unlock
g_pTextures[ TI_LightSpec1D ].Unlock();
}
void Texture::Prepare1DTextures()
{
PrepareSpecTexture();
int iTexIndex= TI_First1D;
static const unsigned char pucDataTest[]=
{
1, // Groesse == 8
255, 255, 255,
7,
255, 255, 255,
0,
16, // Groesse == 128
32, 32, 64,
64,
120, 120, 128,
63,
255, 251, 208,
0,
16, // Groesse == 128
255, 255, 255,
4,
192, 192, 192,
4,
145, 145, 145,
4,
108, 108, 108,
4,
81, 81, 81,
8,
45, 45, 45,
16,
14, 14, 14,
16,
4, 4, 4,
71,
0, 0, 0,
0,
16, // Groesse == 128
80, 0, 165,
16,
38, 3, 238,
18,
0, 183, 195,
12,
0, 217, 110,
18,
1, 232,0,
18,
152, 216,0,
12,
229, 200,0 ,
18,
255, 62,0 ,
15,
225, 18,0 ,
0,
0
};
const unsigned char* pData= pucDataTest;
int ColorIn[ 3 ];
int ColorOut[ 3 ];
while( *pData != 0 )
{
//create Texture
int iTexSize= *pData * 8;
pData++;
/*int iMips= 1;
while( 2 << iMips <= iTexSize )
{
iMips++;
}*/
g_pTextures[ iTexIndex ].Create( iTexSize, 1, 1, 1 );
g_pTextures[ iTexIndex ].Lock();
int iX= 0;
ColorIn[ 0 ]= *pData++;
ColorIn[ 1 ]= *pData++;
ColorIn[ 2 ]= *pData++;
//set Texture Data
while( true )
{
int iLength= *pData;
pData++;
if( iLength == 0 )
{
break;
}
ColorOut[ 0 ]= *pData++;
ColorOut[ 1 ]= *pData++;
ColorOut[ 2 ]= *pData++;
//lerp colors
for( int i= 0; i <= iLength; ++i )
{
int iA= iLength - i;
int iR= ( ColorOut[ 0 ] * i + ColorIn[ 0 ] * iA ) / iLength;
int iG= ( ColorOut[ 1 ] * i + ColorIn[ 1 ] * iA ) / iLength;
int iB= ( ColorOut[ 2 ] * i + ColorIn[ 2 ] * iA ) / iLength;
assert( iX < g_pTextures[ iTexIndex ].m_iSizeX );
((DWORD*)(g_pTextures[ iTexIndex ].m_d3dlb.pBits))[ iX ]=
0xff << 24 |
( iR & 0xff ) << 16 |
( iG & 0xff ) << 8 |
( iB & 0xff );
++iX;
}
--iX;
ColorIn[ 0 ]= ColorOut[ 0 ];
ColorIn[ 1 ]= ColorOut[ 1 ];
ColorIn[ 2 ]= ColorOut[ 2 ];
}
//unlock
g_pTextures[ iTexIndex ].Unlock();
iTexIndex++;
}
}