Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
matrixmapper.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 : WWPhys *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/matrixmapper.cpp $*
26 * *
27 * Original Author:: Greg Hjelstrom *
28 * *
29 * $Author:: Kenny Mitchell *
30 * *
31 * $Modtime:: 06/26/02 4:04p $*
32 * *
33 * $Revision:: 11 $*
34 * *
35 * 06/26/02 KM Matrix name change to avoid MAX conflicts *
36 *---------------------------------------------------------------------------------------------*
37 * Functions: *
38 * MatrixMapperClass::MatrixMapperClass -- Constructor *
39 * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
40 * MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
41 * MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
42 * MatrixMapperClass::Apply -- Apply texture mapper to render states and texture stage states*
43 * MatrixMapperClass::Calculate_Texture_Matrix -- Calculate texture matrix *
44 * CompositeMatrixMapperClass::CompositeMatrixMapperClass -- Constructor *
45 * CompositeMatrixMapperClass::CompositeMatrixMapperClass -- Copy Constructor *
46 * CompositeMatrixMapperClass::~CompositeMatrixMapperClass -- Destructor *
47 * CompositeMatrixMapperClass::~CompositeMatrixMapperClass -- Destructor *
48 * CompositeMatrixMapperClass::Apply -- Apply texture mapper to render states and ts states *
49 * CompositeMatrixMapperClass::Calculate_Texture_Matrix -- Calculate texture matrix *
50 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
51
52
53#include "matrixmapper.h"
54#include "dx8wrapper.h"
55
56
57/***********************************************************************************************
58 * MatrixMapperClass::MatrixMapperClass -- Constructor *
59 * *
60 * Initializes the member variables to defaults *
61 * *
62 * INPUT: *
63 * *
64 * OUTPUT: *
65 * *
66 * WARNINGS: *
67 * *
68 * HISTORY: *
69 * 11/13/99 gth : created *
70 *=============================================================================================*/
81
82/***********************************************************************************************
83 * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
84 * *
85 * INPUT: *
86 * *
87 * OUTPUT: *
88 * *
89 * WARNINGS: *
90 * *
91 * HISTORY: *
92 * 6/20/2001 gth : created *
93 *=============================================================================================*/
94void MatrixMapperClass::Set_Texture_Transform(const Matrix3D & view_to_texture,float texsize)
95{
96 ViewToTexture = Matrix4x4(view_to_texture);
98}
99
100/***********************************************************************************************
101 * MatrixMapperClass::Set_Texture_Transform -- Sets the viewspace-to-texturespace transform *
102 * *
103 * INPUT: *
104 * *
105 * OUTPUT: *
106 * *
107 * WARNINGS: *
108 * *
109 * HISTORY: *
110 * 11/13/99 gth : Created. *
111 *=============================================================================================*/
112void MatrixMapperClass::Set_Texture_Transform(const Matrix4x4 & view_to_texture,float texsize)
113{
114 ViewToTexture=view_to_texture;
115
117}
118
119/***********************************************************************************************
120 * MatrixMapperClass::Update_View_To_Pixel_Transform -- recomputes ViewToPixel *
121 * *
122 * INPUT: *
123 * *
124 * OUTPUT: *
125 * *
126 * WARNINGS: *
127 * *
128 * HISTORY: *
129 * 1/4/00 gth : Created. *
130 *=============================================================================================*/
132{
133 /*
134 ** Create a ViewToPixel matrix which also does all of the offseting and flipping that has
135 ** to take place to get the actual texture coordinates.
136 **
137 ** Here is a description of the math:
138 ** If you transform eye-space points with the ViewToTexture matrix, you then need to compute:
139 ** s = ((x/w) + 1.0f) * 0.5f * ((texwid-2)/texwid)
140 ** t = (1.0f - (y/w)) * 0.5f * ((texwid-2)/texwid)
141 **
142 ** Let K = 0.5 * ((texwid-2)/texwid), Then:
143 ** ((x/w) + 1.0f) * K = (K*x + K*w) / w
144 ** (1.0f - (y/w)) * K = (-K*y + K*w) / w
145 **
146 ** This leads to the following matrix (The KOOK matrix!)
147 ** | K 0 0 K |
148 ** | 0 -K 0 K |
149 ** | 0 0 1 0 |
150 ** | 0 0 0 1 |
151 **
152 ** The code below manually "optimally" pre-multiplies this matrix with the ViewToTexture matrix
153 **
154 ** In addition, the z-coordinate is modified so that it goes from 0 to 1 rather than -1 to +1.
155 ** It can also be flipped if the INVERT_DEPTH_GRADIENT flag is on.
156 */
157 float k = 0.5 * (tex_size - 2.0f) / tex_size;
158
159 ViewToPixel[0][0] = k * ViewToTexture[0][0] + k * ViewToTexture[3][0];
160 ViewToPixel[0][1] = k * ViewToTexture[0][1] + k * ViewToTexture[3][1];
161 ViewToPixel[0][2] = k * ViewToTexture[0][2] + k * ViewToTexture[3][2];
162 ViewToPixel[0][3] = k * ViewToTexture[0][3] + k * ViewToTexture[3][3];
163
164 ViewToPixel[1][0] = -k * ViewToTexture[1][0] + k * ViewToTexture[3][0];
165 ViewToPixel[1][1] = -k * ViewToTexture[1][1] + k * ViewToTexture[3][1];
166 ViewToPixel[1][2] = -k * ViewToTexture[1][2] + k * ViewToTexture[3][2];
167 ViewToPixel[1][3] = -k * ViewToTexture[1][3] + k * ViewToTexture[3][3];
168
170 ViewToPixel[2][0] = -0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
171 ViewToPixel[2][1] = -0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
172 ViewToPixel[2][2] = -0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
173 ViewToPixel[2][3] = -0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
174 } else {
175 ViewToPixel[2][0] = 0.5f * ViewToTexture[2][0] + 0.5f * ViewToTexture[3][0];
176 ViewToPixel[2][1] = 0.5f * ViewToTexture[2][1] + 0.5f * ViewToTexture[3][1];
177 ViewToPixel[2][2] = 0.5f * ViewToTexture[2][2] + 0.5f * ViewToTexture[3][2];
178 ViewToPixel[2][3] = 0.5f * ViewToTexture[2][3] + 0.5f * ViewToTexture[3][3];
179 }
180
182
183 /*
184 ** Store the view space negative z vector for lighting effects
185 */
189 ViewSpaceProjectionNormal.Normalize();
190
191}
192
193/***********************************************************************************************
194 * MatrixMapperClass::Compute_Texture_Coordinate -- compute a single texture coord *
195 * *
196 * INPUT: *
197 * point - 3D point to calculate the texture coordinate for *
198 * set_stq - pointer to texture coordinate, s,t will be stored in X,Y. q will be stored in Z *
199 * *
200 * OUTPUT: *
201 * *
202 * WARNINGS: *
203 * *
204 * HISTORY: *
205 * 1/25/00 gth : Created. *
206 *=============================================================================================*/
208{
209 set_stq->X = ViewToPixel[0][0]*point.X + ViewToPixel[0][1]*point.Y + ViewToPixel[0][2]*point.Z + ViewToPixel[0][3];
210 set_stq->Y = ViewToPixel[1][0]*point.X + ViewToPixel[1][1]*point.Y + ViewToPixel[1][2]*point.Z + ViewToPixel[1][3];
211 set_stq->Z = ViewToPixel[3][0]*point.X + ViewToPixel[3][1]*point.Y + ViewToPixel[3][2]*point.Z + ViewToPixel[3][3];
212}
213
214/***********************************************************************************************
215 * MatrixMapperClass::Apply -- Apply texture mapper to render states and texture stage states *
216 * *
217 * INPUT: *
218 * *
219 * OUTPUT: *
220 * *
221 * WARNINGS: *
222 * *
223 * HISTORY: *
224 * 11/05/01 NH : Created comment block. *
225 *=============================================================================================*/
226void MatrixMapperClass::Apply(int uv_array_index)
227{
228 Matrix4x4 m;
229
230 switch (Type)
231 {
232 case ORTHO_PROJECTION:
233 /*
234 ** Orthographic projection
235 */
236 DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),ViewToPixel);
237 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
238 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
239 break;
241 /*
242 ** Perspective projection
243 */
244 m[0]=ViewToPixel[0];
245 m[1]=ViewToPixel[1];
246 m[2]=ViewToPixel[3];
247 DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
248 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
249 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_PROJECTED|D3DTTFF_COUNT3);
250 break;
251 case DEPTH_GRADIENT:
252 /*
253 ** Depth gradient, Set up second stage texture coordinates to
254 ** apply a depth gradient to the projection. Note that the
255 ** depth values have been set up to vary from 0 to 1 in the
256 ** Update_View_To_Pixel_Transform function.
257 */
258 m[0].Set(0,0,0,GradientUCoord);
259 m[1]=ViewToPixel[2];
260 DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
261 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION);
262 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
263 break;
264 case NORMAL_GRADIENT:
265 /*
266 ** Normal Gradient, Set up the second stage texture coordinates to
267 ** apply a gradient based on the dot product of the vertex normal
268 ** and the projection direction. (NOTE: this is basically texture-
269 ** based diffuse lighting!)
270 */
271 m[0].Set(0,0,0,GradientUCoord);
273 DX8Wrapper::Set_Transform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + Stage),m);
274 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL);
275 DX8Wrapper::Set_DX8_Texture_Stage_State(Stage,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2);
276 break;
277 }
278
279
280}
281
282/***********************************************************************************************
283 * MatrixMapperClass::Calculate_Texture_Matrix -- Calculate texture matrix *
284 * *
285 * INPUT: *
286 * *
287 * OUTPUT: *
288 * *
289 * WARNINGS: *
290 * *
291 * HISTORY: *
292 * 11/06/01 NH : Created comment block. *
293 *=============================================================================================*/
295{
296 // We return ViewToPixel. This is not, strictly speaking, always correct, but it is close
297 // and it is OK not to be 100% correct since this function is not called by the Apply()
298 // function.
299 tex_matrix = ViewToPixel;
300}
301
302/***********************************************************************************************
303 * CompositeMatrixMapperClass::CompositeMatrixMapperClass -- Constructor *
304 * *
305 * INPUT: *
306 * *
307 * OUTPUT: *
308 * *
309 * WARNINGS: *
310 * *
311 * HISTORY: *
312 * 11/05/01 NH : Created. *
313 *=============================================================================================*/
315 MatrixMapperClass(stage),
316 InternalMapper(internal_mapper)
317{
318 if (InternalMapper) {
319 InternalMapper->Add_Ref();
320 }
321}
322
323/***********************************************************************************************
324 * CompositeMatrixMapperClass::CompositeMatrixMapperClass -- Copy Constructor *
325 * *
326 * INPUT: *
327 * *
328 * OUTPUT: *
329 * *
330 * WARNINGS: *
331 * *
332 * HISTORY: *
333 * 11/05/01 NH : Created. *
334 *=============================================================================================*/
343
344/***********************************************************************************************
345 * CompositeMatrixMapperClass::~CompositeMatrixMapperClass -- Destructor *
346 * *
347 * INPUT: *
348 * *
349 * OUTPUT: *
350 * *
351 * WARNINGS: *
352 * *
353 * HISTORY: *
354 * 11/05/01 NH : Created. *
355 *=============================================================================================*/
363
364/***********************************************************************************************
365 * CompositeMatrixMapperClass::Apply -- Apply texture mapper to render states and ts states *
366 * *
367 * INPUT: *
368 * *
369 * OUTPUT: *
370 * *
371 * WARNINGS: *
372 * *
373 * HISTORY: *
374 * 11/05/01 NH : Created. *
375 *=============================================================================================*/
376void CompositeMatrixMapperClass::Apply(int uv_array_index)
377{
378 if (InternalMapper) {
379 // Get the texture matrix from the internal mapper, composite it into ViewToPixel (save off
380 // the previous value of ViewToPixel first), call the base class Apply() function (which will
381 // use the modifiedViewToPixel) and then restore ViewToPixel to its previous state.
382 Matrix4x4 int_mat;
383 InternalMapper->Calculate_Texture_Matrix(int_mat);
384 Matrix4x4 view_to_pixel_copy(ViewToPixel);
385
386 // We need to modify the view-to-pixel matrix to produce q (third texture coordinate values)
387 // equal to one. This is the input which the internal mappers' matrix was designed for (it
388 // is what you get when you use 2D vertex coordinates from the vertex buffer).
389 // For this we need to multiply the matrix by the following matrix:
390 // [1 0 0 0]
391 // [0 1 0 0] This is equivalent to overwriting the third row with the fourth one.
392 // [0 0 0 1]
393 // [0 0 0 1]
394 Matrix4x4 tmp;
395 tmp[0] = ViewToPixel[0];
396 tmp[1] = ViewToPixel[1];
397 tmp[2] = ViewToPixel[3];
398 tmp[3] = ViewToPixel[3];
399
400 // We multiply the matrices in this order so the camera position, transformed by ViewToPixel
401 // is used as the 'input texture coordinates' to be affected by the internal mapper matrix.
402 Matrix4x4::Multiply(int_mat, tmp, &ViewToPixel);
403
404 MatrixMapperClass::Apply(uv_array_index);
405 ViewToPixel = view_to_pixel_copy;
406 } else {
407 MatrixMapperClass::Apply(uv_array_index);
408 }
409}
410
411/***********************************************************************************************
412 * MatrixMapperClass::Calculate_Texture_Matrix -- Calculate texture matrix *
413 * *
414 * INPUT: *
415 * *
416 * OUTPUT: *
417 * *
418 * WARNINGS: *
419 * *
420 * HISTORY: *
421 * 11/06/01 NH : Created comment block. *
422 *=============================================================================================*/
424{
425 if (InternalMapper) {
426 // We return the internal mapper's matrix times ViewToPixel, adjusted to produce the correct
427 // z-value of 1. This is only correct if the mapper is in ORTHO_PROJECTION or
428 // PERSPECTIVE_PROJECTION mode, which should be the case for most uses of this mapper. It is
429 // OK for this function not be be 100% correct in all cases, since it is not used in the
430 // Apply() function.
431 Matrix4x4 int_mat;
432 InternalMapper->Calculate_Texture_Matrix(int_mat);
433
434 // We need to modify the view-to-pixel matrix to produce q (third texture coordinate values)
435 // equal to one. This is the input which the internal mappers' matrix was designed for (it
436 // is what you get when you use 2D vertex coordinates from the vertex buffer).
437 // For this we need to multiply the matrix by the following matrix:
438 // [1 0 0 0]
439 // [0 1 0 0] This is equivalent to overwriting the third row with the fourth one.
440 // [0 0 0 1]
441 // [0 0 0 1]
442 Matrix4x4 tmp;
443 tmp[0] = ViewToPixel[0];
444 tmp[1] = ViewToPixel[1];
445 tmp[2] = ViewToPixel[3];
446 tmp[3] = ViewToPixel[3];
447
448 // We multiply the matrices in this order so the camera position, transformed by ViewToPixel
449 // is used as the 'input texture coordinates' to be affected by the internal mapper matrix.
450 Matrix4x4::Multiply(int_mat, tmp, &tex_matrix);
451 } else {
453 }
454}
#define NULL
Definition BaseType.h:92
@ true
Definition bool.h:59
TextureMapperClass * InternalMapper
virtual ~CompositeMatrixMapperClass(void)
virtual void Calculate_Texture_Matrix(Matrix4x4 &tex_matrix)
virtual void Apply(int uv_array_index)
CompositeMatrixMapperClass(TextureMapperClass *internal_mapper, unsigned int stage)
virtual TextureMapperClass * Clone(void) const
static void Set_DX8_Texture_Stage_State(unsigned stage, D3DTEXTURESTAGESTATETYPE state, unsigned value)
Definition dx8wrapper.h:899
static void Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4 &m)
WWINLINE friend Matrix4x4 Multiply(const Matrix4x4 &a, const Matrix4x4 &b)
Definition matrix4.h:743
MatrixMapperClass(int stage)
Matrix4x4 ViewToPixel
virtual void Apply(int uv_array_index)
Matrix4x4 ViewToTexture
Vector3 ViewSpaceProjectionNormal
void Update_View_To_Pixel_Transform(float texsize)
void Compute_Texture_Coordinate(const Vector3 &point, Vector3 *set_stq)
void Set_Texture_Transform(const Matrix3D &view_to_texture, float texsize)
virtual void Calculate_Texture_Matrix(Matrix4x4 &tex_matrix)
bool Get_Flag(uint32 flag) const
unsigned int Stage
Definition mapper.h:113
TextureMapperClass(unsigned int stage=0)
Definition mapper.cpp:60
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91