From 76e0b1a29e3329655882a7a3ffd5c975f796589d Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:09:28 +0100 Subject: [PATCH 1/2] unify(shader): Merge W3DShaderManager code, move Smudge, W3DSmudge to Core (#1920) --- Core/GameEngine/CMakeLists.txt | 4 +- .../GameEngine/Include/GameClient/Smudge.h | 0 .../Source/GameClient/System/Smudge.cpp | 0 Core/GameEngineDevice/CMakeLists.txt | 4 +- .../Include/W3DDevice/GameClient/W3DSmudge.h | 0 .../Source/W3DDevice/GameClient/W3DSmudge.cpp | 0 .../Include/GameClient/CommandXlat.h | 3 +- .../W3DDevice/GameClient/W3DShaderManager.h | 12 + .../W3DDevice/GameClient/W3DShaderManager.cpp | 905 +++++++++++++++++- .../Source/WWVegas/WW3D2/dx8renderer.cpp | 13 +- .../Source/WWVegas/WW3D2/dx8wrapper.cpp | 6 + .../Source/WWVegas/WW3D2/dx8wrapper.h | 2 +- GeneralsMD/Code/GameEngine/CMakeLists.txt | 4 +- .../Code/GameEngineDevice/CMakeLists.txt | 4 +- .../W3DDevice/GameClient/W3DShaderManager.cpp | 2 - scripts/cpp/unify_move_files.py | 5 + 16 files changed, 904 insertions(+), 60 deletions(-) rename {GeneralsMD/Code => Core}/GameEngine/Include/GameClient/Smudge.h (100%) rename {GeneralsMD/Code => Core}/GameEngine/Source/GameClient/System/Smudge.cpp (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp (100%) diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index faebd73f6c..d1af9c1e69 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -222,7 +222,7 @@ set(GAMEENGINE_SRC # Include/GameClient/Shell.h # Include/GameClient/ShellHooks.h # Include/GameClient/ShellMenuScheme.h -# Include/GameClient/Smudge.h + Include/GameClient/Smudge.h # Include/GameClient/Snow.h # Include/GameClient/Statistics.h # Include/GameClient/TerrainRoads.h @@ -827,7 +827,7 @@ set(GAMEENGINE_SRC # Source/GameClient/System/Image.cpp # Source/GameClient/System/ParticleSys.cpp # Source/GameClient/System/RayEffect.cpp -# Source/GameClient/System/Smudge.cpp + Source/GameClient/System/Smudge.cpp # Source/GameClient/Terrain/TerrainRoads.cpp # Source/GameClient/Terrain/TerrainVisual.cpp Source/GameClient/VideoPlayer.cpp diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Smudge.h b/Core/GameEngine/Include/GameClient/Smudge.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameClient/Smudge.h rename to Core/GameEngine/Include/GameClient/Smudge.h diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/System/Smudge.cpp b/Core/GameEngine/Source/GameClient/System/Smudge.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameClient/System/Smudge.cpp rename to Core/GameEngine/Source/GameClient/System/Smudge.cpp diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt index 1de9abd7d9..00e5468ad8 100644 --- a/Core/GameEngineDevice/CMakeLists.txt +++ b/Core/GameEngineDevice/CMakeLists.txt @@ -63,7 +63,7 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DShaderManager.h # Include/W3DDevice/GameClient/W3DShadow.h # Include/W3DDevice/GameClient/W3DShroud.h -# Include/W3DDevice/GameClient/W3DSmudge.h + Include/W3DDevice/GameClient/W3DSmudge.h # Include/W3DDevice/GameClient/W3DSnow.h # Include/W3DDevice/GameClient/W3DStatusCircle.h # Include/W3DDevice/GameClient/W3DTerrainBackground.h @@ -165,7 +165,7 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/W3DScene.cpp # Source/W3DDevice/GameClient/W3DShaderManager.cpp # Source/W3DDevice/GameClient/W3DShroud.cpp -# Source/W3DDevice/GameClient/W3DSmudge.cpp + Source/W3DDevice/GameClient/W3DSmudge.cpp # Source/W3DDevice/GameClient/W3DSnow.cpp # Source/W3DDevice/GameClient/W3DStatusCircle.cpp # Source/W3DDevice/GameClient/W3DTerrainBackground.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp diff --git a/Generals/Code/GameEngine/Include/GameClient/CommandXlat.h b/Generals/Code/GameEngine/Include/GameClient/CommandXlat.h index b7f5e88b5d..aebea584fa 100644 --- a/Generals/Code/GameEngine/Include/GameClient/CommandXlat.h +++ b/Generals/Code/GameEngine/Include/GameClient/CommandXlat.h @@ -76,6 +76,7 @@ enum FilterTypes CPP_11(: Int) FT_VIEW_BW_FILTER, //filter to apply a black & white filter to the screen. FT_VIEW_MOTION_BLUR_FILTER, //filter to apply motion blur filter to screen. FT_VIEW_CROSSFADE, ///= DC_GEFORCE2) + { + //Check if their driver is newer than what we tested for this vendor +/* if (TheGameLODManager) + { + if (TheGameLODManager->getTestedDriverVersion(W3DShaderManager::getCurrentVendor()) < W3DShaderManager::getCurrentDriverVersion()) + return FALSE; + }*/ + } + } + + W3DFilters[FT_VIEW_DEFAULT]=&screenDefaultFilter; + + return TRUE; +} + +Bool ScreenDefaultFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) +{ + //Right now this filter is only used for smudges, so don't bother if none are present. + if (TheSmudgeManager) + { if (((W3DSmudgeManager *)TheSmudgeManager)->getSmudgeCountLastFrame() == 0) + return FALSE; + } + W3DShaderManager::startRenderToTexture(); + return true; +} + +Bool ScreenDefaultFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) +{ + IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture(); + DEBUG_ASSERTCRASH(tex, ("Require rendered texture.")); + if (!tex) return false; + if (!set(mode)) return false; + + LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); + + struct _TRANS_LIT_TEX_VERTEX { + D3DXVECTOR4 p; + DWORD color; // diffuse color + float u; + float v; + } v[4]; + + Int xpos, ypos, width, height; + + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture + TheTacticalView->getOrigin(&xpos,&ypos); + width=TheTacticalView->getWidth(); + height=TheTacticalView->getHeight(); + + //bottom right + v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); + v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); + //top right + v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); + v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); + //bottom left + v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); + v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); + //top left + v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); + v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); + v[0].color = 0xffffffff; + v[1].color = 0xffffffff; + v[2].color = 0xffffffff; + v[3].color = 0xffffffff; + + //draw polygons like this is very inefficient but for only 2 triangles, it's + //not worth bothering with index/vertex buffers. + pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); + + pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); + + reset(); + return true; +} + +Int ScreenDefaultFilter::set(FilterModes mode) +{ + VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); + DX8Wrapper::Set_Material(vmat); + REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. + DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader); + DX8Wrapper::Set_Texture(0,NULL); + DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices + + DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); + DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); + DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices + + return true; +} + +void ScreenDefaultFilter::reset(void) +{ + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture + DX8Wrapper::Invalidate_Cached_Render_States(); +} + /*========= ScreenBWFilter =============================================================*/ ///converts viewport to black & white. @@ -1063,10 +1207,7 @@ Int ShroudTextureShader::set(Int stage) VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); DX8Wrapper::Set_Material(vmat); REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - if (stage < 2) - DX8Wrapper::Set_Texture(stage, W3DShaderManager::getShaderTexture(0)); - else //stages larger than 1 are not supported by W3D so set them directly - DX8Wrapper::Set_DX8_Texture(stage, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); + DX8Wrapper::Set_Texture(stage, W3DShaderManager::getShaderTexture(0)); //shroud always stored in texture 0 if (stage == 0) { @@ -1127,6 +1268,99 @@ Int ShroudTextureShader::set(Int stage) } void ShroudTextureShader::reset(void) +{ + DX8Wrapper::Set_Texture(m_stageOfSet,NULL); + DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); + DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXCOORDINDEX, m_stageOfSet); + DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); +} + +///Shroud layer rendering shader +class FlatShroudTextureShader : public W3DShaderInterface +{ + virtual Int set(Int pass); ///Peek_D3D_Texture()); + + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + //DX8Wrapper::Apply_Render_State_Changes(); + + DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + //We need to scale so shroud texel stretches over one full terrain cell. Each texel + //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). + W3DShroud *shroud; + if ((shroud=TheTerrainRenderObject->getShroud()) != 0) + { ///@todo: All this code really only need to be done once per camera/view. Find a way to optimize it out. + D3DXMATRIX inv; + float det; + + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + D3DXMATRIX scale,offset; + + //We need to make all world coordinates be relative to the heightmap data origin since that + //is where the shroud begins. + + float xoffset = 0; + float yoffset = 0; + Real width=shroud->getCellWidth(); + Real height=shroud->getCellHeight(); + + if (TheTerrainRenderObject->getMap()) + { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. + xoffset = -(float)shroud->getDrawOriginX() + width; + yoffset = -(float)shroud->getDrawOriginY() + height; + } + + D3DXMatrixTranslation(&offset, xoffset, yoffset,0); + + width = 1.0f/(width*shroud->getTextureWidth()); + height = 1.0f/(height*shroud->getTextureHeight()); + D3DXMatrixScaling(&scale, width, height, 1); + *((D3DXMATRIX *)&curView) = (inv * offset) * scale; + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4x4*)&curView)); + } + m_stageOfSet=stage; + return TRUE; +} + +void FlatShroudTextureShader::reset(void) { if (m_stageOfSet < MAX_TEXTURE_STAGES) DX8Wrapper::Set_Texture(m_stageOfSet,NULL); @@ -1260,6 +1494,29 @@ class TerrainShader2Stage : public W3DShaderInterface void updateNoise2 (D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate=true); ///= DC_GENERIC_PIXEL_SHADER_1_1) { @@ -2011,14 +2278,9 @@ Int RoadShaderPixelShader::init( void ) Int RoadShaderPixelShader::set(Int pass) { - //after we're done with this shader we're going to reset to NULL texture, so set W3D same way. - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); + DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0)); //force WW3D2 system to set it's states so it won't later overwrite our custom settings. DX8Wrapper::Apply_Render_State_Changes(); - //Directly set texture without W3D knowing... but we'll restore to NULL later. - if (W3DShaderManager::getShaderTexture(0)) - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); //tell pixel shader which UV set to use for each stage DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); @@ -2056,8 +2318,10 @@ Int RoadShaderPixelShader::set(Int pass) DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + + DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); + DX8Wrapper::Set_Texture(2,W3DShaderManager::getShaderTexture(2)); + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); @@ -2081,14 +2345,9 @@ Int RoadShaderPixelShader::set(Int pass) void RoadShaderPixelShader::reset(void) { - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture - DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); @@ -2122,9 +2381,8 @@ Int RoadShader2Stage::init( void ) Int RoadShader2Stage::set(Int pass) { - //after we're done with this shader we're going to reset to NULL texture, so set W3D same way. - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); + //First stage always contains base texture. + DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0)); //Force system to apply world/view transforms. DX8Wrapper::Apply_Render_State_Changes(); @@ -2132,10 +2390,6 @@ Int RoadShader2Stage::set(Int pass) DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); DX8Wrapper::Set_DX8_Render_State(D3DRS_LIGHTING, FALSE); - //first texture unit will always contain base road texture - if (W3DShaderManager::getShaderTexture(0)) - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); - // Modulate the diffuse color with the texture as lighting comes from diffuse. DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); @@ -2182,7 +2436,7 @@ Int RoadShader2Stage::set(Int pass) if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE12) { //full shader, apply noise 1 in pass 0. - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); + DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); @@ -2193,14 +2447,14 @@ Int RoadShader2Stage::set(Int pass) { //single noise texture shader if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE1) { //cloud map - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); + DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); } else { //light map - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(2)); terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); @@ -2228,7 +2482,7 @@ Int RoadShader2Stage::set(Int pass) else DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(2)); terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); @@ -2272,10 +2526,6 @@ void RoadShader2Stage::reset(void) { ShaderClass::Invalidate(); - //Free references to textures - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); @@ -2290,9 +2540,11 @@ W3DShaderInterface **MasterShaderList[]= { TerrainShaderList, ShroudShaderList, + FlatShroudShaderList, RoadShaderList, MaskShaderList, CloudShaderList, + FlatTerrainShaderList, NULL }; @@ -2301,6 +2553,7 @@ W3DShaderInterface **MasterShaderList[]= */ W3DFilterInterface **MasterFilterList[]= { + ScreenDefaultFilterList, ScreenBWFilterList, ScreenMotionBlurFilterList, ScreenCrossFadeFilterList, @@ -2344,9 +2597,11 @@ void W3DShaderManager::init(void) D3DSURFACE_DESC desc; // For now, check & see if we are gf3 or higher on the food chain. - Int res=0; + ChipsetType res=DC_UNKNOWN; if ((res=W3DShaderManager::getChipset()) != 0) { + m_currentChipset = res; //cache the current chipset. + //Some of our effects require an offscreen render target, so try creating it here. HRESULT hr=DX8Wrapper::_Get_D3D_Device8()->GetRenderTarget(&m_oldRenderSurface); @@ -2429,12 +2684,12 @@ void W3DShaderManager::shutdown(void) } } - for ( i=0; i < FT_MAX; i++) - { - if (W3DFilters[i]) - { - W3DFilters[i]->shutdown(); - } + for (i=0; i < FT_MAX; i++) + { + if (W3DFilters[i]) + { + W3DFilters[i]->shutdown(); + } } } @@ -2638,9 +2893,12 @@ IDirect3DTexture8 *W3DShaderManager::getRenderTexture(void) return m_renderTexture; } -#define DC_NVIDIA_VENDOR_ID 0x10DE -#define DC_3DFX_VENDOR_ID 0x121A -#define DC_ATI_VENDOR_ID 0x1002 +enum GraphicsVenderID CPP_11(: Int) +{ + DC_NVIDIA_VENDOR_ID = 0x10DE, + DC_3DFX_VENDOR_ID = 0x121A, + DC_ATI_VENDOR_ID = 0x1002 +}; // W3DShaderManager::ChipsetType ======================================================= /** Returns the chipset used by the currently active rendering device. Can be useful @@ -2662,9 +2920,12 @@ ChipsetType W3DShaderManager::getChipset( void ) D3DADAPTER_IDENTIFIER8 did; ::ZeroMemory(&did, sizeof(D3DADAPTER_IDENTIFIER8)); /* HRESULT res = */ d3d8Interface->GetAdapterIdentifier(0,D3DENUM_NO_WHQL_LEVEL,&did); + *((LARGE_INTEGER*)&m_driverVersion) = did.DriverVersion; if(did.VendorId == DC_NVIDIA_VENDOR_ID) { + m_currentVendor = DC_NVIDIA_VENDOR_ID; + if (did.DeviceId == 0x20) return DC_TNT; @@ -2685,6 +2946,8 @@ ChipsetType W3DShaderManager::getChipset( void ) else if(did.VendorId == DC_3DFX_VENDOR_ID) { + m_currentVendor = DC_3DFX_VENDOR_ID; + if (did.DeviceId == 0x0002) return DC_VOODOO2; if (did.DeviceId == 0x0005) @@ -2697,6 +2960,8 @@ ChipsetType W3DShaderManager::getChipset( void ) else if(did.VendorId == DC_ATI_VENDOR_ID) { + m_currentVendor = DC_ATI_VENDOR_ID; + if (did.DeviceId == 0x5144) return DC_RADEON; if (did.DeviceId == 0x514C) @@ -2735,6 +3000,9 @@ ChipsetType W3DShaderManager::getChipset( void ) //============================================================================= HRESULT W3DShaderManager::LoadAndCreateD3DShader(const char* strFilePath, const DWORD* pDeclaration, DWORD Usage, Bool ShaderType, DWORD* pHandle) { + if (getChipset() < DC_GENERIC_PIXEL_SHADER_1_1) + return E_FAIL; //don't allow loading any shaders if hardware can't handle it. + try { File *file = NULL; @@ -2908,3 +3176,554 @@ Real W3DShaderManager::GetCPUBenchTime(void) QueryPerformanceCounter((LARGE_INTEGER *)&endTime64); return ((double)(endTime64-startTime64)/(double)(freq64)); } + + +// W3DShaderManager::setShroudTex ======================================================= +/** Puts the shroud texture into a texture stage. + */ +//============================================================================= +Int W3DShaderManager::setShroudTex(Int stage) +{ + //We need to scale so shroud texel stretches over one full terrain cell. Each texel + //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). + W3DShroud *shroud; + if ((shroud=TheTerrainRenderObject->getShroud()) != 0) + { + DX8Wrapper::Set_Texture(stage, shroud->getShroudTexture()); + + DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); + D3DXMATRIX inv; + float det; + + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + D3DXMATRIX scale,offset; + + //We need to make all world coordinates be relative to the heightmap data origin since that + //is where the shroud begins. + + float xoffset = 0; + float yoffset = 0; + Real width=shroud->getCellWidth(); + Real height=shroud->getCellHeight(); + + if (TheTerrainRenderObject->getMap()) + { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. + xoffset = -(float)shroud->getDrawOriginX() + width; + yoffset = -(float)shroud->getDrawOriginY() + height; + } + + D3DXMatrixTranslation(&offset, xoffset, yoffset,0); + + width = 1.0f/(width*shroud->getTextureWidth()); + height = 1.0f/(height*shroud->getTextureHeight()); + D3DXMatrixScaling(&scale, width, height, 1); + *((D3DXMATRIX *)&curView) = (inv * offset) * scale; + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4x4*)&curView)); + return TRUE; + } + return FALSE; +} + + + +Int FlatTerrainShader2Stage::init( void ) +{ + //no special device validation needed - anything in our min spec should handle this. + + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShader2Stage; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShader2Stage; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=2; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShader2Stage; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=2; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShader2Stage; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=2; + + return TRUE; +} + +void FlatTerrainShader2Stage::reset(void) +{ + ShaderClass::Invalidate(); + + //Free references to textures + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); +} + + +Int FlatTerrainShader2Stage::set(Int pass) +{ + //force WW3D2 system to set it's states so it won't later overwrite our custom settings. + DX8Wrapper::Apply_Render_State_Changes(); + + if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + } else { + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); + } + if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + } else { + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); + } + + switch (pass) + { + case 0: + + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + // Modulate the diffuse color with the texture as lighting comes from diffuse. + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + if (W3DShaderManager::getShaderTexture(0)) { + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + //We need to scale so shroud texel stretches over one full terrain cell. Each texel + //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). + W3DShroud *shroud; + if ((shroud=TheTerrainRenderObject->getShroud()) != 0) + { + D3DXMATRIX inv; + float det; + + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + D3DXMATRIX scale,offset; + + //We need to make all world coordinates be relative to the heightmap data origin since that + //is where the shroud begins. + + float xoffset = 0; + float yoffset = 0; + Real width=shroud->getCellWidth(); + Real height=shroud->getCellHeight(); + + if (TheTerrainRenderObject->getMap()) + { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. + xoffset = -(float)shroud->getDrawOriginX() + width; + yoffset = -(float)shroud->getDrawOriginY() + height; + } + + D3DXMatrixTranslation(&offset, xoffset, yoffset,0); + + width = 1.0f/(width*shroud->getTextureWidth()); + height = 1.0f/(height*shroud->getTextureHeight()); + D3DXMatrixScaling(&scale, width, height, 1); + *((D3DXMATRIX *)&curView) = (inv * offset) * scale; + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0), *((Matrix4x4*)&curView)); + } + } else { + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); + } + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + // Modulate the diffuse color with the texture as lighting comes from diffuse. + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 0 ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); + DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); + break; + case 1: + // Noise/cloud pass + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + //these states apply to all noise/cloud combination passes + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + // Two output coordinates are used. + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + + //blend into frame buffer + DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); + DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); + DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); + + + D3DXMATRIX inv; + float det; + + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12) + { + //setup cloud pass + + terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix + DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView); + //clouds always need bilinear filtering + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + + //setup noise pass + + terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); + DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); + //noise always needs point/linear filtering. Why point!? + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + // Two output coordinates are used. + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); + } + else + { //only 1 noise or cloud texture + // Now setup the texture pipeline. + if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1) + { //setup cloud pass + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + } + else + { + //setup noise pass + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); + terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + } + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); + DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&curView)); + } + break; + } + + return TRUE; +} + + + + + + +Int FlatTerrainShaderPixelShader::shutdown(void) +{ + if (m_dwBasePixelShader) + DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBasePixelShader); + + if (m_dwBase0PixelShader) + DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBase0PixelShader); + + if (m_dwBaseNoise1PixelShader) + DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise1PixelShader); + + if (m_dwBaseNoise2PixelShader) + DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader); + + m_dwBasePixelShader=NULL; + m_dwBase0PixelShader=NULL; + m_dwBaseNoise1PixelShader=NULL; + m_dwBaseNoise2PixelShader=NULL; + + return TRUE; +} + +Int FlatTerrainShaderPixelShader::init( void ) +{ + Int res; + +#ifdef DISABLE_PIXEL_SHADERS + return false; +#endif + + //this shader will also use the 2Stage shader for some of the passes so initialize it too. + if ((res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1) + { + if (res >= DC_GENERIC_PIXEL_SHADER_1_1) + { + //this shader needs some assets that need to be loaded + //shader decleration + DWORD Declaration[]= + { + (D3DVSD_STREAM(0)), + (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position + (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse + (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates + (D3DVSD_REG(3, D3DVSDT_FLOAT2)), // Texture Coordinates + (D3DVSD_END()) + }; + + //base version which doesn't apply any noise textures. + HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrain.pso", &Declaration[0], 0, false, &m_dwBasePixelShader); + if (FAILED(hr)) + return FALSE; + + //base version which doesn't apply any shroud textures. + hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrain0.pso", &Declaration[0], 0, false, &m_dwBase0PixelShader); + if (FAILED(hr)) + return FALSE; + + //version which blends 1 noise texture. + hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise.pso", &Declaration[0], 0, false, &m_dwBaseNoise1PixelShader); + if (FAILED(hr)) + return FALSE; + + //version which blends 2 noise textures. + hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader); + if (FAILED(hr)) + return FALSE; + + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShaderPixelShader; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShaderPixelShader; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShaderPixelShader; + W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShaderPixelShader; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=1; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=1; + W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=1; + return TRUE; + } + } + return FALSE; +} + +Int FlatTerrainShaderPixelShader::set(Int pass) +{ + //setup base pass + Int curStage = 1; + // setup terrain [3/31/2003] + + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_Texture(0, W3DShaderManager::getShaderTexture(2)); + DX8Wrapper::Set_Texture(1, W3DShaderManager::getShaderTexture(2)); + //force WW3D2 system to set it's states so it won't later overwrite our custom settings. + DX8Wrapper::Apply_Render_State_Changes(); + + + + + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + //tell pixel shader which UV set to use for each stage + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_TEXCOORDINDEX, 0 ); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + + if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + } else { + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_POINT); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_POINT); + } + if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); + } else { + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_POINT); + } + + curStage = 0; + + W3DShroud *shroud = TheTerrainRenderObject->getShroud(); + if (shroud) { + + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + //We need to scale so shroud texel stretches over one full terrain cell. Each texel + //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). + { + D3DXMATRIX inv; + float det; + + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + D3DXMATRIX scale,offset; + + //We need to make all world coordinates be relative to the heightmap data origin since that + //is where the shroud begins. + + float xoffset = 0; + float yoffset = 0; + Real width=shroud->getCellWidth(); + Real height=shroud->getCellHeight(); + + if (TheTerrainRenderObject->getMap()) + { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. + xoffset = -(float)shroud->getDrawOriginX() + width; + yoffset = -(float)shroud->getDrawOriginY() + height; + } + + D3DXMatrixTranslation(&offset, xoffset, yoffset,0); + + width = 1.0f/(width*shroud->getTextureWidth()); + height = 1.0f/(height*shroud->getTextureHeight()); + D3DXMatrixScaling(&scale, width, height, 1); + *((D3DXMATRIX *)&curView) = (inv * offset) * scale; + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); + } + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, shroud->getShroudTexture()->Peek_D3D_Texture()); + curStage++; + if (curStage==1) curStage++; + } + + Bool doNoise1 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1 || + W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12); + if (doNoise1) { // Cloud pass. + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMATRIX inv; + float det; + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + // Two output coordinates are used. + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); + terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + + curStage++; + if (curStage==1) curStage++; + } + + Bool doNoise2 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2 || + W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12); + if (doNoise2) + { + Matrix4x4 curView; + DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); + + D3DXMATRIX inv; + float det; + D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); + + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + // Two output coordinates are used. + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); + terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix + DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + + curStage++; + if (curStage==1) curStage++; + } + if (curStage<2) { + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBase0PixelShader); + } else if (curStage==2) { + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBasePixelShader); + } else if (curStage==3) { + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise1PixelShader); + }else if (curStage==4) { + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader); + } + DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ALPHABLENDENABLE, false); + DX8Wrapper::Apply_Render_State_Changes(); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); + return TRUE; +} + +void FlatTerrainShaderPixelShader::reset(void) +{ + DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture + DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture + + DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader + + DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); + DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2); + + DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); + DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3); + + + DX8Wrapper::Invalidate_Cached_Render_States(); +} + + + + + diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp index b088e3361f..687b972af3 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp @@ -199,8 +199,8 @@ DX8TextureCategoryClass::DX8TextureCategoryClass( WWASSERT(pass>=0); WWASSERT(passGet_Mesh_Model_Class()); } - for (int a=0;ashutdown(); } } - } //============================================================================= diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 55ade9d389..3b72228f9d 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -173,6 +173,11 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h") #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/Smudge.h", Game.CORE, "GameEngine/Include/GameClient/Smudge.h") + #unify_move_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/System/Smudge.cpp", Game.CORE, "GameEngine/Source/GameClient/System/Smudge.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp") + return From 6080343027b69f5e02438d81ba998cfd5b9f5689 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:54:08 +0100 Subject: [PATCH 2/2] unify(shader): Move W3DShaderManager to Core (#1920) --- Core/GameEngineDevice/CMakeLists.txt | 4 +- .../W3DDevice/GameClient/W3DShaderManager.h | 0 .../W3DDevice/GameClient/W3DShaderManager.cpp | 0 Generals/Code/GameEngineDevice/CMakeLists.txt | 4 +- .../W3DDevice/GameClient/W3DShaderManager.h | 253 -- .../W3DDevice/GameClient/W3DShaderManager.cpp | 3729 ----------------- .../Code/GameEngineDevice/CMakeLists.txt | 4 +- scripts/cpp/unify_move_files.py | 2 + 8 files changed, 8 insertions(+), 3988 deletions(-) rename {GeneralsMD/Code => Core}/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h (100%) rename {GeneralsMD/Code => Core}/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp (100%) delete mode 100644 Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h delete mode 100644 Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt index 00e5468ad8..6c390f7d84 100644 --- a/Core/GameEngineDevice/CMakeLists.txt +++ b/Core/GameEngineDevice/CMakeLists.txt @@ -60,7 +60,7 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DPropBuffer.h # Include/W3DDevice/GameClient/W3DRoadBuffer.h # Include/W3DDevice/GameClient/W3DScene.h -# Include/W3DDevice/GameClient/W3DShaderManager.h + Include/W3DDevice/GameClient/W3DShaderManager.h # Include/W3DDevice/GameClient/W3DShadow.h # Include/W3DDevice/GameClient/W3DShroud.h Include/W3DDevice/GameClient/W3DSmudge.h @@ -163,7 +163,7 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/W3DPropBuffer.cpp # Source/W3DDevice/GameClient/W3DRoadBuffer.cpp # Source/W3DDevice/GameClient/W3DScene.cpp -# Source/W3DDevice/GameClient/W3DShaderManager.cpp + Source/W3DDevice/GameClient/W3DShaderManager.cpp # Source/W3DDevice/GameClient/W3DShroud.cpp Source/W3DDevice/GameClient/W3DSmudge.cpp # Source/W3DDevice/GameClient/W3DSnow.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt index 0f26cbd753..7d91eaf43e 100644 --- a/Generals/Code/GameEngineDevice/CMakeLists.txt +++ b/Generals/Code/GameEngineDevice/CMakeLists.txt @@ -52,7 +52,7 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DProjectedShadow.h Include/W3DDevice/GameClient/W3DRoadBuffer.h Include/W3DDevice/GameClient/W3DScene.h - Include/W3DDevice/GameClient/W3DShaderManager.h +# Include/W3DDevice/GameClient/W3DShaderManager.h Include/W3DDevice/GameClient/W3DShadow.h Include/W3DDevice/GameClient/W3DShroud.h Include/W3DDevice/GameClient/W3DStatusCircle.h @@ -151,7 +151,7 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/W3DPoly.cpp Source/W3DDevice/GameClient/W3DRoadBuffer.cpp Source/W3DDevice/GameClient/W3DScene.cpp - Source/W3DDevice/GameClient/W3DShaderManager.cpp +# Source/W3DDevice/GameClient/W3DShaderManager.cpp Source/W3DDevice/GameClient/W3DShroud.cpp Source/W3DDevice/GameClient/W3DStatusCircle.cpp Source/W3DDevice/GameClient/W3DTerrainTracks.cpp diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h deleted file mode 100644 index c05274218d..0000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h +++ /dev/null @@ -1,253 +0,0 @@ -/* -** Command & Conquer Generals(tm) -** Copyright 2025 Electronic Arts Inc. -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DShaderManager.h ///////////////////////////////////////////////////////// -// -// Custom shader system that allows more options and easier device validation than -// possible with W3D2. -// -// Author: Mark Wilczynski, August 2001 -// -/////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "WW3D2/texture.h" -enum FilterTypes CPP_11(: Int); -enum FilterModes CPP_11(: Int); -enum CustomScenePassModes CPP_11(: Int); -enum StaticGameLODLevel CPP_11(: Int); -enum ChipsetType CPP_11(: Int); -enum CpuType CPP_11(: Int); -enum GraphicsVenderID CPP_11(: Int); - -class TextureClass; ///forward reference -/** System for managing complex rendering settings which are either not handled by - WW3D2 or need custom paths depending on the video card. This system will determine - the proper shader given video card limitations and also allow the app to query the - hardware for specific features. -*/ -class W3DShaderManager -{ -public: - - //put any custom shaders (not going through W3D) in here. - enum ShaderTypes - { ST_INVALID, //invalid shader type. - ST_TERRAIN_BASE, //shader to apply base terrain texture only - ST_TERRAIN_BASE_NOISE1, //shader to apply base texture and cloud/noise 1. - ST_TERRAIN_BASE_NOISE2, //shader to apply base texture and cloud/noise 2. - ST_TERRAIN_BASE_NOISE12,//shader to apply base texture and both cloud/noise - ST_SHROUD_TEXTURE, //shader to apply shroud texture projection. - ST_MASK_TEXTURE, //shader to apply alpha mask texture projection. - ST_ROAD_BASE, //shader to apply base terrain texture only - ST_ROAD_BASE_NOISE1, //shader to apply base texture and cloud/noise 1. - ST_ROAD_BASE_NOISE2, //shader to apply base texture and cloud/noise 2. - ST_ROAD_BASE_NOISE12,//shader to apply base texture and both cloud/noise - ST_CLOUD_TEXTURE, //shader to project clouds. - ST_FLAT_TERRAIN_BASE, //shader to apply base terrain texture only - ST_FLAT_TERRAIN_BASE_NOISE1, //shader to apply base texture and cloud/noise 1. - ST_FLAT_TERRAIN_BASE_NOISE2, //shader to apply base texture and cloud/noise 2. - ST_FLAT_TERRAIN_BASE_NOISE12,//shader to apply base texture and both cloud/noise - ST_FLAT_SHROUD_TEXTURE, //shader to apply shroud texture projection. - ST_MAX - }; - - - W3DShaderManager(void); ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DShaderManager.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DShaderManager.cpp -// -// Created: Mark Wilczynski, August 2001 -// -// Desc: Perform tests on currently selected WW3D/D3D device to determine -// which of our rendering features are supported. The system allows -// setting up a few custom shaders that are selected based on video -// card features. -// -// To add a new shader to the system: -// 0) Add your shader to the ShaderTypes enum -// 1) Create shader using W3DShaderInterface -// 2) Repeat step 1 for any alternate shaders -// 3) Create list of alternate shaders sorted by order of preference. -// The first shader which passes hardware validation will be selected. -// 4) Add list from step 3) to MasterShaderList[]. -// -//----------------------------------------------------------------------------- - -#include "dx8wrapper.h" -#include "assetmgr.h" -#include "Lib/BaseType.h" -#include "Common/file.h" -#include "Common/FileSystem.h" -#include "W3DDevice/GameClient/W3DShaderManager.h" -#include "W3DDevice/GameClient/W3DShroud.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "W3DDevice/GameClient/W3DCustomScene.h" -#include "W3DDevice/GameClient/W3DSmudge.h" -#include "GameClient/View.h" -#include "GameClient/CommandXlat.h" -#include "GameClient/Display.h" -#include "GameClient/Water.h" -#include "GameLogic/GameLogic.h" -#include "Common/GlobalData.h" -#include "Common/GameLOD.h" -#include "d3dx8tex.h" -#include "dx8caps.h" - - -// Turn this on to turn off pixel shaders. jba[4/3/2003] -#define do_not_DISABLE_PIXEL_SHADERS 1 - -/** Interface definition for custom shaders we define in our app. These shaders can perform more complex - operations than those allowed in the WW3D2 shader system. -*/ -class W3DShaderInterface -{ -public: - Int getNumPasses(void) {return m_numPasses;}; ///SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL);}; - virtual Int init(void) = 0; ///= DC_GEFORCE2) - { - //Check if their driver is newer than what we tested for this vendor -/* if (TheGameLODManager) - { - if (TheGameLODManager->getTestedDriverVersion(W3DShaderManager::getCurrentVendor()) < W3DShaderManager::getCurrentDriverVersion()) - return FALSE; - }*/ - } - } - - W3DFilters[FT_VIEW_DEFAULT]=&screenDefaultFilter; - - return TRUE; -} - -Bool ScreenDefaultFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - //Right now this filter is only used for smudges, so don't bother if none are present. - if (TheSmudgeManager) - { if (((W3DSmudgeManager *)TheSmudgeManager)->getSmudgeCountLastFrame() == 0) - return FALSE; - } - W3DShaderManager::startRenderToTexture(); - return true; -} - -Bool ScreenDefaultFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) -{ - IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture(); - DEBUG_ASSERTCRASH(tex, ("Require rendered texture.")); - if (!tex) return false; - if (!set(mode)) return false; - - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - } v[4]; - - Int xpos, ypos, width, height; - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[0].color = 0xffffffff; - v[1].color = 0xffffffff; - v[2].color = 0xffffffff; - v[3].color = 0xffffffff; - - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - reset(); - return true; -} - -Int ScreenDefaultFilter::set(FilterModes mode) -{ - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - return true; -} - -void ScreenDefaultFilter::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -/*========= ScreenBWFilter =============================================================*/ -///converts viewport to black & white. - -Int ScreenBWFilter::m_fadeFrames; -Int ScreenBWFilter::m_curFadeFrame; -Real ScreenBWFilter::m_curFadeValue; -Int ScreenBWFilter::m_fadeDirection; - -ScreenBWFilter screenBWFilter; -ScreenBWFilterDOT3 screenBWFilterDOT3; //slower version for older cards without pixel shaders. - -///List of different BW shader implementations in order of preference -W3DFilterInterface *ScreenBWFilterList[]= -{ - &screenBWFilter, - &screenBWFilterDOT3, //slower version for older cards without pixel shaders. - NULL -}; - -Int ScreenBWFilter::init(void) -{ - Int res; - HRESULT hr; - - m_dwBWPixelShader = NULL; - m_curFadeFrame = 0; - - if (!W3DShaderManager::canRenderToTexture()) { - // Have to be able to render to texture. - return false; - } - - if ((res=W3DShaderManager::getChipset()) != 0) - { - if (res >= DC_GENERIC_PIXEL_SHADER_1_1) - { - //this shader needs some assets that need to be loaded - //shader decleration - DWORD Declaration[]= - { - (D3DVSD_STREAM(0)), - (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position - (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse - (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_END()) - }; - - //Monochrome pixel shader. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\monochrome.pso", &Declaration[0], 0, false, &m_dwBWPixelShader); - if (FAILED(hr)) - return FALSE; - - W3DFilters[FT_VIEW_BW_FILTER]=&screenBWFilter; - - return TRUE; - } - } - return FALSE; -} - -Bool ScreenBWFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - skipRender = false; - W3DShaderManager::startRenderToTexture(); - return true; -} - -Bool ScreenBWFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) -{ - IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture(); - DEBUG_ASSERTCRASH(tex, ("Require rendered texture.")); - if (!tex) return false; - if (!set(mode)) return false; - - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - } v[4]; - - Int xpos, ypos, width, height; - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[0].color = 0xffffffff; - v[1].color = 0xffffffff; - v[2].color = 0xffffffff; - v[3].color = 0xffffffff; - - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - reset(); - return true; -} - -Int ScreenBWFilter::set(FilterModes mode) -{ - HRESULT hr; - - if (mode > FM_NULL_MODE) - { //rendering a quad with redirected rendering surface tinted by pixel shader - - if (m_fadeDirection > 0) - { //turning effect on - m_curFadeFrame++; - Int fade = m_curFadeFrame; - - if (fadesetViewFilterMode(FM_NULL_MODE); - TheTacticalView->setViewFilter(FT_NULL_FILTER); - m_curFadeFrame = 0; - m_fadeDirection = 0; - } - } - - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - hr=DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBWPixelShader); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(0, D3DXVECTOR4(0.3f, 0.59f, 0.11f, 1.0f), 1); - - D3DXVECTOR4 color(1.0f,1.0f,1.0f,1.0f); //multiply color - - if (mode == FM_VIEW_BW_BLACK_AND_WHITE) - { //back & white mode - color.x=1.0f; - color.y=1.0f; - color.z=1.0f; - } - if (mode == FM_VIEW_BW_RED_AND_WHITE) - { //red is on - color.x = 1.0f; - color.y = 0.0f; - color.z = 0.0f; - //inverse red is on - //red is on -// color.x = 0.0f; -// color.y = 1.0f; -// color.z = 1.0f; - } - if (mode == FM_VIEW_BW_GREEN_AND_WHITE) - { - color.x = 0.0f; - color.y = 1.0f; - color.z = 0.0f; - } - - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(1, color, 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(2, D3DXVECTOR4(m_curFadeValue, m_curFadeValue, m_curFadeValue, 1.0f), 1); -/* DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(2, D3DXVECTOR4(150.0f/255.0f, 150.0f/255.0f, 150.0f/255.0f, 0.0f), 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(3, D3DXVECTOR4((765.0f/450.0f)/3, (765.0f/450.0f)/3, (765.0f/450.0f)/3, 1.0f), 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(4, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0), 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(5, D3DXVECTOR4((60.0f)/255.0f, (60.0f)/255.0f, (60.0f)/255.0f, 0), 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(6, D3DXVECTOR4((157.0f)/255.0f, (157.0f)/255.0f, (157.0f)/255.0f, 0), 1); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShaderConstant(7, D3DXVECTOR4((30.0f)/255.0f, (30.0f)/255.0f, (30.0f)/255.0f, 0), 1); -*/ - return true; - } - return false; -} - -void ScreenBWFilter::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int ScreenBWFilter::shutdown(void) -{ - if (m_dwBWPixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBWPixelShader); - - m_dwBWPixelShader=NULL; - - return TRUE; -} - -/**Alternate version of the above filter which does not require pixel shaders - good for older cards*/ -Int ScreenBWFilterDOT3::init(void) -{ - Int res; - - m_curFadeFrame = 0; - - if (!W3DShaderManager::canRenderToTexture()) { - // Have to be able to render to texture. - return false; - } - - if ((res=W3DShaderManager::getChipset()) != 0) - { - W3DFilters[FT_VIEW_BW_FILTER]=&screenBWFilterDOT3; - return TRUE; - } - return FALSE; -} - -Bool ScreenBWFilterDOT3::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - skipRender = false; - W3DShaderManager::startRenderToTexture(); - return true; -} - -Bool ScreenBWFilterDOT3::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) -{ - IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture(); - DEBUG_ASSERTCRASH(tex, ("Require rendered texture.")); - if (!tex) return false; - if (!set(mode)) return false; - - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - } v[4]; - - Int xpos, ypos, width, height; - - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - - DWORD currentFade=(((Int)((1.0f-m_curFadeValue) * 255.0f))<<24) | 0x00ffffff; //store alpha value - - v[0].color = currentFade; - v[1].color = currentFade; - v[2].color = currentFade; - v[3].color = currentFade; - - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - //Draw B&W version first - if (DX8Wrapper::Get_Current_Caps()->Support_Dot3()) - { //Override W3D states with customizations for grayscale - DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0x80A5CA8E); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG0, D3DTA_TFACTOR | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_CURRENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3); - } - else - { //doesn't have DOT3 blend mode so fake it another way. - DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR, 0x60606060); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - } - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - //Draw normal view blended by current fade level - ShaderClass::Invalidate(); //reset DOT3 blend from above. - ShaderClass shader=ShaderClass::_PresetAlphaShader; - shader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); - DX8Wrapper::Set_Shader(shader); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - //replace texture alpha with vertex alpha - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - reset(); - return true; -} - -Int ScreenBWFilterDOT3::set(FilterModes mode) -{ - if (mode > FM_NULL_MODE) - { //rendering a quad with redirected rendering surface tinted by pixel shader - - if (m_fadeDirection > 0) - { //turning effect on - m_curFadeFrame++; - Int fade = m_curFadeFrame; - - if (fadesetViewFilterMode(FM_NULL_MODE); - TheTacticalView->setViewFilter(FT_NULL_FILTER); - m_curFadeFrame = 0; - m_fadeDirection = 0; - } - } - - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - return true; - } - return false; -} - -void ScreenBWFilterDOT3::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int ScreenBWFilterDOT3::shutdown(void) -{ - return TRUE; -} - -/*========= ScreenCrossFadeFilter =============================================================*/ -///Fades screen between 2 different views of the scene with both being visible at once. - -Int ScreenCrossFadeFilter::m_fadeFrames; -Int ScreenCrossFadeFilter::m_curFadeFrame; -Real ScreenCrossFadeFilter::m_curFadeValue; -Int ScreenCrossFadeFilter::m_fadeDirection; -TextureClass *ScreenCrossFadeFilter::m_fadePatternTexture=NULL; -Bool ScreenCrossFadeFilter::m_skipRender = FALSE; - -ScreenCrossFadeFilter screenCrossFadeFilter; - -///List of different BW shader implementations in order of preference -///@todo: Add a version that doesn't require pixel shader -W3DFilterInterface *ScreenCrossFadeFilterList[]= -{ - &screenCrossFadeFilter, - NULL -}; - -Int ScreenCrossFadeFilter::init(void) -{ - if (!TheDisplay) - return FALSE; //effect is useless without a view so no point initializing for the WB, etc. - - m_curFadeFrame = 0; - - if (!W3DShaderManager::canRenderToTexture()) - // Have to be able to render to texture. - return FALSE; - - //Load an alpha mask texture that will mix foreground/background views. - m_fadePatternTexture=WW3DAssetManager::Get_Instance()->Get_Texture("exmask_g.tga"); - if (!m_fadePatternTexture) - return FALSE; - m_fadePatternTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - m_fadePatternTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - m_fadePatternTexture->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); - - W3DFilters[FT_VIEW_CROSSFADE]=&screenCrossFadeFilter; - - return TRUE; -} - -Bool ScreenCrossFadeFilter::updateFadeLevel(void) -{ - if (m_fadeDirection > 0) - { //turning effect on - m_curFadeFrame++; - Int fade = m_curFadeFrame; - - if (fadesetViewFilterMode(FM_NULL_MODE); - TheTacticalView->setViewFilter(FT_NULL_FILTER); - m_curFadeFrame = 0; - m_fadeDirection = 0; - return false; - } - } - return true; -} - -Bool ScreenCrossFadeFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - if (updateFadeLevel()) - { //if fade has not completed - W3DShaderManager::startRenderToTexture(); - scenePassMode=SCENE_PASS_ALPHA_MASK; - skipRender = false; - m_skipRender=true; //tell the postRender function not to draw into framebuffer yet. - return true; - } - //fade must have completed - return true; -} - -Bool ScreenCrossFadeFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) -{ - IDirect3DTexture8 * tex; - - if (m_skipRender) - { - //don't render anything to frame buffer because we still need to draw the new scene - //that we're fading into. Okay to render on the next call. - m_skipRender = false; - doExtraRender = TRUE; - tex = W3DShaderManager::endRenderToTexture(); - return true; - } - - tex=W3DShaderManager::getRenderTexture(); - - DEBUG_ASSERTCRASH(tex, ("Require last rendered texture.")); - if (!tex) return false; - if (!set(mode)) return false; - - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - float u1; - float v1; - } v[4]; - - Int xpos, ypos, width, height; - Real radius = 0.0f; - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture - if (mode == FM_VIEW_CROSSFADE_CIRCLE) - { DX8Wrapper::_Get_D3D_Device8()->SetTexture(1,m_fadePatternTexture->Peek_D3D_Texture()); - //Use the current fade level to scale the mask texture, for other modes the texture - //comes pre-scaled so doesn't require uv scaling. - radius = (1.0f-m_curFadeValue)*2.0f; - if (radius <= 0) - radius = 0.01f; - radius = 0.5f/radius; - } - - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - -/* Real radius = (1.0f-m_curFadeValue); - if (radius <= 0) - radius = 0.01f; - radius = 25.0f-radius*24.75f; -*/ - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - v[0].u1 = 0.5f+radius; v[0].v1 = 0.5f+radius; - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[1].u1 = 0.5f+radius; v[1].v1 = 0.5f-radius; - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - v[2].u1 = 0.5f-radius; v[2].v1 = 0.5f+radius; - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[3].u1 = 0.5f-radius; v[3].v1 = 0.5f-radius; - - DWORD diffuse = 0xffffffff;//((Int)((m_curFadeValue) * 255.0f) << 24) | 0x00ffffff; //store alpha value in vertex diffuse - - v[0].color = diffuse; - v[1].color = diffuse; - v[2].color = diffuse; - v[3].color = diffuse; - - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2); - -// m_pDev->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT); -// m_pDev->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT); - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - reset(); - return true; -} - -Int ScreenCrossFadeFilter::set(FilterModes mode) -{ - if (mode > FM_NULL_MODE) - { //rendering a quad with redirected rendering surface - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaShader); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - if (mode == FM_VIEW_CROSSFADE_CIRCLE) - { //cross-fading using circle mask stored in stage 1 - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_MIPFILTER, D3DTEXF_NONE); - } - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - - return true; - } - return false; -} - -void ScreenCrossFadeFilter::reset(void) -{ - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int ScreenCrossFadeFilter::shutdown(void) -{ - REF_PTR_RELEASE(m_fadePatternTexture); - - return TRUE; -} - -/*========= ScreenMotionBlurFilter =============================================================*/ -///applies motion blur to viewport. - -ScreenMotionBlurFilter screenMotionBlurFilter; - -Coord3D ScreenMotionBlurFilter::m_zoomToPos; -Bool ScreenMotionBlurFilter::m_zoomToValid = false; - -ScreenMotionBlurFilter::ScreenMotionBlurFilter(): -m_decrement(false), -m_maxCount(0), -m_lastFrame(0), -m_skipRender(false) -{ -} -///List of different motion blur implementations in order of preference -W3DFilterInterface *ScreenMotionBlurFilterList[]= -{ - &screenMotionBlurFilter, - NULL -}; - -Int ScreenMotionBlurFilter::init(void) -{ - if (!W3DShaderManager::canRenderToTexture()) { - // Have to be able to render to texture. - return false; - } - W3DFilters[FT_VIEW_MOTION_BLUR_FILTER]=this; - return true; -} - -Bool ScreenMotionBlurFilter::preRender(Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - skipRender = m_skipRender; - W3DShaderManager::startRenderToTexture(); - return true; -} - -Bool ScreenMotionBlurFilter::postRender(FilterModes mode, Coord2D &scrollDelta,Bool &doExtraRender) -{ - IDirect3DTexture8 * tex = W3DShaderManager::endRenderToTexture(); - DEBUG_ASSERTCRASH(tex, ("Require rendered texture.")); - if (!tex) return false; - if (!set(mode)) return false; - - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - Bool continueEffect = true; - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - } v[4]; - - Int xpos, ypos, width, height; - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,tex); //previously rendered frame inside this texture - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[0].color = 0xffffffff; - v[1].color = 0xffffffff; - v[2].color = 0xffffffff; - v[3].color = 0xffffffff; - - - if (m_additive) { - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ONE); - } else { - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - } - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - DX8Wrapper::Apply_Render_State_Changes(); - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - Coord2D center; - center.x = 0.5f; - center.y = 0.5f; - Bool pan = false; - if (mode>=FM_VIEW_MB_PAN_ALPHA) { - Real len = sqrt(scrollDelta.x*scrollDelta.x + scrollDelta.y*scrollDelta.y); - //center.x += 0.5f * (scrollDelta.x/len); - center.y -= 0.5f; // * (scrollDelta.y/len); - m_decrement = false; - m_maxCount = (len*200*m_panFactor/(Real)DEFAULT_PAN_FACTOR); - if (m_maxCountm_panFactor) - m_maxCount=m_panFactor; - pan = true; - m_priorDelta = scrollDelta; - } else if (mode == FM_VIEW_MB_END_PAN_ALPHA) { - Real len = sqrt(m_priorDelta.x*m_priorDelta.x + m_priorDelta.y*m_priorDelta.y); - center.x += 0.5f * (m_priorDelta.x/len); - center.y -= 0.5f * (m_priorDelta.y/len); - m_decrement = false; - m_maxCount--; - if (m_maxCount<2) { - continueEffect = false; - } - pan = true; - } - - - m_skipRender = false; - if (!pan && m_lastFrame != TheGameLogic->getFrame()) { - if (m_decrement) { - m_maxCount-=COUNT_STEP; - if (m_maxCount<1) { - m_decrement = false; - continueEffect = false; - } else { - m_skipRender = true; - } - } else { - m_maxCount+=COUNT_STEP; - if (m_maxCount>=MAX_COUNT) { - m_decrement = true; - if (m_doZoomTo && m_zoomToValid) { - TheTacticalView->lookAt(&m_zoomToPos); - } else { - continueEffect = false; - } - } else { - m_skipRender = true; - } - } - } - Int i, j; - if (!pan) { - for (i=0; i<4; i++) { - Real factor = 1.0f - (m_maxCount/(Real)MAX_COUNT)*0.90f; - factor = sqrt(factor); - v[i].u = ((v[i].u-center.x)*factor) + center.x; - v[i].v = ((v[i].v-center.y)*factor) + center.y; - } - } - pDev->SetTextureStageState(0,D3DTSS_ALPHAARG1, D3DTA_CURRENT); - pDev->SetTextureStageState(0,D3DTSS_ALPHAARG2, D3DTA_TEXTURE); - pDev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - - DX8Wrapper::Apply_Render_State_Changes(); - { - Int limit = m_maxCount; - if (m_maxCount>30) limit = 30; - for (j=0; jlimit) { - alpha += (m_maxCount-limit)/5; - } - if (m_maxCount==MAX_COUNT) alpha += 60; - } - v[i].color = (alpha<<24)|0x00ffffff; // - if (pan) { - v[i].u = ((v[i].u-center.x)*(factor+.006)) + center.x; - v[i].v = ((v[i].v-center.y)*factor) + center.y; - } else { - v[i].u = ((v[i].u-center.x)*factor) + center.x; - v[i].v = ((v[i].v-center.y)*factor) + center.y; - } - } - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); - - } - } - m_lastFrame = TheGameLogic->getFrame(); - if (pan){ - m_skipRender = false; - } - reset(); - if (!continueEffect) { - m_zoomToValid = false; - } - return continueEffect; -} - -Bool ScreenMotionBlurFilter::setup(FilterModes mode) -{ - - m_additive = false; - - if (mode == FM_VIEW_MB_IN_AND_OUT_SATURATE || - mode == FM_VIEW_MB_IN_SATURATE || - mode == FM_VIEW_MB_OUT_SATURATE) { - m_additive = true; - } - - m_doZoomTo = false; - if (mode == FM_VIEW_MB_IN_AND_OUT_SATURATE || - mode == FM_VIEW_MB_IN_AND_OUT_ALPHA ) { - m_doZoomTo = true; - } - if (mode >= FM_VIEW_MB_PAN_ALPHA) { - m_panFactor = (int)mode - FM_VIEW_MB_PAN_ALPHA; - if (m_panFactor<1) m_panFactor = DEFAULT_PAN_FACTOR; - } - m_skipRender = false; - if (mode != FM_VIEW_MB_END_PAN_ALPHA) - m_maxCount = 0; - m_decrement = false; - m_skipRender = false; - switch (mode) { - case FM_VIEW_MB_OUT_SATURATE: - case FM_VIEW_MB_OUT_ALPHA: - m_maxCount = MAX_COUNT; - m_decrement = TRUE; - break; - } - return true; -} - -Int ScreenMotionBlurFilter::set(FilterModes mode) -{ - if (mode > FM_NULL_MODE) - { //rendering a quad with redirected rendering surface motion blurred - - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueShader); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_ALWAYS); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Apply_Render_State_Changes(); //force update of view and projection matrices - } - return TRUE; -} - -void ScreenMotionBlurFilter::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0,NULL); //previously rendered frame inside this texture - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int ScreenMotionBlurFilter::shutdown(void) -{ - return TRUE; -} - -/*===========================================================================================*/ -/*========= Shroud Shaders =============================================================*/ -/*===========================================================================================*/ - -///Shroud layer rendering shader -class ShroudTextureShader : public W3DShaderInterface -{ - virtual Int set(Int pass); ///m_fogOfWarOn) - DX8Wrapper::Set_Shader(ShaderClass::_PresetAlphaSpriteShader); - else - DX8Wrapper::Set_Shader(ShaderClass::_PresetMultiplicativeSpriteShader); -#else - DX8Wrapper::Set_Shader(ShaderClass::_PresetMultiplicativeSpriteShader); -#endif - } - DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_EQUAL); - - //We need to scale so shroud texel stretches over one full terrain cell. Each texel - //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). - W3DShroud *shroud; - if ((shroud=TheTerrainRenderObject->getShroud()) != 0) - { ///@todo: All this code really only need to be done once per camera/view. Find a way to optimize it out. - D3DXMATRIX inv; - float det; - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - D3DXMATRIX scale,offset; - - //We need to make all world coordinates be relative to the heightmap data origin since that - //is where the shroud begins. - - float xoffset = 0; - float yoffset = 0; - Real width=shroud->getCellWidth(); - Real height=shroud->getCellHeight(); - - if (TheTerrainRenderObject->getMap()) - { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. - xoffset = -(float)shroud->getDrawOriginX() + width; - yoffset = -(float)shroud->getDrawOriginY() + height; - } - - D3DXMatrixTranslation(&offset, xoffset, yoffset,0); - - width = 1.0f/(width*shroud->getTextureWidth()); - height = 1.0f/(height*shroud->getTextureHeight()); - D3DXMatrixScaling(&scale, width, height, 1); - *((D3DXMATRIX *)&curView) = (inv * offset) * scale; - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4x4*)&curView)); - } - m_stageOfSet=stage; - return TRUE; -} - -void ShroudTextureShader::reset(void) -{ - DX8Wrapper::Set_Texture(m_stageOfSet,NULL); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); - DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXCOORDINDEX, m_stageOfSet); - DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); -} - -///Shroud layer rendering shader -class FlatShroudTextureShader : public W3DShaderInterface -{ - virtual Int set(Int pass); ///Peek_D3D_Texture()); - - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - //DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - //We need to scale so shroud texel stretches over one full terrain cell. Each texel - //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). - W3DShroud *shroud; - if ((shroud=TheTerrainRenderObject->getShroud()) != 0) - { ///@todo: All this code really only need to be done once per camera/view. Find a way to optimize it out. - D3DXMATRIX inv; - float det; - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - D3DXMATRIX scale,offset; - - //We need to make all world coordinates be relative to the heightmap data origin since that - //is where the shroud begins. - - float xoffset = 0; - float yoffset = 0; - Real width=shroud->getCellWidth(); - Real height=shroud->getCellHeight(); - - if (TheTerrainRenderObject->getMap()) - { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. - xoffset = -(float)shroud->getDrawOriginX() + width; - yoffset = -(float)shroud->getDrawOriginY() + height; - } - - D3DXMatrixTranslation(&offset, xoffset, yoffset,0); - - width = 1.0f/(width*shroud->getTextureWidth()); - height = 1.0f/(height*shroud->getTextureHeight()); - D3DXMatrixScaling(&scale, width, height, 1); - *((D3DXMATRIX *)&curView) = (inv * offset) * scale; - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4x4*)&curView)); - } - m_stageOfSet=stage; - return TRUE; -} - -void FlatShroudTextureShader::reset(void) -{ - if (m_stageOfSet < MAX_TEXTURE_STAGES) - DX8Wrapper::Set_Texture(m_stageOfSet,NULL); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); - DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXCOORDINDEX, m_stageOfSet); - DX8Wrapper::Set_DX8_Texture_Stage_State(m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); -} - -///Mask layer rendering shader -class MaskTextureShader : public W3DShaderInterface -{ - virtual Int set(Int pass); ///getOrigin(&xpos,&ypos); - - ICoord2D screenPos; - screenPos.x=(Real)TheTacticalView->getWidth()*0.5f; - screenPos.y=(Real)TheTacticalView->getHeight()*0.5f; - TheTacticalView->screenToTerrain(&screenPos,¢erPos); - } - - D3DXMatrixTranslation(&offset, -centerPos.x, -centerPos.y,0); - - D3DXMatrixTranslation(&offsetTextureCenter, 0.5f, 0.5f, 0); //shift coordinates so center of projection falls at uv 0.5,0.5 - - Real worldTexelWidth=(1.0f-fadeLevel)*25.0f; //9 worked well for circle but weird shape requires more stretch to cover. - Real worldTexelHeight=(1.0f-fadeLevel)*25.0f; - - ///@todo: Fix this to work with non 128x128 textures. - if (worldTexelWidth != 0 && worldTexelHeight != 0) - { Real widthScale = 1.0f/(worldTexelWidth*128.0f); - Real heightScale = 1.0f/(worldTexelHeight*128.0f); - D3DXMatrixScaling(&scale, widthScale, heightScale, 1); - *((D3DXMATRIX *)&curView) = ((inv * offset) * scale)*offsetTextureCenter; - } - else - { D3DXMatrixScaling(&scale, 0, 0, 1); //scaling by 0 will set uv coordinates to 0,0 - *((D3DXMATRIX *)&curView) = ((inv * offset) * scale); - } - - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&curView)); - - return TRUE; -} - -void MaskTextureShader::reset(void) -{ - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, 0); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); -} - -/*===========================================================================================*/ -/*========= Terrain Shaders =========================================================*/ -/*===========================================================================================*/ - -///regular terrain shader that should work on all multi-texture video cards (slowest version) -class TerrainShader2Stage : public W3DShaderInterface -{ -public: - float m_xSlidePerSecond ; ///< How far the clouds move per second. - float m_ySlidePerSecond ; ///< How far the clouds move per second. - float m_xOffset; - float m_yOffset; - - virtual Int set(Int pass); ///clip space. - -///Pixel shader based terrain shader - fastest method for the newest cards. -class TerrainShaderPixelShader : public W3DShaderInterface -{ - DWORD m_dwBasePixelShader; ///SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); -} - -void TerrainShader2Stage::updateCloud() -{ - const float frame_time = WW3D::Get_Logic_Frame_Time_Seconds(); - m_xOffset += m_xSlidePerSecond * frame_time; - m_yOffset += m_ySlidePerSecond * frame_time; - - // This moves offsets towards zero when smaller -1.0 or larger 1.0 - m_xOffset -= (Int)m_xOffset; - m_yOffset -= (Int)m_yOffset; -} - -void TerrainShader2Stage::updateNoise1(D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate) -{ - #define STRETCH_FACTOR ((float)(1/(63.0*MAP_XY_FACTOR/2))) /* covers 63/2 tiles */ - - D3DXMATRIX scale; - - D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1); - *destMatrix = *curViewInverse * scale; - - D3DXMATRIX offset; - D3DXMatrixTranslation(&offset, m_xOffset, m_yOffset,0); - *destMatrix *= offset; -} - -void TerrainShader2Stage::updateNoise2(D3DXMATRIX *destMatrix,D3DXMATRIX *curViewInverse, Bool doUpdate) -{ - - D3DXMATRIX scale; - - D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1); - *destMatrix = *curViewInverse * scale; -} - -Int TerrainShader2Stage::set(Int pass) -{ - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } - - switch (pass) - { - case 0: - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); - break; - case 1: - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 ); - // Blend the result using the alpha. (came from diffuse mod texture) - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - // Disable stage 2. - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - break; - case 2: - // Noise/cloud pass - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - //these states apply to all noise/cloud combination passes - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - //blend into frame buffer - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); - - - D3DXMATRIX inv; - float det; - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE12) - { - //setup cloud pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - - updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView); - //clouds always need bilinear filtering - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - //setup noise pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - - updateNoise2(((D3DXMATRIX*)&curView),&inv); - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); - //noise always needs point/linear filtering. Why point!? - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - } - else - { //only 1 noise or cloud texture - // Now setup the texture pipeline. - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE1) - { //setup cloud pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - else - { - //setup noise pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&curView)); - } - break; - } - - return TRUE; -} - -Int TerrainShader8Stage::init( void ) -{ - ChipsetType res; - - //this shader will also use the 2Stage shader for some of the passes so initialize it too. - if (terrainShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_TNT && res <= DC_GEFORCE2) - { - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE]=&terrainShader8Stage; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE]=1; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=&terrainShader8Stage; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=2; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=&terrainShader8Stage; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=2; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=&terrainShader8Stage; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=2; - return TRUE; - } - - return FALSE; -} - -Int TerrainShader8Stage::set(Int pass) -{ - if (pass == 0) - { - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(2, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, 2); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG2, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(3, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, 3); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE | 0 | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(4, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_TEXCOORDINDEX, 4); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG1, D3DTA_CURRENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - DX8Wrapper::Set_DX8_Texture(5, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLOROP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_TEXCOORDINDEX, 5); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG1, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAOP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(6, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_TEXCOORDINDEX, 6); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(7, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_TEXCOORDINDEX, 7); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - } - else - { //setup cloud noise/pass - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - DX8Wrapper::Invalidate_Cached_Render_States(); - - terrainShader2Stage.set(2); - } - return TRUE; -} - -void TerrainShader8Stage::reset(void) -{ - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int TerrainShaderPixelShader::shutdown(void) -{ - if (m_dwBasePixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBasePixelShader); - - if (m_dwBaseNoise1PixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise1PixelShader); - - if (m_dwBaseNoise2PixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader); - - m_dwBasePixelShader=NULL; - m_dwBaseNoise1PixelShader=NULL; - m_dwBaseNoise2PixelShader=NULL; - - return TRUE; -} - -Int TerrainShaderPixelShader::init( void ) -{ - Int res; -#ifdef DISABLE_PIXEL_SHADERS - return false; -#endif - //this shader will also use the 2Stage shader for some of the passes so initialize it too. - if (terrainShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1) - { - if (res >= DC_GENERIC_PIXEL_SHADER_1_1) - { - //this shader needs some assets that need to be loaded - //shader decleration - DWORD Declaration[]= - { - (D3DVSD_STREAM(0)), - (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position - (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse - (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_REG(3, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_END()) - }; - - //base version which doesn't apply any noise textures. - HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrain.pso", &Declaration[0], 0, false, &m_dwBasePixelShader); - if (FAILED(hr)) - return FALSE; - - //version which blends 1 noise texture. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrainnoise.pso", &Declaration[0], 0, false, &m_dwBaseNoise1PixelShader); - if (FAILED(hr)) - return FALSE; - - //version which blends 2 noise textures. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\terrainnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader); - if (FAILED(hr)) - return FALSE; - - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE]=&terrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=&terrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=&terrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=&terrainShaderPixelShader; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE]=1; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE1]=1; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE2]=1; - W3DShadersPassCount[W3DShaderManager::ST_TERRAIN_BASE_NOISE12]=1; - return TRUE; - } - } - return FALSE; -} - -Int TerrainShaderPixelShader::set(Int pass) -{ - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - //setup base pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(1)->Peek_D3D_Texture()); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - //tell pixel shader which UV set to use for each stage - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 ); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } - - if (W3DShaderManager::getCurrentShader() >= W3DShaderManager::ST_TERRAIN_BASE_NOISE1) - { - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE12) - { //full shader - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(3, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView); - - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE3, curView); - - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - } - else - { //single noise texture shader - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise1PixelShader); - - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_TERRAIN_BASE_NOISE1) - { //cloud map - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - else - { //light map - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView); - } - } - else - { //just base texturing - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBasePixelShader); - } - - return TRUE; -} - -void TerrainShaderPixelShader::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture - DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture - - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3); - - - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -///Cloud layer rendering shader - used for objects similar to terrain which only need the cloud layer. -class CloudTextureShader : public W3DShaderInterface -{ - virtual Int set(Int stage); ///SetTexture(stage, W3DShaderManager::getShaderTexture(stage)->Peek_D3D_Texture()); - - m_stageOfSet=stage; - return TRUE; -} - -void CloudTextureShader::reset(void) -{ - //Free reference to texture - DX8Wrapper::_Get_D3D_Device8()->SetTexture(m_stageOfSet, NULL); - //Turn off texture projection - DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|m_stageOfSet); - - DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( m_stageOfSet, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); -} - -/*===========================================================================================*/ -/*========= Road Shaders =========================================================*/ -/*===========================================================================================*/ -class RoadShaderPixelShader : public W3DShaderInterface -{ - DWORD m_dwBaseNoise2PixelShader; ///DeletePixelShader(m_dwBaseNoise2PixelShader); - - m_dwBaseNoise2PixelShader=NULL; - - return TRUE; -} - -Int RoadShaderPixelShader::init( void ) -{ - Int res; - - //this shader will also use the 2Stage shader for some of the passes so initialize it too. - if (roadShader2Stage.init() && (res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1) - { - if (res >= DC_GENERIC_PIXEL_SHADER_1_1) - { - //this shader needs some assets that need to be loaded - //shader decleration - DWORD Declaration[]= - { - (D3DVSD_STREAM(0)), - (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position - (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse - (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_END()) - }; - - //version which blends 2 noise textures. - HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\roadnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader); - if (FAILED(hr)) - return FALSE; - - //Only set this shader for use in dual noise mode. The 2Stage shader will take care of - //all the other modes. - W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE12]=&roadShaderPixelShader; - W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE12]=1; - return TRUE; - } - } - return FALSE; -} - -Int RoadShaderPixelShader::set(Int pass) -{ - DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0)); - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - //tell pixel shader which UV set to use for each stage - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Set_DX8_Render_State(D3DRS_LIGHTING, FALSE); - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); //blend roads into terrain - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) - { DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } - else - { DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); - DX8Wrapper::Set_Texture(2,W3DShaderManager::getShaderTexture(2)); - - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); - - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE2, curView); - - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - return TRUE; -} - -void RoadShaderPixelShader::reset(void) -{ - - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3); - - - DX8Wrapper::Invalidate_Cached_Render_States(); -} - -Int RoadShader2Stage::init( void ) -{ - //no special device validation needed - anything in our min spec should handle this. - W3DShaders[W3DShaderManager::ST_ROAD_BASE]=&roadShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE]=1; - W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE1]=&roadShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE1]=1; - W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE2]=&roadShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE2]=1; - W3DShaders[W3DShaderManager::ST_ROAD_BASE_NOISE12]=&roadShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_ROAD_BASE_NOISE12]=2; - - return TRUE; -} - -Int RoadShader2Stage::set(Int pass) -{ - //First stage always contains base texture. - DX8Wrapper::Set_Texture(0,W3DShaderManager::getShaderTexture(0)); - //Force system to apply world/view transforms. - DX8Wrapper::Apply_Render_State_Changes(); - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZFUNC,D3DCMP_LESSEQUAL); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ZWRITEENABLE,FALSE); - DX8Wrapper::Set_DX8_Render_State(D3DRS_LIGHTING, FALSE); - - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); //blend roads into terrain - - if (pass == 0) - { - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - - if (W3DShaderManager::getCurrentShader() >= W3DShaderManager::ST_ROAD_BASE_NOISE1) - { //second texture unit will contain a noise pass - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - else - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE12) - { //full shader, apply noise 1 in pass 0. - DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //get texture projection matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); - } - else - { //single noise texture shader - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_ROAD_BASE_NOISE1) - { //cloud map - DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(1)); - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - else - { //light map - DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(2)); - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); - } - } - else - { //just base texturing - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - } - } - else - { //pass 1, apply additional noise pass - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - else - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); - - DX8Wrapper::Set_Texture(1,W3DShaderManager::getShaderTexture(2)); - - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv, false); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - //Copy alpha channel into stage 1 but mask out color channel by replacing with white. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - //Force color channel to white by copying the alpha into RGB - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE|D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - //Modulate into existing roads with clouds applied. - only apply where roads are transparent by - //using road texture as a mask. - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_ZERO); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR); - - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView); - } - - return TRUE; -} - -void RoadShader2Stage::reset(void) -{ - ShaderClass::Invalidate(); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); -} - -/** List of all custom shader lists - each list in this list contains variations of the same - shader to allow it to work on different hardware configurations. -*/ -W3DShaderInterface **MasterShaderList[]= -{ - TerrainShaderList, - ShroudShaderList, - FlatShroudShaderList, - RoadShaderList, - MaskShaderList, - CloudShaderList, - FlatTerrainShaderList, - NULL -}; - -/** List of all custom filter lists - each list in this list contains variations of the same - filter to allow it to work on different hardware configurations. -*/ -W3DFilterInterface **MasterFilterList[]= -{ - ScreenDefaultFilterList, - ScreenBWFilterList, - ScreenMotionBlurFilterList, - ScreenCrossFadeFilterList, - NULL -}; - -// W3DShaderManager::W3DShaderManager ========================================= -/** Constructor - just clears some variables */ -//============================================================================= -W3DShaderManager::W3DShaderManager(void) -{ - m_currentShader = ST_INVALID; - m_currentFilter = FT_NULL_FILTER; - m_oldRenderSurface = NULL; - m_renderTexture = NULL; - m_newRenderSurface = NULL; - m_oldDepthSurface = NULL; - m_renderingToTexture = false; - Int i; - for (i=0; iGetRenderTarget(&m_oldRenderSurface); - - m_oldRenderSurface->GetDesc(&desc); - - hr=DX8Wrapper::_Get_D3D_Device8()->CreateTexture(desc.Width,desc.Height,1,D3DUSAGE_RENDERTARGET,desc.Format,D3DPOOL_DEFAULT,&m_renderTexture); - - if (hr != S_OK) - { - if (m_oldRenderSurface) m_oldRenderSurface->Release(); - m_oldRenderSurface = NULL; - m_renderTexture = NULL; - } else { - hr = m_renderTexture->GetSurfaceLevel(0, &m_newRenderSurface); - if (hr != S_OK) - { - if (m_renderTexture) m_renderTexture->Release(); - m_renderTexture = NULL; - m_newRenderSurface = NULL; - } else { - hr = DX8Wrapper::_Get_D3D_Device8()->GetDepthStencilSurface(&m_oldDepthSurface); - if (hr != S_OK) - { - if (m_newRenderSurface) m_newRenderSurface->Release(); - if (m_renderTexture) m_renderTexture->Release(); - m_renderTexture = NULL; - m_newRenderSurface = NULL; - m_oldDepthSurface = NULL; - } - } - } - } - - W3DShaderInterface **shaders; - - for (i=0; MasterShaderList[i] != NULL; i++) - { - shaders=MasterShaderList[i]; - for (j=0; shaders[j] != NULL; j++) - { - if (shaders[j]->init()) - break; //found a working shader - } - } - W3DFilterInterface **filters; - - for (i=0; MasterFilterList[i] != NULL; i++) - { - filters=MasterFilterList[i]; - for (j=0; filters[j] != NULL; j++) - { - if (filters[j]->init()) - break; //found a working shader - } - } - - DEBUG_LOG(("ShaderManager ChipsetID %d", res)); -} - -// W3DShaderManager::shutdown ======================================================= -/** Any shaders which allocate resources will be allowed to free them */ -//============================================================================= -void W3DShaderManager::shutdown(void) -{ - if (m_newRenderSurface) m_newRenderSurface->Release(); - if (m_renderTexture) m_renderTexture->Release(); - if (m_oldRenderSurface) m_oldRenderSurface->Release(); - if (m_oldDepthSurface) m_oldDepthSurface->Release(); - m_renderTexture = NULL; - m_newRenderSurface = NULL; - m_oldDepthSurface = NULL; - m_oldRenderSurface = NULL; - m_currentShader = ST_INVALID; - m_currentFilter = FT_NULL_FILTER; - //release any assets associated with a shader (vertex/pixel shaders, textures, etc.) - Int i=0; - for (; ishutdown(); - } - } - - for (i=0; i < FT_MAX; i++) - { - if (W3DFilters[i]) - { - W3DFilters[i]->shutdown(); - } - } -} - -//============================================================================= -void W3DShaderManager::updateCloud() -{ - terrainShader2Stage.updateCloud(); -} - -// W3DShaderManager::getShaderPasses ======================================================= -/** Return number of renderig passes required in perform the desired shader on current - hardware. App will need to re-render the polygons this many times to complete the - effect. - */ -//============================================================================= -Int W3DShaderManager::getShaderPasses(ShaderTypes shader) -{ - return W3DShadersPassCount[shader]; -} - -// W3DShaderManager::setShader ======================================================= -/** Must call this method before each rendering pass in order to perform proper D3D - setup for each shader. - */ -//============================================================================= -Int W3DShaderManager::setShader(ShaderTypes shader, Int pass) -{ - if (shader == m_currentShader && pass == m_currentShaderPass) - return TRUE; //shader is already set - m_currentShader=shader; - m_currentShaderPass = pass; - if (W3DShaders[shader]) - return W3DShaders[shader]->set(pass); - return FALSE; -} - -// W3DShaderManager::resetShader ======================================================= -/** Must call this method after all polygons and rendering passes have been submitted. - This method allows D3D to reset itself to a default state that doesn't conflict - with the WW3D2 Shader system. - */ -//============================================================================= -void W3DShaderManager::resetShader(ShaderTypes shader) -{ - if (m_currentShader == ST_INVALID) - return; //last shader is already reset. - if (W3DShaders[shader]) - W3DShaders[shader]->reset(); - m_currentShader = ST_INVALID; -} -// W3DShaderManager::filterPreRender ======================================================= -/** Call to view filter shaders before rendering starts. - */ -//============================================================================= -Bool W3DShaderManager::filterPreRender(FilterTypes filter, Bool &skipRender, CustomScenePassModes &scenePassMode) -{ - if (W3DFilters[filter]) - { Bool result=W3DFilters[filter]->preRender(skipRender,scenePassMode); - if (result) - m_currentFilter = filter; - return result; - } - return FALSE; -} - -// W3DShaderManager::filterPostRender ======================================================= -/** Call to view filter shaders after rendering is complete. - */ -//============================================================================= -Bool W3DShaderManager::filterPostRender(FilterTypes filter, FilterModes mode, Coord2D &scrollDelta, Bool &doExtraRender) -{ - if (W3DFilters[filter]) - return W3DFilters[filter]->postRender(mode, scrollDelta,doExtraRender); - - m_currentFilter = FT_NULL_FILTER; - return FALSE; -} - -// W3DShaderManager::filterPostRender ======================================================= -/** Call to view filter shaders after rendering is complete. - */ -//============================================================================= - static Bool filterSetup(FilterTypes filter, FilterModes mode); -Bool W3DShaderManager::filterSetup(FilterTypes filter, FilterModes mode) -{ - if (W3DFilters[filter]) - return W3DFilters[filter]->setup(mode); - return FALSE; -} - -/*Draws 2 triangles covering the viewport given the current render states*/ -void W3DShaderManager::drawViewport(Int color) -{ - LPDIRECT3DDEVICE8 pDev=DX8Wrapper::_Get_D3D_Device8(); - - struct _TRANS_LIT_TEX_VERTEX { - D3DXVECTOR4 p; - DWORD color; // diffuse color - float u; - float v; - } v[4]; - - Int xpos, ypos, width, height; - - TheTacticalView->getOrigin(&xpos,&ypos); - width=TheTacticalView->getWidth(); - height=TheTacticalView->getHeight(); - - //bottom right - v[0].p = D3DXVECTOR4( xpos+width-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[0].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[0].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top right - v[1].p = D3DXVECTOR4( xpos+width-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[1].u = (Real)(xpos+width)/(Real)TheDisplay->getWidth(); v[1].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - //bottom left - v[2].p = D3DXVECTOR4( xpos-0.5f, ypos+height-0.5f, 0.0f, 1.0f ); - v[2].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[2].v = (Real)(ypos+height)/(Real)TheDisplay->getHeight(); - //top left - v[3].p = D3DXVECTOR4( xpos-0.5f, ypos-0.5f, 0.0f, 1.0f ); - v[3].u = (Real)(xpos)/(Real)TheDisplay->getWidth(); v[3].v = (Real)(ypos)/(Real)TheDisplay->getHeight(); - v[0].color = color; - v[1].color = color; - v[2].color = color; - v[3].color = color; - - //draw polygons like this is very inefficient but for only 2 triangles, it's - //not worth bothering with index/vertex buffers. - pDev->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - pDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(_TRANS_LIT_TEX_VERTEX)); -} - -// W3DShaderManager::startRenderToTexture ======================================================= -/** Starts rendering to a texture. - */ -//============================================================================= -void W3DShaderManager::startRenderToTexture(void) -{ - DEBUG_ASSERTCRASH(!m_renderingToTexture, ("Already rendering to texture - cannot nest calls.")); - - if (m_renderingToTexture || m_newRenderSurface==NULL || m_oldDepthSurface==NULL) return; - HRESULT hr = DX8Wrapper::_Get_D3D_Device8()->SetRenderTarget(m_newRenderSurface,m_oldDepthSurface); - DEBUG_ASSERTCRASH(hr==S_OK, ("Set target failed unexpectedly.")); - if (hr != S_OK) - return; - m_renderingToTexture = true; - if (TheGlobalData->m_showSoftWaterEdge) - { //Soft water edges use frame buffer destination alpha so we must clear it to a known value. - if (m_currentFilter == FT_VIEW_MOTION_BLUR_FILTER || m_currentFilter == FT_VIEW_CROSSFADE) - { //these filters rely on the previous frame being visible so we must be careful about clearing - //frame buffer. Only clear the alpha channel - DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_ALPHA); //only clear alpha - ShaderClass shader=ShaderClass::_PresetOpaqueSolidShader; - shader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); - shader.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE); - DX8Wrapper::Set_Shader(shader); - - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); //no need to keep a reference since it's a preset. - - drawViewport(0x00ffffff | (((Int)(TheWaterTransparency->m_minWaterOpacity*255.0f)) <<24)); - DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE); //disable writes to alpha - } - else //normal clear that overwrites everything. - DX8Wrapper::Clear(true, false, Vector3( 0.0f, 0.0f, 0.0f ), TheWaterTransparency->m_minWaterOpacity); - } -} - -// W3DShaderManager::startRenderToTexture ======================================================= -/** Ends rendering to a texture. - */ -//============================================================================= -IDirect3DTexture8 *W3DShaderManager::endRenderToTexture(void) -{ - DEBUG_ASSERTCRASH(m_renderingToTexture, ("Not rendering to texture.")); - if (!m_renderingToTexture) return NULL; - HRESULT hr = DX8Wrapper::_Get_D3D_Device8()->SetRenderTarget(m_oldRenderSurface,m_oldDepthSurface); //restore original render target - DEBUG_ASSERTCRASH(hr==S_OK, ("Set target failed unexpectedly.")); - if (hr == S_OK) - { - //assume render target texure will be in stage 0. Most hardware has "conditional" support for - //non-power-of-2 textures so we must force some required states: - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE); - - m_renderingToTexture = false; - } - return m_renderTexture; -} - -/**Returns texture containing the image that was last rendered using any of the effects requiring render target -textures. Used mostly for cross-fading effects that need an unmodified version of the view before the effect -was applied. NOTE: This texture does not survive device reset.. so quit effect on reset!*/ -IDirect3DTexture8 *W3DShaderManager::getRenderTexture(void) -{ - return m_renderTexture; -} - -enum GraphicsVenderID CPP_11(: Int) -{ - DC_NVIDIA_VENDOR_ID = 0x10DE, - DC_3DFX_VENDOR_ID = 0x121A, - DC_ATI_VENDOR_ID = 0x1002 -}; - -// W3DShaderManager::ChipsetType ======================================================= -/** Returns the chipset used by the currently active rendering device. Can be useful - for coding around specific driver bugs. - */ -//============================================================================= -ChipsetType W3DShaderManager::getChipset( void ) -{ - //check if globaldata has an override for current chipset - if (TheGlobalData && TheGlobalData->m_chipSetType != DC_UNKNOWN) - return (ChipsetType)TheGlobalData->m_chipSetType; - - ChipsetType chip=DC_UNKNOWN; - IDirect3D8* d3d8Interface=DX8Wrapper::_Get_D3D8(); - - if (d3d8Interface && DX8Wrapper::_Get_D3D_Device8()) - { - - D3DADAPTER_IDENTIFIER8 did; - ::ZeroMemory(&did, sizeof(D3DADAPTER_IDENTIFIER8)); - /* HRESULT res = */ d3d8Interface->GetAdapterIdentifier(0,D3DENUM_NO_WHQL_LEVEL,&did); - *((LARGE_INTEGER*)&m_driverVersion) = did.DriverVersion; - - if(did.VendorId == DC_NVIDIA_VENDOR_ID) - { - m_currentVendor = DC_NVIDIA_VENDOR_ID; - - if (did.DeviceId == 0x20) - return DC_TNT; - - if (did.DeviceId >= 0x28 && did.DeviceId < 0x100) - return DC_TNT2; - - if ( (did.DeviceId >= 0x100 && did.DeviceId <= 0x103) || //GeForce - (did.DeviceId >= 0x110 && did.DeviceId <= 0x113) || //GeForce2 MX - (did.DeviceId >= 0x150 && did.DeviceId <= 0x153) ) //GeForce2 - return DC_GEFORCE2; - - if (did.DeviceId >= 0x200 && did.DeviceId < 0x250) - return DC_GEFORCE3; - - if (did.DeviceId >= 0x250) - return DC_GEFORCE4; - } - else - if(did.VendorId == DC_3DFX_VENDOR_ID) - { - m_currentVendor = DC_3DFX_VENDOR_ID; - - if (did.DeviceId == 0x0002) - return DC_VOODOO2; - if (did.DeviceId == 0x0005) - return DC_VOODOO3; - if (did.DeviceId == 0x0008) ///@todo: Just guessing on this one - find actual Voodoo4 deviceID. - return DC_VOODOO4; - if (did.DeviceId == 0x0009) - return DC_VOODOO5; - } - else - if(did.VendorId == DC_ATI_VENDOR_ID) - { - m_currentVendor = DC_ATI_VENDOR_ID; - - if (did.DeviceId == 0x5144) - return DC_RADEON; - if (did.DeviceId == 0x514C) - return DC_RADEON_8500; - if (did.DeviceId == 0x4e44) - return DC_RADEON_9700; - } - - //None of the vendor specific ID's matched so use generic means to classify the card - Int maxTextures=DX8Wrapper::Get_Current_Caps()->Get_Max_Simultaneous_Textures(); - Real pixelShaderVersion; - - char buf[256]; - - //Convert version to Real - sprintf(buf,"%d.%d",DX8Wrapper::Get_Current_Caps()->Get_Pixel_Shader_Major_Version(),DX8Wrapper::Get_Current_Caps()->Get_Pixel_Shader_Minor_Version()); - sscanf(buf,"%f",&pixelShaderVersion); - - if (maxTextures >= 4) - { if (pixelShaderVersion >= 1.1f) - chip=DC_GENERIC_PIXEL_SHADER_1_1; - if (pixelShaderVersion >= 1.4f) - chip=DC_GENERIC_PIXEL_SHADER_1_4; - if (maxTextures >= 8 && pixelShaderVersion >= 2.0f) - chip=DC_GENERIC_PIXEL_SHADER_2_0; - } - } - - return chip; -} - -//============================================================================= -// WaterRenderObjClass::LoadAndCreateShader -//============================================================================= -/** Loads and creates a D3D pixel or vertex shader.*/ -//============================================================================= -HRESULT W3DShaderManager::LoadAndCreateD3DShader(const char* strFilePath, const DWORD* pDeclaration, DWORD Usage, Bool ShaderType, DWORD* pHandle) -{ - if (getChipset() < DC_GENERIC_PIXEL_SHADER_1_1) - return E_FAIL; //don't allow loading any shaders if hardware can't handle it. - - try - { - File *file = NULL; - HRESULT hr; - - file = TheFileSystem->openFile(strFilePath, File::READ | File::BINARY); - if (file == NULL) - { - OutputDebugString("Could not find file \n" ); - return E_FAIL; - } - - FileInfo fileInfo; - TheFileSystem->getFileInfo(AsciiString(strFilePath), &fileInfo); - DWORD dwFileSize = fileInfo.sizeLow; - - const DWORD* pShader = (DWORD*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwFileSize); - if (!pShader) - { - OutputDebugString( "Failed to allocate memory to load shader\n " ); - return E_FAIL; - } - - file->read((void *)pShader, dwFileSize); - - file->close(); - file = NULL; - - if (ShaderType) // SHADERTYPE_VERTEX - { - hr = DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader(pDeclaration, pShader, pHandle, Usage); - } - else // SHADERTYPE_PIXEL - { - hr = DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader(pShader, pHandle); - } - - HeapFree(GetProcessHeap(), 0, (void*)pShader); - - if (FAILED(hr)) - { - OutputDebugString( "Failed to create shader\n "); - return E_FAIL; - } - } - catch(...) - { - OutputDebugString( "Error opening file \n" ); - return E_FAIL; - } - - return S_OK; -} - -//For the MP test, we're enforcing high min-spec requirements that need to be verified. -#define MIN_INTEL_CPU_FREQ 1300 -#define MIN_AMD_CPU_FREQ 1100 -#define MIN_ACCEPTED_FREQUENCY 1300 -#define MIN_ACCEPTED_MEMORY (1024*1024*256) //256 MB -#define MIN_ACCEPTED_TEXTURE_MEMORY (1024*1024*30) //30 MB - -/**Hack to give gameengine access to this function*/ -Bool testMinimumRequirements(ChipsetType *videoChipType, CpuType *cpuType, Int *cpuFreq, MemValueType *numRAM, Real *intBenchIndex, Real *floatBenchIndex, Real *memBenchIndex) -{ - return W3DShaderManager::testMinimumRequirements(videoChipType,cpuType,cpuFreq,numRAM,intBenchIndex,floatBenchIndex,memBenchIndex); -} - -Bool W3DShaderManager::testMinimumRequirements(ChipsetType *videoChipType, CpuType *cpuType, Int *cpuFreq, MemValueType *numRAM, Real *intBenchIndex, Real *floatBenchIndex, Real *memBenchIndex) -{ - if (videoChipType) - *videoChipType = getChipset(); - - if (cpuType) - { - *cpuType = XX; //unknown - - //Check if it's an Athlon - if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_AMD && - CPUDetectClass::Get_AMD_Processor() >= CPUDetectClass::AMD_PROCESSOR_ATHLON_025) - *cpuType = K7; - - //Check if it's a P3 - if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_INTEL && - CPUDetectClass::Get_Intel_Processor() >= CPUDetectClass::INTEL_PROCESSOR_PENTIUM_III_MODEL_7) - *cpuType = P3; - //Check if it's a P4 - if (CPUDetectClass::Get_Processor_Manufacturer() == CPUDetectClass::MANUFACTURER_INTEL && - CPUDetectClass::Get_Intel_Processor() >= CPUDetectClass::INTEL_PROCESSOR_PENTIUM4) - *cpuType = P4; - } - - if (cpuFreq) - *cpuFreq=CPUDetectClass::Get_Processor_Speed(); - - if (numRAM) - *numRAM=CPUDetectClass::Get_Total_Physical_Memory(); - - if (intBenchIndex && floatBenchIndex && memBenchIndex) - { - // TheSuperHackers @tweak Aliendroid1 19/06/2025 Legacy benchmarking code was removed. - // Since modern hardware always meets the minimum requirements, we preset the benchmark "results" to a high value. - *intBenchIndex = 10.0f; - *floatBenchIndex = 10.0f; - *memBenchIndex = 10.0f; - } - - return TRUE; -} - -/**Try to guess how well the video card will handle the game assuming very fast CPU*/ -StaticGameLODLevel W3DShaderManager::getGPUPerformanceIndex(void) -{ - ChipsetType chipType; - StaticGameLODLevel detailSetting=STATIC_GAME_LOD_LOW; //assume lowest settings for now. - - if ((chipType=getChipset()) != DC_UNKNOWN) - { //a known video card so we can make some assumptions - if (chipType >= DC_GEFORCE2) - detailSetting=STATIC_GAME_LOD_LOW; //these cards need multiple terrain passes. - if (chipType >= DC_GENERIC_PIXEL_SHADER_1_1) //these cards can do terrain in single pass. - detailSetting=STATIC_GAME_LOD_VERY_HIGH; - } - - return detailSetting; -} - -/**We need a hardware independent method to compare different CPU's. For lack of anything better, we'll -use time to calculate PIE using a slow random number algorithm.*/ - -/**Used to test function call overhead*/ -void add(float *sum,float *addend) -{ - *sum = *sum + *addend; -} - -/**Returns seconds needed to run the test*/ -Real W3DShaderManager::GetCPUBenchTime(void) -{ - float ztot, yran, ymult, ymod, x, y, z, pi, prod; - long int low, ixran, itot, j, iprod; - - __int64 endTime64,freq64,startTime64; - QueryPerformanceFrequency((LARGE_INTEGER *)&freq64); - QueryPerformanceCounter((LARGE_INTEGER *)&startTime64); - - ztot = 0.0; - low = 1; - ixran = 1907; - yran = 5813.0; - ymult = 1307.0; - ymod = 5471.0; - itot = 560000; //total iterations. This value ends up running at ~30 fps on our P4-2.2Ghz. - - for(j=1; j<=itot; j++) - { - iprod = 27611 * ixran; - ixran = iprod - 74383*(long int)(iprod/74383); - x = (float)ixran / 74383.0; - prod = ymult * yran; - yran = (prod - ymod*(long int)(prod/ymod)); - y = yran / ymod; - z = x*x + y*y; - add(&ztot,&z); - if ( z <= 1.0 ) - { - low = low + 1; - } - } - pi = 4.0 * (float)low/(float)itot; - - QueryPerformanceCounter((LARGE_INTEGER *)&endTime64); - return ((double)(endTime64-startTime64)/(double)(freq64)); -} - - -// W3DShaderManager::setShroudTex ======================================================= -/** Puts the shroud texture into a texture stage. - */ -//============================================================================= -Int W3DShaderManager::setShroudTex(Int stage) -{ - //We need to scale so shroud texel stretches over one full terrain cell. Each texel - //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). - W3DShroud *shroud; - if ((shroud=TheTerrainRenderObject->getShroud()) != 0) - { - DX8Wrapper::Set_Texture(stage, shroud->getShroudTexture()); - - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); - D3DXMATRIX inv; - float det; - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - D3DXMATRIX scale,offset; - - //We need to make all world coordinates be relative to the heightmap data origin since that - //is where the shroud begins. - - float xoffset = 0; - float yoffset = 0; - Real width=shroud->getCellWidth(); - Real height=shroud->getCellHeight(); - - if (TheTerrainRenderObject->getMap()) - { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. - xoffset = -(float)shroud->getDrawOriginX() + width; - yoffset = -(float)shroud->getDrawOriginY() + height; - } - - D3DXMatrixTranslation(&offset, xoffset, yoffset,0); - - width = 1.0f/(width*shroud->getTextureWidth()); - height = 1.0f/(height*shroud->getTextureHeight()); - D3DXMatrixScaling(&scale, width, height, 1); - *((D3DXMATRIX *)&curView) = (inv * offset) * scale; - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+stage), *((Matrix4x4*)&curView)); - return TRUE; - } - return FALSE; -} - - - -Int FlatTerrainShader2Stage::init( void ) -{ - //no special device validation needed - anything in our min spec should handle this. - - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=2; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=2; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShader2Stage; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=2; - - return TRUE; -} - -void FlatTerrainShader2Stage::reset(void) -{ - ShaderClass::Invalidate(); - - //Free references to textures - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); -} - - -Int FlatTerrainShader2Stage::set(Int pass) -{ - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - switch (pass) - { - case 0: - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - if (W3DShaderManager::getShaderTexture(0)) { - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(0)->Peek_D3D_Texture()); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - //We need to scale so shroud texel stretches over one full terrain cell. Each texel - //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). - W3DShroud *shroud; - if ((shroud=TheTerrainRenderObject->getShroud()) != 0) - { - D3DXMATRIX inv; - float det; - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - D3DXMATRIX scale,offset; - - //We need to make all world coordinates be relative to the heightmap data origin since that - //is where the shroud begins. - - float xoffset = 0; - float yoffset = 0; - Real width=shroud->getCellWidth(); - Real height=shroud->getCellHeight(); - - if (TheTerrainRenderObject->getMap()) - { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. - xoffset = -(float)shroud->getDrawOriginX() + width; - yoffset = -(float)shroud->getDrawOriginY() + height; - } - - D3DXMatrixTranslation(&offset, xoffset, yoffset,0); - - width = 1.0f/(width*shroud->getTextureWidth()); - height = 1.0f/(height*shroud->getTextureHeight()); - D3DXMatrixScaling(&scale, width, height, 1); - *((D3DXMATRIX *)&curView) = (inv * offset) * scale; - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0), *((Matrix4x4*)&curView)); - } - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - } - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); - break; - case 1: - // Noise/cloud pass - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - //these states apply to all noise/cloud combination passes - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - //blend into frame buffer - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); - - - D3DXMATRIX inv; - float det; - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12) - { - //setup cloud pass - - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, curView); - //clouds always need bilinear filtering - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - - //setup noise pass - - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, curView); - //noise always needs point/linear filtering. Why point!? - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - } - else - { //only 1 noise or cloud texture - // Now setup the texture pipeline. - if (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1) - { //setup cloud pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - else - { - //setup noise pass - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&curView)); - } - break; - } - - return TRUE; -} - - - - - - -Int FlatTerrainShaderPixelShader::shutdown(void) -{ - if (m_dwBasePixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBasePixelShader); - - if (m_dwBase0PixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBase0PixelShader); - - if (m_dwBaseNoise1PixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise1PixelShader); - - if (m_dwBaseNoise2PixelShader) - DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(m_dwBaseNoise2PixelShader); - - m_dwBasePixelShader=NULL; - m_dwBase0PixelShader=NULL; - m_dwBaseNoise1PixelShader=NULL; - m_dwBaseNoise2PixelShader=NULL; - - return TRUE; -} - -Int FlatTerrainShaderPixelShader::init( void ) -{ - Int res; - -#ifdef DISABLE_PIXEL_SHADERS - return false; -#endif - - //this shader will also use the 2Stage shader for some of the passes so initialize it too. - if ((res=W3DShaderManager::getChipset()) >= DC_GENERIC_PIXEL_SHADER_1_1) - { - if (res >= DC_GENERIC_PIXEL_SHADER_1_1) - { - //this shader needs some assets that need to be loaded - //shader decleration - DWORD Declaration[]= - { - (D3DVSD_STREAM(0)), - (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // Position - (D3DVSD_REG(1, D3DVSDT_D3DCOLOR)), // Diffuse - (D3DVSD_REG(2, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_REG(3, D3DVSDT_FLOAT2)), // Texture Coordinates - (D3DVSD_END()) - }; - - //base version which doesn't apply any noise textures. - HRESULT hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrain.pso", &Declaration[0], 0, false, &m_dwBasePixelShader); - if (FAILED(hr)) - return FALSE; - - //base version which doesn't apply any shroud textures. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrain0.pso", &Declaration[0], 0, false, &m_dwBase0PixelShader); - if (FAILED(hr)) - return FALSE; - - //version which blends 1 noise texture. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise.pso", &Declaration[0], 0, false, &m_dwBaseNoise1PixelShader); - if (FAILED(hr)) - return FALSE; - - //version which blends 2 noise textures. - hr = W3DShaderManager::LoadAndCreateD3DShader("shaders\\fterrainnoise2.pso", &Declaration[0], 0, false, &m_dwBaseNoise2PixelShader); - if (FAILED(hr)) - return FALSE; - - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=&flatTerrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=&flatTerrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=&flatTerrainShaderPixelShader; - W3DShaders[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=&flatTerrainShaderPixelShader; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE]=1; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1]=1; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2]=1; - W3DShadersPassCount[W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12]=1; - return TRUE; - } - } - return FALSE; -} - -Int FlatTerrainShaderPixelShader::set(Int pass) -{ - //setup base pass - Int curStage = 1; - // setup terrain [3/31/2003] - - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_Texture(0, W3DShaderManager::getShaderTexture(2)); - DX8Wrapper::Set_Texture(1, W3DShaderManager::getShaderTexture(2)); - //force WW3D2 system to set it's states so it won't later overwrite our custom settings. - DX8Wrapper::Apply_Render_State_Changes(); - - - - - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - //tell pixel shader which UV set to use for each stage - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - curStage = 0; - - W3DShroud *shroud = TheTerrainRenderObject->getShroud(); - if (shroud) { - - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - //We need to scale so shroud texel stretches over one full terrain cell. Each texel - //is 1/128 the size of full texture. (assuming 128x128 vid-mem texture). - { - D3DXMATRIX inv; - float det; - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - D3DXMATRIX scale,offset; - - //We need to make all world coordinates be relative to the heightmap data origin since that - //is where the shroud begins. - - float xoffset = 0; - float yoffset = 0; - Real width=shroud->getCellWidth(); - Real height=shroud->getCellHeight(); - - if (TheTerrainRenderObject->getMap()) - { //subtract origin position from all coordinates. Origin is shifted by 1 cell width/height to allow for unused border texels. - xoffset = -(float)shroud->getDrawOriginX() + width; - yoffset = -(float)shroud->getDrawOriginY() + height; - } - - D3DXMatrixTranslation(&offset, xoffset, yoffset,0); - - width = 1.0f/(width*shroud->getTextureWidth()); - height = 1.0f/(height*shroud->getTextureHeight()); - D3DXMatrixScaling(&scale, width, height, 1); - *((D3DXMATRIX *)&curView) = (inv * offset) * scale; - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); - } - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State( curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, shroud->getShroudTexture()->Peek_D3D_Texture()); - curStage++; - if (curStage==1) curStage++; - } - - Bool doNoise1 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE1 || - W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12); - if (doNoise1) { // Cloud pass. - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(2)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise1(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - curStage++; - if (curStage==1) curStage++; - } - - Bool doNoise2 = (W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE2 || - W3DShaderManager::getCurrentShader() == W3DShaderManager::ST_FLAT_TERRAIN_BASE_NOISE12); - if (doNoise2) - { - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - terrainShader2Stage.updateNoise2(((D3DXMATRIX*)&curView),&inv); //update curView with texture matrix - DX8Wrapper::_Set_DX8_Transform((D3DTRANSFORMSTATETYPE )(D3DTS_TEXTURE0+curStage), *((Matrix4x4*)&curView)); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(curStage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - curStage++; - if (curStage==1) curStage++; - } - if (curStage<2) { - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBase0PixelShader); - } else if (curStage==2) { - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBasePixelShader); - } else if (curStage==3) { - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise1PixelShader); - }else if (curStage==4) { - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(m_dwBaseNoise2PixelShader); - } - DX8Wrapper::_Get_D3D_Device8()->SetRenderState(D3DRS_ALPHABLENDENABLE, false); - DX8Wrapper::Apply_Render_State_Changes(); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(curStage, W3DShaderManager::getShaderTexture(3)->Peek_D3D_Texture()); - return TRUE; -} - -void FlatTerrainShaderPixelShader::reset(void) -{ - DX8Wrapper::_Get_D3D_Device8()->SetTexture(2,NULL); //release reference to any texture - DX8Wrapper::_Get_D3D_Device8()->SetTexture(3,NULL); //release reference to any texture - - DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0); //turn off pixel shader - - DX8Wrapper::_Get_D3D_Device8()->SetTexture(0, NULL); - DX8Wrapper::_Get_D3D_Device8()->SetTexture(1, NULL); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|0); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|1); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|2); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU|3); - - - DX8Wrapper::Invalidate_Cached_Render_States(); -} - - - - - diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt index d2eb50e26e..40c75076c3 100644 --- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt @@ -60,7 +60,7 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DPropBuffer.h Include/W3DDevice/GameClient/W3DRoadBuffer.h Include/W3DDevice/GameClient/W3DScene.h - Include/W3DDevice/GameClient/W3DShaderManager.h +# Include/W3DDevice/GameClient/W3DShaderManager.h Include/W3DDevice/GameClient/W3DShadow.h Include/W3DDevice/GameClient/W3DShroud.h # Include/W3DDevice/GameClient/W3DSmudge.h @@ -163,7 +163,7 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/W3DPropBuffer.cpp Source/W3DDevice/GameClient/W3DRoadBuffer.cpp Source/W3DDevice/GameClient/W3DScene.cpp - Source/W3DDevice/GameClient/W3DShaderManager.cpp +# Source/W3DDevice/GameClient/W3DShaderManager.cpp Source/W3DDevice/GameClient/W3DShroud.cpp # Source/W3DDevice/GameClient/W3DSmudge.cpp Source/W3DDevice/GameClient/W3DSnow.cpp diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 3b72228f9d..c7e80a9325 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -177,6 +177,8 @@ def main(): #unify_move_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/System/Smudge.cpp", Game.CORE, "GameEngine/Source/GameClient/System/Smudge.cpp") #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSmudge.h") #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSmudge.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp") return