/* ** 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 : WWSHADE * * * * $Archive:: wwshade/shd8bumpdiff.cpp $* * * * $Author:: Kenny_m * * $Modtime:: 07/08/02 3:40p $* * * * $Revision:: 1 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "dx8fvf.h" #include "dx8wrapper.h" #include "assetmgr.h" #include "rinfo.h" #include "camera.h" #include "shdmesh.h" #include "texproject.h" #include "shdbumpdiff.h" #include "shd8bumpdiff.h" #include "shd8bumpdiff_constants.h" #include "shdclassids.h" // shader code declarations #include "shd8bumpdiff.vsh_code.h" #include "shd8bumpdiff.psh_code.h" #include "shd8ssbumpdiff.vsh_code.h" #include "shd8ssbumpdiff.psh_code.h" ShdHWVertexShader Shd8BumpDiffClass::Vertex_Shader; ShdHWPixelShader Shd8BumpDiffClass::Pixel_Shader; ShdHWPixelShader Shd8BumpDiffClass::Self_Shadow_Pixel_Shader; ShdHWVertexShader Shd8BumpDiffClass::Self_Shadow_Vertex_Shader; Matrix4x4 Shd8BumpDiffClass::View_Projection_Matrix; Shd8BumpDiffClass::Shd8BumpDiffClass(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,0.0f); const Vector3& d=Definition->Get_Diffuse(); Diffuse.Set(d.X,d.Y,d.Z,0.0f); const Vector2& db=Definition->Get_Diffuse_Bumpiness(); Bumpiness.Set(db.X,db.Y,0,0); } Shd8BumpDiffClass::~Shd8BumpDiffClass(void) { REF_PTR_RELEASE(Texture); REF_PTR_RELEASE(NormalMap); } void Shd8BumpDiffClass::Init(void) { // 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() }; Pixel_Shader.Create(shd8bumpdiff_psh_code); Vertex_Shader.Create ( shd8bumpdiff_vsh_code, vertex_shader_declaration ); Self_Shadow_Pixel_Shader.Create(shd8ssbumpdiff_psh_code); Self_Shadow_Vertex_Shader.Create ( shd8ssbumpdiff_vsh_code, vertex_shader_declaration ); } void Shd8BumpDiffClass::Shutdown(void) { Vertex_Shader.Destroy(); Pixel_Shader.Destroy(); Self_Shadow_Pixel_Shader.Destroy(); Self_Shadow_Vertex_Shader.Destroy(); } void Shd8BumpDiffClass::Apply_Shared(int cur_pass, RenderInfoClass& rinfo) { // set vertex shader if (cur_pass==0) { DX8Wrapper::Set_Vertex_Shader(Vertex_Shader.Peek_Shader()); } else { DX8Wrapper::Set_Vertex_Shader(Self_Shadow_Vertex_Shader.Peek_Shader()); } // set vertex shader constants DX8Wrapper::Set_Vertex_Shader_Constant(CV_CONST, D3DXVECTOR4(0.0f, 1.0f, 0.5f, 2.0f), 1); // set pixel shader if (cur_pass==0) { DX8Wrapper::Set_Pixel_Shader(Pixel_Shader.Peek_Shader()); } else { DX8Wrapper::Set_Pixel_Shader(Self_Shadow_Pixel_Shader.Peek_Shader()); } // 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); } void Shd8BumpDiffClass::Apply_Instance(int cur_pass, RenderInfoClass& rinfo) { if (cur_pass==0) { DX8Wrapper::Set_Texture(0, NormalMap); DX8Wrapper::Set_Texture(1, Texture); } else { ZTextureClass* ztex=DX8Wrapper::Get_Shadow_Map(0); DX8Wrapper::Set_Texture(0, Texture); DX8Wrapper::Set_Vertex_Shader_Constant(CV_TEXMAP,&Self_Shadow_Transform,4); } // 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 Shd8BumpDiffClass::Get_Vertex_Stream_Count() const { return 1; } unsigned Shd8BumpDiffClass::Get_Vertex_Size(unsigned stream) const { return sizeof(VertexFormatXYZNDUV1TG3); } void Shd8BumpDiffClass::Copy_Vertex_Stream ( unsigned stream, void* dest_buffer, const VertexStreamStruct& vss, unsigned vertex_count ) { VertexFormatXYZNDUV1TG3* verts=(VertexFormatXYZNDUV1TG3*)dest_buffer; for (unsigned i=0; iIs_Applying_Shadow_Map()) { if (pass==1) // just do once { // is rendering self shadowed object Setup_Self_Shadow_Info(*mesh,*rinfo); } return (pass==1); } return (pass==0); } /********************************************************************************************** //! Set up transform for shadow maps /*! 06/07/02 KM created */ void Shd8BumpDiffClass::Setup_Self_Shadow_Info(ShdMeshClass& mesh, RenderInfoClass& rinfo) { Matrix4x4 tex_mat=mesh.Peek_Texture_Projector()->Peek_Mapper()->Get_Texture_Transform(); //set special texture matrix for shadow mapping ZTextureClass* smap=DX8Wrapper::Get_Shadow_Map(0); // todo KJM assign shadow map from rinfo if (!smap) return; float off_x=0.5f+(0.5f/(float)smap->Get_Width()); float off_y=0.5f+(0.5f/(float)smap->Get_Height()); unsigned int bits=Get_Num_Depth_Bits(smap->Get_Texture_Format()); float range=(float)(0xFFFFFFFF>>(32-bits)); float bias=0.0f;//-0.001f*range; Matrix4x4 sb_mat ( Vector4(0.5f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, -0.5f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, range, 0.0f), Vector4(off_x, off_y, bias, 1.0f) ); Matrix4x4 view2tex; Matrix4x4::Multiply(sb_mat,tex_mat,&view2tex); Matrix4x4 world; world.Init(mesh.Get_Transform()); Matrix4x4 view; view.Init(rinfo.Camera.Get_View_Matrix()); Matrix4x4 vw_mat; Matrix4x4::Multiply(world,view,&vw_mat); Matrix4x4::Multiply(view2tex,vw_mat,&Self_Shadow_Transform); }