Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
shdrenderer.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/shdrenderer.cpp $*
26 *
27 * Org Author:: Jani_p
28 * *
29 * $Author:: Kenny_m
30 *
31 * $Modtime:: 7/29/02 1:50p $*
32 * *
33 * $Revision:: 3 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * 6/02/02 5:59p KM Added render info and light environment support $*
38 * 7/29/02 1:50p KM Added VB and IB usage flags for software vertex shaders
39 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40
41#include "shdrenderer.h"
42#include "shdforcelinks.h"
43#include "shdmesh.h"
44#include "shdsubmesh.h"
45#include "shddef.h"
46#include "shddefmanager.h"
47#include "shdclassids.h"
48#include "wwdebug.h"
49#include "dx8vertexbuffer.h"
50#include "dx8indexbuffer.h"
51#include "dx8wrapper.h"
52#include "rinfo.h"
53#include "camera.h"
54#include "texture.h"
55#include "ww3dformat.h"
56#include "wwprofile.h"
57#include "sortingrenderer.h"
58#include "meshmatdesc.h"
59
60static DynamicVectorClass<Vector3> _TempVertexBuffer;
61static DynamicVectorClass<Vector3> _TempNormalBuffer;
62
63ShdRendererClass* ShdRendererClass::ShdRenderer=NULL;
64
68
72
74// Initialize the rendering system. This is the place to create different versions
75// (such as DX8, DX9, OGL) of the rendering system, if needed.
78{
80
81 WWASSERT(!ShdRenderer);
82
83 ShdRenderer=new ShdDX8RendererClass();
84
86}
87
89{
90 ShdDefClass* def;
91 for (int i=SHDDEF_CLASSID_DUMMY+1; i<SHDDEF_CLASSID_LAST; i++)
92 {
94 if (def != NULL) {
95 def->Init();
96 REF_PTR_RELEASE(def);
97 }
98 }
99}
100
102// Release the renderer system. At this point, all the meshes must have been
103// unregistered.
106{
108
109 WWASSERT(ShdRenderer);
110
111 delete ShdRenderer;
112 ShdRenderer=0;
113}
114
116{
117 ShdDefClass* def;
118 for (int i=SHDDEF_CLASSID_DUMMY+1; i<SHDDEF_CLASSID_LAST; i++)
119 {
121 if (def) {
122 def->Shutdown();
123 REF_PTR_RELEASE(def);
124 }
125 }
126}
127
129// DirectX8 renderer utility class declaration
131
135
140
142{
143 WWASSERT(node);
144 node->Add_Ref();
145 node->Set_Renderer_List_Container(this,Pass);
146 LinkedNodes.Add_Tail(node);
147}
148
150{
151 while (!LinkedNodes.Is_Empty()) {
152 ShdRendererNodeClass* node=LinkedNodes.Remove_Head();
153// REF_PTR_RELEASE(node);
154 delete node;
155 }
156}
157
159{
160 ShdRendererNodeClass* prev_node=NULL;
161 while (!VisibleNodes.Is_Empty())
162 {
163 ShdRendererNodeClass* node=VisibleNodes.Remove_Head();
164 node->Apply_Shared_Shader_Settings(prev_node,Pass);
165 node->Flush(Pass);
166 prev_node=node;
167 }
168
169}
170
171
173{
174public:
176 virtual ~MeshContainerClass();
177
179// void Add_Visible_Node(ShdRendererNodeClass* node,int pass);
180 void Flush();
181
182private:
183
184// ShdRendererNodeList VisibleNodeList[SHD_MAX_PASSES];
185 RendererListContainerList RendererListContainers[SHD_MAX_PASSES];
186};
187
192{
193public:
195 virtual ~ShdDX8RendererNodeClass();
196
197 virtual void Render(RenderInfoClass& rinfo);
198 virtual void Flush(int pass);
199 virtual void Apply_Shared_Shader_Settings(ShdRendererNodeClass* prev,int pass);
200
201 virtual bool Greater_Than(const ShdRendererNodeClass&, int pass) const;
202 virtual bool Similar_Enough(const ShdRendererNodeClass&, int pass) const;
203
204private:
205
207 ShdMeshClass* Mesh;
208 ShdSubMeshClass* SubMesh;
209 VertexBufferClass** VertexBuffers;
210 IndexBufferClass* IndexBuffer;
211 LightEnvironmentClass LightEnvironment; // todo KJM optimize for output lights
212 RenderInfoClass* RenderInfo;
213};
214
216// DirectX8 renderer implementation
219{
220 MeshCategories=new MeshContainerClass*[SHDDEF_CLASSID_LAST];
221 for (int i=0;i<SHDDEF_CLASSID_LAST;++i)
222 {
223 MeshCategories[i]=0;
224 }
225}
226
228{
229 for (int i=0;i<SHDDEF_CLASSID_LAST;++i)
230 {
231 if (MeshCategories[i])
232 {
233 REF_PTR_RELEASE(MeshCategories[i]);
234 delete MeshCategories[i];
235 MeshCategories[i]=0;
236 }
237 }
238 delete[] MeshCategories;
239 MeshCategories=0;
240}
241
243{
244 // Danger! Assuming ShdDX8RendererNodeClass!
245 const ShdDX8RendererNodeClass* src=static_cast<const ShdDX8RendererNodeClass*>(&s);
246
247 WWASSERT(SubMesh && src->SubMesh);
248 return SubMesh->Peek_Shader()->Greater_Than(*src->SubMesh->Peek_Shader(),pass);
249}
250
252{
253 // Danger! Assuming ShdDX8RendererNodeClass!
254 const ShdDX8RendererNodeClass* src=static_cast<const ShdDX8RendererNodeClass*>(&s);
255
256 WWASSERT(SubMesh && src->SubMesh);
257 return SubMesh->Peek_Shader()->Similar_Enough(*src->SubMesh->Peek_Shader(),pass);
258}
259
260
262// Register mesh to the rendering system
265(
266 ShdMeshClass* mesh,
267 ShdSubMeshClass* sub_mesh
268)
269{
270 ShdInterfaceClass* shd=sub_mesh->Peek_Shader();
271 const ShdDefClass* def=shd->Peek_Definition();
272 uint32 class_id=def->Get_Class_ID();
274 if (!MeshCategories[class_id])
275 {
276 MeshCategories[class_id]=new MeshContainerClass();
277 }
278 return MeshCategories[class_id]->Register_Mesh(mesh,sub_mesh);
279}
280
282// Flush the list of visible meshes
285{
286 WWPROFILE("ShdDX8RendererClass::Flush");
287
291
292 SNAPSHOT_SAY(("ShdDX8RendererClass::Flush()\n"));
293 for (int i=0;i<SHDDEF_CLASSID_LAST;++i)
294 {
295 if (MeshCategories[i])
296 {
297 MeshCategories[i]->Flush();
298 }
299 }
302}
303
304
305
307// MeshContiner is used for each shader type. Meshes are assigned to a container
308// when they're first rendered and they link themselves to container's visible list
309// each frame they're visible.
314
316{
317 for (int pass=0; pass<SHD_MAX_PASSES; pass++)
318 {
319 while (!RendererListContainers[pass].Is_Empty()) {
320 RendererListContainerClass* cont=RendererListContainers[pass].Remove_Head();
321 cont->Unregister_All();
322 REF_PTR_RELEASE(cont);
323 }
324 }
325}
326
328// RendererNodeClass acts as a link between ShdMeshClass, ShdSubMeshClass and the
329// rendering system.
332(
333 ShdMeshClass* mesh,
334 ShdSubMeshClass* sub_mesh
335)
336{
337 ShdDX8RendererNodeClass* node=new ShdDX8RendererNodeClass(this,mesh,sub_mesh);
338 ShdInterfaceClass* shdi=sub_mesh->Peek_Shader();
339 WWASSERT(shdi);
340 for (int pass=0; pass<shdi->Get_Pass_Count(); pass++)
341 {
342 RendererListContainerIterator ite(&RendererListContainers[pass]);
343 ite.Last();
344 while (!ite.Is_Done()) {
346 if (cont) {
348 ite2.First();
349 // Container should delete itself when the last node is removed, so we must
350 // never have an empty node.
351 WWASSERT(!ite2.Is_Done());
352
353 ShdRendererNodeClass* obj=ite2.Peek_Obj();
354 if (obj) {
355 if (node->Greater_Than(*obj,pass)) {
356 // If similar enough, add to the same renderer container, otherwise create a new one
357 if (node->Similar_Enough(*obj,pass)) {
358 cont->Register_Renderer(node);
359 }
360 else {
362 new_cont->Register_Renderer(node);
363 RendererListContainers[pass].Add_After(new_cont,new_cont);
364 }
365 break;
366 }
367 }
368 }
369 ite.Prev();
370 }
371 if (ite.Is_Done()) {
373 new_cont->Register_Renderer(node);
374 RendererListContainers[pass].Add(new_cont);
375 }
376 }
377
378 return node;
379}
380
382// Render all visible nodes and clear the visible list.
385{
386 SNAPSHOT_SAY(("ShdDX8RendererClass::MeshContainerClass::Flush()\n"));
387
388 for (int pass=0; pass<SHD_MAX_PASSES; pass++)
389 {
390 RendererListContainerIterator ite(&RendererListContainers[pass]);
391 ite.First();
392 while (!ite.Is_Done()) {
394 cont->Flush();
395 ite.Next();
396 }
397 }
398}
399
400
401/***********************************************************************************************
402 * ShdDX8RendererNodeClass::ShdDX8RendererNodeClass --
403 * Init the mesh for rendering... this node is used for all subsequent rendering of
404 * the particular mesh.
405 * INPUT: *
406 * *
407 * OUTPUT: *
408 * *
409 * WARNINGS: *
410 * *
411 * HISTORY: *
412 * 4/20/2002 jp : Created
413 * 5/26/2002 kjm : Updated stream handling for per-pixel shaders *
414 * 6/02/2002 kjm : Added light environment handling
415 * 7/29/2002 kjm : Added VB and IB usage flags for software vertex shaders
416 *=============================================================================================*/
418(
420 ShdMeshClass* mesh,
421 ShdSubMeshClass* sub_mesh
422)
423: Container(container),
424 Mesh(NULL),
425 SubMesh(NULL),
426 VertexBuffers(NULL),
427 IndexBuffer(NULL)
428{
429 REF_PTR_SET(Container,container);
430 REF_PTR_SET(Mesh,mesh);
431 REF_PTR_SET(SubMesh,sub_mesh);
432
433 // create usage depending on associated shader's processing behaviour KM
435
436 if (!SubMesh->Peek_Shader()->Use_HW_Vertex_Processing())
437 {
439 }
440
441 int count=SubMesh->Get_Visible_Polygon_Count();
442 if (!count) count=SubMesh->Get_Polygon_Count();
443 unsigned index_count=count*3;
444 if (SubMesh->Is_Sorting()) {
445 IndexBuffer=new SortingIndexBufferClass(index_count);
446 }
447 else {
448 IndexBuffer=new DX8IndexBufferClass(index_count,ib_usage);
449 }
450 IndexBufferClass::WriteLockClass ilock(IndexBuffer);
451 const TriIndex* indices=SubMesh->Get_Polygon_Array();
452 int i;
453 int j=0;
454 for (i=SubMesh->Get_First_Visible_Polygon();i<count+SubMesh->Get_First_Visible_Polygon();++i)
455 {
456 ilock.Get_Index_Array()[j++]=indices[i][0];
457 ilock.Get_Index_Array()[j++]=indices[i][1];
458 ilock.Get_Index_Array()[j++]=indices[i][2];
459 }
460
461 // Don't use static vertex buffers if skin
462 if (SubMesh->Get_Flag(MeshGeometryClass::SKIN)) {
463 return;
464 }
465
466 // Compose the vertex and index buffers
468 vss.Locations=SubMesh->Get_Vertex_Array();
469 vss.Normals=SubMesh->Get_Vertex_Normal_Array();
470 for (unsigned stage=0;stage<MAX_TEXTURE_STAGES;++stage)
471 {
472 vss.UV[stage]=SubMesh->Get_UV_Array(stage);
473 }
474 vss.DiffuseInt=SubMesh->Get_Diffuse_Array();
475 vss.S=SubMesh->Get_Tangent_Basis_S_Array();
476 vss.T=SubMesh->Get_Tangent_Basis_T_Array();
477 vss.SxT=SubMesh->Get_Tangent_Basis_SxT_Array();
478
479 unsigned vertex_count=SubMesh->Get_Vertex_Count();
480 unsigned stream_count=SubMesh->Peek_Shader()->Get_Vertex_Stream_Count();
481 WWASSERT(stream_count>0);
482
483 // create usage depending on associated shader's processing behaviour KM
485
486 if (!SubMesh->Peek_Shader()->Use_HW_Vertex_Processing())
487 {
489 }
490
491 VertexBuffers=new VertexBufferClass*[stream_count];
492 unsigned n;
493 for (n=0;n<stream_count;++n)
494 {
495 unsigned vertex_size=SubMesh->Peek_Shader()->Get_Vertex_Size(n);
496
497 if (SubMesh->Is_Sorting()) {
498 VertexBuffers[n]=
499 new SortingVertexBufferClass(vertex_count);
500 }
501 else {
502 VertexBuffers[n]=
504 (
505 0,
506 vertex_count,
507 vb_usage,
508 vertex_size
509 );
510 }
511
512 VertexBufferClass::WriteLockClass vlock(VertexBuffers[n]);
513 SubMesh->Peek_Shader()->Copy_Vertex_Stream
514 (
515 n,
516 vlock.Get_Vertex_Array(),
517 vss,
518 SubMesh->Get_Vertex_Count()
519 );
520 }
521}
522
524{
525 unsigned stream_count=SubMesh->Peek_Shader()->Get_Vertex_Stream_Count();
526 unsigned n;
527 for (n=0;n<stream_count;++n)
528 {
529 REF_PTR_RELEASE(VertexBuffers[n]);
530 }
531 delete[] VertexBuffers;
532 VertexBuffers=NULL;
533
534 REF_PTR_RELEASE(IndexBuffer);
535 REF_PTR_RELEASE(Mesh);
536 REF_PTR_RELEASE(SubMesh);
537 REF_PTR_RELEASE(Container);
538}
539
540/***********************************************************************************************
541 * ShdDX8RendererNodeClass::Render -- Render node
542 *
543 * INPUT: *
544 * *
545 * OUTPUT: *
546 * *
547 * WARNINGS: *
548 * *
549 * HISTORY: *
550 * 4/20/2002 jp : Created
551 * 6/02/2002 kjm : Added light environment handling
552 *=============================================================================================*/
554{
555 RenderInfo=&rinfo;
556 if (rinfo.light_environment)
557 {
558 memcpy(&LightEnvironment,rinfo.light_environment,sizeof(LightEnvironmentClass));
559 }
560 else {
561 LightEnvironment.Reset(Vector3(0.0f,0.0f,0.0f),Vector3(0.0f,0.0f,0.0f));
562 }
563
564 Connect();
565}
566
567bool enable_rnd=true;
569{
570 WWASSERT(RenderInfo);
571
572 // pass selection for this instance
573 if (!SubMesh->Peek_Shader()->Pass_Selection(Mesh,RenderInfo,cur_pass))
574 {
575 return;
576 }
577
578 SNAPSHOT_SAY(("ShdDX8RendererNodeClass::Flush(%d) - %s\n",cur_pass,SubMesh->Get_Name()));
579
580 // BEGIN OF SKIN CODE
581 if (SubMesh->Get_Flag(MeshGeometryClass::SKIN)) {
582 DX8Wrapper::Set_Vertex_Buffer(NULL); // Free up the reference to the current vertex buffer
583 // (in case it is the dynamic, which may have to be resized)
584
585 unsigned vertex_count=SubMesh->Get_Vertex_Count();
586 unsigned stream_count=SubMesh->Peek_Shader()->Get_Vertex_Stream_Count();
587 WWASSERT(stream_count>0);
588
589 // For now there are restrictions in vertex buffer format with skinning
591 WWASSERT(SubMesh->Peek_Shader()->Get_Vertex_Size(0)==fi.Get_FVF_Size());
592
596 vertex_count);
597 SNAPSHOT_SAY(("DynamicVBAccess - %s - %d vertices\n",SubMesh->Is_Sorting() ? "sorting" : "non-sorting",vertex_count));
598
599 if (_TempVertexBuffer.Length() < (int)vertex_count) _TempVertexBuffer.Resize(vertex_count);
600 if (_TempNormalBuffer.Length() < (int)vertex_count) _TempNormalBuffer.Resize(vertex_count);
601 Vector3* loc=&(_TempVertexBuffer[0]);
602 Vector3* norm=&(_TempNormalBuffer[0]);
603 WWASSERT(Mesh->Get_Container());
604 SubMesh->Get_Deformed_Vertices(loc,norm,Mesh->Get_Container()->Get_HTree());
605
606 // Compose the vertex and index buffers
608 vss.Locations=loc;
609 vss.Normals=norm;
610 for (unsigned stage=0;stage<MAX_TEXTURE_STAGES;++stage)
611 {
612 vss.UV[stage]=SubMesh->Get_UV_Array(stage);
613 }
614 vss.DiffuseInt=SubMesh->Get_Diffuse_Array();
615 vss.S=SubMesh->Get_Tangent_Basis_S_Array();
616 vss.T=SubMesh->Get_Tangent_Basis_T_Array();
617 vss.SxT=SubMesh->Get_Tangent_Basis_SxT_Array();
618
619 WWASSERT(stream_count==1);
620 {
622 SubMesh->Peek_Shader()->Copy_Vertex_Stream
623 (
624 0,//stream
626 vss,
627 SubMesh->Get_Vertex_Count()
628 );
629 }
630 DX8Wrapper::Set_Vertex_Buffer(vb);//stream 0
631
632 DX8Wrapper::Set_Index_Buffer(IndexBuffer,0);
633 DX8Wrapper::Set_Transform(D3DTS_WORLD,Matrix3D(true));//Mesh->Get_Transform());
634
635 DX8Wrapper::Set_Light_Environment(&LightEnvironment);
636 SubMesh->Peek_Shader()->Apply_Instance(cur_pass, *RenderInfo);
637
638 if (SubMesh->Is_Sorting()) {
640 (
641 0,
642 SubMesh->Get_Visible_Polygon_Count() ? SubMesh->Get_Visible_Polygon_Count() : SubMesh->Get_Polygon_Count(),
643 0,
644 SubMesh->Get_Vertex_Count()
645 );
646 }
647 else {
649 (
650 0,
651 SubMesh->Get_Visible_Polygon_Count() ? SubMesh->Get_Visible_Polygon_Count() : SubMesh->Get_Polygon_Count(),
652 0,
653 SubMesh->Get_Vertex_Count()
654 );
655 }
656
657 return;
658 }
659
660 // END OF SKIN CODE
661
662
663 for (unsigned n=0;n<SubMesh->Peek_Shader()->Get_Vertex_Stream_Count();++n)
664 {
665 DX8Wrapper::Set_Vertex_Buffer(VertexBuffers[n],n);
666 }
667
668 DX8Wrapper::Set_Index_Buffer(IndexBuffer,0);
669 DX8Wrapper::Set_Transform(D3DTS_WORLD,Mesh->Get_Transform());
670
671 DX8Wrapper::Set_Light_Environment(&LightEnvironment);
672 SubMesh->Peek_Shader()->Apply_Instance(cur_pass, *RenderInfo);
673
674 if (SubMesh->Is_Sorting()) {
676 (
677 0,
678 SubMesh->Get_Visible_Polygon_Count() ? SubMesh->Get_Visible_Polygon_Count() : SubMesh->Get_Polygon_Count(),
679 0,
680 SubMesh->Get_Vertex_Count()
681 );
682 }
683 else {
685 (
686 0,
687 SubMesh->Get_Visible_Polygon_Count() ? SubMesh->Get_Visible_Polygon_Count() : SubMesh->Get_Polygon_Count(),
688 0,
689 SubMesh->Get_Vertex_Count()
690 );
691 }
692
693}
694
696{
697 // If the previously set shader is not the same type as this, we need to set
698 // all render states to default state.
699 if (prev_node) {
700 ShdDX8RendererNodeClass* prev_dx8_node=static_cast<ShdDX8RendererNodeClass*>(prev_node); // Illegal to pass another type!
701 ShdInterfaceClass* shd=prev_dx8_node->SubMesh->Peek_Shader();
702 if (shd->Get_Class_ID()!=SubMesh->Peek_Shader()->Get_Class_ID()) {
704 }
705 }
706 SubMesh->Peek_Shader()->Apply_Shared(pass, *RenderInfo);
707}
708
#define NULL
Definition BaseType.h:92
#define WWASSERT
unsigned long uint32
Definition bittype.h:46
static void Set_Vertex_Buffer(const VertexBufferClass *vb, unsigned stream=0)
static void Invalidate_Cached_Render_States(void)
static void Set_Light_Environment(LightEnvironmentClass *light_env)
Set the light environment. This is a lighting model which used up to four directional lights to produ...
static void Apply_Default_State()
Resets render device to default state.
static void Set_Index_Buffer(const IndexBufferClass *ib, unsigned short index_base_offset)
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_Transform(D3DTRANSFORMSTATETYPE transform, const Matrix4x4 &m)
static void Apply_Render_State_Changes()
VertexFormatXYZNDUV2 * Get_Formatted_Vertex_Array()
unsigned Get_FVF_Size() const
Definition dx8fvf.h:280
void First(GenericMultiListClass *list)
Definition multilist.h:182
void Last(GenericMultiListClass *list)
Definition multilist.h:184
ObjectType * Peek_Obj(void)
Definition multilist.h:306
void Add_Ref(void) const
Definition refcount.cpp:171
RefCountClass(void)
Definition refcount.h:108
LightEnvironmentClass * light_environment
Definition rinfo.h:109
ShdRendererNodeList & Peek_Linked_Nodes()
Definition shdrenderer.h:72
void Register_Renderer(ShdRendererNodeClass *node)
ShdRendererNodeClass * Register_Mesh(ShdMeshClass *mesh, ShdSubMeshClass *sub_mesh)
virtual ~ShdDX8RendererClass()
virtual ShdRendererNodeClass * Register_Mesh(ShdMeshClass *mesh, ShdSubMeshClass *sub_mesh)
virtual void Flush()
virtual bool Greater_Than(const ShdRendererNodeClass &, int pass) const
virtual void Apply_Shared_Shader_Settings(ShdRendererNodeClass *prev, int pass)
virtual bool Similar_Enough(const ShdRendererNodeClass &, int pass) const
virtual void Flush(int pass)
virtual void Render(RenderInfoClass &rinfo)
ShdDX8RendererNodeClass(ShdDX8RendererClass::MeshContainerClass *container, ShdMeshClass *mesh, ShdSubMeshClass *sub_mesh)
virtual void Shutdown()=0
WWINLINE uint32 Get_Class_ID(void) const
Definition shddef.h:97
virtual void Init()=0
static ShdDefClass * Create_ShdDefClass_Instance(uint32 class_id)
virtual int Get_Pass_Count(void)=0
WWINLINE int Get_Class_ID() const
const ShdDefClass * Peek_Definition(void)
returns a pointer to the definition for this shader
static void Shutdown()
static void Init()
virtual ~ShdRendererClass()
static void Init_Shaders()
static void Shutdown_Shaders()
void Set_Renderer_List_Container(RendererListContainerClass *cont, int pass)
virtual void Apply_Shared_Shader_Settings(ShdRendererNodeClass *prev_node, int pass)=0
virtual void Flush(int pass)=0
ShdInterfaceClass * Peek_Shader(void) const
Definition shdsubmesh.h:79
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)
const unsigned dynamic_fvf_type
@ BUFFER_TYPE_DYNAMIC_DX8
Definition dx8wrapper.h:90
@ BUFFER_TYPE_DYNAMIC_SORTING
Definition dx8wrapper.h:91
const unsigned MAX_TEXTURE_STAGES
Definition dx8wrapper.h:76
Vector3i16 TriIndex
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define REF_PTR_SET(dst, src)
Definition refcount.h:79
@ SHDDEF_CLASSID_DUMMY
Definition shdclassids.h:48
@ SHDDEF_CLASSID_LAST
Definition shdclassids.h:55
const int SHD_MAX_PASSES
bool enable_rnd
MultiListIterator< ShdRendererNodeClass > ShdRendererNodeListIterator
Definition shdrenderer.h:55
MultiListClass< RendererListContainerClass > RendererListContainerList
Definition shdrenderer.h:56
MultiListIterator< RendererListContainerClass > RendererListContainerIterator
Definition shdrenderer.h:57
const Vector3 * Normals
const Vector2 * UV[MAX_TEXTURE_STAGES]
const Vector3 * S
const Vector3 * SxT
const Vector3 * T
const unsigned * DiffuseInt
const Vector3 * Locations
#define SNAPSHOT_SAY(x)
Definition ww3d.h:68
#define WWPROFILE(name)
Definition wwprofile.h:270