From c5b542d38c75a1c2d3d458b0b2dd3f92a3407d54 Mon Sep 17 00:00:00 2001
From: stm <14291421+stephanmeesters@users.noreply.github.com>
Date: Thu, 14 May 2026 12:41:17 +0200
Subject: [PATCH] unify(ww3d2): Move dx8fvf, dx8indexbuffer, dx8vertexbuffer to
Core
---
.../Source/WWVegas/WW3D2/CMakeLists.txt | 16 +-
.../Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp | 0
.../Libraries/Source/WWVegas/WW3D2/dx8fvf.h | 0
.../Source/WWVegas/WW3D2/dx8indexbuffer.cpp | 0
.../Source/WWVegas/WW3D2/dx8indexbuffer.h | 0
.../Source/WWVegas/WW3D2/dx8renderer.cpp | 0
.../Source/WWVegas/WW3D2/dx8renderer.h | 0
.../Source/WWVegas/WW3D2/dx8vertexbuffer.cpp | 0
.../Source/WWVegas/WW3D2/dx8vertexbuffer.h | 0
.../Source/WWVegas/WW3D2/CMakeLists.txt | 16 +-
.../Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp | 103 -
.../Libraries/Source/WWVegas/WW3D2/dx8fvf.h | 281 --
.../Source/WWVegas/WW3D2/dx8indexbuffer.cpp | 541 ----
.../Source/WWVegas/WW3D2/dx8indexbuffer.h | 197 --
.../Source/WWVegas/WW3D2/dx8renderer.cpp | 2287 -----------------
.../Source/WWVegas/WW3D2/dx8renderer.h | 351 ---
.../Source/WWVegas/WW3D2/dx8vertexbuffer.cpp | 904 -------
.../Source/WWVegas/WW3D2/dx8vertexbuffer.h | 253 --
.../Source/WWVegas/WW3D2/CMakeLists.txt | 16 +-
scripts/cpp/unify_move_files.py | 9 +
20 files changed, 33 insertions(+), 4941 deletions(-)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8fvf.h (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8renderer.h (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp (100%)
rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h (100%)
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.h
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.h
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
diff --git a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index 9ff4754aec9..69f7f239492 100644
--- a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -45,21 +45,21 @@ set(WW3D2_SRC
dllist.h
dx8caps.cpp
dx8caps.h
- #dx8fvf.cpp
- #dx8fvf.h
- #dx8indexbuffer.cpp
- #dx8indexbuffer.h
+ dx8fvf.cpp
+ dx8fvf.h
+ dx8indexbuffer.cpp
+ dx8indexbuffer.h
dx8list.h
dx8polygonrenderer.cpp
dx8polygonrenderer.h
- #dx8renderer.cpp
- #dx8renderer.h
+ dx8renderer.cpp
+ dx8renderer.h
dx8rendererdebugger.cpp
dx8rendererdebugger.h
dx8texman.cpp
dx8texman.h
- #dx8vertexbuffer.cpp
- #dx8vertexbuffer.h
+ dx8vertexbuffer.cpp
+ dx8vertexbuffer.h
dx8webbrowser.cpp
dx8webbrowser.h
dx8wrapper.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8fvf.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.h
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8fvf.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8renderer.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8renderer.h
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8renderer.h
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
similarity index 100%
rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
rename to Core/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index d1fb7a8dbf1..a63287dcd88 100644
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -45,19 +45,19 @@ set(WW3D2_SRC
#dllist.h
# dx8caps.cpp
# dx8caps.h
- dx8fvf.cpp
- dx8fvf.h
- dx8indexbuffer.cpp
- dx8indexbuffer.h
+# dx8fvf.cpp
+# dx8fvf.h
+# dx8indexbuffer.cpp
+# dx8indexbuffer.h
#dx8list.h
#dx8polygonrenderer.cpp
#dx8polygonrenderer.h
- dx8renderer.cpp
- dx8renderer.h
+# dx8renderer.cpp
+# dx8renderer.h
#dx8texman.cpp
#dx8texman.h
- dx8vertexbuffer.cpp
- dx8vertexbuffer.h
+# dx8vertexbuffer.cpp
+# dx8vertexbuffer.h
#dx8webbrowser.cpp
#dx8webbrowser.h
# dx8wrapper.cpp
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
deleted file mode 100644
index b24c295d3d5..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-** Command & Conquer Generals(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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8fvf.h $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 5:06p $*
- * *
- * $Revision:: 7 $*
- * *
- * 06/26/02 KM VB Vertex format update for shaders *
- * 07/17/02 KM VB Vertex format update for displacement mapping *
- * 08/01/02 KM VB Vertex format update for cube mapping *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#include "dx8fvf.h"
-#include "wwstring.h"
-#include
-
-static unsigned Get_FVF_Vertex_Size(unsigned FVF)
-{
- return D3DXGetFVFVertexSize(FVF);
-}
-
-FVFInfoClass::FVFInfoClass(unsigned FVF_)
- :
- FVF(FVF_),
- fvf_size(Get_FVF_Vertex_Size(FVF))
-{
- location_offset=0;
- blend_offset=location_offset;
-
- if ((FVF&D3DFVF_XYZ)==D3DFVF_XYZ) blend_offset+=3*sizeof(float);
- normal_offset=blend_offset;
-
- if ( ((FVF&D3DFVF_XYZB4)==D3DFVF_XYZB4) &&
- ((FVF&D3DFVF_LASTBETA_UBYTE4)==D3DFVF_LASTBETA_UBYTE4) ) normal_offset+=3*sizeof(float)+sizeof(DWORD);
- diffuse_offset=normal_offset;
-
- if ((FVF&D3DFVF_NORMAL)==D3DFVF_NORMAL) diffuse_offset+=3*sizeof(float);
- specular_offset=diffuse_offset;
-
- if ((FVF&D3DFVF_DIFFUSE)==D3DFVF_DIFFUSE) specular_offset+=sizeof(DWORD);
- texcoord_offset[0]=specular_offset;
-
- if ((FVF&D3DFVF_SPECULAR)==D3DFVF_SPECULAR) texcoord_offset[0]+=sizeof(DWORD);
-
- for (unsigned int i=1; i.
-*/
-
-/***********************************************************************************************
- *** 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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8fvf.h $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 5:06p $*
- * *
- * $Revision:: 7 $*
- * *
- * 06/26/02 KM VB Vertex format update for shaders *
- * 07/17/02 KM VB Vertex format update for displacement mapping *
- * 08/01/02 KM VB Vertex format update for cube mapping *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include
-#ifdef WWDEBUG
-#include "wwdebug.h"
-#endif
-
-class StringClass;
-
-enum {
- DX8_FVF_XYZ = D3DFVF_XYZ,
- DX8_FVF_XYZN = D3DFVF_XYZ|D3DFVF_NORMAL,
- DX8_FVF_XYZNUV1 = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1,
- DX8_FVF_XYZNUV2 = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2,
- DX8_FVF_XYZNDUV1 = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1|D3DFVF_DIFFUSE,
- DX8_FVF_XYZNDUV2 = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2|D3DFVF_DIFFUSE,
- DX8_FVF_XYZDUV1 = D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_DIFFUSE,
- DX8_FVF_XYZDUV2 = D3DFVF_XYZ|D3DFVF_TEX2|D3DFVF_DIFFUSE,
- DX8_FVF_XYZUV1 = D3DFVF_XYZ|D3DFVF_TEX1,
- DX8_FVF_XYZUV2 = D3DFVF_XYZ|D3DFVF_TEX2,
- DX8_FVF_XYZNDUV1TG3 = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX4|D3DFVF_TEXCOORDSIZE2(0)|D3DFVF_TEXCOORDSIZE3(1)|D3DFVF_TEXCOORDSIZE3(2)|D3DFVF_TEXCOORDSIZE3(3)),
- DX8_FVF_XYZNUV2DMAP = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE4(1) | D3DFVF_TEXCOORDSIZE2(2) ),
- DX8_FVF_XYZNDCUBEMAP = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE //|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE3(0)
-};
-
-// ----------------------------------------------------------------------------
-//
-// Util structures for vertex buffer handling. Cast the void pointer returned
-// by the vertex buffer to one of these structures.
-//
-// ----------------------------------------------------------------------------
-
-struct VertexFormatXYZ
-{
- float x;
- float y;
- float z;
-};
-
-struct VertexFormatXYZNUV1
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- float u1;
- float v1;
-};
-
-struct VertexFormatXYZNUV2
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- float u1;
- float v1;
- float u2;
- float v2;
-};
-
-struct VertexFormatXYZN
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
-};
-
-struct VertexFormatXYZNDUV1
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- unsigned diffuse;
- float u1;
- float v1;
-};
-
-struct VertexFormatXYZNDUV2
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- unsigned diffuse;
- float u1;
- float v1;
- float u2;
- float v2;
-};
-
-struct VertexFormatXYZDUV1
-{
- float x;
- float y;
- float z;
- unsigned diffuse;
- float u1;
- float v1;
-};
-
-struct VertexFormatXYZDUV2
-{
- float x;
- float y;
- float z;
- unsigned diffuse;
- float u1;
- float v1;
- float u2;
- float v2;
-};
-
-struct VertexFormatXYZUV1
-{
- float x;
- float y;
- float z;
- float u1;
- float v1;
-};
-
-struct VertexFormatXYZUV2
-{
- float x;
- float y;
- float z;
- float u1;
- float v1;
- float u2;
- float v2;
-};
-
-// todo KJM compress
-struct VertexFormatXYZNDUV1TG3
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- unsigned diffuse;
- float u1;
- float v1;
- float Sx;
- float Sy;
- float Sz;
- float Tx;
- float Ty;
- float Tz;
- float SxTx;
- float SxTy;
- float SxTz;
-};
-
-
-// displacement mapping format
-struct VertexFormatXYZNUV2DMAP
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- float T1x;
- float T1y;
- float T1z;
- float T1w;
- float T2x;
- float T2y;
-};
-
-// cube map format (texcoords are normally generated)
-struct VertexFormatXYZNDCUBEMAP
-{
- float x;
- float y;
- float z;
- float nx;
- float ny;
- float nz;
- unsigned diffuse;
-// float u1;
-// float v1;
-// float w1;
-};
-
-// FVF info class can be created for any legal FVF. It constructs information
-// of offsets to various elements in the vertex buffer.
-
-class FVFInfoClass
-{
- W3DMPO_CODE(FVFInfoClass)
-
- mutable unsigned FVF;
- mutable unsigned fvf_size;
-
- unsigned location_offset;
- unsigned normal_offset;
- unsigned blend_offset;
- unsigned texcoord_offset[D3DDP_MAXTEXCOORD];
- unsigned diffuse_offset;
- unsigned specular_offset;
-public:
- FVFInfoClass(unsigned FVF);
-
- unsigned Get_Location_Offset() const { return location_offset; }
- unsigned Get_Normal_Offset() const { return normal_offset; }
-#ifdef WWDEBUG
- inline unsigned Get_Tex_Offset(unsigned int n) const { WWASSERT(n.
-*/
-
-/***********************************************************************************************
- *** 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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8indexbuffer.cpp $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 11/09/01 3:12p $*
- * *
- * $Revision:: 26 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//#define INDEX_BUFFER_LOG
-
-#include "dx8indexbuffer.h"
-#include "dx8wrapper.h"
-#include "dx8caps.h"
-#include "sphere.h"
-#include "thread.h"
-#include "wwmemlog.h"
-
-#define DEFAULT_IB_SIZE 5000
-
-static bool _DynamicSortingIndexArrayInUse=false;
-static SortingIndexBufferClass* _DynamicSortingIndexArray;
-static unsigned short _DynamicSortingIndexArraySize=0;
-static unsigned short _DynamicSortingIndexArrayOffset=0;
-
-static bool _DynamicDX8IndexBufferInUse=false;
-static DX8IndexBufferClass* _DynamicDX8IndexBuffer=nullptr;
-static unsigned short _DynamicDX8IndexBufferSize=DEFAULT_IB_SIZE;
-static unsigned short _DynamicDX8IndexBufferOffset=0;
-
-static int _IndexBufferCount;
-static int _IndexBufferTotalIndices;
-static int _IndexBufferTotalSize;
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-IndexBufferClass::IndexBufferClass(unsigned type_, unsigned short index_count_)
- :
- index_count(index_count_),
- type(type_),
- engine_refs(0)
-{
- WWASSERT(type==BUFFER_TYPE_DX8 || type==BUFFER_TYPE_SORTING);
- WWASSERT(index_count);
-
- _IndexBufferCount++;
- _IndexBufferTotalIndices+=index_count;
- _IndexBufferTotalSize+=index_count*sizeof(unsigned short);
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("New IB, %d indices, size %d bytes",index_count,index_count*sizeof(unsigned short)));
- WWDEBUG_SAY(("Total IB count: %d, total %d indices, total size %d bytes",
- _IndexBufferCount,
- _IndexBufferTotalIndices,
- _IndexBufferTotalSize));
-#endif
-}
-
-IndexBufferClass::~IndexBufferClass()
-{
- _IndexBufferCount--;
- _IndexBufferTotalIndices-=index_count;
- _IndexBufferTotalSize-=index_count*sizeof(unsigned short);
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("Delete IB, %d indices, size %d bytes",index_count,index_count*sizeof(unsigned short)));
- WWDEBUG_SAY(("Total IB count: %d, total %d indices, total size %d bytes",
- _IndexBufferCount,
- _IndexBufferTotalIndices,
- _IndexBufferTotalSize));
-#endif
-}
-
-unsigned IndexBufferClass::Get_Total_Buffer_Count()
-{
- return _IndexBufferCount;
-}
-
-unsigned IndexBufferClass::Get_Total_Allocated_Indices()
-{
- return _IndexBufferTotalIndices;
-}
-
-unsigned IndexBufferClass::Get_Total_Allocated_Memory()
-{
- return _IndexBufferTotalSize;
-}
-
-void IndexBufferClass::Add_Engine_Ref() const
-{
- engine_refs++;
-}
-
-void IndexBufferClass::Release_Engine_Ref() const
-{
- engine_refs--;
- WWASSERT(engine_refs>=0);
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void IndexBufferClass::Copy(unsigned int* indices,unsigned first_index,unsigned count)
-{
- WWASSERT(indices);
-
- if (first_index) {
- DX8IndexBufferClass::AppendLockClass l(this,first_index,count);
- unsigned short* inds=l.Get_Index_Array();
- for (unsigned v=0;vEngine_Refs());
- index_buffer->Add_Ref();
- switch (index_buffer->Type()) {
- case BUFFER_TYPE_DX8:
- DX8_Assert();
- DX8_ErrorCode(static_cast(index_buffer)->Get_DX8_Index_Buffer()->Lock(
- 0,
- index_buffer->Get_Index_Count()*sizeof(WORD),
- (unsigned char**)&indices,
- flags));
- break;
- case BUFFER_TYPE_SORTING:
- indices=static_cast(index_buffer)->index_buffer;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-// ----------------------------------------------------------------------------
-
-IndexBufferClass::WriteLockClass::~WriteLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (index_buffer->Type()) {
- case BUFFER_TYPE_DX8:
- DX8_Assert();
- DX8_ErrorCode(static_cast(index_buffer)->index_buffer->Unlock());
- break;
- case BUFFER_TYPE_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
- index_buffer->Release_Ref();
-}
-
-// ----------------------------------------------------------------------------
-
-IndexBufferClass::AppendLockClass::AppendLockClass(IndexBufferClass* index_buffer_,unsigned start_index, unsigned index_range)
- :
- index_buffer(index_buffer_)
-{
- DX8_THREAD_ASSERT();
- WWASSERT(start_index+index_range<=index_buffer->Get_Index_Count());
- WWASSERT(index_buffer);
- WWASSERT(!index_buffer->Engine_Refs());
- index_buffer->Add_Ref();
- switch (index_buffer->Type()) {
- case BUFFER_TYPE_DX8:
- DX8_Assert();
- DX8_ErrorCode(static_cast(index_buffer)->index_buffer->Lock(
- start_index*sizeof(unsigned short),
- index_range*sizeof(unsigned short),
- (unsigned char**)&indices,
- 0));
- break;
- case BUFFER_TYPE_SORTING:
- indices=static_cast(index_buffer)->index_buffer+start_index;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-IndexBufferClass::AppendLockClass::~AppendLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (index_buffer->Type()) {
- case BUFFER_TYPE_DX8:
- DX8_Assert();
- DX8_ErrorCode(static_cast(index_buffer)->index_buffer->Unlock());
- break;
- case BUFFER_TYPE_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
- index_buffer->Release_Ref();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-DX8IndexBufferClass::DX8IndexBufferClass(unsigned short index_count_,UsageType usage)
- :
- IndexBufferClass(BUFFER_TYPE_DX8,index_count_)
-{
- DX8_THREAD_ASSERT();
- WWASSERT(index_count);
- unsigned usage_flags=
- D3DUSAGE_WRITEONLY|
- ((usage&USAGE_DYNAMIC) ? D3DUSAGE_DYNAMIC : 0)|
- ((usage&USAGE_NPATCHES) ? D3DUSAGE_NPATCHES : 0)|
- ((usage&USAGE_SOFTWAREPROCESSING) ? D3DUSAGE_SOFTWAREPROCESSING : 0);
- if (!DX8Wrapper::Get_Current_Caps()->Support_TnL()) {
- usage_flags|=D3DUSAGE_SOFTWAREPROCESSING;
- }
-
- HRESULT ret=DX8Wrapper::_Get_D3D_Device8()->CreateIndexBuffer(
- sizeof(WORD)*index_count,
- usage_flags,
- D3DFMT_INDEX16,
- (usage&USAGE_DYNAMIC) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED,
- &index_buffer);
-
- if (SUCCEEDED(ret)) {
- return;
- }
-
- WWDEBUG_SAY(("Index buffer creation failed, trying to release assets..."));
-
- // Index buffer creation failed, so try releasing least used textures and flushing the mesh cache.
-
- // Free all textures that haven't been used in the last 5 seconds
- TextureClass::Invalidate_Old_Unused_Textures(5000);
-
- // Invalidate the mesh cache
- WW3D::_Invalidate_Mesh_Cache();
-
- // Try again...
- ret=DX8Wrapper::_Get_D3D_Device8()->CreateIndexBuffer(
- sizeof(WORD)*index_count,
- usage_flags,
- D3DFMT_INDEX16,
- (usage&USAGE_DYNAMIC) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED,
- &index_buffer);
-
- if (SUCCEEDED(ret)) {
- WWDEBUG_SAY(("...Index buffer creation successful"));
- }
-
- // If it still fails it is fatal
- DX8_ErrorCode(ret);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8IndexBufferClass::~DX8IndexBufferClass()
-{
- index_buffer->Release();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-SortingIndexBufferClass::SortingIndexBufferClass(unsigned short index_count_)
- :
- IndexBufferClass(BUFFER_TYPE_SORTING,index_count_)
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(index_count);
-
- index_buffer=W3DNEWARRAY unsigned short[index_count];
-}
-
-// ----------------------------------------------------------------------------
-
-SortingIndexBufferClass::~SortingIndexBufferClass()
-{
- delete[] index_buffer;
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-DynamicIBAccessClass::DynamicIBAccessClass(unsigned short type_, unsigned short index_count_)
- :
- IndexCount(index_count_),
- IndexBuffer(nullptr),
- Type(type_)
-{
- WWASSERT(Type==BUFFER_TYPE_DYNAMIC_DX8 || Type==BUFFER_TYPE_DYNAMIC_SORTING);
- if (Type==BUFFER_TYPE_DYNAMIC_DX8) {
- Allocate_DX8_Dynamic_Buffer();
- }
- else {
- Allocate_Sorting_Dynamic_Buffer();
- }
-}
-
-DynamicIBAccessClass::~DynamicIBAccessClass()
-{
- REF_PTR_RELEASE(IndexBuffer);
- if (Type==BUFFER_TYPE_DYNAMIC_DX8) {
- _DynamicDX8IndexBufferInUse=false;
- _DynamicDX8IndexBufferOffset+=IndexCount;
- }
- else {
- _DynamicSortingIndexArrayInUse=false;
- _DynamicSortingIndexArrayOffset+=IndexCount;
- }
-}
-
-void DynamicIBAccessClass::_Deinit()
-{
- WWASSERT ((_DynamicDX8IndexBuffer == nullptr) || (_DynamicDX8IndexBuffer->Num_Refs() == 1));
- REF_PTR_RELEASE(_DynamicDX8IndexBuffer);
- _DynamicDX8IndexBufferInUse=false;
- _DynamicDX8IndexBufferSize=DEFAULT_IB_SIZE;
- _DynamicDX8IndexBufferOffset=0;
-
- WWASSERT ((_DynamicSortingIndexArray == nullptr) || (_DynamicSortingIndexArray->Num_Refs() == 1));
- REF_PTR_RELEASE(_DynamicSortingIndexArray);
- _DynamicSortingIndexArrayInUse=false;
- _DynamicSortingIndexArraySize=0;
- _DynamicSortingIndexArrayOffset=0;
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-DynamicIBAccessClass::WriteLockClass::WriteLockClass(DynamicIBAccessClass* ib_access_)
- :
- DynamicIBAccess(ib_access_)
-{
- DX8_THREAD_ASSERT();
- DynamicIBAccess->IndexBuffer->Add_Ref();
- switch (DynamicIBAccess->Get_Type()) {
- case BUFFER_TYPE_DYNAMIC_DX8:
- WWASSERT(DynamicIBAccess);
-// WWASSERT(!dynamic_dx8_index_buffer->Engine_Refs());
- DX8_Assert();
- DX8_ErrorCode(
- static_cast(DynamicIBAccess->IndexBuffer)->Get_DX8_Index_Buffer()->Lock(
- DynamicIBAccess->IndexBufferOffset*sizeof(WORD),
- DynamicIBAccess->Get_Index_Count()*sizeof(WORD),
- (unsigned char**)&Indices,
- !DynamicIBAccess->IndexBufferOffset ? D3DLOCK_DISCARD : D3DLOCK_NOOVERWRITE));
- break;
- case BUFFER_TYPE_DYNAMIC_SORTING:
- Indices=static_cast(DynamicIBAccess->IndexBuffer)->index_buffer;
- Indices+=DynamicIBAccess->IndexBufferOffset;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-DynamicIBAccessClass::WriteLockClass::~WriteLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (DynamicIBAccess->Get_Type()) {
- case BUFFER_TYPE_DYNAMIC_DX8:
- DX8_Assert();
- DX8_ErrorCode(static_cast(DynamicIBAccess->IndexBuffer)->Get_DX8_Index_Buffer()->Unlock());
- break;
- case BUFFER_TYPE_DYNAMIC_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
- DynamicIBAccess->IndexBuffer->Release_Ref();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void DynamicIBAccessClass::Allocate_DX8_Dynamic_Buffer()
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(!_DynamicDX8IndexBufferInUse);
- _DynamicDX8IndexBufferInUse=true;
-
- // If requesting more indices than dynamic index buffer can fit, delete the ib
- // and adjust the size to the new count.
- if (IndexCount>_DynamicDX8IndexBufferSize) {
- REF_PTR_RELEASE(_DynamicDX8IndexBuffer);
- _DynamicDX8IndexBufferSize=IndexCount;
- if (_DynamicDX8IndexBufferSizeSupport_NPatches()) {
- usage|=DX8IndexBufferClass::USAGE_NPATCHES;
- }
-
- _DynamicDX8IndexBuffer=NEW_REF(DX8IndexBufferClass,(
- _DynamicDX8IndexBufferSize,
- (DX8IndexBufferClass::UsageType)usage));
- _DynamicDX8IndexBufferOffset=0;
- }
-
- // Any room at the end of the buffer?
- if (((unsigned)IndexCount+_DynamicDX8IndexBufferOffset)>_DynamicDX8IndexBufferSize) {
- _DynamicDX8IndexBufferOffset=0;
- }
-
- REF_PTR_SET(IndexBuffer,_DynamicDX8IndexBuffer);
- IndexBufferOffset=_DynamicDX8IndexBufferOffset;
-}
-
-void DynamicIBAccessClass::Allocate_Sorting_Dynamic_Buffer()
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(!_DynamicSortingIndexArrayInUse);
- _DynamicSortingIndexArrayInUse=true;
-
- unsigned new_index_count=_DynamicSortingIndexArrayOffset+IndexCount;
- WWASSERT(new_index_count<65536);
- if (new_index_count>_DynamicSortingIndexArraySize) {
- REF_PTR_RELEASE(_DynamicSortingIndexArray);
- _DynamicSortingIndexArraySize=new_index_count;
- if (_DynamicSortingIndexArraySize.
-*/
-
-/***********************************************************************************************
- *** 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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8indexbuffer.h $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Jani_p $*
- * *
- * $Modtime:: 7/10/01 12:27p $*
- * *
- * $Revision:: 12 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "wwdebug.h"
-#include "sphere.h"
-
-class DX8Wrapper;
-class SortingRendererClass;
-struct IDirect3DIndexBuffer8;
-class DX8IndexBufferClass;
-class SortingIndexBufferClass;
-
-// ----------------------------------------------------------------------------
-
-class IndexBufferClass : public RefCountClass
-{
-protected:
- virtual ~IndexBufferClass() override;
-public:
- IndexBufferClass(unsigned type, unsigned short index_count);
-
- void Copy(unsigned int* indices,unsigned start_index,unsigned index_count);
- void Copy(unsigned short* indices,unsigned start_index,unsigned index_count);
-
- unsigned short Get_Index_Count() const { return index_count; }
-
- unsigned Type() const { return type; }
-
- void Add_Engine_Ref() const;
- void Release_Engine_Ref() const;
- unsigned Engine_Refs() const { return engine_refs; }
-
- class WriteLockClass
- {
- IndexBufferClass* index_buffer;
- unsigned short* indices;
- public:
- WriteLockClass(IndexBufferClass* index_buffer, int flags=0);
- ~WriteLockClass();
-
- unsigned short* Get_Index_Array() { return indices; }
- };
-
- class AppendLockClass
- {
- IndexBufferClass* index_buffer;
- unsigned short* indices;
- public:
- AppendLockClass(IndexBufferClass* index_buffer,unsigned start_index, unsigned index_range);
- ~AppendLockClass();
-
- unsigned short* Get_Index_Array() { return indices; }
- };
-
- static unsigned Get_Total_Buffer_Count();
- static unsigned Get_Total_Allocated_Indices();
- static unsigned Get_Total_Allocated_Memory();
-
-protected:
- mutable int engine_refs;
- unsigned short index_count; // number of indices
- unsigned type;
-};
-
-
-// HY 2/14/01
-// Created
-class DynamicIBAccessClass
-{
- W3DMPO_CODE(DynamicIBAccessClass)
-
- friend DX8Wrapper;
- friend SortingRendererClass;
-
- unsigned Type;
- unsigned short IndexCount;
- unsigned short IndexBufferOffset;
- IndexBufferClass* IndexBuffer;
-
- void Allocate_Sorting_Dynamic_Buffer();
- void Allocate_DX8_Dynamic_Buffer();
-
-public:
- DynamicIBAccessClass(unsigned short type, unsigned short index_count);
- ~DynamicIBAccessClass();
-
- unsigned Get_Type() const { return Type; }
- unsigned short Get_Index_Count() const { return IndexCount; }
-
- // Call at the end of the execution, or at whatever time you wish to release
- // the recycled dynamic index buffer.
- static void _Deinit();
- static void _Reset(bool frame_changed);
- static unsigned short Get_Default_Index_Count(); ///.
-*/
-
-/***********************************************************************************************
- *** 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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8renderer.cpp $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 06/27/02 1:27p $*
- * *
- * $Revision:: 111 $*
- * *
- * 06/27/02 KM Changes to max texture stage caps *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//#define ENABLE_CATEGORY_LOG
-//#define ENABLE_STRIPING
-
-#include "dx8renderer.h"
-#include "dx8wrapper.h"
-#include "dx8polygonrenderer.h"
-#include "dx8vertexbuffer.h"
-#include "dx8indexbuffer.h"
-#include "dx8fvf.h"
-#include "dx8caps.h"
-#include "dx8rendererdebugger.h"
-#include "wwdebug.h"
-#include "wwprofile.h"
-#include "wwmemlog.h"
-#include "rinfo.h"
-#include "statistics.h"
-#include "meshmdl.h"
-#include "vp.h"
-#include "decalmsh.h"
-#include "matpass.h"
-#include "camera.h"
-#include "stripoptimizer.h"
-#include "meshgeometry.h"
-
-/*
-** Global Instance of the DX8MeshRender
-*/
-DX8MeshRendererClass TheDX8MeshRenderer;
-bool DX8TextureCategoryClass::m_gForceMultiply = false; // Forces opaque materials to use the multiply blend - pseudo transparent effect. jba.
-// ----------------------------------------------------------------------------
-
-static DynamicVectorClass _TempVertexBuffer;
-static DynamicVectorClass _TempNormalBuffer;
-
-static MultiListClass _RegisteredMeshList;
-static TextureCategoryList texture_category_delete_list;
-static FVFCategoryList fvf_category_container_delete_list;
-
-// helper data structure
-class PolyRemover : public MultiListObjectClass
-{
-public:
- DX8TextureCategoryClass * src;
- DX8TextureCategoryClass * dest;
- DX8PolygonRendererClass * pr;
-};
-
-typedef MultiListClass PolyRemoverList;
-typedef MultiListIterator PolyRemoverListIterator;
-
-#define VERTEX_BUFFER_OVERFLOW 0xffff //'Generals' flag to signal when a mesh didn't fit in streaming vertex buffer.
-
-/**
-** PolyRenderTaskClass
-** This is a record of a polyrendere that needs to be rendered
-** for this frame. Since MeshClass instances can share meshmodels
-** (and therefore their dx8 polygon renderers) this record contains
-** a pointer to the polygon renderer and the MeshClass instance that
-** it is being rendered for.
-*/
-class PolyRenderTaskClass : public AutoPoolClass
-{
-public:
- PolyRenderTaskClass(DX8PolygonRendererClass * p_renderer,MeshClass * p_mesh) :
- Renderer(p_renderer),
- Mesh(p_mesh),
- NextVisible(nullptr)
- {
- WWASSERT(Renderer != nullptr);
- WWASSERT(Mesh != nullptr);
- Mesh->Add_Ref();
- }
-
- ~PolyRenderTaskClass()
- {
- Mesh->Release_Ref();
- }
-
- DX8PolygonRendererClass * Peek_Polygon_Renderer() { return Renderer; }
- MeshClass * Peek_Mesh() { return Mesh; }
-
- PolyRenderTaskClass * Get_Next_Visible() { return NextVisible; }
- void Set_Next_Visible(PolyRenderTaskClass * prtc) { NextVisible = prtc; }
-
-protected:
-
- DX8PolygonRendererClass * Renderer;
- MeshClass * Mesh;
- PolyRenderTaskClass * NextVisible;
-
-};
-
-DEFINE_AUTO_POOL(PolyRenderTaskClass, 256);
-
-/**
-** MatPassTaskClass
-** This is the record of a material pass that needs to be rendered on
-** a particular mesh. These are linked into the FVF container which
-** contains the mesh model. They are also pooled to remove memory
-** allocation overhead.
-*/
-class MatPassTaskClass : public AutoPoolClass
-{
-public:
- MatPassTaskClass(MaterialPassClass * pass,MeshClass * mesh) :
- MaterialPass(pass),
- Mesh(mesh),
- NextVisible(nullptr)
- {
- WWASSERT(MaterialPass != nullptr);
- WWASSERT(Mesh != nullptr);
- MaterialPass->Add_Ref();
- Mesh->Add_Ref();
- }
-
- ~MatPassTaskClass()
- {
- MaterialPass->Release_Ref();
- Mesh->Release_Ref();
- }
-
- MaterialPassClass * Peek_Material_Pass() { return MaterialPass; }
- MeshClass * Peek_Mesh() { return Mesh; }
-
- MatPassTaskClass * Get_Next_Visible() { return NextVisible; }
- void Set_Next_Visible(MatPassTaskClass * mpr) { NextVisible = mpr; }
-
-private:
-
- MaterialPassClass * MaterialPass;
- MeshClass * Mesh;
- MatPassTaskClass * NextVisible;
-};
-
-DEFINE_AUTO_POOL(MatPassTaskClass, 256);
-
-
-// ----------------------------------------------------------------------------
-
-
-inline static bool Equal_Material(const VertexMaterialClass* mat1,const VertexMaterialClass* mat2)
-{
- int crc0 = mat1 ? mat1->Get_CRC() : 0;
- int crc1 = mat2 ? mat2->Get_CRC() : 0;
- return (crc0 == crc1);
-}
-
-
-DX8TextureCategoryClass::DX8TextureCategoryClass(
- DX8FVFCategoryContainer* container_,
- TextureClass** texs,
- ShaderClass shd,
- VertexMaterialClass* mat,
- int pass_)
- :
- pass(pass_),
- shader(shd),
- render_task_head(nullptr),
- material(mat),
- container(container_)
-{
- WWASSERT(pass>=0);
- WWASSERT(passAdd_Ref();
-}
-
-DX8TextureCategoryClass::~DX8TextureCategoryClass()
-{
- // Unregistering the mesh where polygon renderers are connected to kills all polygon renderers
- while (DX8PolygonRendererClass* p_renderer=PolygonRendererList.Get_Head()) {
- TheDX8MeshRenderer.Unregister_Mesh_Type(p_renderer->Get_Mesh_Model_Class());
- }
- for (int a=0;aSet_Next_Visible(render_task_head);
- render_task_head = new_prt;
-
- container->Add_Visible_Texture_Category(this,pass);
-}
-
-void DX8TextureCategoryClass::Add_Polygon_Renderer(DX8PolygonRendererClass* p_renderer,DX8PolygonRendererClass* add_after_this)
-{
- WWASSERT(p_renderer!=nullptr);
- WWASSERT(!PolygonRendererList.Contains(p_renderer));
-
- if (add_after_this != nullptr) {
- bool res = PolygonRendererList.Add_After(p_renderer,add_after_this,false);
- WWASSERT(res);
- } else {
- PolygonRendererList.Add(p_renderer);
- }
-
- p_renderer->Set_Texture_Category(this);
-}
-
-void DX8TextureCategoryClass::Remove_Polygon_Renderer(DX8PolygonRendererClass* p_renderer)
-{
- PolygonRendererList.Remove(p_renderer);
- p_renderer->Set_Texture_Category(nullptr);
- if (PolygonRendererList.Peek_Head() == nullptr) {
- container->Remove_Texture_Category(this);
- texture_category_delete_list.Add_Tail(this);
- }
-}
-
-
-void DX8FVFCategoryContainer::Remove_Texture_Category(DX8TextureCategoryClass* tex_category)
-{
- unsigned pass=0;
- for (;passSet_Next_Visible(new_mpr);
- }
-
- visible_matpass_tail = new_mpr;
- AnythingToRender=true;
-}
-
-void DX8FVFCategoryContainer::Render_Procedural_Material_Passes()
-{
- // additional passes
- MatPassTaskClass * mpr = visible_matpass_head;
- MatPassTaskClass * last_mpr = nullptr;
- bool renderTasksRemaining=false;
-
- while (mpr != nullptr) {
- SNAPSHOT_SAY(("Render_Procedural_Material_Pass"));
-
- MeshClass * mesh = mpr->Peek_Mesh();
-
- if (mesh->Get_Base_Vertex_Offset() == VERTEX_BUFFER_OVERFLOW) //check if this mesh is valid
- { //skip this mesh so it gets rendered later after vertices are filled in.
- last_mpr = mpr;
- mpr = mpr->Get_Next_Visible();
- renderTasksRemaining = true;
- continue;
- }
-
- mpr->Peek_Mesh()->Render_Material_Pass(mpr->Peek_Material_Pass(),index_buffer);
- MatPassTaskClass * next_mpr = mpr->Get_Next_Visible();
-
- // remove from list, then delete
- if (last_mpr == nullptr) {
- visible_matpass_head = next_mpr;
- } else {
- last_mpr->Set_Next_Visible(next_mpr);
- }
-
- delete mpr;
- mpr = next_mpr;
- }
-
- visible_matpass_tail = renderTasksRemaining ? last_mpr : nullptr;
-}
-
-void DX8RigidFVFCategoryContainer::Add_Delayed_Visible_Material_Pass(MaterialPassClass * pass, MeshClass * mesh)
-{
- MatPassTaskClass * new_mpr = new MatPassTaskClass(pass,mesh);
-
- if (delayed_matpass_head == nullptr) {
- WWASSERT(delayed_matpass_tail == nullptr);
- delayed_matpass_head = new_mpr;
- } else {
- WWASSERT(delayed_matpass_tail != nullptr);
- delayed_matpass_tail->Set_Next_Visible(new_mpr);
- }
-
- delayed_matpass_tail = new_mpr;
- AnyDelayedPassesToRender=true;
-}
-
-void DX8RigidFVFCategoryContainer::Render_Delayed_Procedural_Material_Passes()
-{
- if (!Any_Delayed_Passes_To_Render()) return;
- AnyDelayedPassesToRender=false;
-
- DX8Wrapper::Set_Vertex_Buffer(vertex_buffer);
- DX8Wrapper::Set_Index_Buffer(index_buffer,0);
-
- SNAPSHOT_SAY(("DX8RigidFVFCategoryContainer::Render_Delayed_Procedural_Material_Passes()"));
-
- // additional passes
- MatPassTaskClass * mpr = delayed_matpass_head;
- while (mpr != nullptr) {
-
- mpr->Peek_Mesh()->Render_Material_Pass(mpr->Peek_Material_Pass(),index_buffer);
- MatPassTaskClass * next_mpr = mpr->Get_Next_Visible();
-
- delete mpr;
- mpr = next_mpr;
- }
-
- delayed_matpass_head = delayed_matpass_tail = nullptr;
-}
-
-
-void DX8TextureCategoryClass::Log(bool only_visible)
-{
-#ifdef ENABLE_CATEGORY_LOG
- StringClass work(255,true);
- work.Format(" DX8TextureCategoryClass");
-
- StringClass work2(255,true);
- for (int stage=0;stageGet_Name() : "-");
- work+=work2;
- }
- work2.Format("\n material: %x (%s)\n shader: %x", material, material ? material->Get_Name() : "-", shader);
- work+=work2;
- WWDEBUG_SAY((work));
-
- work.Format(" %8s %8s %6s %6s %6s %5s %s",
- "idx_cnt",
- "poly_cnt",
- "i_offs",
- "min_vi",
- "vi_rng",
- "ident",
- "name");
- WWDEBUG_SAY((work));
-
- DX8PolygonRendererListIterator it(&PolygonRendererList);
- while (!it.Is_Done()) {
-
- DX8PolygonRendererClass* p_renderer = it.Peek_Obj();
-
- PolyRenderTaskClass * prtc=render_task_head;
- while (prtc) {
- if (prtc->Peek_Polygon_Renderer()==p_renderer) break;
- prtc = prtc->Get_Next_Visible();
- }
-
- if (prtc != nullptr) {
- WWDEBUG_SAY(("+"));
- p_renderer->Log();
- } else {
- if (!only_visible) {
- WWDEBUG_SAY(("-"));
- p_renderer->Log();
- }
- }
- it.Next();
- }
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-DX8FVFCategoryContainer::DX8FVFCategoryContainer(unsigned FVF_,bool sorting_)
- :
- FVF(FVF_),
- sorting(sorting_),
- visible_matpass_head(nullptr),
- visible_matpass_tail(nullptr),
- index_buffer(nullptr),
- used_indices(0),
- passes(MAX_PASSES),
- uv_coordinate_channels(0),
- AnythingToRender(false),
- AnyDelayedPassesToRender(false)
-{
- if ((FVF&D3DFVF_TEX1)==D3DFVF_TEX1) uv_coordinate_channels=1;
- if ((FVF&D3DFVF_TEX2)==D3DFVF_TEX2) uv_coordinate_channels=2;
- if ((FVF&D3DFVF_TEX3)==D3DFVF_TEX3) uv_coordinate_channels=3;
- if ((FVF&D3DFVF_TEX4)==D3DFVF_TEX4) uv_coordinate_channels=4;
- if ((FVF&D3DFVF_TEX5)==D3DFVF_TEX5) uv_coordinate_channels=5;
- if ((FVF&D3DFVF_TEX6)==D3DFVF_TEX6) uv_coordinate_channels=6;
- if ((FVF&D3DFVF_TEX7)==D3DFVF_TEX7) uv_coordinate_channels=7;
- if ((FVF&D3DFVF_TEX8)==D3DFVF_TEX8) uv_coordinate_channels=8;
-}
-
-// ----------------------------------------------------------------------------
-
-DX8FVFCategoryContainer::~DX8FVFCategoryContainer()
-{
- REF_PTR_RELEASE(index_buffer);
-
- for (unsigned p=0;pPeek_Texture(stage)==texture) {
- // Compare all stage's textures
- dest_tex_category=dest_it.Peek_Obj();
- bool all_textures_same = true;
- for (unsigned int s = 0; s < MeshMatDescClass::MAX_TEX_STAGES; s++) {
- if (stage!=s) {
- all_textures_same = all_textures_same && (dest_tex_category->Peek_Texture(s) == ref_category->Peek_Texture(s));
- }
- }
- if (all_textures_same &&
- Equal_Material(dest_tex_category->Peek_Material(),ref_category->Peek_Material()) &&
- dest_tex_category->Get_Shader()==ref_category->Get_Shader()) {
- return dest_tex_category;
- }
- }
- dest_it.Next();
- }
- return nullptr;
-}
-
-DX8TextureCategoryClass* DX8FVFCategoryContainer::Find_Matching_Texture_Category(
- VertexMaterialClass* vmat,
- unsigned pass,
- DX8TextureCategoryClass* ref_category)
-{
- // Find texture category which matches ref_category's properties but has 'vmat' on given pass
- DX8TextureCategoryClass* dest_tex_category=nullptr;
- TextureCategoryListIterator dest_it(&texture_category_list[pass]);
- while (!dest_it.Is_Done()) {
- if (Equal_Material(dest_it.Peek_Obj()->Peek_Material(),vmat)) {
- // Compare all stage's textures
- dest_tex_category=dest_it.Peek_Obj();
- bool all_textures_same = true;
- for (unsigned int s = 0; s < MeshMatDescClass::MAX_TEX_STAGES; s++)
- all_textures_same = all_textures_same && (dest_tex_category->Peek_Texture(s) == ref_category->Peek_Texture(s));
- if (all_textures_same &&
- dest_tex_category->Get_Shader()==ref_category->Get_Shader()) {
- return dest_tex_category;
- }
- }
- dest_it.Next();
- }
- return nullptr;
-}
-
-void DX8FVFCategoryContainer::Change_Polygon_Renderer_Texture(
- DX8PolygonRendererList& polygon_renderer_list,
- TextureClass* texture,
- TextureClass* new_texture,
- unsigned pass,
- unsigned stage)
-{
- WWASSERT(passPeek_Texture(stage)==texture) {
- foundtexture=true;
- DX8PolygonRendererListIterator poly_it(&polygon_renderer_list);
- while (!poly_it.Is_Done()) {
- // If source texture category contains polygon renderer, move to destination category
- DX8PolygonRendererClass* polygon_renderer=poly_it.Peek_Obj();
- DX8TextureCategoryClass *prc=polygon_renderer->Get_Texture_Category();
-
- if (prc==src_tex_category) {
- DX8TextureCategoryClass* dest_tex_category=Find_Matching_Texture_Category(new_texture,pass,stage,src_tex_category);
-
- if (!dest_tex_category) {
- TextureClass * tmp_textures[MeshMatDescClass::MAX_TEX_STAGES];
- for (int s=0;sPeek_Texture(s);
- }
- tmp_textures[stage]=new_texture;
-
- DX8TextureCategoryClass * new_tex_category=W3DNEW DX8TextureCategoryClass(
- this,
- tmp_textures,
- src_tex_category->Get_Shader(),
- const_cast(src_tex_category->Peek_Material()),
- pass);
-
- /*
- ** Add the texture category object into the list, immediately after any existing
- ** texture category object which uses the same texture. This will result in
- ** the list always having matching texture categories next to each other.
- */
- bool found_similar_category = false;
- TextureCategoryListIterator tex_it(&texture_category_list[pass]);
- while (!tex_it.Is_Done()) {
- // Categorize according to first stage's texture for now
- if (tex_it.Peek_Obj()->Peek_Texture(0) == tmp_textures[0]) {
- texture_category_list[pass].Add_After(new_tex_category,tex_it.Peek_Obj());
- found_similar_category = true;
- break;
- }
- tex_it.Next();
- }
-
- if (!found_similar_category) {
- texture_category_list[pass].Add_Tail(new_tex_category);
- }
- dest_tex_category=new_tex_category;
- }
- PolyRemover *rem=W3DNEW PolyRemover;
- rem->src=src_tex_category;
- rem->dest=dest_tex_category;
- rem->pr=polygon_renderer;
- prl.Add(rem);
- }
- poly_it.Next();
- }
- }
- else
- // quit loop if we've got a texture change
- if (foundtexture) break;
- src_it.Next();
- }
-
- PolyRemoverListIterator prli(&prl);
-
- while (!prli.Is_Done())
- {
- PolyRemover *rem=prli.Peek_Obj();
- rem->src->Remove_Polygon_Renderer(rem->pr);
- rem->dest->Add_Polygon_Renderer(rem->pr);
- prli.Remove_Current_Object();
- delete rem;
- }
-}
-
-void DX8FVFCategoryContainer::Change_Polygon_Renderer_Material(
- DX8PolygonRendererList& polygon_renderer_list,
- VertexMaterialClass* vmat,
- VertexMaterialClass* new_vmat,
- unsigned pass)
-{
- WWASSERT(passPeek_Material()==vmat) {
- DX8PolygonRendererListIterator poly_it(&polygon_renderer_list);
- while (!poly_it.Is_Done()) {
- // If source texture category contains polygon renderer, move to destination category
- DX8PolygonRendererClass* polygon_renderer=poly_it.Peek_Obj();
- DX8TextureCategoryClass *prc=polygon_renderer->Get_Texture_Category();
- if (prc==src_tex_category) {
- foundtexture=true;
- DX8TextureCategoryClass* dest_tex_category=Find_Matching_Texture_Category(new_vmat,pass,src_tex_category);
-
- if (!dest_tex_category) {
- TextureClass * tmp_textures[MeshMatDescClass::MAX_TEX_STAGES];
- for (int s=0;sPeek_Texture(s);
- }
-
- DX8TextureCategoryClass * new_tex_category=W3DNEW DX8TextureCategoryClass(
- this,
- tmp_textures,
- src_tex_category->Get_Shader(),
- const_cast(new_vmat),
- pass);
-
- /*
- ** Add the texture category object into the list, immediately after any existing
- ** texture category object which uses the same texture. This will result in
- ** the list always having matching texture categories next to each other.
- */
- bool found_similar_category = false;
- TextureCategoryListIterator tex_it(&texture_category_list[pass]);
- while (!tex_it.Is_Done()) {
- // Categorize according to first stage's texture for now
- if (tex_it.Peek_Obj()->Peek_Texture(0) == tmp_textures[0]) {
- texture_category_list[pass].Add_After(new_tex_category,tex_it.Peek_Obj());
- found_similar_category = true;
- break;
- }
- tex_it.Next();
- }
-
- if (!found_similar_category) {
- texture_category_list[pass].Add_Tail(new_tex_category);
- }
- dest_tex_category=new_tex_category;
- }
- PolyRemover *rem=W3DNEW PolyRemover;
- rem->src=src_tex_category;
- rem->dest=dest_tex_category;
- rem->pr=polygon_renderer;
- prl.Add(rem);
- }
- poly_it.Next();
- }
- }
- else
- if (foundtexture) break;
- src_it.Next();
- }
-
- PolyRemoverListIterator prli(&prl);
-
- while (!prli.Is_Done())
- {
- PolyRemover *rem=prli.Peek_Obj();
- rem->src->Remove_Polygon_Renderer(rem->pr);
- rem->dest->Add_Polygon_Renderer(rem->pr);
- prli.Remove_Current_Object();
- delete rem;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned DX8FVFCategoryContainer::Define_FVF(MeshModelClass* mmc,bool enable_lighting)
-{
- if ((!!mmc->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) {
- return dynamic_fvf_type;
- }
-
- unsigned fvf=D3DFVF_XYZ;
-
- int tex_coord_count=mmc->Get_UV_Array_Count();
-
- if (mmc->Get_Color_Array(0,false)) {
- fvf|=D3DFVF_DIFFUSE;
- }
- if (mmc->Get_Color_Array(1,false)) {
- fvf|=D3DFVF_SPECULAR;
- }
-
- switch (tex_coord_count) {
- default:
- case 0:
- break;
- case 1: fvf|=D3DFVF_TEX1; break;
- case 2: fvf|=D3DFVF_TEX2; break;
- case 3: fvf|=D3DFVF_TEX3; break;
- case 4: fvf|=D3DFVF_TEX4; break;
- case 5: fvf|=D3DFVF_TEX5; break;
- case 6: fvf|=D3DFVF_TEX6; break;
- case 7: fvf|=D3DFVF_TEX7; break;
- case 8: fvf|=D3DFVF_TEX8; break;
- }
-
- if (!mmc->Needs_Vertex_Normals()) { //enable_lighting || mmc->Get_Flag(MeshModelClass::PRELIT_MASK)) {
- return fvf;
- }
-
- fvf|=D3DFVF_NORMAL; // Realtime-lit
- return fvf;
-}
-
-// ----------------------------------------------------------------------------
-
-DX8RigidFVFCategoryContainer::DX8RigidFVFCategoryContainer(unsigned FVF,bool sorting_)
- :
- DX8FVFCategoryContainer(FVF,sorting_),
- vertex_buffer(nullptr),
- used_vertices(0),
- delayed_matpass_head(nullptr),
- delayed_matpass_tail(nullptr)
-{
-}
-
-// ----------------------------------------------------------------------------
-
-DX8RigidFVFCategoryContainer::~DX8RigidFVFCategoryContainer()
-{
- REF_PTR_RELEASE(vertex_buffer);
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8RigidFVFCategoryContainer::Log(bool only_visible)
-{
-#ifdef ENABLE_CATEGORY_LOG
- StringClass work(255,true);
- work.Format("DX8RigidFVFCategoryContainer --------------");
- WWDEBUG_SAY((work));
- if (vertex_buffer) {
- StringClass fvfname(255,true);
- vertex_buffer->FVF_Info().Get_FVF_Name(fvfname);
- work.Format("VB size (used/total): %d/%d FVF: %s",used_vertices,vertex_buffer->Get_Vertex_Count(),fvfname);
- WWDEBUG_SAY((work));
- }
- else {
- WWDEBUG_SAY(("EMPTY VB"));
- }
- if (index_buffer) {
- work.Format("IB size (used/total): %d/%d",used_indices,index_buffer->Get_Index_Count());
- WWDEBUG_SAY((work));
- }
- else {
- WWDEBUG_SAY(("EMPTY IB"));
- }
-
- for (unsigned p=0;pLog(only_visible);
- it.Next();
- }
- }
-#endif
-}
-
-// ----------------------------------------------------------------------------
-//
-// Generic render function for rigid meshes
-//
-// ----------------------------------------------------------------------------
-
-void DX8RigidFVFCategoryContainer::Render()
-{
- if (!Anything_To_Render()) return;
- AnythingToRender=false;
-
- DX8Wrapper::Set_Vertex_Buffer(vertex_buffer);
- DX8Wrapper::Set_Index_Buffer(index_buffer,0);
-
- SNAPSHOT_SAY(("DX8RigidFVFCategoryContainer::Render()"));
- for (unsigned p=0;pRender();
- }
- }
-
- Render_Procedural_Material_Passes();
-}
-
-// ----------------------------------------------------------------------------
-
-bool DX8RigidFVFCategoryContainer::Check_If_Mesh_Fits(MeshModelClass* mmc)
-{
- if (!vertex_buffer) return true; // No VB created - mesh will fit as a new vb will be created when inserting
- unsigned required_vertices=mmc->Get_Vertex_Count();
- unsigned available_vertices=vertex_buffer->Get_Vertex_Count()-used_vertices;
- unsigned required_polygons=mmc->Get_Polygon_Count();
- if (mmc->Get_Gap_Filler()) {
- required_polygons+=mmc->Get_Gap_Filler()->Get_Polygon_Count();
- }
- unsigned required_indices=required_polygons*3*mmc->Get_Pass_Count();
- unsigned available_indices=index_buffer->Get_Index_Count()-used_indices;
- if (
- required_vertices<=available_vertices &&
- (required_indices)<=available_indices) {
- return true;
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------
-
-class Vertex_Split_Table
-{
- MeshModelClass* mmc;
- bool npatch_enable;
- unsigned polygon_count;
- TriIndex* polygon_array;
-
- bool allocated_polygon_array;
-
-public:
- Vertex_Split_Table(MeshModelClass* mmc_)
- :
- mmc(mmc_),
- npatch_enable(false),
- allocated_polygon_array(false)
- {
- if (DX8Wrapper::Get_Current_Caps()->Support_NPatches() && mmc->Needs_Vertex_Normals()) {
- if (mmc->Get_Flag(MeshGeometryClass::ALLOW_NPATCHES)) {
- npatch_enable=true;
- }
- }
-
- const GapFillerClass* gap_filler=mmc->Get_Gap_Filler();
- polygon_count=mmc->Get_Polygon_Count();
- if (gap_filler) polygon_count+=gap_filler->Get_Polygon_Count();
-// if (mmc->Get_Gap_Filler_Polygon_Count()) {
- allocated_polygon_array=true;
- polygon_array=W3DNEWARRAY TriIndex[polygon_count];
- memcpy(
- polygon_array,
- mmc->Get_Polygon_Array(),
- mmc->Get_Polygon_Count()*sizeof(TriIndex));
- if (gap_filler) {
- memcpy(
- polygon_array+mmc->Get_Polygon_Count(),
- gap_filler->Get_Polygon_Array(),
- gap_filler->Get_Polygon_Count()*sizeof(TriIndex));
- }
-// }
-// else {
-// polygon_array=const_cast(mmc->Get_Polygon_Array());
-// }
-
- }
-
- ~Vertex_Split_Table()
- {
- if (allocated_polygon_array) {
- delete[] polygon_array;
- }
- }
-
- const Vector3* Get_Vertex_Array() const
- {
- return mmc->Get_Vertex_Array();
- }
-
- const Vector3* Get_Vertex_Normal_Array() const
- {
- return mmc->Get_Vertex_Normal_Array();
- }
-
- const unsigned* Get_Color_Array(unsigned index) const
- {
- return mmc->Get_Color_Array(index,false);
- }
-
- const Vector2* Get_UV_Array(unsigned uv_array_index) const
- {
- return mmc->Get_UV_Array_By_Index(uv_array_index);
- }
-
- unsigned Get_Vertex_Count() const
- {
- return mmc->Get_Vertex_Count();
- }
-
- unsigned Get_Polygon_Count() const
- {
- return polygon_count;
- }
-
- unsigned Get_Pass_Count() const
- {
- return mmc->Get_Pass_Count();
- }
-
- TextureClass* Peek_Texture(unsigned idx,unsigned pass,unsigned stage)
- {
- if (mmc->Has_Texture_Array(pass,stage)) {
- if (idx>=unsigned(mmc->Get_Polygon_Count())) {
- WWASSERT(mmc->Get_Gap_Filler());
- return mmc->Get_Gap_Filler()->Get_Texture_Array(pass,stage)[idx-mmc->Get_Polygon_Count()];
- }
- return mmc->Peek_Texture(idx,pass,stage);
- }
- return mmc->Peek_Single_Texture(pass,stage);
- }
-
- VertexMaterialClass* Peek_Material(unsigned idx,unsigned pass)
- {
- if (mmc->Has_Material_Array(pass)) {
- if (idx>=unsigned(mmc->Get_Polygon_Count())) {
- WWASSERT(mmc->Get_Gap_Filler());
- return mmc->Get_Gap_Filler()->Get_Material_Array(pass)[idx-mmc->Get_Polygon_Count()];
- }
- return mmc->Peek_Material(mmc->Get_Polygon_Array()[idx][0],pass);
- }
- return mmc->Peek_Single_Material(pass);
- }
-
- ShaderClass Peek_Shader(unsigned idx,unsigned pass)
- {
- if (mmc->Has_Shader_Array(pass)) {
- ShaderClass shader;
-
- if (idx>=unsigned(mmc->Get_Polygon_Count())) {
- WWASSERT(mmc->Get_Gap_Filler());
- shader=mmc->Get_Gap_Filler()->Get_Shader_Array(pass)[idx-mmc->Get_Polygon_Count()];
- }
- else shader=mmc->Get_Shader(idx,pass);
-
- if (npatch_enable) {
- shader.Set_NPatch_Enable(ShaderClass::NPATCH_ENABLE);
- }
-
- return shader;
- }
- if (!npatch_enable) return mmc->Get_Single_Shader(pass);
- ShaderClass shader=mmc->Get_Single_Shader(pass);
- shader.Set_NPatch_Enable(ShaderClass::NPATCH_ENABLE);
- return shader;
-
- }
-
- MeshModelClass* Get_Mesh_Model_Class()
- {
- return mmc;
- }
-
- unsigned short* Get_Polygon_Array(unsigned pass)
- {
- return (unsigned short*)polygon_array;
- }
-};
-
-// ----------------------------------------------------------------------------
-
-void DX8RigidFVFCategoryContainer::Add_Mesh(MeshModelClass* mmc_)
-{
- WWASSERT(Check_If_Mesh_Fits(mmc_));
-
- Vertex_Split_Table split_table(mmc_);
- int needed_vertices=split_table.Get_Vertex_Count();
-
- /*
- ** This FVFCategoryContainer doesn't have a vertex buffer yet so allocate one big
- ** enough to contain this mesh.
- */
- if (!vertex_buffer) {
- int vb_size=4000;
- if (vb_sizeFVF_Info().Get_FVF()==FVF); // Only one sorting FVF type!
- }
- else {
- vertex_buffer=NEW_REF(DX8VertexBufferClass,(
- FVF,
- vb_size,
- (DX8Wrapper::Get_Current_Caps()->Support_NPatches() && WW3D::Get_NPatches_Level()>1) ? DX8VertexBufferClass::USAGE_NPATCHES : DX8VertexBufferClass::USAGE_DEFAULT));
- }
- }
-
- /*
- ** Append this mesh's vertices to the vertex buffer.
- */
-
- VertexBufferClass::AppendLockClass l(vertex_buffer,used_vertices,split_table.Get_Vertex_Count());
- const FVFInfoClass fi=vertex_buffer->FVF_Info();
- unsigned char *vb=(unsigned char*) l.Get_Vertex_Array();
- unsigned int i;
- const Vector3 *locs=split_table.Get_Vertex_Array();
- const Vector3 *norms=split_table.Get_Vertex_Normal_Array();
- const unsigned *diffuse=split_table.Get_Color_Array(0);
- const unsigned *specular=split_table.Get_Color_Array(1);
- for (i=0; iPeek_Texture(stage) == texs[stage]);
- }
- if (all_textures_same && Equal_Material(tex_category->Peek_Material(),mat) && tex_category->Get_Shader()==shader) {
- used_indices+=tex_category->Add_Mesh(split_table,vertex_offset,used_indices,index_buffer,pass);
- fit_in_existing_category = true;
- break;
- }
- it.Next();
- }
-
- if (!fit_in_existing_category) {
-
- DX8TextureCategoryClass * new_tex_category=W3DNEW DX8TextureCategoryClass(this,texs,shader,mat,pass);
- used_indices+=new_tex_category->Add_Mesh(split_table,vertex_offset,used_indices,index_buffer,pass);
-
- /*
- ** Add the texture category object into the list, immediately after any existing
- ** texture category object which uses the same texture. This will result in
- ** the list always having matching texture categories next to each other.
- */
- bool found_similar_category = false;
- TextureCategoryListIterator it(&texture_category_list[pass]);
- while (!it.Is_Done()) {
- // Categorize according to first stage's texture for now
- if (it.Peek_Obj()->Peek_Texture(0) == texs[0]) {
- texture_category_list[pass].Add_After(new_tex_category,it.Peek_Obj());
- found_similar_category = true;
- break;
- }
- it.Next();
- }
-
- if (!found_similar_category) {
- texture_category_list[pass].Add_Tail(new_tex_category);
- }
- }
-}
-
-const unsigned MAX_ADDED_TYPE_COUNT=64;
-struct Textures_Material_And_Shader_Booking_Struct
-{
- TextureClass* added_textures[MeshMatDescClass::MAX_TEX_STAGES][MAX_ADDED_TYPE_COUNT];
- VertexMaterialClass* added_materials[MAX_ADDED_TYPE_COUNT];
- ShaderClass added_shaders[MAX_ADDED_TYPE_COUNT];
- unsigned added_type_count;
-
- Textures_Material_And_Shader_Booking_Struct() : added_type_count(0) {}
-
- bool Add_Textures_Material_And_Shader(TextureClass** texs, VertexMaterialClass* mat, ShaderClass shd)
- {
- for (unsigned a=0;aSupport_NPatches() && WW3D::Get_NPatches_Level()>1) ? DX8IndexBufferClass::USAGE_NPATCHES : DX8IndexBufferClass::USAGE_DEFAULT));
- }
- }
-
- for (unsigned pass=0;passGet_Index_Count());
- WWDEBUG_SAY((work));
- }
- else {
- WWDEBUG_SAY(("EMPTY IB"));
- }
-
- for (unsigned pass=0;passLog(only_visible);
- it.Next();
- }
- }
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8SkinFVFCategoryContainer::Render()
-{
- SNAPSHOT_SAY(("DX8SkinFVFCategoryContainer::Render()"));
- if (!Anything_To_Render()) {
- SNAPSHOT_SAY(("Nothing to render"));
- return;
- }
- AnythingToRender=false;
-
- DX8Wrapper::Set_Vertex_Buffer(nullptr); // Free up the reference to the current vertex buffer
- // (in case it is the dynamic, which may have to be resized)
-
- //'Generals' customization to allow more than 65535 vertices
- unsigned int maxVertexCount=VisibleVertexCount;
- if (maxVertexCount > 65535)
- { //clamp vertex count to maximum size that can be indexed by 16-bit index
- maxVertexCount = 65535;
- }
-
- DynamicVBAccessClass vb(
- sorting ? BUFFER_TYPE_DYNAMIC_SORTING : BUFFER_TYPE_DYNAMIC_DX8,
- dynamic_fvf_type,
- maxVertexCount);
- SNAPSHOT_SAY(("DynamicVBAccess - %s - %d vertices",sorting ? "sorting" : "non-sorting",VisibleVertexCount));
-
- unsigned int renderedVertexCount=0;
-
- MeshClass * mesh = VisibleSkinHead;
- MeshClass * remainingMesh = VisibleSkinHead;
- while (renderedVertexCount < VisibleVertexCount)
- { mesh = remainingMesh;
- { DynamicVBAccessClass::WriteLockClass l(&vb);
- VertexFormatXYZNDUV2 * dest_verts = l.Get_Formatted_Vertex_Array();
- unsigned vertex_offset=0;
- remainingMesh = nullptr;
-
- while (mesh != nullptr) {
-
- MeshModelClass * mmc = mesh->Peek_Model();
- int mesh_vertex_count=mmc->Get_Vertex_Count();
- //'Generals' mod to deal with cases where not all meshes fit in VB.
- if (vertex_offset+mesh_vertex_count > maxVertexCount || remainingMesh)
- { //flag mesh so we know it didn't fit in the vertex buffer
- mesh->Set_Base_Vertex_Offset(VERTEX_BUFFER_OVERFLOW);
- if (remainingMesh == nullptr)
- remainingMesh = mesh; //start of meshes that didn't fit in buffer
- mesh = mesh->Peek_Next_Visible_Skin(); //skip rendering this mesh
- continue;
- }
-
-
- // If this assert hits, a skinned mesh has probably been added to the scene more than once.
- // Example: A skinned mesh was added to the scene then it was attached to a bone without being removed from the scene.
- WWASSERT((vertex_offset+mesh_vertex_count)<=VisibleVertexCount);
- DX8_RECORD_SKIN_RENDER(mesh->Get_Num_Polys(),mesh_vertex_count);
-
- if (_TempVertexBuffer.Length() < mesh_vertex_count) _TempVertexBuffer.Resize(mesh_vertex_count);
- if (_TempNormalBuffer.Length() < mesh_vertex_count) _TempNormalBuffer.Resize(mesh_vertex_count);
-
- Vector3* loc=&(_TempVertexBuffer[0]);
- Vector3* norm=&(_TempNormalBuffer[0]);
- const Vector2* uv0=mmc->Get_UV_Array_By_Index(0);
- const Vector2* uv1=mmc->Get_UV_Array_By_Index(1);
- const unsigned* diffuse=mmc->Get_Color_Array(0,false);
-
- VertexFormatXYZNDUV2* verts=dest_verts+vertex_offset;
-
- mesh->Get_Deformed_Vertices(loc,norm);
-
- for (int v=0;vSet_Base_Vertex_Offset(vertex_offset);
- vertex_offset+=mesh_vertex_count;
- renderedVertexCount += mesh_vertex_count;
-
- mesh = mesh->Peek_Next_Visible_Skin();
- }
- }
-
- SNAPSHOT_SAY(("Set vb: %x ib: %x",&vb.FVF_Info(),index_buffer));
-
- DX8Wrapper::Set_Vertex_Buffer(vb);
- DX8Wrapper::Set_Index_Buffer(index_buffer,0);
-
- //Flush the meshes which fit in the vertex buffer, applying all texture variations
- for (unsigned pass=0;passRender();
- it.Next();
- }
- }
-
- Render_Procedural_Material_Passes();
- }
-
- //remove all the rendered data from queues
- for (unsigned pass=0;passGet_Polygon_Count();
- if (mmc->Get_Gap_Filler()) {
- required_polygons+=mmc->Get_Gap_Filler()->Get_Polygon_Count();
- }
-
- if ((required_polygons*3*mmc->Get_Pass_Count())<=index_buffer->Get_Index_Count()-used_indices) {
- return true;
- }
- return false;
-}
-
-void DX8SkinFVFCategoryContainer::clearVisibleSkinList()
-{
- while (VisibleSkinHead != nullptr)
- {
- MeshClass* next = VisibleSkinHead->Peek_Next_Visible_Skin();
- VisibleSkinHead->Set_Next_Visible_Skin(nullptr);
- VisibleSkinHead = next;
- }
- VisibleSkinHead = nullptr;
- VisibleSkinTail = nullptr;
- VisibleVertexCount = 0;
-}
-
-void DX8SkinFVFCategoryContainer::Add_Visible_Skin(MeshClass * mesh)
-{
- if (mesh->Peek_Next_Visible_Skin() != nullptr || mesh == VisibleSkinTail)
- {
- DEBUG_CRASH(("Mesh %s is already a visible skin, and we tried to add it again... please notify Mark W or Steven J immediately!",mesh->Get_Name()));
- return;
- }
- if (VisibleSkinHead == nullptr)
- VisibleSkinTail = mesh;
- mesh->Set_Next_Visible_Skin(VisibleSkinHead);
- VisibleSkinHead = mesh;
- VisibleVertexCount += mesh->Peek_Model()->Get_Vertex_Count();
-}
-
-
-// ----------------------------------------------------------------------------
-
-void DX8SkinFVFCategoryContainer::Reset()
-{
- clearVisibleSkinList();
-
- for (unsigned pass=0;passType()==BUFFER_TYPE_SORTING || index_buffer->Type()==BUFFER_TYPE_DYNAMIC_SORTING) {
- stripify=false;
- }
-#endif // ;
- const TriIndex* src_indices=(const TriIndex*)split_table.Get_Polygon_Array(pass);//mmc->Get_Polygon_Array();
-
- if (stripify) {
- int* triangles=W3DNEWARRAY int[index_count];
- int triangle_index_count=0;
- for (int i=0;iSet_Vertex_Index_Range(vmin,vmax-vmin+1);
- }
- }
- delete[] strip;
- }
-
- // Need to check stripify again as it may be changed to false by the previous statement
- if (!stripify ) {
- DX8PolygonRendererClass* p_renderer=W3DNEW DX8PolygonRendererClass(
- index_count,
- split_table.Get_Mesh_Model_Class(),
- this,
- vertex_offset,
- index_offset,
- false,
- pass);
- PolygonRendererList.Add_Tail(p_renderer);
-
- IndexBufferClass::AppendLockClass l(index_buffer,index_offset,index_count);
- unsigned short* dst_indices=l.Get_Index_Array();
-
- unsigned short vmin=0xffff;
- unsigned short vmax=0;
-
- /*
- ** Iterate over the polys for this pass, adding each one that matches this texture+material+shader
- */
- for (int i=0;iGet_Vertex_Count());
-
- /*
- ** Remember the min and max vertex indices that these polygons used (for optimization)
- */
- p_renderer->Set_Vertex_Index_Range(vmin,vmax-vmin+1);
- WWASSERT(index_count<=unsigned(split_table.Get_Polygon_Count()*3));
- }
- }
-
- return index_count;
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8TextureCategoryClass::Render()
-{
- #ifdef WWDEBUG
- if (!WW3D::Expose_Prelit()) {
- #endif
-
- for (unsigned i=0;iGet_Texture_Name().str() : "null"));
- DX8Wrapper::Set_Texture(i,Peek_Texture(i));
- }
-
- #ifdef WWDEBUG
- }
- #endif
-
- SNAPSHOT_SAY(("Set_Material(%s)",Peek_Material() ? Peek_Material()->Get_Name() : "null"));
- VertexMaterialClass *vmaterial=(VertexMaterialClass *)Peek_Material(); //ugly cast from const but we'll restore it after changes so okay. -MW
- DX8Wrapper::Set_Material(vmaterial);
-
- SNAPSHOT_SAY(("Set_Shader(%x)",Get_Shader().Get_Bits()));
- ShaderClass theShader = Get_Shader();
-
- //Setup an alpha blend version of this shader just in case it's needed. -MW
- ShaderClass theAlphaShader = theShader;
- theAlphaShader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_SRC_ALPHA);
- theAlphaShader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA);
- //if we want to allow other translucent polygons behind this mesh, we need to disable z-write but
- //this will cause sorting errors on this mesh.
- //theAlphaShader.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE);
-
- DX8Wrapper::Set_Shader(theShader);
-
- if (m_gForceMultiply && theShader.Get_Dst_Blend_Func() == ShaderClass::DSTBLEND_ZERO) {
- theShader.Set_Dst_Blend_Func(ShaderClass::DSTBLEND_SRC_COLOR);
- theShader.Set_Src_Blend_Func(ShaderClass::SRCBLEND_ZERO);
- DX8Wrapper::Set_Shader(theShader);
- //VertexMaterialClass *material = VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
- //DX8Wrapper::Set_Material(material);
- //REF_PTR_RELEASE(material);
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR);
- }
-
-
- bool renderTasksRemaining=false;
-
- PolyRenderTaskClass * prt = render_task_head;
- PolyRenderTaskClass * last_prt = nullptr;
-
- while (prt) {
-
- /*
- ** Dig out the parameters for this render task
- */
- DX8PolygonRendererClass * renderer = prt->Peek_Polygon_Renderer();
- MeshClass * mesh = prt->Peek_Mesh();
-
- if (mesh->Get_Base_Vertex_Offset() == VERTEX_BUFFER_OVERFLOW) //check if this mesh is valid
- { //skip this mesh so it gets rendered later after vertices are filled in.
- last_prt = prt;
- prt = prt->Get_Next_Visible();
- renderTasksRemaining = true;
- continue;
- }
-
- SNAPSHOT_SAY(("mesh = %s",mesh->Get_Name()));
-
- #ifdef WWDEBUG
- // Debug rendering: if it exists, expose prelighting on this mesh by disabling all base textures.
- if (WW3D::Expose_Prelit()) {
- switch (mesh->Peek_Model()->Get_Flag (MeshGeometryClass::PRELIT_MASK)) {
-
- unsigned i;
-
- case MeshGeometryClass::PRELIT_VERTEX:
-
- // Disable texturing on all stages and passes.
- for (i = 0; i < MeshMatDescClass::MAX_TEX_STAGES; i++)
- {
- DX8Wrapper::Set_Texture (i, nullptr);
- }
- break;
-
- case MeshGeometryClass::PRELIT_LIGHTMAP_MULTI_PASS:
-
- // Disable texturing on all but the last pass.
- if (pass == mesh->Peek_Model()->Get_Pass_Count() - 1) {
- for (i = 0; i < MeshMatDescClass::MAX_TEX_STAGES; i++)
- {
- DX8Wrapper::Set_Texture (i, Peek_Texture (i));
- }
- } else {
- for (i = 0; i < MAX_TEXTURE_STAGES; i++) {
- DX8Wrapper::Set_Texture (i, nullptr);
- }
- }
- break;
-
- case MeshGeometryClass::PRELIT_LIGHTMAP_MULTI_TEXTURE:
-
- // Disable texturing on all but the zeroth stage of each pass.
- DX8Wrapper::Set_Texture (0, Peek_Texture (0));
- for (i = 1; i < MeshMatDescClass::MAX_TEX_STAGES; i++)
- {
- DX8Wrapper::Set_Texture (i, nullptr);
- }
- break;
-
- default:
- for (i = 0; i < MeshMatDescClass::MAX_TEX_STAGES; i++)
- {
- DX8Wrapper::Set_Texture (i, Peek_Texture (i));
- }
- break;
- }
- }
- #endif
-
- /*
- ** If the user is not installing LightEnvironmentClasses, we leave the lighting render
- ** states untouched. This way they can set a couple global lights that affect the entire scene.
- */
- LightEnvironmentClass * lenv = mesh->Get_Lighting_Environment();
- if (lenv != nullptr) {
- SNAPSHOT_SAY(("LightEnvironment, lights: %d",lenv->Get_Light_Count()));
- DX8Wrapper::Set_Light_Environment(lenv);
- }
- else {
- SNAPSHOT_SAY(("No light environment"));
- }
-
- /*
- ** Support for ALIGNED and ORIENTED camera modes
- */
- const Matrix3D* world_transform = &mesh->Get_Transform();
- bool identity=mesh->Is_Transform_Identity();
- Matrix3D tmp_world;
-
- if (mesh->Peek_Model()->Get_Flag(MeshModelClass::ALIGNED)) {
- SNAPSHOT_SAY(("Camera mode ALIGNED"));
-
- Vector3 mesh_position;
- Vector3 camera_z_vector;
-
- TheDX8MeshRenderer.Peek_Camera()->Get_Transform().Get_Z_Vector(&camera_z_vector);
- mesh->Get_Transform().Get_Translation(&mesh_position);
-
- tmp_world.Obj_Look_At(mesh_position,mesh_position + camera_z_vector,0.0f);
- world_transform = &tmp_world;
-
- } else if (mesh->Peek_Model()->Get_Flag(MeshModelClass::ORIENTED)) {
- SNAPSHOT_SAY(("Camera mode ORIENTED"));
-
- Vector3 mesh_position;
- Vector3 camera_position;
-
- TheDX8MeshRenderer.Peek_Camera()->Get_Transform().Get_Translation(&camera_position);
- mesh->Get_Transform().Get_Translation(&mesh_position);
-
- tmp_world.Obj_Look_At(mesh_position,camera_position,0.0f);
- world_transform = &tmp_world;
-
- } else if (mesh->Peek_Model()->Get_Flag(MeshModelClass::SKIN)) {
- SNAPSHOT_SAY(("Set world identity (for skin)"));
-
- tmp_world.Make_Identity();
- world_transform = &tmp_world;
- identity=true;
- }
-
-
- if (identity) {
- SNAPSHOT_SAY(("Set_World_Identity"));
- DX8Wrapper::Set_World_Identity();
- }
- else {
- SNAPSHOT_SAY(("Set_World_Transform"));
- DX8Wrapper::Set_Transform(D3DTS_WORLD,*world_transform);
- }
-
-
-//--------------------------------------------------------------------
- if (mesh->Get_ObjectScale() != 1.0f)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, TRUE);
-//--------------------------------------------------------------------
- /*
- ** Render mesh using either sorting or immediate pipeline
- */
- //(gth) this if statement's contents are not tabbed to avoid perforce merge problems...
- if (!DX8RendererDebugger::Is_Enabled() || !mesh->Is_Disabled_By_Debugger()) {
-
- if ((!!mesh->Peek_Model()->Get_Flag(MeshGeometryClass::SORT)) && WW3D::Is_Sorting_Enabled()) {
- renderer->Render_Sorted(mesh->Get_Base_Vertex_Offset(),mesh->Get_Bounding_Sphere());
- } else {
- //non-transparent mesh that will be rendered immediately. Okay to adjust the shader/material
- //if necessary
- if (mesh->Get_Alpha_Override() != 1.0 || (mesh->Get_User_Data() && *(int *)mesh->Get_User_Data() == RenderObjClass::USER_DATA_MATERIAL_OVERRIDE))
- { //mesh has material override of some kind
- //adjust the opacity of this model
- float oldOpacity=vmaterial->Get_Opacity();
- Vector3 oldDiffuse;
- Vector2 oldUVOffset;
- unsigned int oldUVOffsetSyncTime;
- vmaterial->Get_Diffuse(&oldDiffuse);
- LinearOffsetTextureMapperClass *oldMapper=(LinearOffsetTextureMapperClass *)vmaterial->Peek_Mapper();
- if ( mesh->Get_User_Data() && *(int *)mesh->Get_User_Data() == RenderObjClass::USER_DATA_MATERIAL_OVERRIDE && oldMapper && oldMapper->Mapper_ID() == TextureMapperClass::MAPPER_ID_LINEAR_OFFSET)
- { RenderObjClass::Material_Override *matOverride=(RenderObjClass::Material_Override *)mesh->Get_User_Data();
- oldUVOffsetSyncTime = oldMapper->Get_LastUsedSyncTime();
- oldMapper->Set_LastUsedSyncTime(WW3D::Get_Sync_Time()); //make sure zero time passes for the mapper.
- oldMapper->Get_Current_UV_Offset(oldUVOffset);
- oldMapper->Set_Current_UV_Offset(matOverride->customUVOffset);
- }
- else
- oldMapper=nullptr;
-
- if (mesh->Get_Alpha_Override() != 1.0)
- {
- if (mesh->Is_Additive())
- { //additvie blended mesh can't switch to alpha or we will get a black outline.
- //so adjust diffuse color instead.
- vmaterial->Set_Diffuse(mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override(),mesh->Get_Alpha_Override());
- theAlphaShader = theShader; //keep using additive blending.
- }
- vmaterial->Set_Opacity(mesh->Get_Alpha_Override());
- DX8Wrapper::Set_Shader(theAlphaShader);
- DX8Wrapper::Apply_Render_State_Changes();
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHAREF,(int)((float)0x60*mesh->Get_Alpha_Override()));
-
- renderer->Render(mesh->Get_Base_Vertex_Offset());
-
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHAREF,0x60);
- vmaterial->Set_Opacity(oldOpacity); //restore previous value
- vmaterial->Set_Diffuse(oldDiffuse.X,oldDiffuse.Y,oldDiffuse.Z);
- DX8Wrapper::Set_Shader(theShader); //restore previous value
- }
- else
- renderer->Render(mesh->Get_Base_Vertex_Offset());
-
- if (oldMapper) //did we override the uv offset?
- { oldMapper->Set_LastUsedSyncTime(oldUVOffsetSyncTime);
- oldMapper->Set_Current_UV_Offset(oldUVOffset);
- }
- DX8Wrapper::Set_Material(nullptr); //force a reset of vertex material since we secretly changed opacity
- DX8Wrapper::Set_Material(vmaterial); //restore previous material.
- }
- else
- renderer->Render(mesh->Get_Base_Vertex_Offset());
- }
-//--------------------------------------------------------------------
- if (mesh->Get_ObjectScale() != 1.0f)
- DX8Wrapper::Set_DX8_Render_State(D3DRS_NORMALIZENORMALS, FALSE);
-//--------------------------------------------------------------------
-
-
-
-
- }
-
- /*
- ** Move to the next render task. Note that the delete should be fast because prt's are pooled
- */
- PolyRenderTaskClass * next_prt = prt->Get_Next_Visible();
-
- // remove from list, then delete
- if (last_prt == nullptr) {
- render_task_head = next_prt;
- } else {
- last_prt->Set_Next_Visible(next_prt);
- }
-
- delete prt;
- prt = next_prt;
- }
-
- if (!renderTasksRemaining)
- {
- WWASSERT(!render_task_head);
- Clear_Render_List();
- }
-}
-
-void DX8TextureCategoryClass::Clear_Render_List()
-{
- while (render_task_head != nullptr)
- {
- PolyRenderTaskClass* next = render_task_head->Get_Next_Visible();
- delete render_task_head;
- render_task_head = next;
- }
-}
-
-
-DX8MeshRendererClass::DX8MeshRendererClass()
- :
- camera(nullptr),
- enable_lighting(true),
- texture_category_container_list_skin(nullptr),
- visible_decal_meshes(nullptr)
-{
-}
-
-DX8MeshRendererClass::~DX8MeshRendererClass()
-{
- Shutdown();
-}
-
-void DX8MeshRendererClass::Init()
-{
- // DMS - Only allocate one if we have not already (leak fix)
- if(!texture_category_container_list_skin)
- texture_category_container_list_skin = W3DNEW FVFCategoryList;
-}
-
-void DX8MeshRendererClass::Shutdown()
-{
- camera = nullptr;
- visible_decal_meshes = nullptr;
- Invalidate(true);
- Clear_Pending_Delete_Lists();
- _TempVertexBuffer.Clear(); //free memory
- _TempNormalBuffer.Clear();
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8MeshRendererClass::Clear_Pending_Delete_Lists()
-{
- while (DX8TextureCategoryClass* category=texture_category_delete_list.Remove_Head()) {
- delete category;
- }
- while (DX8FVFCategoryContainer* container=fvf_category_container_delete_list.Remove_Head()) {
- delete container;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static void Add_Rigid_Mesh_To_Container(FVFCategoryList* container_list,unsigned fvf,MeshModelClass* mmc)
-{
- WWASSERT(container_list);
- DX8FVFCategoryContainer * container = nullptr;
- bool sorting=((!!mmc->Get_Flag(MeshModelClass::SORT)) && WW3D::Is_Sorting_Enabled() && (mmc->Get_Sort_Level() == SORT_LEVEL_NONE));
-
- FVFCategoryListIterator it(container_list);
- while (!it.Is_Done()) {
- container = it.Peek_Obj();
- if (sorting==container->Is_Sorting() && container->Check_If_Mesh_Fits(mmc)) {
- container->Add_Mesh(mmc);
- return;
- }
- it.Next();
- }
-
- container=W3DNEW DX8RigidFVFCategoryContainer(fvf,sorting);
- container_list->Add_Tail(container);
- container->Add_Mesh(mmc);
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8MeshRendererClass::Unregister_Mesh_Type(MeshModelClass* mmc)
-{
- while (DX8PolygonRendererClass* n=mmc->PolygonRendererList.Remove_Head()) {
- delete n;
- }
- _RegisteredMeshList.Remove(mmc);
-
- // Also remove the gap filler!
- if (mmc->GapFiller) {
- GapFillerClass* gf=mmc->GapFiller;
- mmc->GapFiller=nullptr;
- delete gf;
- }
-
-}
-
-
-void DX8MeshRendererClass::Register_Mesh_Type(MeshModelClass* mmc)
-{
- WWMEMLOG(MEM_GEOMETRY);
-#ifdef ENABLE_CATEGORY_LOG
- WWDEBUG_SAY(("Registering mesh: %s (%d polys, %d verts + %d gap polygons)",mmc->Get_Name(),mmc->Get_Polygon_Count(),mmc->Get_Vertex_Count(),mmc->Get_Gap_Filler_Polygon_Count()));
-#endif
- bool skin=(mmc->Get_Flag(MeshModelClass::SKIN) && mmc->VertexBoneLink);
- bool sorting=((!!mmc->Get_Flag(MeshModelClass::SORT)) && WW3D::Is_Sorting_Enabled() && (mmc->Get_Sort_Level() == SORT_LEVEL_NONE));
-
- if (skin) {
-
- /*
- ** This mesh is a skin. Add it to a DX8SkinFVFCategoryContainer.
- */
- WWASSERT(texture_category_container_list_skin);
-
- FVFCategoryListIterator it(texture_category_container_list_skin);
- while (!it.Is_Done()) {
- DX8FVFCategoryContainer * container = it.Peek_Obj();
- if (sorting==container->Is_Sorting() && container->Check_If_Mesh_Fits(mmc)) {
- container->Add_Mesh(mmc);
- return;
- }
- it.Next();
- }
-
- DX8FVFCategoryContainer * new_container=W3DNEW DX8SkinFVFCategoryContainer(sorting);
- texture_category_container_list_skin->Add_Tail(new_container);
- new_container->Add_Mesh(mmc);
-
- } else {
-
- /*
- ** We should never try to add the same mesh model to the system twice.
- */
- WWASSERT_PRINT(_RegisteredMeshList.Contains(mmc) == false,("Mesh name: %s",mmc->Get_Name()));
-
- /*
- ** If the previous step didn't add the mesh, then we have to actually process this mesh
- */
- if (!_RegisteredMeshList.Contains(mmc)) {
-
- unsigned fvf=DX8FVFCategoryContainer::Define_FVF(mmc,enable_lighting);
-
- /*
- ** Search for an existing FVF Category Container that matches this mesh
- */
- int i=0;
- for (;iPeek_Head();
- if (container && container->Get_FVF()!=fvf) continue;
-
- Add_Rigid_Mesh_To_Container(list,fvf,mmc);
- break;
- }
-
- if (i==texture_category_container_lists_rigid.Count()) {
-
- /*
- ** We couldn't find an existing FVF category container so we have to add one. Future
- ** meshes that use this FVF will also be able to use this container.
- */
- FVFCategoryList * new_fvf_category = W3DNEW FVFCategoryList();
- texture_category_container_lists_rigid.Add(new_fvf_category);
- Add_Rigid_Mesh_To_Container(new_fvf_category,fvf,mmc);
- }
-
- /*
- ** Done processing the mesh, add its polygon renderers to the global registered mesh list
- */
- if (mmc->PolygonRendererList.Is_Empty() == false) {
- _RegisteredMeshList.Add_Tail(mmc);
- }
- else {
- WWDEBUG_SAY(("Error: Register_Mesh_Type failed! file: %s line: %d",__FILE__,__LINE__));
- }
- }
- }
-}
-
-static unsigned statistics_requested=0;
-
-void DX8MeshRendererClass::Request_Log_Statistics()
-{
- statistics_requested=WW3D::Get_Frame_Count();
-}
-
-
-// ---------------------------------------------------------------------------
-//
-// Render all meshes that are added to visible lists
-//
-// ---------------------------------------------------------------------------
-
-static void Render_FVF_Category_Container_List(FVFCategoryList& list)
-{
- FVFCategoryListIterator it(&list);
- while (!it.Is_Done()) {
- it.Peek_Obj()->Render();
- it.Next();
- }
-}
-
-static void Render_FVF_Category_Container_List_Delayed_Passes(FVFCategoryList& list)
-{
- FVFCategoryListIterator it(&list);
- while (!it.Is_Done()) {
- it.Peek_Obj()->Render_Delayed_Procedural_Material_Passes();
- it.Next();
- }
-}
-
-void DX8MeshRendererClass::Flush()
-{
- int i;
-
- WWPROFILE("DX8MeshRenderer::Flush");
- if (!camera) return;
- Log_Statistics_String(true);
-
- /*
- ** Render the FVF categories. Note that it is critical that skins be
- ** rendered *after* the rigid meshes. This is caused by the fact that an object may
- ** have its base passes disabled and a translucent procedural material pass rendered
- ** instead. In this case, technically we have to delay rendering of the material pass but
- ** for skins we just render these passes as we go because we can assume that the
- ** bulk of the meshes have already been drawn (there would be extra overhead involved
- ** in solving this for skins)
- */
- for (i=0;iSet_Next_Visible(visible_decal_meshes);
- visible_decal_meshes = decalmesh;
-}
-
-void DX8MeshRendererClass::Render_Decal_Meshes()
-{
- DecalMeshClass * decal_mesh = visible_decal_meshes;
- if (!decal_mesh) return;
-
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,8);
-
- while (decal_mesh != nullptr) {
- decal_mesh->Render();
- decal_mesh = decal_mesh->Peek_Next_Visible();
- }
- visible_decal_meshes = nullptr;
-
- DX8Wrapper::Set_DX8_Render_State(D3DRS_ZBIAS,0);
-}
-
-// ----------------------------------------------------------------------------
-
-static void Log_Container_List(FVFCategoryList& container_list,bool only_visible)
-{
- FVFCategoryListIterator it(&container_list);
- while (!it.Is_Done()) {
- it.Peek_Obj()->Log(only_visible);
- it.Next();
- }
-}
-
-void DX8MeshRendererClass::Log_Statistics_String(bool only_visible)
-{
- if (statistics_requested!=WW3D::Get_Frame_Count()) return;
-
- for (int i=0;i.
-*/
-
-/***********************************************************************************************
- *** 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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8renderer.h $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * Author : Kenny Mitchell *
- * *
- * $Modtime:: 06/27/02 1:27p $*
- * *
- * $Revision:: 29 $*
- * *
- * 06/27/02 KM Changes to max texture stage caps *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "wwstring.h"
-#include "simplevec.h"
-#include "Vector.h"
-#include "dx8list.h"
-#include "shader.h"
-#include "dx8wrapper.h"
-#include "meshmatdesc.h"
-
-class IndexBufferClass;
-class VertexBufferClass;
-class DX8RenderTypeArrayClass;
-class MeshClass;
-class MeshModelClass;
-class DX8PolygonRendererClass;
-class Vertex_Split_Table;
-class DX8FVFCategoryContainer;
-class DecalMeshClass;
-class MaterialPassClass;
-class MatPassTaskClass;
-class PolyRenderTaskClass;
-class TextureClass;
-class VertexMaterialClass;
-class CameraClass;
-
-#define RECORD_RENDER(I,P) render_stats[I].count++; render_stats[I].polys+=P;
-
-/**
-** DX8TextureCategoryClass
-** This class is used for each Material-Texture-Shader combination that is encountered during rendering.
-** Each polygon_renderer that uses the same 'TextureCategory' will be linked to the 'TextureCategory' object.
-** Then, all polygons will be rendered in 'TextureCategory' batches to reduce the number of stage changes
-** (and most importantly, texture changes) that we cause in DX8.
-*/
-class DX8TextureCategoryClass : public MultiListObjectClass
-{
- int pass;
- TextureClass * textures[MeshMatDescClass::MAX_TEX_STAGES];
- ShaderClass shader;
- VertexMaterialClass * material;
- DX8PolygonRendererList PolygonRendererList;
- DX8FVFCategoryContainer* container;
-
- PolyRenderTaskClass * render_task_head; // polygon renderers queued for rendering
- static bool m_gForceMultiply; // Forces opaque materials to use the multiply blend - pseudo transparent effect. jba.
-
-public:
-
- DX8TextureCategoryClass(DX8FVFCategoryContainer* container,TextureClass** textures, ShaderClass shd, VertexMaterialClass* mat,int pass);
- virtual ~DX8TextureCategoryClass() override;
-
- void Add_Render_Task(DX8PolygonRendererClass * p_renderer,MeshClass * p_mesh);
-
- void Render();
- bool Anything_To_Render() { return (render_task_head != nullptr); }
- void Clear_Render_List();
-
- TextureClass * Peek_Texture(int stage) { return textures[stage]; }
- const VertexMaterialClass * Peek_Material() { return material; }
- ShaderClass Get_Shader() { return shader; }
-
- DX8PolygonRendererList& Get_Polygon_Renderer_List() { return PolygonRendererList; }
-
- unsigned Add_Mesh(
- Vertex_Split_Table& split_buffer,
- unsigned vertex_offset,
- unsigned index_offset,
- IndexBufferClass* index_buffer,
- unsigned pass);
- void Log(bool only_visible);
-
- void Remove_Polygon_Renderer(DX8PolygonRendererClass* p_renderer);
- void Add_Polygon_Renderer(DX8PolygonRendererClass* p_renderer,DX8PolygonRendererClass* add_after_this=nullptr);
-
-
- DX8FVFCategoryContainer * Get_Container() { return container; }
-
- // Force multiply blend on all objects inserted from now on. (Doesn't affect the objects that are already in the lists)
- static void SetForceMultiply(bool multiply) { m_gForceMultiply=multiply; }
-
-};
-
-// ----------------------------------------------------------------------------
-
-/**
-** DX8FVFCategoryContainer
-*/
-
-class DX8FVFCategoryContainer : public MultiListObjectClass
-{
-public:
- enum {
- MAX_PASSES=4
- };
-protected:
-
- TextureCategoryList texture_category_list[MAX_PASSES];
- TextureCategoryList visible_texture_category_list[MAX_PASSES];
-
- MatPassTaskClass * visible_matpass_head;
- MatPassTaskClass * visible_matpass_tail;
-
- IndexBufferClass * index_buffer;
- int used_indices;
- unsigned FVF;
- unsigned passes;
- unsigned uv_coordinate_channels;
- bool sorting;
- bool AnythingToRender;
- bool AnyDelayedPassesToRender;
-
- void Generate_Texture_Categories(Vertex_Split_Table& split_table,unsigned vertex_offset);
- void Insert_To_Texture_Category(
- Vertex_Split_Table& split_table,
- TextureClass** textures,
- VertexMaterialClass* mat,
- ShaderClass shader,
- int pass,
- unsigned vertex_offset);
-
- bool Anything_To_Render() { return AnythingToRender; }
- bool Any_Delayed_Passes_To_Render() { return AnyDelayedPassesToRender; }
-
- void Render_Procedural_Material_Passes();
-
- DX8TextureCategoryClass* Find_Matching_Texture_Category(
- TextureClass* texture,
- unsigned pass,
- unsigned stage,
- DX8TextureCategoryClass* ref_category);
-
- DX8TextureCategoryClass* Find_Matching_Texture_Category(
- VertexMaterialClass* vmat,
- unsigned pass,
- DX8TextureCategoryClass* ref_category);
-
-public:
-
- DX8FVFCategoryContainer(unsigned FVF,bool sorting);
- virtual ~DX8FVFCategoryContainer() override;
-
- static unsigned Define_FVF(MeshModelClass* mmc,bool enable_lighting);
- bool Is_Sorting() const { return sorting; }
-
- void Change_Polygon_Renderer_Texture(
- DX8PolygonRendererList& polygon_renderer_list,
- TextureClass* texture,
- TextureClass* new_texture,
- unsigned pass,
- unsigned stage);
-
- void Change_Polygon_Renderer_Material(
- DX8PolygonRendererList& polygon_renderer_list,
- VertexMaterialClass* vmat,
- VertexMaterialClass* new_vmat,
- unsigned pass);
-
- void Remove_Texture_Category(DX8TextureCategoryClass* tex_category);
-
- virtual void Render()=0;
- virtual void Add_Mesh(MeshModelClass* mmc)=0;
- virtual void Log(bool only_visible)=0;
- virtual bool Check_If_Mesh_Fits(MeshModelClass* mmc)=0;
-
- unsigned Get_FVF() const { return FVF; }
-
- void Add_Visible_Texture_Category(DX8TextureCategoryClass * tex_category,int pass)
- {
- WWASSERT(pass texture_category_container_lists_rigid;
- FVFCategoryList * texture_category_container_list_skin;
-
- DecalMeshClass * visible_decal_meshes;
-
-
-};
-
-extern DX8MeshRendererClass TheDX8MeshRenderer;
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
deleted file mode 100644
index 756ffd2db20..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
-** Command & Conquer Generals(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 : ww3d *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8vertexbuffer.cpp $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 5:06p $*
- * *
- * $Revision:: 39 $*
- * *
- * 06/26/02 KM VB Vertex format size update for shaders *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-//#define VERTEX_BUFFER_LOG
-
-#include "dx8vertexbuffer.h"
-#include "dx8wrapper.h"
-#include "dx8fvf.h"
-#include "dx8caps.h"
-#include "thread.h"
-#include "wwmemlog.h"
-#include
-
-#define DEFAULT_VB_SIZE 5000
-
-static bool _DynamicSortingVertexArrayInUse=false;
-//static VertexFormatXYZNDUV2* _DynamicSortingVertexArray=nullptr;
-static SortingVertexBufferClass* _DynamicSortingVertexArray=nullptr;
-static unsigned short _DynamicSortingVertexArraySize=0;
-static unsigned short _DynamicSortingVertexArrayOffset=0;
-
-static bool _DynamicDX8VertexBufferInUse=false;
-static DX8VertexBufferClass* _DynamicDX8VertexBuffer=nullptr;
-static unsigned short _DynamicDX8VertexBufferSize=DEFAULT_VB_SIZE;
-static unsigned short _DynamicDX8VertexBufferOffset=0;
-
-static const FVFInfoClass _DynamicFVFInfo(dynamic_fvf_type);
-
-static int _DX8VertexBufferCount=0;
-
-static int _VertexBufferCount;
-static int _VertexBufferTotalVertices;
-static int _VertexBufferTotalSize;
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::VertexBufferClass(unsigned type_, unsigned FVF, unsigned short vertex_count_)
- :
- VertexCount(vertex_count_),
- type(type_),
- engine_refs(0)
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(VertexCount);
- WWASSERT(type==BUFFER_TYPE_DX8 || type==BUFFER_TYPE_SORTING);
- WWASSERT(FVF != 0);
- fvf_info=W3DNEW FVFInfoClass(FVF);
-
- _VertexBufferCount++;
- _VertexBufferTotalVertices+=VertexCount;
- _VertexBufferTotalSize+=VertexCount*fvf_info->Get_FVF_Size();
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("New VB, %d vertices, size %d bytes",VertexCount,VertexCount*fvf_info->Get_FVF_Size()));
- WWDEBUG_SAY(("Total VB count: %d, total %d vertices, total size %d bytes",
- _VertexBufferCount,
- _VertexBufferTotalVertices,
- _VertexBufferTotalSize));
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::~VertexBufferClass()
-{
- _VertexBufferCount--;
- _VertexBufferTotalVertices-=VertexCount;
- _VertexBufferTotalSize-=VertexCount*fvf_info->Get_FVF_Size();
-
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("Delete VB, %d vertices, size %d bytes",VertexCount,VertexCount*fvf_info->Get_FVF_Size()));
- WWDEBUG_SAY(("Total VB count: %d, total %d vertices, total size %d bytes",
- _VertexBufferCount,
- _VertexBufferTotalVertices,
- _VertexBufferTotalSize));
-#endif
- delete fvf_info;
-}
-
-unsigned VertexBufferClass::Get_Total_Buffer_Count()
-{
- return _VertexBufferCount;
-}
-
-unsigned VertexBufferClass::Get_Total_Allocated_Vertices()
-{
- return _VertexBufferTotalVertices;
-}
-
-unsigned VertexBufferClass::Get_Total_Allocated_Memory()
-{
- return _VertexBufferTotalSize;
-}
-
-
-// ----------------------------------------------------------------------------
-
-void VertexBufferClass::Add_Engine_Ref() const
-{
- engine_refs++;
-}
-
-// ----------------------------------------------------------------------------
-
-void VertexBufferClass::Release_Engine_Ref() const
-{
- engine_refs--;
- WWASSERT(engine_refs>=0);
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::WriteLockClass::WriteLockClass(VertexBufferClass* VertexBuffer, int flags)
- :
- VertexBufferLockClass(VertexBuffer)
-{
- DX8_THREAD_ASSERT();
- WWASSERT(VertexBuffer);
- WWASSERT(!VertexBuffer->Engine_Refs());
- VertexBuffer->Add_Ref();
- switch (VertexBuffer->Type()) {
- case BUFFER_TYPE_DX8:
-#ifdef VERTEX_BUFFER_LOG
- {
- StringClass fvf_name;
- VertexBuffer->FVF_Info().Get_FVF_Name(fvf_name);
- WWDEBUG_SAY(("VertexBuffer->Lock(start_index: 0, index_range: 0(%d), fvf_size: %d, fvf: %s)",
- VertexBuffer->Get_Vertex_Count(),
- VertexBuffer->FVF_Info().Get_FVF_Size(),
- fvf_name));
- }
-#endif
- DX8_Assert();
- DX8_ErrorCode(static_cast(VertexBuffer)->Get_DX8_Vertex_Buffer()->Lock(
- 0,
- 0,
- (unsigned char**)&Vertices,
- flags)); //flags
- break;
- case BUFFER_TYPE_SORTING:
- Vertices=static_cast(VertexBuffer)->VertexBuffer;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::WriteLockClass::~WriteLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (VertexBuffer->Type()) {
- case BUFFER_TYPE_DX8:
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("VertexBuffer->Unlock()"));
-#endif
- DX8_Assert();
- DX8_ErrorCode(static_cast(VertexBuffer)->Get_DX8_Vertex_Buffer()->Unlock());
- break;
- case BUFFER_TYPE_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
- VertexBuffer->Release_Ref();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::AppendLockClass::AppendLockClass(VertexBufferClass* VertexBuffer,unsigned start_index, unsigned index_range)
- :
- VertexBufferLockClass(VertexBuffer)
-{
- DX8_THREAD_ASSERT();
- WWASSERT(VertexBuffer);
- WWASSERT(!VertexBuffer->Engine_Refs());
- WWASSERT(start_index+index_range<=VertexBuffer->Get_Vertex_Count());
- VertexBuffer->Add_Ref();
- switch (VertexBuffer->Type()) {
- case BUFFER_TYPE_DX8:
-#ifdef VERTEX_BUFFER_LOG
- {
- StringClass fvf_name;
- VertexBuffer->FVF_Info().Get_FVF_Name(fvf_name);
- WWDEBUG_SAY(("VertexBuffer->Lock(start_index: %d, index_range: %d, fvf_size: %d, fvf: %s)",
- start_index,
- index_range,
- VertexBuffer->FVF_Info().Get_FVF_Size(),
- fvf_name));
- }
-#endif
- DX8_Assert();
- DX8_ErrorCode(static_cast(VertexBuffer)->Get_DX8_Vertex_Buffer()->Lock(
- start_index*VertexBuffer->FVF_Info().Get_FVF_Size(),
- index_range*VertexBuffer->FVF_Info().Get_FVF_Size(),
- (unsigned char**)&Vertices,
- 0)); // Default (no) flags
- break;
- case BUFFER_TYPE_SORTING:
- Vertices=static_cast(VertexBuffer)->VertexBuffer+start_index;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-VertexBufferClass::AppendLockClass::~AppendLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (VertexBuffer->Type()) {
- case BUFFER_TYPE_DX8:
- DX8_Assert();
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("VertexBuffer->Unlock()"));
-#endif
- DX8_ErrorCode(static_cast(VertexBuffer)->Get_DX8_Vertex_Buffer()->Unlock());
- break;
- case BUFFER_TYPE_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
- VertexBuffer->Release_Ref();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-SortingVertexBufferClass::SortingVertexBufferClass(unsigned short VertexCount)
- :
- VertexBufferClass(BUFFER_TYPE_SORTING, dynamic_fvf_type, VertexCount)
-{
- WWMEMLOG(MEM_RENDERER);
- VertexBuffer=W3DNEWARRAY VertexFormatXYZNDUV2[VertexCount];
-}
-
-// ----------------------------------------------------------------------------
-
-SortingVertexBufferClass::~SortingVertexBufferClass()
-{
- delete[] VertexBuffer;
-}
-
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-// bool dynamic=false,bool softwarevp=false);
-
-DX8VertexBufferClass::DX8VertexBufferClass(unsigned FVF, unsigned short vertex_count_, UsageType usage)
- :
- VertexBufferClass(BUFFER_TYPE_DX8, FVF, vertex_count_),
- VertexBuffer(nullptr)
-{
- Create_Vertex_Buffer(usage);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8VertexBufferClass::DX8VertexBufferClass(
- const Vector3* vertices,
- const Vector3* normals,
- const Vector2* tex_coords,
- unsigned short VertexCount,
- UsageType usage)
- :
- VertexBufferClass(BUFFER_TYPE_DX8, D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_NORMAL, VertexCount),
- VertexBuffer(nullptr)
-{
- WWASSERT(vertices);
- WWASSERT(normals);
- WWASSERT(tex_coords);
-
- Create_Vertex_Buffer(usage);
- Copy(vertices,normals,tex_coords,0,VertexCount);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8VertexBufferClass::DX8VertexBufferClass(
- const Vector3* vertices,
- const Vector3* normals,
- const Vector4* diffuse,
- const Vector2* tex_coords,
- unsigned short VertexCount,
- UsageType usage)
- :
- VertexBufferClass(BUFFER_TYPE_DX8, D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_NORMAL|D3DFVF_DIFFUSE, VertexCount),
- VertexBuffer(nullptr)
-{
- WWASSERT(vertices);
- WWASSERT(normals);
- WWASSERT(tex_coords);
- WWASSERT(diffuse);
-
- Create_Vertex_Buffer(usage);
- Copy(vertices,normals,tex_coords,diffuse,0,VertexCount);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8VertexBufferClass::DX8VertexBufferClass(
- const Vector3* vertices,
- const Vector4* diffuse,
- const Vector2* tex_coords,
- unsigned short VertexCount,
- UsageType usage)
- :
- VertexBufferClass(BUFFER_TYPE_DX8, D3DFVF_XYZ|D3DFVF_TEX1|D3DFVF_DIFFUSE, VertexCount),
- VertexBuffer(nullptr)
-{
- WWASSERT(vertices);
- WWASSERT(tex_coords);
- WWASSERT(diffuse);
-
- Create_Vertex_Buffer(usage);
- Copy(vertices,tex_coords,diffuse,0,VertexCount);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8VertexBufferClass::DX8VertexBufferClass(
- const Vector3* vertices,
- const Vector2* tex_coords,
- unsigned short VertexCount,
- UsageType usage)
- :
- VertexBufferClass(BUFFER_TYPE_DX8, D3DFVF_XYZ|D3DFVF_TEX1, VertexCount),
- VertexBuffer(nullptr)
-{
- WWASSERT(vertices);
- WWASSERT(tex_coords);
-
- Create_Vertex_Buffer(usage);
- Copy(vertices,tex_coords,0,VertexCount);
-}
-
-// ----------------------------------------------------------------------------
-
-DX8VertexBufferClass::~DX8VertexBufferClass()
-{
-#ifdef VERTEX_BUFFER_LOG
- WWDEBUG_SAY(("VertexBuffer->Release()"));
- _DX8VertexBufferCount--;
- WWDEBUG_SAY(("Current vertex buffer count: %d",_DX8VertexBufferCount));
-#endif
- VertexBuffer->Release();
-}
-
-// ----------------------------------------------------------------------------
-//
-//
-//
-// ----------------------------------------------------------------------------
-
-void DX8VertexBufferClass::Create_Vertex_Buffer(UsageType usage)
-{
- DX8_THREAD_ASSERT();
- WWASSERT(!VertexBuffer);
-
-#ifdef VERTEX_BUFFER_LOG
- StringClass fvf_name;
- FVF_Info().Get_FVF_Name(fvf_name);
- WWDEBUG_SAY(("CreateVertexBuffer(fvfsize=%d, vertex_count=%d, D3DUSAGE_WRITEONLY|%s|%s, fvf: %s, %s)",
- FVF_Info().Get_FVF_Size(),
- VertexCount,
- (usage&USAGE_DYNAMIC) ? "D3DUSAGE_DYNAMIC" : "-",
- (usage&USAGE_SOFTWAREPROCESSING) ? "D3DUSAGE_SOFTWAREPROCESSING" : "-",
- fvf_name,
- (usage&USAGE_DYNAMIC) ? "D3DPOOL_DEFAULT" : "D3DPOOL_MANAGED"));
- _DX8VertexBufferCount++;
- WWDEBUG_SAY(("Current vertex buffer count: %d",_DX8VertexBufferCount));
-#endif
-
- unsigned usage_flags=
- D3DUSAGE_WRITEONLY|
- ((usage&USAGE_DYNAMIC) ? D3DUSAGE_DYNAMIC : 0)|
- ((usage&USAGE_NPATCHES) ? D3DUSAGE_NPATCHES : 0)|
- ((usage&USAGE_SOFTWAREPROCESSING) ? D3DUSAGE_SOFTWAREPROCESSING : 0);
- // New Code
- if (!DX8Wrapper::Get_Current_Caps()->Support_TnL()) {
- usage_flags|=D3DUSAGE_SOFTWAREPROCESSING;
- }
-
- HRESULT ret=DX8Wrapper::_Get_D3D_Device8()->CreateVertexBuffer(
- FVF_Info().Get_FVF_Size()*VertexCount,
- usage_flags,
- FVF_Info().Get_FVF(),
- (usage&USAGE_DYNAMIC) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED,
- &VertexBuffer);
- if (SUCCEEDED(ret)) {
- return;
- }
-
- WWDEBUG_SAY(("Vertex buffer creation failed, trying to release assets..."));
-
- // Vertex buffer creation failed, so try releasing least used textures and flushing the mesh cache.
-
- // Free all textures that haven't been used in the last 5 seconds
- TextureClass::Invalidate_Old_Unused_Textures(5000);
-
- // Invalidate the mesh cache
- WW3D::_Invalidate_Mesh_Cache();
-
- //@todo: Find some way to invalidate the textures too
- ret = DX8Wrapper::_Get_D3D_Device8()->ResourceManagerDiscardBytes(0);
-
- // Try again...
- ret=DX8Wrapper::_Get_D3D_Device8()->CreateVertexBuffer(
- FVF_Info().Get_FVF_Size()*VertexCount,
- usage_flags,
- FVF_Info().Get_FVF(),
- (usage&USAGE_DYNAMIC) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED,
- &VertexBuffer);
-
- if (SUCCEEDED(ret)) {
- WWDEBUG_SAY(("...Vertex buffer creation successful"));
- }
-
- // If it still fails it is fatal
- DX8_ErrorCode(ret);
-
- /* Old Code
- DX8CALL(CreateVertexBuffer(
- FVF_Info().Get_FVF_Size()*VertexCount,
- usage_flags,
- FVF_Info().Get_FVF(),
- (usage&USAGE_DYNAMIC) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED,
- &VertexBuffer));
- */
-}
-
-// ----------------------------------------------------------------------------
-
-void DX8VertexBufferClass::Copy(const Vector3* loc, const Vector3* norm, const Vector2* uv, unsigned first_vertex,unsigned count)
-{
- WWASSERT(loc);
- WWASSERT(norm);
- WWASSERT(uv);
- WWASSERT(count<=VertexCount);
- WWASSERT(FVF_Info().Get_FVF()==DX8_FVF_XYZNUV1);
-
- if (first_vertex) {
- VertexBufferClass::AppendLockClass l(this,first_vertex,count);
- VertexFormatXYZNUV1* verts=(VertexFormatXYZNUV1*)l.Get_Vertex_Array();
- for (unsigned v=0;vNum_Refs() == 1));
- REF_PTR_RELEASE(_DynamicDX8VertexBuffer);
- _DynamicDX8VertexBufferInUse=false;
- _DynamicDX8VertexBufferSize=DEFAULT_VB_SIZE;
- _DynamicDX8VertexBufferOffset=0;
-
- WWASSERT ((_DynamicSortingVertexArray == nullptr) || (_DynamicSortingVertexArray->Num_Refs() == 1));
- REF_PTR_RELEASE(_DynamicSortingVertexArray);
- WWASSERT(!_DynamicSortingVertexArrayInUse);
- _DynamicSortingVertexArrayInUse=false;
- _DynamicSortingVertexArraySize=0;
- _DynamicSortingVertexArrayOffset=0;
-}
-
-void DynamicVBAccessClass::Allocate_DX8_Dynamic_Buffer()
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(!_DynamicDX8VertexBufferInUse);
- _DynamicDX8VertexBufferInUse=true;
-
- // If requesting more vertices than dynamic vertex buffer can fit, delete the vb
- // and adjust the size to the new count.
- if (VertexCount>_DynamicDX8VertexBufferSize) {
- REF_PTR_RELEASE(_DynamicDX8VertexBuffer);
- _DynamicDX8VertexBufferSize=VertexCount;
- if (_DynamicDX8VertexBufferSizeSupport_NPatches()) {
- usage|=DX8VertexBufferClass::USAGE_NPATCHES;
- }
-
- _DynamicDX8VertexBuffer=NEW_REF(DX8VertexBufferClass,(
- dynamic_fvf_type,
- _DynamicDX8VertexBufferSize,
- (DX8VertexBufferClass::UsageType)usage));
- _DynamicDX8VertexBufferOffset=0;
- }
-
- // Any room at the end of the buffer?
- if (((unsigned)VertexCount+_DynamicDX8VertexBufferOffset)>_DynamicDX8VertexBufferSize) {
- _DynamicDX8VertexBufferOffset=0;
- }
-
- REF_PTR_SET(VertexBuffer,_DynamicDX8VertexBuffer);
- VertexBufferOffset=_DynamicDX8VertexBufferOffset;
-}
-
-void DynamicVBAccessClass::Allocate_Sorting_Dynamic_Buffer()
-{
- WWMEMLOG(MEM_RENDERER);
- WWASSERT(!_DynamicSortingVertexArrayInUse);
- _DynamicSortingVertexArrayInUse=true;
-
- unsigned new_vertex_count=_DynamicSortingVertexArrayOffset+VertexCount;
- WWASSERT(new_vertex_count<65536);
- if (new_vertex_count>_DynamicSortingVertexArraySize) {
- REF_PTR_RELEASE(_DynamicSortingVertexArray);
- _DynamicSortingVertexArraySize=new_vertex_count;
- if (_DynamicSortingVertexArraySizeGet_Type()) {
- case BUFFER_TYPE_DYNAMIC_DX8:
-#ifdef VERTEX_BUFFER_LOG
- {
- WWASSERT(!dx8_lock);
- dx8_lock++;
- StringClass fvf_name;
- DynamicVBAccess->VertexBuffer->FVF_Info().Get_FVF_Name(fvf_name);
- WWDEBUG_SAY(("DynamicVertexBuffer->Lock(start_index: %d, index_range: %d, fvf_size: %d, fvf: %s)",
- DynamicVBAccess->VertexBufferOffset,
- DynamicVBAccess->Get_Vertex_Count(),
- DynamicVBAccess->VertexBuffer->FVF_Info().Get_FVF_Size(),
- fvf_name));
- }
-#endif
- WWASSERT(_DynamicDX8VertexBuffer);
-// WWASSERT(!_DynamicDX8VertexBuffer->Engine_Refs());
-
- DX8_Assert();
- // Lock with discard contents if the buffer offset is zero
- DX8_ErrorCode(static_cast(DynamicVBAccess->VertexBuffer)->Get_DX8_Vertex_Buffer()->Lock(
- DynamicVBAccess->VertexBufferOffset*_DynamicDX8VertexBuffer->FVF_Info().Get_FVF_Size(),
- DynamicVBAccess->Get_Vertex_Count()*DynamicVBAccess->VertexBuffer->FVF_Info().Get_FVF_Size(),
- (unsigned char**)&Vertices,
- D3DLOCK_NOSYSLOCK | (!DynamicVBAccess->VertexBufferOffset ? D3DLOCK_DISCARD : D3DLOCK_NOOVERWRITE)));
- break;
- case BUFFER_TYPE_DYNAMIC_SORTING:
- Vertices=static_cast(DynamicVBAccess->VertexBuffer)->VertexBuffer;
- Vertices+=DynamicVBAccess->VertexBufferOffset;
-// vertices=_DynamicSortingVertexArray+_DynamicSortingVertexArrayOffset;
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-DynamicVBAccessClass::WriteLockClass::~WriteLockClass()
-{
- DX8_THREAD_ASSERT();
- switch (DynamicVBAccess->Get_Type()) {
- case BUFFER_TYPE_DYNAMIC_DX8:
-#ifdef VERTEX_BUFFER_LOG
- dx8_lock--;
- WWASSERT(!dx8_lock);
- WWDEBUG_SAY(("DynamicVertexBuffer->Unlock()"));
-#endif
- DX8_Assert();
- DX8_ErrorCode(static_cast(DynamicVBAccess->VertexBuffer)->Get_DX8_Vertex_Buffer()->Unlock());
- break;
- case BUFFER_TYPE_DYNAMIC_SORTING:
- break;
- default:
- WWASSERT(0);
- break;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-void DynamicVBAccessClass::_Reset(bool frame_changed)
-{
- _DynamicSortingVertexArrayOffset=0;
- if (frame_changed) _DynamicDX8VertexBufferOffset=0;
-}
-
-unsigned short DynamicVBAccessClass::Get_Default_Vertex_Count()
-{
- return _DynamicDX8VertexBufferSize;
-}
-
diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
deleted file mode 100644
index 1c0a632e44d..00000000000
--- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
-** Command & Conquer Generals(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 : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/dx8vertexbuffer.h $*
- * *
- * Original Author:: Jani Penttinen *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 5:06p $*
- * *
- * $Revision:: 26 $*
- * *
- * 06/26/02 KM VB Vertex format size update for shaders *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-#pragma once
-
-#include "always.h"
-#include "wwdebug.h"
-#include "dx8fvf.h"
-
-const unsigned dynamic_fvf_type=D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2|D3DFVF_DIFFUSE;
-
-class DX8Wrapper;
-class SortingRendererClass;
-class Vector2;
-class Vector3;
-class Vector4;
-class StringClass;
-class DX8VertexBufferClass;
-class FVFInfoClass;
-struct IDirect3DVertexBuffer8;
-class VertexBufferClass;
-struct VertexFormatXYZNDUV2;
-
-class VertexBufferLockClass
-{
-protected:
- VertexBufferClass* VertexBuffer;
- void* Vertices;
-
- // This class can't be used directly, so constructor as to be protected
- VertexBufferLockClass(VertexBufferClass* vertex_buffer_) : VertexBuffer(vertex_buffer_) {}
-public:
- void* Get_Vertex_Array() { return Vertices; }
-};
-
-/**
-** DX8VertexBufferClass
-** This class wraps a DX8 vertex buffer. Use the lock objects to modify or append to the vertex buffer.
-*/
-class VertexBufferClass : public RefCountClass
-{
-protected:
- VertexBufferClass(unsigned type, unsigned FVF, unsigned short VertexCount);
- virtual ~VertexBufferClass() override;
-public:
-
- const FVFInfoClass& FVF_Info() const { return *fvf_info; }
- unsigned short Get_Vertex_Count() const { return VertexCount; }
- unsigned Type() const { return type; }
-
- void Add_Engine_Ref() const;
- void Release_Engine_Ref() const;
- unsigned Engine_Refs() const { return engine_refs; }
-
- class WriteLockClass : public VertexBufferLockClass
- {
- public:
- WriteLockClass(VertexBufferClass* vertex_buffer, int flags=0);
- ~WriteLockClass();
- };
-
- class AppendLockClass : public VertexBufferLockClass
- {
- public:
- AppendLockClass(VertexBufferClass* vertex_buffer,unsigned start_index, unsigned index_range);
- ~AppendLockClass();
- };
-
- static unsigned Get_Total_Buffer_Count();
- static unsigned Get_Total_Allocated_Vertices();
- static unsigned Get_Total_Allocated_Memory();
-
-protected:
- unsigned type;
- unsigned short VertexCount;
- mutable int engine_refs;
- FVFInfoClass* fvf_info;
-};
-
-
-
-/**
-** Dynamic vertex buffer access is a wrapper to a single cycled dynamic vertex
-** buffer.
-** DynamicVBAccess gains an access to the dynamic vertex buffer and only
-** only of these are allowed at any one time.
-**
-** The dynamic fvf buffers are always of the same type.
-**
-** NOTE: Dynamic vertex buffers accessors should only be used locally!
-**
-*/
-
-class DynamicVBAccessClass
-{
- friend DX8Wrapper;
- friend SortingRendererClass;
-
- const FVFInfoClass& FVFInfo;
- unsigned Type;
- unsigned short VertexCount;
- unsigned short VertexBufferOffset;
- VertexBufferClass* VertexBuffer;
-// static VertexFormatXYZNDUV2* _Get_Sorting_Vertex_Array();
-
- void Allocate_Sorting_Dynamic_Buffer();
- void Allocate_DX8_Dynamic_Buffer();
-public:
- // Type parameter can be either BUFFER_TYPE_DYNAMIC_DX8 or BUFFER_TYPE_DYNAMIC_SORTING.
-
- // Note: Even though the constructor takes fvf as a parameter, currently the
- // only acceptable parameter is "dynamic_fvf_type". Any other type will
- // result to an assert.
- DynamicVBAccessClass(unsigned type,unsigned fvf,unsigned short vertex_count);
- ~DynamicVBAccessClass();
-
- // Access fvf
- const FVFInfoClass& FVF_Info() const { return FVFInfo; }
- unsigned Get_Type() const { return Type; }
- unsigned short Get_Vertex_Count() const { return VertexCount; }
-
- // Call at the end of the execution, or at whatever time you wish to release
- // the recycled dynamic vertex buffer.
- static void _Deinit();
- static void _Reset(bool frame_changed);
- static unsigned short Get_Default_Vertex_Count(); ///VertexBuffer->FVF_Info().Get_FVF() == (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX2|D3DFVF_DIFFUSE));
- return Vertices;
-}
-
-// ----------------------------------------------------------------------------
-
-/**
-** DX8VertexBufferClass
-** This class wraps a DX8 vertex buffer. Use the lock objects to modify or append to the vertex buffer.
-*/
-class DX8VertexBufferClass : public VertexBufferClass
-{
- W3DMPO_CODE(DX8VertexBufferClass)
-protected:
- virtual ~DX8VertexBufferClass() override;
-public:
- enum UsageType {
- USAGE_DEFAULT=0,
- USAGE_DYNAMIC=1,
- USAGE_SOFTWAREPROCESSING=2,
- USAGE_NPATCHES=4
- };
-
- DX8VertexBufferClass(unsigned FVF, unsigned short VertexCount, UsageType usage=USAGE_DEFAULT);
- DX8VertexBufferClass(const Vector3* vertices, const Vector3* normals, const Vector2* tex_coords, unsigned short VertexCount,UsageType usage=USAGE_DEFAULT);
- DX8VertexBufferClass(const Vector3* vertices, const Vector3* normals, const Vector4* diffuse, const Vector2* tex_coords, unsigned short VertexCount,UsageType usage=USAGE_DEFAULT);
- DX8VertexBufferClass(const Vector3* vertices, const Vector4* diffuse, const Vector2* tex_coords, unsigned short VertexCount,UsageType usage=USAGE_DEFAULT);
- DX8VertexBufferClass(const Vector3* vertices, const Vector2* tex_coords, unsigned short VertexCount,UsageType usage=USAGE_DEFAULT);
-
- IDirect3DVertexBuffer8* Get_DX8_Vertex_Buffer() { return VertexBuffer; }
-
- void Copy(const Vector3* loc, unsigned first_vertex, unsigned count);
- void Copy(const Vector3* loc, const Vector2* uv, unsigned first_vertex, unsigned count);
- void Copy(const Vector3* loc, const Vector3* norm, unsigned first_vertex, unsigned count);
- void Copy(const Vector3* loc, const Vector3* norm, const Vector2* uv, unsigned first_vertex, unsigned count);
- void Copy(const Vector3* loc, const Vector3* norm, const Vector2* uv, const Vector4* diffuse, unsigned first_vertex, unsigned count);
- void Copy(const Vector3* loc, const Vector2* uv, const Vector4* diffuse, unsigned first_vertex, unsigned count);
-
-protected:
- IDirect3DVertexBuffer8* VertexBuffer;
-
- void Create_Vertex_Buffer(UsageType usage);
-};
-
-
-/**
-** SortingVertexBufferClass
-** This class acts as a vertex buffer for the vertices that need to be passed to alpha renderer.
-*/
-class SortingVertexBufferClass : public VertexBufferClass
-{
- W3DMPO_CODE(SortingVertexBufferClass)
-
- friend DX8Wrapper;
- friend SortingRendererClass;
- friend VertexBufferClass::WriteLockClass;
- friend VertexBufferClass::AppendLockClass;
- friend DynamicVBAccessClass::WriteLockClass;
-
- VertexFormatXYZNDUV2* VertexBuffer;
-
-protected:
- virtual ~SortingVertexBufferClass() override;
-public:
- SortingVertexBufferClass(unsigned short VertexCount);
-};
diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
index e1a1eaa9c79..cd6a3a731c1 100644
--- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
+++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
@@ -45,21 +45,21 @@ set(WW3D2_SRC
#dllist.h
# dx8caps.cpp
# dx8caps.h
- dx8fvf.cpp
- dx8fvf.h
- dx8indexbuffer.cpp
- dx8indexbuffer.h
+# dx8fvf.cpp
+# dx8fvf.h
+# dx8indexbuffer.cpp
+# dx8indexbuffer.h
#dx8list.h
#dx8polygonrenderer.cpp
#dx8polygonrenderer.h
- dx8renderer.cpp
- dx8renderer.h
+# dx8renderer.cpp
+# dx8renderer.h
# dx8rendererdebugger.cpp
# dx8rendererdebugger.h
#dx8texman.cpp
#dx8texman.h
- dx8vertexbuffer.cpp
- dx8vertexbuffer.h
+# dx8vertexbuffer.cpp
+# dx8vertexbuffer.h
#dx8webbrowser.cpp
#dx8webbrowser.h
# dx8wrapper.cpp
diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py
index b293dd29157..936b08844e6 100644
--- a/scripts/cpp/unify_move_files.py
+++ b/scripts/cpp/unify_move_files.py
@@ -536,6 +536,15 @@ def main():
#unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/System/Damage.cpp", Game.CORE, "GameEngine/Source/GameLogic/System/Damage.cpp")
#unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp", Game.CORE, "GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp")
#unify_file(Game.ZEROHOUR, "GameEngine/Source/GameLogic/System/RankInfo.cpp", Game.CORE, "GameEngine/Source/GameLogic/System/RankInfo.cpp")
+
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8fvf.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8fvf.h")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.h")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8renderer.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8renderer.h")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.h")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8fvf.cpp")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8indexbuffer.cpp")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8renderer.cpp")
+ #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/dx8vertexbuffer.cpp")
return