/* ** Command & Conquer Generals Zero Hour(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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : WW3D * * * * $Archive:: /Commando/Code/ww3d2/shd7bumpdiff.cpp $* * * * $Author:: Kenny_m * * $Modtime:: 6/06/02 11:18p $* * * * $Revision:: 2 $* * * * 06/06/02 KM added software vertex shader fallback check *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "dx8fvf.h" #include "dx8wrapper.h" #include "assetmgr.h" #include "rinfo.h" #include "camera.h" #include "shdhwshader.h" #include "shdbumpdiff.h" #include "shd7bumpdiff.h" #include "shd7bumpdiff_constants.h" #include "shdclassids.h" // shader code declarations #include "shd7bumpdiffpass0.vsh_code.h" #include "shd7bumpdiffpass1.vsh_code.h" ShdHWVertexShader Shd7BumpDiffClass::Pass_0_Vertex_Shader; ShdHWVertexShader Shd7BumpDiffClass::Pass_1_Vertex_Shader; Matrix4x4 Shd7BumpDiffClass::View_Projection_Matrix; Shd7BumpDiffClass::Shd7BumpDiffClass(const ShdDefClass* def) : ShdInterfaceClass(def,SHDDEF_CLASSID_BUMPDIFF), Texture(NULL), NormalMap(NULL) { ShdBumpDiffDefClass* Definition=(ShdBumpDiffDefClass*)def; Texture=WW3DAssetManager::Get_Instance()->Get_Texture ( Definition->Get_Texture_Name() ); NormalMap=WW3DAssetManager::Get_Instance()->Get_Texture ( Definition->Get_Bump_Map_Name() ); const Vector3& a=Definition->Get_Ambient(); Ambient.Set(a.X,a.Y,a.Z,1.0f); const Vector3& d=Definition->Get_Diffuse(); Diffuse.Set(d.X,d.Y,d.Z,1.0f); const Vector2& db=Definition->Get_Diffuse_Bumpiness(); Bumpiness.Set(db.X,db.Y,0.0f,0.0f); } Shd7BumpDiffClass::~Shd7BumpDiffClass() { REF_PTR_RELEASE(Texture); REF_PTR_RELEASE(NormalMap); } void Shd7BumpDiffClass::Init() { // Create vertex shader DWORD vertex_shader_declaration[]= { D3DVSD_STREAM(0), (D3DVSD_REG(0, D3DVSDT_FLOAT3)), // vertex position (D3DVSD_REG(1, D3DVSDT_FLOAT3)), // vertex normal (D3DVSD_REG(2, D3DVSDT_D3DCOLOR)), // vertex color (D3DVSD_REG(3, D3DVSDT_FLOAT2)), // vertex texture coords (D3DVSD_REG(4, D3DVSDT_FLOAT3)), // vertex S basis (D3DVSD_REG(5, D3DVSDT_FLOAT3)), // vertex T basis (D3DVSD_REG(6, D3DVSDT_FLOAT3)), // vertex SxT basis D3DVSD_END() }; Pass_0_Vertex_Shader.Create ( shd7bumpdiffpass0_vsh_code, vertex_shader_declaration ); Pass_1_Vertex_Shader.Create ( shd7bumpdiffpass1_vsh_code, vertex_shader_declaration ); } void Shd7BumpDiffClass::Shutdown() { Pass_0_Vertex_Shader.Destroy(); Pass_1_Vertex_Shader.Destroy(); } //********************************************************************************************** //! Apply shared states for 2 pass DX7 bump diffuse /*! 6/03/02 8:12a KJM Created */ void Shd7BumpDiffClass::Apply_Shared(int pass, RenderInfoClass& rinfo) { // vertex processing behavior DX8Wrapper::Set_DX8_Render_State(D3DRS_SOFTWAREVERTEXPROCESSING,!Pass_0_Vertex_Shader.Is_Using_Hardware()); // fixed function uses pass through by default DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); if (pass==0) { // set vertex shader DX8Wrapper::Set_Vertex_Shader(Pass_0_Vertex_Shader.Peek_Shader()); // set texture stage settings DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 ); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); 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_COLOROP, D3DTOP_MODULATE); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_COLORARG2, D3DTA_SPECULAR ); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAOP, D3DTOP_ADDSMOOTH ); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); 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_Render_State(D3DRS_ALPHABLENDENABLE, TRUE); DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ZERO); } else { // set vertex shader DX8Wrapper::Set_Vertex_Shader(Pass_1_Vertex_Shader.Peek_Shader()); // set texture stage settings DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 ); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT); 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_COLOROP, D3DTOP_MODULATE); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_COLORARG2, D3DTA_SPECULAR ); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); DX8Wrapper::Set_DX8_Texture_Stage_State(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); 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_Render_State(D3DRS_ALPHABLENDENABLE, TRUE); DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND, D3DBLEND_ONE); } // set constants DX8Wrapper::Set_Vertex_Shader_Constant(CV_CONST, D3DXVECTOR4(0.0f, 1.0f, 0.5f, 2.0f), 1); // calculate shader view projection matrix Matrix4x4 view_matrix; DX8Wrapper::Get_Transform(D3DTS_VIEW, view_matrix); Matrix4x4 proj_matrix; DX8Wrapper::Get_Transform(D3DTS_PROJECTION, proj_matrix); Matrix4x4::Multiply(proj_matrix, view_matrix, &View_Projection_Matrix); } //********************************************************************************************** //! Apply per instance states for 2 pass DX7 bump diffuse /*! 6/03/02 8:12a KJM Created */ void Shd7BumpDiffClass::Apply_Instance(int cur_pass, RenderInfoClass& rinfo) { DX8Wrapper::Set_Texture(0, NormalMap); DX8Wrapper::Set_Texture(1, Texture); // set vertex shader constants Matrix4x4 world; DX8Wrapper::Get_Transform(D3DTS_WORLD, world); Matrix4x4 world_view_proj_matrix; Matrix4x4::Multiply(View_Projection_Matrix,world,&world_view_proj_matrix); DX8Wrapper::Set_Vertex_Shader_Constant(CV_WORLD_VIEW_PROJECTION, &world_view_proj_matrix, 4); DX8Wrapper::Set_Vertex_Shader_Constant(CV_WORLD, &world, 4); ShdHWVertexShader::Light ( rinfo, Ambient, Diffuse ); DX8Wrapper::Set_Vertex_Shader_Constant(CV_BUMPINESS, &Bumpiness, 1); } unsigned Shd7BumpDiffClass::Get_Vertex_Stream_Count() const { return 1; } unsigned Shd7BumpDiffClass::Get_Vertex_Size(unsigned stream) const { return sizeof(VertexFormatXYZNDUV1TG3); } void Shd7BumpDiffClass::Copy_Vertex_Stream ( unsigned stream, void* dest_buffer, const VertexStreamStruct& vss, unsigned vertex_count ) { VertexFormatXYZNDUV1TG3* verts=(VertexFormatXYZNDUV1TG3*)dest_buffer; for (unsigned i=0; i