Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
linegrp.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 : Linegroup.cpp *
24 * *
25 * $Archive:: $*
26 * *
27 * Original Author:: Hector Yee *
28 * *
29 * $Author:: Kenny Mitchell *
30 * *
31 * $Modtime:: 06/26/02 4:04p $*
32 * *
33 * $Revision:: 2 $*
34 * *
35 * 06/26/02 KM Matrix name change to avoid MAX conflicts *
36 *---------------------------------------------------------------------------------------------*
37 * Functions: *
38 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
39
40#include "sharebuf.h"
41#include "linegrp.h"
42#include "texture.h"
43#include "vertmaterial.h"
44#include "dx8wrapper.h"
45#include "wwmath.h"
46#include "rinfo.h"
47#include "camera.h"
48#include "dx8indexbuffer.h"
49#include "dx8vertexbuffer.h"
50#include "sortingrenderer.h"
51
52// Line groups are a rendering primitive similar to point groups
53// They are tetrahedra which are aligned with the view plane with their centers
54// at StartLineLoc. The apex of the tetrahedron is at EndLineLoc.
55// They can be individually colored LineDiffuse
56// and the LineUCoord determines the U coordinate of the texture to use
57// the V coordinate is always 0 at the flat end of the tetrahedron
58// and 1 at the apex
64 ALT(NULL),
67 LineCount(0),
69 Flags(0),
70 Shader(ShaderClass::_PresetAdditiveSpriteShader),
71 DefaultLineSize(0.0f),
72 DefaultLineColor(1.0f, 1.0f, 1.0f),
73 DefaultLineAlpha(1.0f),
75 DefaultTailDiffuse(0.0f, 0.0f, 0.0f, 0.0f),
77{
78}
79
91
96 ShareBufferClass<Vector4> *taildiffuse,
100 int active_line_count
101 )
102{
103 // The Line locations arrays are NOT optional!
104 WWASSERT(startlocs);
105 WWASSERT(endlocs);
106
107 // Ensure lengths of all arrays are the same:
108 WWASSERT(startlocs->Get_Count() == endlocs->Get_Count());
109 WWASSERT(!diffuse || startlocs->Get_Count() == diffuse->Get_Count());
110 WWASSERT(!alt || startlocs->Get_Count() == alt->Get_Count());
111 WWASSERT(!sizes || startlocs->Get_Count() == sizes->Get_Count());
112 WWASSERT(!ucoords || startlocs->Get_Count() == ucoords->Get_Count());
113 WWASSERT(!taildiffuse || startlocs->Get_Count() == taildiffuse->Get_Count());
114
115 REF_PTR_SET(StartLineLoc,startlocs);
116 REF_PTR_SET(EndLineLoc,endlocs);
117 REF_PTR_SET(LineDiffuse,diffuse);
118 REF_PTR_SET(TailDiffuse,taildiffuse);
120 REF_PTR_SET(LineSize,sizes);
121 REF_PTR_SET(LineUCoord,ucoords);
122
123 if (ALT) {
124 LineCount = active_line_count;
125 } else {
126 LineCount = (active_line_count >= 0) ? active_line_count : StartLineLoc->Get_Count();
127 }
128
129}
130
132{
133 DefaultLineSize = size;
134}
135
137{
138 return DefaultLineSize;
139}
140
142{
143 DefaultLineColor = color;
144}
145
150
152{
153 DefaultTailDiffuse = tdiffuse;
154}
155
160
162{
163 DefaultLineAlpha = alpha;
164}
165
167{
168 return DefaultLineAlpha;
169}
170
172{
173 DefaultLineUCoord = ucoord;
174}
175
177{
178 return DefaultLineUCoord;
179}
180
182{
183 if (on) Flags |= 1 << flag;
184 else
185 Flags &= ~(1 << flag);
186}
187
189{
190 return (Flags >> flag) & 0x1;
191}
192
194{
195 REF_PTR_SET(Texture,texture);
196}
197
199{
200 if (Texture) Texture->Add_Ref();
201 return Texture;
202}
203
208
210{
211 Shader = shader;
212}
213
218
220{
221 LineMode = linemode;
222}
223
228
230{
231 int i;
232
233 // If no lines, do nothing:
234 if (LineCount == 0) return;
235
236 // Shader handling
238
239 // If there is a color or alpha array enable gradient in shader - otherwise disable.
240 float value_255 = 0.9961f; //254 / 255
241 bool default_white_opaque = ( DefaultLineColor.X > value_255 &&
242 DefaultLineColor.Y > value_255 &&
243 DefaultLineColor.Z > value_255 &&
244 DefaultLineAlpha > value_255);
245
246 if (LineDiffuse || !default_white_opaque || !Texture) {
247 Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_MODULATE);
248 } else {
249 Shader.Set_Primary_Gradient(ShaderClass::GRADIENT_DISABLE);
250 }
251
252 // If Texture is non-NULL enable texturing in shader - otherwise disable.
253 if (Texture) {
255 } else {
257 }
258
263 REF_PTR_RELEASE(linemat);
264
265 WWASSERT(StartLineLoc && StartLineLoc->Get_Array());
266 WWASSERT(EndLineLoc && EndLineLoc->Get_Array());
267
268 // Enable sorting if the primitives are translucent and alpha testing is not enabled.
269 const bool sort = (Shader.Get_Dst_Blend_Func() != ShaderClass::DSTBLEND_ZERO) && (Shader.Get_Alpha_Test() == ShaderClass::ALPHATEST_DISABLE) && (WW3D::Is_Sorting_Enabled());
270
271 // the 3 offsets in view space
272 const static Vector3 offset_a = Vector3(WWMath::Cos(WWMATH_PI / 2), WWMath::Sin(WWMATH_PI /2 ), 0);
273 const static Vector3 offset_b = Vector3(WWMath::Cos(7 * WWMATH_PI / 6), WWMath::Sin(7 * WWMATH_PI / 6), 0);
274 const static Vector3 offset_c = Vector3(WWMath::Cos(11 * WWMATH_PI / 6), WWMath::Sin(11 * WWMATH_PI / 6), 0);
275
276 static Vector3 offset[3];
277
278 offset[0].Set(offset_a);
279 offset[1].Set(offset_b);
280 offset[2].Set(offset_c);
281
282 // Save off the view matrix
283 Matrix4x4 view;
284 DX8Wrapper::Get_Transform(D3DTS_VIEW, view);
285
286 Matrix4x4 identity(true);
287 DX8Wrapper::Set_Transform(D3DTS_WORLD, identity);
288
289 // if the points are in world space, transform the offsets
290 if (Get_Flag(TRANSFORM)) {
291 Matrix3D xform_mat;
292 xform_mat = rinfo.Camera.Get_Transform();
293 xform_mat.Set_Translation(Vector3(0, 0, 0));
294 xform_mat.Get_Orthogonal_Inverse(xform_mat);
295 for (i = 0; i < 3; i++) {
296 Matrix3D::Transform_Vector(xform_mat, offset[i], &offset[i]);
297 }
298 } else {
299 DX8Wrapper::Set_Transform(D3DTS_VIEW, identity);
300 }
301
302 int num_tris=0;
303 int num_indices=0;
304 int num_vertices=0;
305
306 switch (LineMode) {
307 case TETRAHEDRON:
308 num_tris =4 * LineCount;
309 num_indices =3 * num_tris;
310 num_vertices =4 * LineCount;
311 break;
312 case PRISM:
313 num_tris =8 * LineCount;
314 num_indices =3 * num_tris;
315 num_vertices =6 * LineCount;
316 break;
317 }
318
319 // construct the tetrahedra in the index buffers
320 // assume first vertex is the apex, followed by offset[0-3]
321
323
324 {
326 unsigned short *ibptr = lock.Get_Index_Array();
327 unsigned short j, idx;
328 try {
329 switch (LineMode) {
330 case TETRAHEDRON:
331 for (j=0; j<LineCount; j++) {
332 idx = 4 * j;
333 // apex, offset[1], offset[0]
334 *ibptr++ = idx + 0;
335 *ibptr++ = idx + 2;
336 *ibptr++ = idx + 1;
337 // apex, offset[2], offset[1]
338 *ibptr++ = idx + 0;
339 *ibptr++ = idx + 3;
340 *ibptr++ = idx + 2;
341 // apex, offset[0], offset[2]
342 *ibptr++ = idx + 0;
343 *ibptr++ = idx + 1;
344 *ibptr++ = idx + 3;
345 // offset[0-3]
346 *ibptr++ = idx + 1;
347 *ibptr++ = idx + 2;
348 *ibptr++ = idx + 3;
349 }
350 break;
351 case PRISM:
352 for (j=0; j<LineCount; j++) {
353 idx = 6 * j;
354 // starting cap 0,1,2
355 *ibptr++ = idx + 0;
356 *ibptr++ = idx + 1;
357 *ibptr++ = idx + 2;
358 // left side
359 *ibptr++ = idx + 0;
360 *ibptr++ = idx + 3;
361 *ibptr++ = idx + 1;
362 *ibptr++ = idx + 1;
363 *ibptr++ = idx + 3;
364 *ibptr++ = idx + 4;
365 // bottom side
366 *ibptr++ = idx + 1;
367 *ibptr++ = idx + 4;
368 *ibptr++ = idx + 5;
369 *ibptr++ = idx + 1;
370 *ibptr++ = idx + 5;
371 *ibptr++ = idx + 2;
372 // right side
373 *ibptr++ = idx + 0;
374 *ibptr++ = idx + 2;
375 *ibptr++ = idx + 5;
376 *ibptr++ = idx + 0;
377 *ibptr++ = idx + 5;
378 *ibptr++ = idx + 3;
379 // end cap
380 *ibptr++ = idx + 3;
381 *ibptr++ = idx + 5;
382 *ibptr++ = idx + 4;
383 }
384 break;
385 }
387 } catch(...) {
389 }
390 } // writing to ib
391
392 // make the vertex buffers
393
395
396 {
398
400
401 Vector3 loc, start, end;
402 int point, j;
403 float size = DefaultLineSize;
405 float ucoord = DefaultLineUCoord;
406 Vector4 taildiffuse = DefaultTailDiffuse;
407
408 for (i = 0; i < LineCount; i++)
409 {
410 point = (ALT) ? ALT->Get_Element(i) : i;
411 if (LineSize) size = LineSize->Get_Element(point);
412 if (LineDiffuse) diffuse = LineDiffuse->Get_Element(point);
413 if (LineUCoord) ucoord = LineUCoord->Get_Element(point);
414 if (TailDiffuse) taildiffuse = TailDiffuse->Get_Element(point);
415
416 end.Set(EndLineLoc->Get_Element(point));
417 start.Set(StartLineLoc->Get_Element(point));
418
419 switch (LineMode) {
420 case TETRAHEDRON:
421 // apex
422 vb->x = end.X;
423 vb->y = end.Y;
424 vb->z = end.Z;
425 vb->diffuse = DX8Wrapper::Convert_Color(taildiffuse);
426 vb->u1 = ucoord;
427 vb->v1 = 1.0f;
428 vb++;
429
430 for (j=0; j<3; j++) {
431 loc.Set(start + size * offset[j]);
432 vb->x = loc.X;
433 vb->y = loc.Y;
434 vb->z = loc.Z;
435 vb->diffuse = DX8Wrapper::Convert_Color(diffuse);
436 vb->u1 = ucoord;
437 vb->v1 = 0.0f;
438 vb++;
439 }
440 break;
441 case PRISM:
442 // start cap
443 for (j = 0; j < 3; j++) {
444 loc.Set(start + size * offset[j]);
445 vb->x = loc.X;
446 vb->y = loc.Y;
447 vb->z = loc.Z;
448 vb->diffuse = DX8Wrapper::Convert_Color(diffuse);
449 vb->u1 = ucoord;
450 vb->v1 = 0.0f;
451 vb++;
452 }
453 // Do not merge loops. The vb has to be written in a specific order
454 // (This is to optimize AGP memory write)
455
456 // end cap
457 for (j=0; j<3; j++) {
458 loc.Set(end + size * offset[j]);
459 vb->x = loc.X;
460 vb->y = loc.Y;
461 vb->z = loc.Z;
462 vb->diffuse = DX8Wrapper::Convert_Color(taildiffuse);
463 vb->u1 = ucoord;
464 vb->v1 = 1.0f;
465 vb++;
466 }
467 break;
468 }
469
470 }
471 } // writing to vb
472
475
476 if (sort) {
477 SortingRendererClass::Insert_Triangles(0, num_tris, 0, num_vertices);
478 } else {
479 DX8Wrapper::Draw_Triangles(0, num_tris, 0, num_vertices);
480 }
481
482 // restore the matrices
483 DX8Wrapper::Set_Transform(D3DTS_VIEW, view);
484}
485
487{
488 switch (LineMode) {
489 case TETRAHEDRON:
490 return LineCount * 4;
491 break;
492 case PRISM:
493 return LineCount * 8;
494 break;
495 }
496 WWASSERT(0);
497 return 0;
498}
#define NULL
Definition BaseType.h:92
UnicodeString alt
#define WWASSERT
#define WWMATH_PI
Definition wwmath.h:56
static void Set_Vertex_Buffer(const VertexBufferClass *vb, unsigned stream=0)
static void Set_Texture(unsigned stage, TextureBaseClass *texture)
static void Set_Index_Buffer(const IndexBufferClass *ib, unsigned short index_base_offset)
static Vector4 Convert_Color(unsigned color)
Definition dx8wrapper.h:958
static void Draw_Triangles(unsigned buffer_type, unsigned short start_index, unsigned short polygon_count, unsigned short min_vertex_index, unsigned short vertex_count)
static void Set_Material(const VertexMaterialClass *material)
static void Set_Shader(const ShaderClass &shader)
static void Get_Transform(D3DTRANSFORMSTATETYPE transform, Matrix4x4 &m)
static void Set_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4 &m)
VertexFormatXYZNDUV2 * Get_Formatted_Vertex_Array()
void Set_Texture(TextureClass *texture)
Definition linegrp.cpp:193
float DefaultLineSize
Definition linegrp.h:126
TextureClass * Peek_Texture(void)
Definition linegrp.cpp:204
void Set_Shader(const ShaderClass &shader)
Definition linegrp.cpp:209
Vector4 DefaultTailDiffuse
Definition linegrp.h:130
TextureClass * Get_Texture(void)
Definition linegrp.cpp:198
ShaderClass Shader
Definition linegrp.h:122
ShareBufferClass< float > * LineUCoord
Definition linegrp.h:118
void Set_Line_Color(const Vector3 &color)
Definition linegrp.cpp:141
float Get_Line_UCoord(void)
Definition linegrp.cpp:176
ShareBufferClass< Vector4 > * LineDiffuse
Definition linegrp.h:114
LineGroupClass(void)
Definition linegrp.cpp:59
float Get_Line_Alpha(void)
Definition linegrp.cpp:166
virtual ~LineGroupClass(void)
Definition linegrp.cpp:80
int Get_Flag(FlagsType flag)
Definition linegrp.cpp:188
void Render(RenderInfoClass &rinfo)
Definition linegrp.cpp:229
void Set_Line_Mode(LineModeType linemode)
Definition linegrp.cpp:219
ShareBufferClass< Vector3 > * StartLineLoc
Definition linegrp.h:112
Vector4 Get_Tail_Diffuse(void)
Definition linegrp.cpp:156
void Set_Line_UCoord(float ucoord)
Definition linegrp.cpp:171
ShareBufferClass< unsigned int > * ALT
Definition linegrp.h:116
void Set_Line_Alpha(float alpha)
Definition linegrp.cpp:161
void Set_Line_Size(float size)
Definition linegrp.cpp:131
Vector3 DefaultLineColor
Definition linegrp.h:127
float DefaultLineAlpha
Definition linegrp.h:128
Vector3 Get_Line_Color(void)
Definition linegrp.cpp:146
ShareBufferClass< Vector4 > * TailDiffuse
Definition linegrp.h:115
ShareBufferClass< float > * LineSize
Definition linegrp.h:117
ShaderClass Get_Shader(void)
Definition linegrp.cpp:214
ShareBufferClass< Vector3 > * EndLineLoc
Definition linegrp.h:113
TextureClass * Texture
Definition linegrp.h:121
LineModeType LineMode
Definition linegrp.h:131
void Set_Flag(FlagsType flag, bool on)
Definition linegrp.cpp:181
LineModeType Get_Line_Mode(void)
Definition linegrp.cpp:224
float Get_Line_Size(void)
Definition linegrp.cpp:136
void Set_Tail_Diffuse(const Vector4 &tdiffuse)
Definition linegrp.cpp:151
void Set_Arrays(ShareBufferClass< Vector3 > *startlocs, ShareBufferClass< Vector3 > *endlocs, ShareBufferClass< Vector4 > *diffuse=NULL, ShareBufferClass< Vector4 > *taildiffuse=NULL, ShareBufferClass< unsigned int > *alt=NULL, ShareBufferClass< float > *sizes=NULL, ShareBufferClass< float > *ucoords=NULL, int active_line_count=-1)
Definition linegrp.cpp:92
unsigned int Flags
Definition linegrp.h:125
int Get_Polygon_Count(void)
Definition linegrp.cpp:486
float DefaultLineUCoord
Definition linegrp.h:129
WWINLINE void Set_Translation(const Vector3 &t)
Definition matrix3d.h:219
void Get_Orthogonal_Inverse(Matrix3D &set_inverse) const
Definition matrix3d.cpp:570
static WWINLINE void Transform_Vector(const Matrix3D &tm, const Vector3 &in, Vector3 *out)
Definition matrix3d.h:1742
CameraClass & Camera
Definition rinfo.h:100
const Matrix3D & Get_Transform(void) const
Definition rendobj.h:617
@ GRADIENT_DISABLE
Definition shader.h:192
@ GRADIENT_MODULATE
Definition shader.h:193
@ TEXTURING_DISABLE
Definition shader.h:219
@ TEXTURING_ENABLE
Definition shader.h:220
@ CULL_MODE_ENABLE
Definition shader.h:159
@ ALPHATEST_DISABLE
Definition shader.h:96
@ DSTBLEND_ZERO
Definition shader.h:172
int Get_Count(void)
Definition sharebuf.h:64
static void Insert_Triangles(const SphereClass &bounding_sphere, unsigned short start_index, unsigned short polygon_count, unsigned short min_vertex_index, unsigned short vertex_count)
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
static VertexMaterialClass * Get_Preset(PresetType type)
static bool Is_Sorting_Enabled(void)
Definition ww3d.h:220
static float Sin(float val)
Definition wwmath.h:378
static float Cos(float val)
Definition wwmath.h:356
int IndexBufferExceptionFunc(void)
const unsigned dynamic_fvf_type
@ BUFFER_TYPE_DYNAMIC_DX8
Definition dx8wrapper.h:90
@ BUFFER_TYPE_DYNAMIC_SORTING
Definition dx8wrapper.h:91
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define REF_PTR_SET(dst, src)
Definition refcount.h:79
unsigned char flag
Definition vchannel.cpp:273