Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
shdhwshader.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19 /***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/shdhwshader.cpp $*
26 * *
27 * $Org Author:: Kenny_m
28 * *
29 * $Author:: Kenny_m
30 *
31 * $Modtime:: 07/07/02 12:18p $*
32 * *
33 * $Revision:: 3 $*
34 * *
35 * 06/06/02 KM added software vertex shader fallback check
36 * 07/07/02 KM Generic shader functions for factoring HW shader code
37 *---------------------------------------------------------------------------------------------*
38 * Functions: *
39 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40
41#include <stdio.h>
42#include "shdhwshader.h"
43#include "dx8wrapper.h"
44#include "rinfo.h"
45#include "shdhw_constants.h"
46
47//**********************************************************************************************
49
52{
53 int result;
54
55#ifdef WIN32
56 STARTUPINFO si;
57 PROCESS_INFORMATION pi;
58 memset(&pi, 0, sizeof(pi));
59 memset(&si, 0, sizeof(si));
60 si.cb = sizeof(si);
61 si.dwFlags=STARTF_USESHOWWINDOW;
62 si.wShowWindow=SW_HIDE;
63
64 static bool found=false;
65 static char work_dir[_MAX_PATH];
66
67 if (!found)
68 {
69 char* shader_path="\\shaders\\";
70
71 ::GetCurrentDirectory(_MAX_PATH,work_dir);
72 strcat(work_dir,shader_path);
73 }
74
75 result=CreateProcess(0,cmd,0,0,0,0,0,work_dir,&si,&pi);
76
77 if (result)
78 {
79 WaitForSingleObject(pi.hThread, INFINITE);
80
81 // Close process and thread handles.
82 CloseHandle(pi.hProcess);
83 CloseHandle(pi.hThread);
84
85 found=true;
86 }
87 else
88 {
89 int err=GetLastError();
90 MessageBox
91 (
92 NULL,
93 "Failed to execute preprocessor on shader\n"
94 "Ensure shaders folder is in application subdirectory\n",
95 "Shader Asset Error",
96 MB_OK
97 );
98 WWASSERT_PRINT(result,"Failed to execute preprocessor on shader (ensure shaders folder is in application subdirectory)");
99 }
100#else
101 result=system(cmd);
102#endif
103}
104
105
106//**********************************************************************************************
108
111(
112 char* file_name,
113 LPD3DXBUFFER* constants,
114 LPD3DXBUFFER* shader_code
115)
116{
117 char shell_command[_MAX_PATH];
118 char temp_path[_MAX_PATH];
119 char temp_file[_MAX_PATH];
120
121
122 GetTempPath(_MAX_PATH, temp_path);
123 GetTempFileName(temp_path,"shd",1,temp_file);
124
125 _snprintf
126 (
127 shell_command,
128 sizeof(shell_command),
129 "shaders\\rspp %s %s",
130 file_name,
131 temp_file
132 );
133
134 LPD3DXBUFFER* errors=NULL;
135
136 Shell_Run(shell_command);
137
138 HRESULT result=D3DXAssembleShaderFromFile
139 (
140 temp_file,
141 NULL,
142 constants,
143 shader_code,
144 errors
145 );
146 WWASSERT_PRINT(result==D3D_OK,"Failed to assemble shader from file");
147}
148
149// 06/06/02 KM added software vertex shader fallback check
150bool ShdHWVertexShader::Using_Hardware=true;
151
152//**********************************************************************************************
154
160
161//**********************************************************************************************
163
166{
167 if (Shader)
168 {
169 DX8Wrapper::_Get_D3D_Device8()->SetVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE);
170 DX8Wrapper::_Get_D3D_Device8()->DeleteVertexShader(Shader);
171 Shader=0;
172 }
173}
174
175//**********************************************************************************************
177
181(
182 char* file_name,
183 DWORD* vertex_shader_declaration
184)
185{
186 // Create vertex shader
187 LPD3DXBUFFER shader_code=NULL;
188
190 (
191 file_name,
192 NULL,
193 &shader_code
194 );
195
196 // try hardware first
197 Using_Hardware=true;
198 HRESULT result=DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader
199 (
200 (DWORD*)vertex_shader_declaration,
201 (DWORD*)shader_code->GetBufferPointer(),
202 (DWORD*)&Shader,
203 0
204 );
205 if (result!=D3D_OK)
206 {
207 // try software
208 Using_Hardware=false;
209 result=DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader
210 (
211 (DWORD*)vertex_shader_declaration,
212 (DWORD*)shader_code->GetBufferPointer(),
213 (DWORD*)&Shader,
214 D3DUSAGE_SOFTWAREPROCESSING
215 );
216 WWASSERT_PRINT(result==D3D_OK,"Failed to create vertex shader");
217 }
218
219 if (shader_code) shader_code->Release();
220
221 return Shader;
222}
223
224
225//**********************************************************************************************
227
230(
231 DWORD* shader_code_str,
232 DWORD* vertex_shader_declaration
233)
234{
235 HRESULT result;
236 LPD3DXBUFFER shader_code=NULL;
237 LPD3DXBUFFER errors=NULL;
238
239 result=D3DXAssembleShader
240 (
241 shader_code_str,
242 strlen((char*)shader_code_str),
243 NULL,//D3DXASM_DEBUG,
244 NULL,
245 &shader_code,
246 &errors
247 );
248 if (result!=D3D_OK)
249 {
250 OutputDebugString((char*)errors->GetBufferPointer());
251 WWASSERT_PRINT(result==D3D_OK,"Failed to assemble shader");
252 }
253
254 // try hardware first
255 Using_Hardware=true;
256 result=DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader
257 (
258 (DWORD*)vertex_shader_declaration,
259 (DWORD*)shader_code->GetBufferPointer(),
260 (DWORD*)&Shader,
261 0
262 );
263 if (result!=D3D_OK)
264 {
265 // try software
266 Using_Hardware=false;
267 result=DX8Wrapper::_Get_D3D_Device8()->CreateVertexShader
268 (
269 (DWORD*)vertex_shader_declaration,
270 (DWORD*)shader_code->GetBufferPointer(),
271 (DWORD*)&Shader,
272 D3DUSAGE_SOFTWAREPROCESSING
273 );
274 WWASSERT_PRINT(result==D3D_OK,"Failed to create vertex shader");
275 if (result!=D3D_OK)
276 {
277 OutputDebugString((char*)shader_code_str);
278 }
279 }
280
281 return Shader;
282}
283
284//**********************************************************************************************
286
292
293//**********************************************************************************************
295
298{
299 if (Shader)
300 {
301 DX8Wrapper::_Get_D3D_Device8()->SetPixelShader(0);
302 DX8Wrapper::_Get_D3D_Device8()->DeletePixelShader(Shader);
303 Shader=0;
304 }
305}
306
307//**********************************************************************************************
309
312{
313 // Create pixel shader
314 LPD3DXBUFFER shader_code=NULL;
315
317 (
318 file_name,
319 NULL,
320 &shader_code
321 );
322
323 HRESULT result=DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader
324 (
325 (DWORD*)shader_code->GetBufferPointer(),
326 (DWORD*)&Shader
327 );
328 WWASSERT_PRINT(result==D3D_OK,"Failed to create pixel shader");
329
330 return Shader;
331}
332
333
334//**********************************************************************************************
336
339{
340 HRESULT result;
341 LPD3DXBUFFER shader_code=NULL;
342 LPD3DXBUFFER errors;
343
344 result=D3DXAssembleShader
345 (
346 shader_code_str,
347 strlen((char*)shader_code_str),
348 NULL,
349 NULL,
350 &shader_code,
351 &errors
352 );
353 if (result!=D3D_OK)
354 {
355 OutputDebugString((char*)errors->GetBufferPointer());
356 WWASSERT_PRINT(result==D3D_OK,"Failed to assemble shader");
357 }
358
359 result=DX8Wrapper::_Get_D3D_Device8()->CreatePixelShader
360 (
361 (DWORD*)shader_code->GetBufferPointer(),
362 (DWORD*)&Shader
363 );
364 WWASSERT_PRINT(result==D3D_OK,"Failed to create pixel shader");
365
366 return Shader;
367}
368
369
370//**********************************************************************************************
372
375(
376 RenderInfoClass& rinfo,
377 Vector4& ambient,
378 Vector4& diffuse,
379 Vector4& specular
380)
381{
383
384 Vector4 light_ambient(1,1,1,1);
385
386 if (lenv)
387 {
388 int num_lights=lenv->Get_Light_Count();
389
390 // most cases set up and use the light environment
391 if (num_lights)
392 {
393 const Vector3& amb=lenv->Get_Equivalent_Ambient();
394 light_ambient.Set
395 (
396 amb.X,
397 amb.Y,
398 amb.Z,
399 0
400 );
401 int i;
402
404
405 if (num_lights>max) num_lights=max;
406
407 Vector4 cdir, ccol;
408 for (i=0;i<max;i++)
409 {
410 if (i<num_lights)
411 {
412 Vector3 rot;
413 const Vector3& dir=lenv->Get_Light_Direction(i);
414 const Vector3& col=lenv->Get_Light_Diffuse(i);
415
416 cdir.Set(dir.X,dir.Y,dir.Z,1.0f);
417 ccol.Set(col.X,col.Y,col.Z,1.0f);
418 }
419 else
420 {
421 // if no light just set color to zero
422 ccol.Set(0,0,0,0);
423 }
424
427 }
428 }
429 else
430 {
431 const Vector3& amb_col=DX8Wrapper::Get_Ambient();
432
433 light_ambient.X=amb_col.X;
434 light_ambient.Y=amb_col.Y;
435 light_ambient.Z=amb_col.Z;
436
437 // otherwise have to extract light from render state
439 int i;
440
441 RenderStateStruct state;
443 Vector4 cdir, ccol;
444
445 for (i=0;i<max;i++)
446 {
447 if (state.LightEnable[i])
448 {
449 D3DLIGHT8& light=state.Lights[i];
450
451 // handle directional and positional lights
452 if (light.Type==D3DLIGHT_DIRECTIONAL)
453 {
454 const D3DXVECTOR3& dir=state.Lights[i].Direction;
455
456 cdir.Set(-dir.x,-dir.y,-dir.z,0.0f);
457 }
458 else
459 {
460 const D3DXVECTOR3& pos=state.Lights[i].Position;
461
462 // just normalise the light position for now (as only appears to be used in w3dview)
463 cdir.Set(pos.x,pos.y,pos.z,0.0f);
464 }
465
466 cdir.Normalize();
467 ccol.Set
468 (
469 state.Lights[i].Diffuse.r,
470 state.Lights[i].Diffuse.g,
471 state.Lights[i].Diffuse.b,
472 1.0f
473 );
474 }
475 else
476 {
477 // if no light just set color to zero
478 ccol.Set(0,0,0,0);
479 }
480
483 }
484 }
485 }
486
487 light_ambient.X*=ambient.X;
488 light_ambient.Y*=ambient.Y;
489 light_ambient.Z*=ambient.Z;
490
494}
495
496//**********************************************************************************************
498
501(
502 RenderInfoClass& rinfo,
503 Vector4& ambient,
504 Vector4& diffuse
505)
506{
507 Vector4 specular(0,0,0,0);
508 Light(rinfo,ambient,diffuse,specular);
509}
510
#define NULL
Definition BaseType.h:92
#define max(x, y)
Definition BaseType.h:105
unsigned long DWORD
Definition bittype.h:57
char dir[_MAX_DIR]
Definition autorun.cpp:215
static IDirect3DDevice8 * _Get_D3D_Device8()
Definition dx8wrapper.h:530
static void Set_Vertex_Shader_Constant(int reg, const void *data, int count)
Definition dx8wrapper.h:739
static void Get_Render_State(RenderStateStruct &state)
static const Vector3 & Get_Ambient()
Definition dx8wrapper.h:524
int Get_Light_Count(void) const
const Vector3 & Get_Light_Direction(int i) const
const Vector3 & Get_Equivalent_Ambient(void) const
const Vector3 & Get_Light_Diffuse(int i) const
LightEnvironmentClass * light_environment
Definition rinfo.h:109
DWORD Create(char *file_name)
Create Pixel Shader from a file.
void Destroy()
Destroy this pixel shader.
virtual ~ShdHWPixelShader()
Destruct this pixel shader.
void Shell_Run(char *cmd)
Execute and wait for a hidden shell command.
void Preprocess_And_Assemble_Shader_From_File(char *file_name, LPD3DXBUFFER *constants, LPD3DXBUFFER *shader_code)
Preprocess and assemble a HW shader from file.
virtual ~ShdHWVertexShader()
Destruct this vertex shader.
DWORD Create(char *file_name, DWORD *vertex_shader_declaration)
Create Vertex Shader from a file and vertex stream declaration.
void Destroy()
Destroy this vertex shader.
static void Light(RenderInfoClass &rinfo, Vector4 &ambient, Vector4 &diffuse, Vector4 &specular)
Apply generic lighting.
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
float Y
Definition vector4.h:67
float Z
Definition vector4.h:68
WWINLINE void Set(float x, float y, float z, float w)
Definition vector4.h:80
float X
Definition vector4.h:66
void Normalize(void)
Definition vector4.h:276
#define CV_LIGHT_COLOR_0
#define CV_DIFFUSE
#define CV_SPECULAR
#define CV_AMBIENT
#define CV_LIGHT_DIRECTION_0
D3DLIGHT8 Lights[4]
Definition dx8wrapper.h:185
#define WWASSERT_PRINT(expr, string)
Definition wwdebug.h:135