/* ** 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 : Max2W3d * * * * $Archive:: /Commando/Code/Tools/max2w3d/GameMtlShaderDlg.cpp $* * * * Author:: Greg Hjelstrom * * * * $Modtime:: 2/26/99 7:23p $* * * * $Revision:: 13 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * GameMtlShaderDlg::GameMtlShaderDlg -- constructor * * GameMtlShaderDlg::~GameMtlShaderDlg -- destructor * * GameMtlShaderDlg::Dialog_Proc -- windows message handler * * GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls * * GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog * * GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting * * GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material * * GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader * * GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "GameMtlShaderDlg.h" #include "GameMtlDlg.h" #include "GameMtl.h" #include "resource.h" /* ** Shader Blend Setting Presets */ // Note: the array has NUM_SHADER_BLEND_PRESETS + 1 entries (due to the 'Custom' entry). #define NUM_SHADER_BLEND_PRESETS 8 static char * _ShaderBlendSettingPresetNames[NUM_SHADER_BLEND_PRESETS + 1] = { "Opaque", "Add", "Multiply", "Multiply and Add", "Screen", "Alpha Blend", "Alpha Test", "Alpha Test and Blend", "------ Custom -----" }; struct ShaderBlendSettingPreset { int SrcBlend; int DestBlend; bool DepthMask; bool AlphaTest; }; static const ShaderBlendSettingPreset ShaderBlendSettingPresets[NUM_SHADER_BLEND_PRESETS] = { {W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ZERO, true, false}, // Opaque {W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ONE, false, false}, // Add {W3DSHADER_SRCBLENDFUNC_ZERO, W3DSHADER_DESTBLENDFUNC_SRC_COLOR, false, false}, // Multiply {W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_SRC_COLOR, false, false}, // Multiply and Add {W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_COLOR, false, false}, // Screen {W3DSHADER_SRCBLENDFUNC_SRC_ALPHA, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA, false, false}, // Alpha Blend {W3DSHADER_SRCBLENDFUNC_ONE, W3DSHADER_DESTBLENDFUNC_ZERO, true, true}, // Alpha Test {W3DSHADER_SRCBLENDFUNC_SRC_ALPHA, W3DSHADER_DESTBLENDFUNC_ONE_MINUS_SRC_ALPHA, true, true} // Alpha Test and Blend }; /*********************************************************************************************** * GameMtlShaderDlg::GameMtlShaderDlg -- constructor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/23/98 GTH : Created. * *=============================================================================================*/ GameMtlShaderDlg::GameMtlShaderDlg ( HWND parent, IMtlParams * imp, GameMtl * mtl, int pass ) : GameMtlFormClass(imp,mtl,pass) { Create_Form(parent,IDD_GAMEMTL_SHADER); } /*********************************************************************************************** * GameMtlShaderDlg::~GameMtlShaderDlg -- destructor * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * *=============================================================================================*/ GameMtlShaderDlg::~GameMtlShaderDlg() { } /*********************************************************************************************** * GameMtlShaderDlg::Dialog_Proc -- windows message handler * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/23/98 GTH : Created. * *=============================================================================================*/ BOOL GameMtlShaderDlg::Dialog_Proc (HWND dlg_wnd, UINT message, WPARAM wparam, LPARAM lparam) { int cursel; int i; int id = LOWORD(wparam); int code = HIWORD(wparam); switch (message) { case WM_INITDIALOG: for(i = 0; i <= NUM_SHADER_BLEND_PRESETS; i++) { SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_ADDSTRING,0,(LONG)_ShaderBlendSettingPresetNames[i]); } SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_SETCURSEL,0,0); break; case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE: { IParams->RollupMouseMessage(dlg_wnd,message,wparam,lparam); } return FALSE; case WM_COMMAND: { if (code == CBN_SELCHANGE) { switch (id) { case IDC_DEPTHCOMPARE_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_DEPTHCOMPARE_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Depth_Compare(PassIndex,cursel); break; case IDC_DESTBLEND_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_DESTBLEND_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Dest_Blend(PassIndex,cursel); TheMtl->Notify_Changed(); Set_Preset(); break; case IDC_PRIGRADIENT_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_PRIGRADIENT_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Pri_Gradient(PassIndex,cursel); TheMtl->Notify_Changed(); break; case IDC_SECGRADIENT_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_SECGRADIENT_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Sec_Gradient(PassIndex,cursel); TheMtl->Notify_Changed(); break; case IDC_SRCBLEND_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_SRCBLEND_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Src_Blend(PassIndex,cursel); TheMtl->Notify_Changed(); Set_Preset(); break; case IDC_DETAILCOLOR_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILCOLOR_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Detail_Color_Func(PassIndex,cursel); TheMtl->Notify_Changed(); break; case IDC_DETAILALPHA_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_DETAILALPHA_COMBO,CB_GETCURSEL,0,0); TheMtl->Set_Detail_Alpha_Func(PassIndex,cursel); TheMtl->Notify_Changed(); break; case IDC_PRESET_COMBO: cursel = SendDlgItemMessage(dlg_wnd,IDC_PRESET_COMBO,CB_GETCURSEL,0,0); Apply_Preset(cursel); break; } } else { switch(id) { case IDC_DEPTHMASK_CHECK: if (SendDlgItemMessage(dlg_wnd,IDC_DEPTHMASK_CHECK,BM_GETCHECK,0,0)) { TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_ENABLE); } else { TheMtl->Set_Depth_Mask(PassIndex,W3DSHADER_DEPTHMASK_WRITE_DISABLE); } Set_Preset(); break; case IDC_ALPHATEST_CHECK: if (SendDlgItemMessage(dlg_wnd,IDC_ALPHATEST_CHECK,BM_GETCHECK,0,0)) { TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_ENABLE); } else { TheMtl->Set_Alpha_Test(PassIndex,W3DSHADER_ALPHATEST_DISABLE); } Set_Preset(); break; case IDC_SHADER_DEFAULTS_BUTTON: Set_Advanced_Defaults(); break; } } } } return FALSE; } /*********************************************************************************************** * GameMtlShaderDlg::ReloadDialog -- reload the contents of all of the controls * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/23/98 GTH : Created. * *=============================================================================================*/ void GameMtlShaderDlg::ReloadDialog(void) { DebugPrint("GameMtlShaderDlg::ReloadDialog\n"); SendDlgItemMessage(m_hWnd, IDC_DESTBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Dest_Blend(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_SRCBLEND_COMBO, CB_SETCURSEL, TheMtl->Get_Src_Blend(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_PRIGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Pri_Gradient(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_SECGRADIENT_COMBO, CB_SETCURSEL, TheMtl->Get_Sec_Gradient(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_DEPTHCOMPARE_COMBO, CB_SETCURSEL, TheMtl->Get_Depth_Compare(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_DETAILCOLOR_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Color_Func(PassIndex), 0 ); SendDlgItemMessage(m_hWnd, IDC_DETAILALPHA_COMBO, CB_SETCURSEL, TheMtl->Get_Detail_Alpha_Func(PassIndex), 0 ); Set_Preset(); SetCheckBox(m_hWnd,IDC_DEPTHMASK_CHECK, TheMtl->Get_Depth_Mask(PassIndex)); SetCheckBox(m_hWnd,IDC_ALPHATEST_CHECK, TheMtl->Get_Alpha_Test(PassIndex)); } /*********************************************************************************************** * GameMtlShaderDlg::ActivateDlg -- activate/deactivate the dialog * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/23/98 GTH : Created. * *=============================================================================================*/ void GameMtlShaderDlg::ActivateDlg(BOOL onoff) { // shader has no color swatches which need to be activated... } /*********************************************************************************************** * GameMtlShaderDlg::Apply_Preset -- apply a preset shader setting * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/23/98 GTH : Created. * *=============================================================================================*/ void GameMtlShaderDlg::Apply_Preset(int preset_index) { if (preset_index < 0 || preset_index >= NUM_SHADER_BLEND_PRESETS) return; const ShaderBlendSettingPreset &preset = ShaderBlendSettingPresets[preset_index]; TheMtl->Set_Src_Blend(PassIndex, preset.SrcBlend); TheMtl->Set_Dest_Blend(PassIndex, preset.DestBlend); int depth_mask = preset.DepthMask ? W3DSHADER_DEPTHMASK_WRITE_ENABLE : W3DSHADER_DEPTHMASK_WRITE_DISABLE; TheMtl->Set_Depth_Mask(PassIndex, depth_mask); int alpha_test = preset.AlphaTest ? W3DSHADER_ALPHATEST_ENABLE : W3DSHADER_ALPHATEST_DISABLE; TheMtl->Set_Alpha_Test(PassIndex, alpha_test); TheMtl->Notify_Changed(); ReloadDialog(); } /*********************************************************************************************** * GameMtlShaderDlg::Set_Preset -- determine preset shader setting from game material * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 02/26/99 NH : Created. * *=============================================================================================*/ void GameMtlShaderDlg::Set_Preset(void) { for (int i = 0; i < NUM_SHADER_BLEND_PRESETS; i++) { if (CompareShaderToBlendPreset(ShaderBlendSettingPresets[i])) break; } SendDlgItemMessage(m_hWnd, IDC_PRESET_COMBO, CB_SETCURSEL, i, 0); } /*********************************************************************************************** * GameMtlShaderDlg::CompareShaderToBlendPreset -- compare preset to game material shader * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 02/26/99 NH : Created. * *=============================================================================================*/ bool GameMtlShaderDlg::CompareShaderToBlendPreset(const ShaderBlendSettingPreset &blend_preset) { if (TheMtl->Get_Src_Blend(PassIndex) != blend_preset.SrcBlend) return false; if (TheMtl->Get_Dest_Blend(PassIndex) != blend_preset.DestBlend) return false; bool depthmask = TheMtl->Get_Depth_Mask(PassIndex) != W3DSHADER_DEPTHMASK_WRITE_DISABLE; if (depthmask != blend_preset.DepthMask) return false; bool alphatest = TheMtl->Get_Alpha_Test(PassIndex) != W3DSHADER_ALPHATEST_DISABLE; if (alphatest != blend_preset.AlphaTest) return false; return true; } /*********************************************************************************************** * GameMtlShaderDlg::Set_Advanced_Defaults -- set advanced settings to defaults * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 02/26/99 NH : Created. * *=============================================================================================*/ void GameMtlShaderDlg::Set_Advanced_Defaults(void) { TheMtl->Set_Pri_Gradient(PassIndex, W3DSHADER_PRIGRADIENT_DEFAULT); TheMtl->Set_Sec_Gradient(PassIndex, W3DSHADER_SECGRADIENT_DEFAULT); TheMtl->Set_Depth_Compare(PassIndex, W3DSHADER_DEPTHCOMPARE_DEFAULT); TheMtl->Set_Detail_Color_Func(PassIndex, W3DSHADER_DETAILCOLORFUNC_DEFAULT); TheMtl->Set_Detail_Alpha_Func(PassIndex, W3DSHADER_DETAILALPHAFUNC_DEFAULT); TheMtl->Notify_Changed(); ReloadDialog(); }