/* ** Command & Conquer Renegade(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:: /VSS_Sync/ww3d2/shader.h $* * * * Author:: Greg Hjelstrom * * * * $Modtime:: 10/26/01 2:56p $* * * * $Revision:: 17 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef SHADER_H #define SHADER_H #include "always.h" #if defined (SR_OS_SOLARIS) #undef PASS_MAX #endif class DX8Wrapper; struct W3dMaterial3Struct; // Re-written shader class // Hector Yee 1/24/01 enum ShaderShiftConstants { SHIFT_DEPTHCOMPARE = 0, // bit shift for depth comparison setting SHIFT_DEPTHMASK = 3, // bit shift for depth mask setting SHIFT_COLORMASK = 4, // bit shift for color mask setting SHIFT_DSTBLEND = 5, // bit shift for destination blend setting SHIFT_FOG = 8, // bit shift for fog setting SHIFT_PRIGRADIENT = 10, // bit shift for primary gradient setting SHIFT_SECGRADIENT = 13, // bit shift for secondary gradient setting SHIFT_SRCBLEND = 14, // bit shift for source blend setting SHIFT_TEXTURING = 16, // bit shift for texturing setting (1 bit) SHIFT_NPATCHENABLE = 17, // bit shift for npatch enabling SHIFT_ALPHATEST = 18, // bit shift for alpha test setting SHIFT_CULLMODE = 19, // bit shift for cullmode setting SHIFT_POSTDETAILCOLORFUNC = 20, // bit shift for post-detail color function setting SHIFT_POSTDETAILALPHAFUNC = 24 // bit shift for post-detail alpha function setting }; #define SHADE_CNST(depth_compare, depth_mask, color_mask, src_blend, dst_blend, fog, pri_grad, sec_grad, texture, alpha_test, cullmode, post_det_color, post_det_alpha) \ ( (depth_compare) << SHIFT_DEPTHCOMPARE | (depth_mask) << SHIFT_DEPTHMASK | \ (color_mask) << SHIFT_COLORMASK | (dst_blend) << SHIFT_DSTBLEND | (fog) << SHIFT_FOG | \ (pri_grad) << SHIFT_PRIGRADIENT | (sec_grad) << SHIFT_SECGRADIENT | \ (src_blend) << SHIFT_SRCBLEND | (texture) << SHIFT_TEXTURING | \ (alpha_test) << SHIFT_ALPHATEST | (cullmode) << SHIFT_CULLMODE | \ (post_det_color) << SHIFT_POSTDETAILCOLORFUNC | \ (post_det_alpha) << SHIFT_POSTDETAILALPHAFUNC) class ShaderClass { friend DX8Wrapper; void Apply(); public: enum AlphaTestType { ALPHATEST_DISABLE= 0,// disable alpha testing (default) ALPHATEST_ENABLE, // enable alpha testing ALPHATEST_MAX // end of enumeration }; enum DepthCompareType { PASS_NEVER=0, // pass never PASS_LESS, // pass if incoming less than stored PASS_EQUAL, // pass if incoming equal to stored PASS_LEQUAL, // pass if incoming less than or equal to stored (default) PASS_GREATER, // pass if incoming greater than stored PASS_NOTEQUAL, // pass if incoming not equal to stored PASS_GEQUAL, // pass if incoming greater than or equal to stored PASS_ALWAYS, // pass always PASS_MAX // end of enumeration }; enum DepthMaskType { DEPTH_WRITE_DISABLE=0, // disable depth buffer writes DEPTH_WRITE_ENABLE, // enable depth buffer writes (default) DEPTH_WRITE_MAX // end of enumeration }; enum ColorMaskType { COLOR_WRITE_DISABLE=0, // disable color buffer writes COLOR_WRITE_ENABLE, // enable color buffer writes (default) COLOR_WRITE_MAX // end of enumeration }; enum DetailAlphaFuncType { DETAILALPHA_DISABLE=0, // local (default) DETAILALPHA_DETAIL, // other DETAILALPHA_SCALE, // local * other DETAILALPHA_INVSCALE, // ~(~local * ~other) = local + (1-local)*other DETAILALPHA_MAX // end of enumeration }; enum DetailColorFuncType { DETAILCOLOR_DISABLE=0, // 0000 local (default) DETAILCOLOR_DETAIL, // 0001 other DETAILCOLOR_SCALE, // 0010 local * other DETAILCOLOR_INVSCALE, // 0011 ~(~local * ~other) = local + (1-local)*other DETAILCOLOR_ADD, // 0100 local + other DETAILCOLOR_SUB, // 0101 local - other DETAILCOLOR_SUBR, // 0110 other - local DETAILCOLOR_BLEND, // 0111 (localAlpha)*local + (~localAlpha)*other DETAILCOLOR_DETAILBLEND, // 1000 (otherAlpha)*local + (~otherAlpha)*other DETAILCOLOR_MAX // end of enumeration }; enum CullModeType { CULL_MODE_DISABLE=0, CULL_MODE_ENABLE, CULL_MODE_MAX }; enum NPatchEnableType { NPATCH_DISABLE=0, NPATCH_ENABLE, NPATCH_TYPE_MAX }; enum DstBlendFuncType { DSTBLEND_ZERO=0, // destination pixel doesn't affect blending (default) DSTBLEND_ONE, // destination pixel added unmodified DSTBLEND_SRC_COLOR, // destination pixel multiplied by fragment RGB components DSTBLEND_ONE_MINUS_SRC_COLOR, // destination pixel multiplied by one minus (i.e. inverse) fragment RGB components DSTBLEND_SRC_ALPHA, // destination pixel multiplied by fragment alpha component DSTBLEND_ONE_MINUS_SRC_ALPHA, // destination pixel multiplied by fragment inverse alpha DSTBLEND_MAX // end of enumeration }; enum FogFuncType { FOG_DISABLE=0, // don't perform fogging (default) FOG_ENABLE, // apply fog, f*fogColor + (1-f)*fragment FOG_SCALE_FRAGMENT, // fog scalar value multiplies fragment, (1-f)*fragment FOG_WHITE, // fog scalar value replaces fragment, f*fogColor FOG_MAX // end of enumeration }; enum PriGradientType { GRADIENT_DISABLE=0, // 000 disable primary gradient (same as OpenGL 'decal' texture blend) GRADIENT_MODULATE, // 001 modulate fragment ARGB by gradient ARGB (default) GRADIENT_ADD, // 010 add gradient RGB to fragment RGB, copy gradient A to fragment A GRADIENT_BUMPENVMAP, // 011 GRADIENT_BUMPENVMAPLUMINANCE, // 100 GRADIENT_DOTPRODUCT3, // 101 GRADIENT_MAX // end of enumeration }; enum SecGradientType { SECONDARY_GRADIENT_DISABLE=0, // don't draw secondary gradient (default) SECONDARY_GRADIENT_ENABLE, // add secondary gradient RGB to fragment RGB SECONDARY_GRADIENT_MAX // end of enumeration }; enum SrcBlendFuncType { SRCBLEND_ZERO=0, // fragment not added to color buffer SRCBLEND_ONE, // fragment added unmodified to color buffer (default) SRCBLEND_SRC_ALPHA, // fragment RGB components multiplied by fragment A SRCBLEND_ONE_MINUS_SRC_ALPHA, // fragment RGB components multiplied by fragment inverse (one minus) A SRCBLEND_MAX // end of enumeration }; enum TexturingType { TEXTURING_DISABLE=0, // no texturing (treat fragment initial color as 1,1,1,1) TEXTURING_ENABLE, // enable texturing TEXTURING_MAX // end of enumeration }; enum StaticSortCategoryType { SSCAT_OPAQUE, SSCAT_ALPHA_TEST, SSCAT_ADDITIVE, SSCAT_OTHER }; enum { MASK_DEPTHCOMPARE = (7<<0), // mask for depth comparison setting MASK_DEPTHMASK = (1<<3), // mask for depth mask setting MASK_COLORMASK = (1<<4), // mask for color mask setting MASK_DSTBLEND = (7<<5), // mask for destination blend setting MASK_FOG = (3<<8), // mask for fog setting MASK_PRIGRADIENT = (7<<10), // mask for primary gradient setting MASK_SECGRADIENT = (1<<13), // mask for secondary gradient setting MASK_SRCBLEND = (3<<14), // mask for source blend setting MASK_TEXTURING = (1<<16), // mask for texturing setting MASK_NPATCHENABLE = (1<<17), // mask for npatch enable MASK_ALPHATEST = (1<<18), // mask for alpha test enable MASK_CULLMODE = (1<<19), // mask for cullmode setting MASK_POSTDETAILCOLORFUNC= (15<<20), // mask for post detail color function setting MASK_POSTDETAILALPHAFUNC= (7<<24) // mask for post detail alpha function setting }; ShaderClass(void) { Reset(); } ShaderClass(const ShaderClass & s) { ShaderBits=s.ShaderBits; } ShaderClass(const unsigned int d) { ShaderBits=d; } bool operator == (const ShaderClass & s) { return ShaderBits == s.ShaderBits; } bool operator != (const ShaderClass & s) { return ShaderBits != s.ShaderBits; } inline unsigned int Get_Bits(void) const { return ShaderBits; } inline int Uses_Alpha(void) const { // check if alpha test is enabled if (Get_Alpha_Test() != ALPHATEST_DISABLE) return true; DstBlendFuncType dst = Get_Dst_Blend_Func(); if (dst == DSTBLEND_SRC_ALPHA || dst == DSTBLEND_ONE_MINUS_SRC_ALPHA) return true; SrcBlendFuncType src = Get_Src_Blend_Func(); return (src == SRCBLEND_SRC_ALPHA || src == SRCBLEND_ONE_MINUS_SRC_ALPHA); } inline int Uses_Fog(void) const { return (Get_Fog_Func() != FOG_DISABLE); } inline int Uses_Primary_Gradient(void) const { return (Get_Primary_Gradient() != GRADIENT_DISABLE); } inline int Uses_Secondary_Gradient(void) const { return (Get_Secondary_Gradient() != SECONDARY_GRADIENT_DISABLE); } inline int Uses_Texture(void) const { return (Get_Texturing() != TEXTURING_DISABLE); } inline int Uses_Post_Detail_Texture(void) const { if (Get_Texturing() == TEXTURING_DISABLE) return false; return ((Get_Post_Detail_Color_Func() != DETAILCOLOR_DISABLE) || (Get_Post_Detail_Alpha_Func() != DETAILALPHA_DISABLE)); } inline void Reset(void); inline DepthCompareType Get_Depth_Compare(void) const { return (DepthCompareType)(ShaderBits&MASK_DEPTHCOMPARE>>SHIFT_DEPTHCOMPARE); } inline DepthMaskType Get_Depth_Mask(void) const { return (DepthMaskType)((ShaderBits&MASK_DEPTHMASK)>>SHIFT_DEPTHMASK); } inline ColorMaskType Get_Color_Mask(void) const { return (ColorMaskType)((ShaderBits&MASK_COLORMASK)>>SHIFT_COLORMASK); } inline DetailAlphaFuncType Get_Post_Detail_Alpha_Func(void) const { return (DetailAlphaFuncType)((ShaderBits&MASK_POSTDETAILALPHAFUNC)>>SHIFT_POSTDETAILALPHAFUNC); } inline DetailColorFuncType Get_Post_Detail_Color_Func(void) const { return (DetailColorFuncType)((ShaderBits&MASK_POSTDETAILCOLORFUNC)>>SHIFT_POSTDETAILCOLORFUNC); } inline AlphaTestType Get_Alpha_Test(void) const { return (AlphaTestType)((ShaderBits&MASK_ALPHATEST)>>SHIFT_ALPHATEST); } inline CullModeType Get_Cull_Mode(void) const { return (CullModeType)((ShaderBits&MASK_CULLMODE)>>SHIFT_CULLMODE); } inline DstBlendFuncType Get_Dst_Blend_Func(void) const { return (DstBlendFuncType)((ShaderBits&MASK_DSTBLEND)>>SHIFT_DSTBLEND); } inline FogFuncType Get_Fog_Func(void) const { return (FogFuncType)((ShaderBits&MASK_FOG)>>SHIFT_FOG); } inline PriGradientType Get_Primary_Gradient(void) const { return (PriGradientType)((ShaderBits&MASK_PRIGRADIENT)>>SHIFT_PRIGRADIENT); } inline SecGradientType Get_Secondary_Gradient(void) const { return (SecGradientType)((ShaderBits&MASK_SECGRADIENT)>>SHIFT_SECGRADIENT); } inline SrcBlendFuncType Get_Src_Blend_Func(void) const { return (SrcBlendFuncType)((ShaderBits&MASK_SRCBLEND)>>SHIFT_SRCBLEND); } inline TexturingType Get_Texturing(void) const { return (TexturingType)((ShaderBits&MASK_TEXTURING)>>SHIFT_TEXTURING); } inline NPatchEnableType Get_NPatch_Enable(void) const { return (NPatchEnableType)((ShaderBits&MASK_NPATCHENABLE)>>SHIFT_NPATCHENABLE); } inline void Set_Depth_Compare(DepthCompareType x) { ShaderBits&=~MASK_DEPTHCOMPARE;ShaderBits|=(x<