#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 #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++; } }