From e7e0a34dff74dfb814fad6e43f4ecab390e8807b Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:48:27 +0200 Subject: [PATCH 1/2] unify(ww3d2): Merge SortingRenderer (#2772) --- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 371 ++++++------------ 1 file changed, 121 insertions(+), 250 deletions(-) diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index e2ba6fbd2ec..48f0840ae92 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -66,148 +66,86 @@ struct ShortVectorIStruct unsigned short i; unsigned short j; unsigned short k; - - ShortVectorIStruct(unsigned short i_,unsigned short j_,unsigned short k_) : i(i_),j(j_),k(k_) {} - ShortVectorIStruct() {} }; struct TempIndexStruct { ShortVectorIStruct tri; unsigned short idx; - - TempIndexStruct() {} - TempIndexStruct(const ShortVectorIStruct& tri_, unsigned short idx_) - : - tri(tri_), - idx(idx_) - { - } + float z; }; +bool operator <(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z < r.z; } +bool operator <=(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z <= r.z; } +bool operator >(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z > r.z; } +bool operator >=(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z >= r.z; } +bool operator ==(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z == r.z; } // ---------------------------------------------------------------------------- -// -// InsertionSort (T* array, K *keys, int l, int r) -// Performs insertion sort on array 'array' elements [l-r]. Uses values from array -// 'keys' as sort keys. -// -// ---------------------------------------------------------------------------- - -template -void InsertionSort ( - T* array, // array to sort - K* keys, // sort keys - int l, // first item - int r) // last item +static +void InsertionSort(TempIndexStruct *begin, TempIndexStruct *end) { - for (int i = l+1; i < r; i++) { - K v=keys[i]; - T tv=array[i]; - int j=i; - - while (keys[j-1] > v) { - keys[j]=keys[j-1]; - array[j]=array[j-1]; - j--; - if (j == l) break; - }; - keys[j]=v; - array[j]=tv; + for (TempIndexStruct *iter = begin + 1; iter < end; ++iter) { + TempIndexStruct val = iter[0]; + TempIndexStruct *insert = iter; + while (insert != begin && insert[-1] > val) { + insert[0] = insert[-1]; + insert -= 1; + } + insert[0] = val; } } // ---------------------------------------------------------------------------- -// -// QuickSort (T* array, K* a, int l, int r) -// -// Performs quicksort on array 'array'. Uses values from array 'keys' as sort keys. -// -// Once the length of the array to be sorted is less than 8, the routine calls -// InsertionSort() to perform the actual sorting work. -// -// ---------------------------------------------------------------------------- - -template -void QuickSort ( - T* array, // array to sort - K* keys, // sort keys - int l, // first element - int r) // last element +static +void Sort(TempIndexStruct *begin, TempIndexStruct *end) { - if (r-l <= 8) { - InsertionSort(array,keys,l,r+1); - return; - } - - K t; - K v=keys[r]; - T ttemp; - int i=l-1; - int j=r; - - do { - do { i++; } while (i0 && keys[j]>v); - - WWASSERT(j>=0); - WWASSERT(i<=r); - - ttemp=array[i]; array[i]=array[j]; array[j]=ttemp; - t=keys[i]; keys[i]=keys[j]; keys[j]=t; - } while (j>i); - - array[j]=array[i]; - array[i]=array[r]; - array[r]=ttemp; - keys[j]=keys[i]; - keys[i]=keys[r]; - keys[r]=t; - - if (i-1>l) QuickSort(array,keys,l,i-1); - if (r>i+1) QuickSort(array,keys,i+1,r); -} - -// ---------------------------------------------------------------------------- -// -// Sorts and array. Uses values from array 'keys' as sort keys. -// -// ---------------------------------------------------------------------------- - -template -void Sort ( - T* array, // array to sort - K *keys, // sort keys - int count) // array element count -{ - bool do_insertion = false; - - if (count<=1) return; // only one element.. return.. - - int c=0; // count number of rise pairs - int i; - for (i = 1; i < count; i++) - if (keys[i] >= keys[i-1]) c++; - - if (c+1 == count) return; // array already sorted - if (c<50) do_insertion=true; // array smaller than 50 should use insertion sort - - if (c end[-1]) { + std::swap(begin[1], end[-1]); + } + if (begin[0] > end[-1]) { + std::swap(begin[0], end[-1]); + } + if (begin[1] > begin[0]) { + std::swap(begin[1], begin[0]); } - if (!c) return; - - do_insertion = true; + // *begin is now the partitioning element + TempIndexStruct *begin1 = begin + 1; // TODO: Temp fix until I find out who is passing me NaN + TempIndexStruct *end1 = end - 1; // TODO: Temp fix until I find out who is passing me NaN + TempIndexStruct *left = begin + 1; + TempIndexStruct *right = end - 1; + for (;;) { +#if 0 // TODO: Temp fix until I find out who is passing me NaN. + do ++left; while (left[0] < begin[0]); // Scan up to find element >= than partition + do --right; while (right[0] > begin[0]); // Scan down to find element <= than partition +#else + do ++left; while (left < end1 && left[0] < begin[0]); // Scan up to find element >= than partition + do --right; while (right > begin1 && right[0] > begin[0]); // Scan down to find element <= than partition +#endif + if (right < left) break; // Pointers crossed. Partitioning completed. + std::swap(left[0], right[0]); // Exchange elements. + } + std::swap(begin[0], right[0]); // Insert partition element + + // Sort the smaller subarray first then the larger + if (right - begin > end - (right + 1)) { + Sort(right + 1, end); + Sort(begin, right); + } else { + Sort(begin, right); + Sort(right + 1, end); + } } - if (do_insertion) InsertionSort(array,keys,0,count); - else QuickSort(array,keys,0,count-1); // quick sort } // ---------------------------------------------------------------------------- @@ -250,18 +188,8 @@ static SortingNodeStruct* Get_Sorting_Struct() // // ---------------------------------------------------------------------------- -static float* vertex_z_array; -static float* polygon_z_array; -static unsigned * node_id_array; -static unsigned * sorted_node_id_array; -static ShortVectorIStruct* polygon_index_array; -static unsigned vertex_z_array_count; -static unsigned polygon_z_array_count; -static unsigned node_id_array_count; -static unsigned sorted_node_id_array_count; -static unsigned polygon_index_array_count; -TempIndexStruct* temp_index_array; -unsigned temp_index_array_count; +static TempIndexStruct* temp_index_array; +static unsigned temp_index_array_count; static TempIndexStruct* Get_Temp_Index_Array(unsigned count) { @@ -275,67 +203,6 @@ static TempIndexStruct* Get_Temp_Index_Array(unsigned count) return temp_index_array; } -static float* Get_Vertex_Z_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_VERTEX_COUNT) - count = DEFAULT_SORTING_VERTEX_COUNT; - if (count>vertex_z_array_count) { - delete[] vertex_z_array; - vertex_z_array=W3DNEWARRAY float[count]; - vertex_z_array_count=count; - } - return vertex_z_array; -} - -static float* Get_Polygon_Z_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_POLY_COUNT) - count = DEFAULT_SORTING_POLY_COUNT; - if (count>polygon_z_array_count) { - delete[] polygon_z_array; - polygon_z_array=W3DNEWARRAY float[count]; - polygon_z_array_count=count; - } - return polygon_z_array; -} - -static unsigned * Get_Node_Id_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_POLY_COUNT) - count = DEFAULT_SORTING_POLY_COUNT; - if (count>node_id_array_count) { - delete[] node_id_array; - node_id_array=W3DNEWARRAY unsigned[count]; - node_id_array_count=count; - } - return node_id_array; -} - -static unsigned * Get_Sorted_Node_Id_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_POLY_COUNT) - count = DEFAULT_SORTING_POLY_COUNT; - if (count>sorted_node_id_array_count) { - delete[] sorted_node_id_array; - sorted_node_id_array=W3DNEWARRAY unsigned[count]; - sorted_node_id_array_count=count; - } - return sorted_node_id_array; -} - -static ShortVectorIStruct* Get_Polygon_Index_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_POLY_COUNT) - count = DEFAULT_SORTING_POLY_COUNT; - if (count>polygon_index_array_count) { - delete[] polygon_index_array; - polygon_index_array=W3DNEWARRAY ShortVectorIStruct[count]; - polygon_index_array_count=count; - } - return polygon_index_array; -} - - // ---------------------------------------------------------------------------- // // Insert triangles to the sorting system. @@ -542,9 +409,7 @@ void SortingRendererClass::Flush_Sorting_Pool() SNAPSHOT_SAY(("SortingSystem - Flush")); // Fill dynamic index buffer with sorting index buffer vertices - unsigned * node_id_array=Get_Node_Id_Array(overlapping_polygon_count); - float* polygon_z_array=Get_Polygon_Z_Array(overlapping_polygon_count); - ShortVectorIStruct* polygon_idx_array=(ShortVectorIStruct*)Get_Polygon_Index_Array(overlapping_polygon_count); + TempIndexStruct* tis=Get_Temp_Index_Array(overlapping_polygon_count); unsigned vertexAllocCount = overlapping_vertex_count; if (DynamicVBAccessClass::Get_Default_Vertex_Count() < DEFAULT_SORTING_VERTEX_COUNT) @@ -555,14 +420,12 @@ void SortingRendererClass::Flush_Sorting_Pool() DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertexAllocCount/*overlapping_vertex_count*/); { DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access); - VertexFormatXYZNDUV2* dest_verts=lock.Get_Formatted_Vertex_Array(); + VertexFormatXYZNDUV2* dest_verts=(VertexFormatXYZNDUV2 *)lock.Get_Formatted_Vertex_Array(); unsigned polygon_array_offset=0; unsigned vertex_array_offset=0; for (unsigned node_id=0;node_idvertex_count); - VertexFormatXYZNDUV2* src_verts=nullptr; SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); WWASSERT(vertex_buffer); @@ -572,14 +435,14 @@ void SortingRendererClass::Flush_Sorting_Pool() src_verts+=state->sorting_state.index_base_offset; src_verts+=state->min_vertex_index; + // If you have a crash in here and "dest_verts" points to illegal memory area, + // it is because D3D is in illegal state, and the only known cure is rebooting. + // This illegal state is usually caused by Quake3-engine powered games such as MOHAA. + memcpy(dest_verts, src_verts, sizeof(VertexFormatXYZNDUV2)*state->vertex_count); + dest_verts += state->vertex_count; + D3DXMATRIX d3d_mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - D3DXMatrixTranspose(&d3d_mtx,&d3d_mtx); const Matrix4x4& mtx=(const Matrix4x4&)d3d_mtx; - unsigned i=0; - for (;ivertex_count;++i,++src_verts) { - vertex_z_array[i] = (mtx[2][0] * src_verts->x + mtx[2][1] * src_verts->y + mtx[2][2] * src_verts->z + mtx[2][3]); - *dest_verts++=*src_verts; - } unsigned short* indices=nullptr; SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); @@ -589,41 +452,61 @@ void SortingRendererClass::Flush_Sorting_Pool() indices+=state->start_index; indices+=state->sorting_state.iba_offset; - for (i=0;ipolygon_count;++i) { - unsigned short idx1=indices[i*3]-state->min_vertex_index; - unsigned short idx2=indices[i*3+1]-state->min_vertex_index; - unsigned short idx3=indices[i*3+2]-state->min_vertex_index; - WWASSERT(idx1vertex_count); - WWASSERT(idx2vertex_count); - WWASSERT(idx3vertex_count); - float z1=vertex_z_array[idx1]; - float z2=vertex_z_array[idx2]; - float z3=vertex_z_array[idx3]; - float z=(z1+z2+z3)/3.0f; - unsigned array_index=i+polygon_array_offset; - WWASSERT(array_indexpolygon_count;++i) { + unsigned short idx1=indices[i*3]-state->min_vertex_index; + unsigned short idx2=indices[i*3+1]-state->min_vertex_index; + unsigned short idx3=indices[i*3+2]-state->min_vertex_index; + WWASSERT(idx1vertex_count); + WWASSERT(idx2vertex_count); + WWASSERT(idx3vertex_count); + const VertexFormatXYZNDUV2 *v1 = src_verts + idx1; + const VertexFormatXYZNDUV2 *v2 = src_verts + idx2; + const VertexFormatXYZNDUV2 *v3 = src_verts + idx3; + unsigned array_index=i+polygon_array_offset; + WWASSERT(array_indextri.i = idx1 + vertex_array_offset; + tis_ptr->tri.j = idx2 + vertex_array_offset; + tis_ptr->tri.k = idx3 + vertex_array_offset; + tis_ptr->idx = node_id; + tis_ptr->z = (v1->z + v2->z + v3->z)/3.0f; + DEBUG_ASSERTCRASH((! _isnan(tis_ptr->z) && _finite(tis_ptr->z)), ("Triangle has invalid center")); + } + } else { + for (int i=0;ipolygon_count;++i) { + unsigned short idx1=indices[i*3]-state->min_vertex_index; + unsigned short idx2=indices[i*3+1]-state->min_vertex_index; + unsigned short idx3=indices[i*3+2]-state->min_vertex_index; + WWASSERT(idx1vertex_count); + WWASSERT(idx2vertex_count); + WWASSERT(idx3vertex_count); + const VertexFormatXYZNDUV2 *v1 = src_verts + idx1; + const VertexFormatXYZNDUV2 *v2 = src_verts + idx2; + const VertexFormatXYZNDUV2 *v3 = src_verts + idx3; + unsigned array_index=i+polygon_array_offset; + WWASSERT(array_indextri.i = idx1 + vertex_array_offset; + tis_ptr->tri.j = idx2 + vertex_array_offset; + tis_ptr->tri.k = idx3 + vertex_array_offset; + tis_ptr->idx = node_id; + tis_ptr->z = (mtx[0][2]*(v1->x + v2->x + v3->x) + + mtx[1][2]*(v1->y + v2->y + v3->y) + + mtx[2][2]*(v1->z + v2->z + v3->z))/3.0f + mtx[3][2]; + DEBUG_ASSERTCRASH((! _isnan(tis_ptr->z) && _finite(tis_ptr->z)), ("Triangle has invalid center")); + } } state->min_vertex_index=vertex_array_offset; polygon_array_offset+=state->polygon_count; vertex_array_offset+=state->vertex_count; - } } - TempIndexStruct* tis=Get_Temp_Index_Array(overlapping_polygon_count); - unsigned a=0; - for (;a(tis,polygon_z_array,overlapping_polygon_count); + Sort(tis, tis + overlapping_polygon_count); /* ///@todo: Add code to break up rendering into multiple index buffer fills to allow more than 65536/3 triangles. -MW int total_overlapping_polygon_count = overlapping_polygon_count; @@ -738,7 +621,10 @@ void SortingRendererClass::Flush() } } + bool old_enable=DX8Wrapper::_Is_Triangle_Draw_Enabled(); + DX8Wrapper::_Enable_Triangle_Draw(_EnableTriangleDraw); Flush_Sorting_Pool(); + DX8Wrapper::_Enable_Triangle_Draw(old_enable); DX8Wrapper::Set_Index_Buffer(nullptr,0); DX8Wrapper::Set_Vertex_Buffer(nullptr); @@ -775,21 +661,6 @@ void SortingRendererClass::Deinit() delete head; } - delete[] vertex_z_array; - vertex_z_array=nullptr; - vertex_z_array_count=0; - delete[] polygon_z_array; - polygon_z_array=nullptr; - polygon_z_array_count=0; - delete[] node_id_array; - node_id_array=nullptr; - node_id_array_count=0; - delete[] sorted_node_id_array; - sorted_node_id_array=nullptr; - sorted_node_id_array_count=0; - delete[] polygon_index_array; - polygon_index_array=nullptr; - polygon_index_array_count=0; delete[] temp_index_array; temp_index_array=nullptr; temp_index_array_count=0; From f898980fedbf1ed6b91b3185afbd83db07e5f9c9 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 6 Jun 2026 19:54:49 +0200 Subject: [PATCH 2/2] unify(ww3d2): Move SortingRenderer to Core (#2772) --- .../Source/WWVegas/WW3D2/CMakeLists.txt | 4 +- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 0 .../Source/WWVegas/WW3D2/sortingrenderer.h | 0 .../Source/WWVegas/WW3D2/CMakeLists.txt | 4 +- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 740 ------------------ .../Source/WWVegas/WW3D2/sortingrenderer.h | 62 -- .../Source/WWVegas/WW3D2/CMakeLists.txt | 4 +- scripts/cpp/unify_move_files.py | 3 + 8 files changed, 9 insertions(+), 808 deletions(-) rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp (100%) rename {GeneralsMD/Code => Core}/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h (100%) delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp delete mode 100644 Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h diff --git a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index 69f7f239492..ecebd564696 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -181,8 +181,8 @@ set(WW3D2_SRC shdlib.h snappts.cpp snapPts.h - #sortingrenderer.cpp - #sortingrenderer.h + sortingrenderer.cpp + sortingrenderer.h soundlibrarybridge.h soundrobj.cpp soundrobj.h diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp similarity index 100% rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp rename to Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h similarity index 100% rename from GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h rename to Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index a63287dcd88..281ee585c85 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -176,8 +176,8 @@ set(WW3D2_SRC #shattersystem.h #snappts.cpp #snapPts.h - sortingrenderer.cpp - sortingrenderer.h +# sortingrenderer.cpp +# sortingrenderer.h #soundlibrarybridge.h #soundrobj.cpp #soundrobj.h diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp deleted file mode 100644 index 48f0840ae92..00000000000 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ /dev/null @@ -1,740 +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/sortingrenderer.cpp $* - * * - * Original Author:: Greg Hjelstrom * - * * - * Author : Kenny Mitchell * - * * - * $Modtime:: 06/27/02 1:27p $* - * * - * $Revision:: 2 $* - * * - * 06/26/02 KM Matrix name change to avoid MAX conflicts * - * 06/27/02 KM Changes to max texture stage caps * - *---------------------------------------------------------------------------------------------* - * Functions: * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -#include "sortingrenderer.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "dx8wrapper.h" -#include "vertmaterial.h" -#include "texture.h" -#include "d3d8.h" -#include "d3dx8math.h" -#include "statistics.h" -#include -#include - - -bool SortingRendererClass::_EnableTriangleDraw=true; -static unsigned DEFAULT_SORTING_POLY_COUNT = 16384; // (count * 3) must be less than 65536 -static unsigned DEFAULT_SORTING_VERTEX_COUNT = 32768; // count must be less than 65536 - -void SortingRendererClass::SetMinVertexBufferSize( unsigned val ) -{ - DEFAULT_SORTING_VERTEX_COUNT = val; - DEFAULT_SORTING_POLY_COUNT = val/2; //typically have 2:1 vertex:triangle ratio. -} - -struct ShortVectorIStruct -{ - unsigned short i; - unsigned short j; - unsigned short k; -}; - -struct TempIndexStruct -{ - ShortVectorIStruct tri; - unsigned short idx; - float z; -}; - -bool operator <(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z < r.z; } -bool operator <=(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z <= r.z; } -bool operator >(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z > r.z; } -bool operator >=(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z >= r.z; } -bool operator ==(const TempIndexStruct &l, const TempIndexStruct &r) { return l.z == r.z; } -// ---------------------------------------------------------------------------- -static -void InsertionSort(TempIndexStruct *begin, TempIndexStruct *end) -{ - for (TempIndexStruct *iter = begin + 1; iter < end; ++iter) { - TempIndexStruct val = iter[0]; - TempIndexStruct *insert = iter; - while (insert != begin && insert[-1] > val) { - insert[0] = insert[-1]; - insert -= 1; - } - insert[0] = val; - } -} - -// ---------------------------------------------------------------------------- -static -void Sort(TempIndexStruct *begin, TempIndexStruct *end) -{ - const int diff = end - begin; - if (diff <= 16) { - // Insertion sort has less overhead for small arrays - InsertionSort(begin, end); - } else { - // Choose the median of begin, mid, and (end - 1) as the partitioning element. - // Rearrange so that *(begin + 1) <= *begin <= *(end - 1). These will be guard - // elements. - TempIndexStruct *mid = begin + diff/2; - std::swap(mid[0], begin[1]); - if (begin[1] > end[-1]) { - std::swap(begin[1], end[-1]); - } - if (begin[0] > end[-1]) { - std::swap(begin[0], end[-1]); - } - if (begin[1] > begin[0]) { - std::swap(begin[1], begin[0]); - } - - // *begin is now the partitioning element - TempIndexStruct *begin1 = begin + 1; // TODO: Temp fix until I find out who is passing me NaN - TempIndexStruct *end1 = end - 1; // TODO: Temp fix until I find out who is passing me NaN - TempIndexStruct *left = begin + 1; - TempIndexStruct *right = end - 1; - for (;;) { -#if 0 // TODO: Temp fix until I find out who is passing me NaN. - do ++left; while (left[0] < begin[0]); // Scan up to find element >= than partition - do --right; while (right[0] > begin[0]); // Scan down to find element <= than partition -#else - do ++left; while (left < end1 && left[0] < begin[0]); // Scan up to find element >= than partition - do --right; while (right > begin1 && right[0] > begin[0]); // Scan down to find element <= than partition -#endif - if (right < left) break; // Pointers crossed. Partitioning completed. - std::swap(left[0], right[0]); // Exchange elements. - } - std::swap(begin[0], right[0]); // Insert partition element - - // Sort the smaller subarray first then the larger - if (right - begin > end - (right + 1)) { - Sort(right + 1, end); - Sort(begin, right); - } else { - Sort(begin, right); - Sort(right + 1, end); - } - } -} - -// ---------------------------------------------------------------------------- - -class SortingNodeStruct : public DLNodeClass -{ - W3DMPO_CODE(SortingNodeStruct) - -public: - RenderStateStruct sorting_state; - - SphereClass bounding_sphere; - - Vector3 transformed_center; - unsigned short start_index; // First index used in the ib - unsigned short polygon_count; // Polygon count to process (3 indices = one polygon) - unsigned short min_vertex_index; // First index used in the vb - unsigned short vertex_count; // Number of vertices used in vb -}; - -static DLListClass sorted_list; -static DLListClass clean_list; -static unsigned total_sorting_vertices; - -static SortingNodeStruct* Get_Sorting_Struct() -{ - - SortingNodeStruct* state=clean_list.Head(); - if (state) { - state->Remove(); - return state; - } - state=W3DNEW SortingNodeStruct(); - return state; -} - -// ---------------------------------------------------------------------------- -// -// Temporary arrays for the sorting system -// -// ---------------------------------------------------------------------------- - -static TempIndexStruct* temp_index_array; -static unsigned temp_index_array_count; - -static TempIndexStruct* Get_Temp_Index_Array(unsigned count) -{ - if (count < DEFAULT_SORTING_POLY_COUNT) - count = DEFAULT_SORTING_POLY_COUNT; - if (count>temp_index_array_count) { - delete[] temp_index_array; - temp_index_array=W3DNEWARRAY TempIndexStruct[count]; - temp_index_array_count=count; - } - return temp_index_array; -} - -// ---------------------------------------------------------------------------- -// -// Insert triangles to the sorting system. -// -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Insert_Triangles( - const SphereClass& bounding_sphere, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - if (!WW3D::Is_Sorting_Enabled()) { - DX8Wrapper::Draw_Triangles(start_index,polygon_count,min_vertex_index,vertex_count); - return; - } - - SNAPSHOT_SAY(("SortingRenderer::Insert(start_i: %d, polygons : %d, min_vi: %d, vertex_count: %d)", - start_index,polygon_count,min_vertex_index,vertex_count)); - - - DX8_RECORD_SORTING_RENDER(polygon_count,vertex_count); - - SortingNodeStruct* state=Get_Sorting_Struct(); - - DX8Wrapper::Get_Render_State(state->sorting_state); - - WWASSERT( - ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_DYNAMIC_SORTING))); - - - state->bounding_sphere=bounding_sphere; - state->start_index=start_index; - state->polygon_count=polygon_count; - state->min_vertex_index=min_vertex_index; - state->vertex_count=vertex_count; - - SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); - WWASSERT(vertex_buffer); - WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); - - D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; - D3DXVECTOR4 transformed_vec; - D3DXVec3Transform( - &transformed_vec, - &vec, - &mtx); - state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); - - - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - SortingNodeStruct* node=sorted_list.Head(); - while (node) { - if (state->transformed_center.Z>node->transformed_center.Z) { - if (sorted_list.Head()==sorted_list.Tail()) - sorted_list.Add_Head(state); - else - state->Insert_Before(node); - break; - } - node=node->Succ(); - } - if (!node) sorted_list.Add_Tail(state); - -#ifdef WWDEBUG - unsigned short* indices=nullptr; - SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); - WWASSERT(index_buffer); - indices=index_buffer->index_buffer; - WWASSERT(indices); - indices+=state->start_index; - indices+=state->sorting_state.iba_offset; - - for (int i=0;ipolygon_count;++i) { - unsigned short idx1=indices[i*3]-state->min_vertex_index; - unsigned short idx2=indices[i*3+1]-state->min_vertex_index; - unsigned short idx3=indices[i*3+2]-state->min_vertex_index; - WWASSERT(idx1vertex_count); - WWASSERT(idx2vertex_count); - WWASSERT(idx3vertex_count); - } -#endif // WWDEBUG -} - -// ---------------------------------------------------------------------------- -// -// Insert triangles to the sorting system, with no bounding information. -// -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Insert_Triangles( - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count) -{ - SphereClass sphere(Vector3(0.0f,0.0f,0.0f),0.0f); - Insert_Triangles(sphere,start_index,polygon_count,min_vertex_index,vertex_count); -} - -// ---------------------------------------------------------------------------- -// -// Flush all sorting polygons. -// -// ---------------------------------------------------------------------------- - -void Release_Refs(SortingNodeStruct* state) -{ - int i; - for (i=0;isorting_state.vertex_buffers[i]); - } - REF_PTR_RELEASE(state->sorting_state.index_buffer); - REF_PTR_RELEASE(state->sorting_state.material); - for (i=0;iGet_Max_Textures_Per_Pass();++i) - { - REF_PTR_RELEASE(state->sorting_state.Textures[i]); - } -} - -static unsigned overlapping_node_count; -static unsigned overlapping_polygon_count; -static unsigned overlapping_vertex_count; -static const unsigned MAX_OVERLAPPING_NODES=4096; -static SortingNodeStruct* overlapping_nodes[MAX_OVERLAPPING_NODES]; - -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Insert_To_Sorting_Pool(SortingNodeStruct* state) -{ - if (overlapping_node_count>=MAX_OVERLAPPING_NODES) { - Release_Refs(state); - delete state; - WWASSERT(0); - return; - } - - overlapping_nodes[overlapping_node_count]=state; - overlapping_vertex_count+=state->vertex_count; - overlapping_polygon_count+=state->polygon_count; - overlapping_node_count++; -} - -// ---------------------------------------------------------------------------- -//static unsigned prevLight = 0xffffffff; - -static void Apply_Render_State(RenderStateStruct& render_state) -{ - DX8Wrapper::Set_Shader(render_state.shader); - - DX8Wrapper::Set_Material(render_state.material); - - for (int i=0;iGet_Max_Textures_Per_Pass();++i) - { - DX8Wrapper::Set_Texture(i,render_state.Textures[i]); - } - - DX8Wrapper::_Set_DX8_Transform(D3DTS_WORLD,render_state.world); - DX8Wrapper::_Set_DX8_Transform(D3DTS_VIEW,render_state.view); - - - if (!render_state.material->Get_Lighting()) - return; //no point changing lights if they are ignored. - //prevLight = render_state.lightsHash; - - if (render_state.LightEnable[0]) { - DX8Wrapper::Set_DX8_Light(0,&render_state.Lights[0]); - if (render_state.LightEnable[1]) { - DX8Wrapper::Set_DX8_Light(1,&render_state.Lights[1]); - if (render_state.LightEnable[2]) { - DX8Wrapper::Set_DX8_Light(2,&render_state.Lights[2]); - if (render_state.LightEnable[3]) { - DX8Wrapper::Set_DX8_Light(3,&render_state.Lights[3]); - } - else { - DX8Wrapper::Set_DX8_Light(3,nullptr); - } - } - else { - DX8Wrapper::Set_DX8_Light(2,nullptr); - } - } - else { - DX8Wrapper::Set_DX8_Light(1,nullptr); - } - } - else { - DX8Wrapper::Set_DX8_Light(0,nullptr); - } - - -} - -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Flush_Sorting_Pool() -{ - if (!overlapping_node_count) return; - - SNAPSHOT_SAY(("SortingSystem - Flush")); - - // Fill dynamic index buffer with sorting index buffer vertices - TempIndexStruct* tis=Get_Temp_Index_Array(overlapping_polygon_count); - - unsigned vertexAllocCount = overlapping_vertex_count; - if (DynamicVBAccessClass::Get_Default_Vertex_Count() < DEFAULT_SORTING_VERTEX_COUNT) - vertexAllocCount = DEFAULT_SORTING_VERTEX_COUNT; //make sure that we force the DX8 dynamic vertex buffer to maximum size - if (overlapping_vertex_count > vertexAllocCount) - vertexAllocCount = overlapping_vertex_count; - WWASSERT(DEFAULT_SORTING_VERTEX_COUNT == 1 || vertexAllocCount <= DEFAULT_SORTING_VERTEX_COUNT); - DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertexAllocCount/*overlapping_vertex_count*/); - { - DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access); - VertexFormatXYZNDUV2* dest_verts=(VertexFormatXYZNDUV2 *)lock.Get_Formatted_Vertex_Array(); - - unsigned polygon_array_offset=0; - unsigned vertex_array_offset=0; - for (unsigned node_id=0;node_id(state->sorting_state.vertex_buffers[0]); - WWASSERT(vertex_buffer); - src_verts=vertex_buffer->VertexBuffer; - WWASSERT(src_verts); - src_verts+=state->sorting_state.vba_offset; - src_verts+=state->sorting_state.index_base_offset; - src_verts+=state->min_vertex_index; - - // If you have a crash in here and "dest_verts" points to illegal memory area, - // it is because D3D is in illegal state, and the only known cure is rebooting. - // This illegal state is usually caused by Quake3-engine powered games such as MOHAA. - memcpy(dest_verts, src_verts, sizeof(VertexFormatXYZNDUV2)*state->vertex_count); - dest_verts += state->vertex_count; - - D3DXMATRIX d3d_mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - const Matrix4x4& mtx=(const Matrix4x4&)d3d_mtx; - - unsigned short* indices=nullptr; - SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); - WWASSERT(index_buffer); - indices=index_buffer->index_buffer; - WWASSERT(indices); - indices+=state->start_index; - indices+=state->sorting_state.iba_offset; - - if (mtx[0][2] == 0.0f && mtx[1][2] == 0.0f && mtx[3][2] == 0.0f && mtx[2][2] == 1.0f) { - // The common case for particle systems. - for (int i=0;ipolygon_count;++i) { - unsigned short idx1=indices[i*3]-state->min_vertex_index; - unsigned short idx2=indices[i*3+1]-state->min_vertex_index; - unsigned short idx3=indices[i*3+2]-state->min_vertex_index; - WWASSERT(idx1vertex_count); - WWASSERT(idx2vertex_count); - WWASSERT(idx3vertex_count); - const VertexFormatXYZNDUV2 *v1 = src_verts + idx1; - const VertexFormatXYZNDUV2 *v2 = src_verts + idx2; - const VertexFormatXYZNDUV2 *v3 = src_verts + idx3; - unsigned array_index=i+polygon_array_offset; - WWASSERT(array_indextri.i = idx1 + vertex_array_offset; - tis_ptr->tri.j = idx2 + vertex_array_offset; - tis_ptr->tri.k = idx3 + vertex_array_offset; - tis_ptr->idx = node_id; - tis_ptr->z = (v1->z + v2->z + v3->z)/3.0f; - DEBUG_ASSERTCRASH((! _isnan(tis_ptr->z) && _finite(tis_ptr->z)), ("Triangle has invalid center")); - } - } else { - for (int i=0;ipolygon_count;++i) { - unsigned short idx1=indices[i*3]-state->min_vertex_index; - unsigned short idx2=indices[i*3+1]-state->min_vertex_index; - unsigned short idx3=indices[i*3+2]-state->min_vertex_index; - WWASSERT(idx1vertex_count); - WWASSERT(idx2vertex_count); - WWASSERT(idx3vertex_count); - const VertexFormatXYZNDUV2 *v1 = src_verts + idx1; - const VertexFormatXYZNDUV2 *v2 = src_verts + idx2; - const VertexFormatXYZNDUV2 *v3 = src_verts + idx3; - unsigned array_index=i+polygon_array_offset; - WWASSERT(array_indextri.i = idx1 + vertex_array_offset; - tis_ptr->tri.j = idx2 + vertex_array_offset; - tis_ptr->tri.k = idx3 + vertex_array_offset; - tis_ptr->idx = node_id; - tis_ptr->z = (mtx[0][2]*(v1->x + v2->x + v3->x) + - mtx[1][2]*(v1->y + v2->y + v3->y) + - mtx[2][2]*(v1->z + v2->z + v3->z))/3.0f + mtx[3][2]; - DEBUG_ASSERTCRASH((! _isnan(tis_ptr->z) && _finite(tis_ptr->z)), ("Triangle has invalid center")); - } - } - - state->min_vertex_index=vertex_array_offset; - - polygon_array_offset+=state->polygon_count; - vertex_array_offset+=state->vertex_count; - } - } - - Sort(tis, tis + overlapping_polygon_count); - -/* ///@todo: Add code to break up rendering into multiple index buffer fills to allow more than 65536/3 triangles. -MW - int total_overlapping_polygon_count = overlapping_polygon_count; - while ( > 0) - { - if ((total_overlapping_polygon_count*3) > 65535) - { //overflowed the index buffer, must break into multiple batches - overlapping_polygon_count = 65535/3; - } - else - overlapping_polygon_count = total_overlapping_polygon_count; - - //insert rendering code here!! - - total_overlapping_polygon_count -= overlapping_polygon_count; - } -*/ - unsigned polygonAllocCount = overlapping_polygon_count; - if ((unsigned)(DynamicIBAccessClass::Get_Default_Index_Count()/3) < DEFAULT_SORTING_POLY_COUNT) - polygonAllocCount = DEFAULT_SORTING_POLY_COUNT; //make sure that we force the DX8 index buffer to maximum size - if (overlapping_polygon_count > polygonAllocCount) - polygonAllocCount = overlapping_polygon_count; - WWASSERT(DEFAULT_SORTING_POLY_COUNT <= 1 || polygonAllocCount <= DEFAULT_SORTING_POLY_COUNT); - - DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,polygonAllocCount*3); - { - DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access); - ShortVectorIStruct* sorted_polygon_index_array=(ShortVectorIStruct*)lock.Get_Index_Array(); - - for (unsigned a=0;asorting_state); - - DX8Wrapper::Draw_Triangles( - start_index*3, - count_to_render, - state->min_vertex_index, - state->vertex_count); - - count_to_render=0; - start_index=i; - node_id=tis[i].idx; - } - count_to_render++; //keep track of number of polygons of same kind - } - - // Render any remaining polygons... - if (count_to_render) { - SortingNodeStruct* state=overlapping_nodes[node_id]; - Apply_Render_State(state->sorting_state); - - DX8Wrapper::Draw_Triangles( - start_index*3, - count_to_render, - state->min_vertex_index, - state->vertex_count); - } - - // Release all references and return nodes back to the clean list for the frame... - for (node_id=0;node_idRemove(); - - if ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_DYNAMIC_SORTING)) { - Insert_To_Sorting_Pool(state); - } - else { - DX8Wrapper::Set_Render_State(state->sorting_state); - DX8Wrapper::Draw_Triangles(state->start_index,state->polygon_count,state->min_vertex_index,state->vertex_count); - DX8Wrapper::Release_Render_State(); - Release_Refs(state); - clean_list.Add_Head(state); - } - } - - bool old_enable=DX8Wrapper::_Is_Triangle_Draw_Enabled(); - DX8Wrapper::_Enable_Triangle_Draw(_EnableTriangleDraw); - Flush_Sorting_Pool(); - DX8Wrapper::_Enable_Triangle_Draw(old_enable); - - DX8Wrapper::Set_Index_Buffer(nullptr,0); - DX8Wrapper::Set_Vertex_Buffer(nullptr); - total_sorting_vertices=0; - - DynamicIBAccessClass::_Reset(false); - DynamicVBAccessClass::_Reset(false); - - - DX8Wrapper::Set_Transform(D3DTS_VIEW,old_view); - DX8Wrapper::Set_Transform(D3DTS_WORLD,old_world); - -} - -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Deinit() -{ - SortingNodeStruct *head = nullptr; - - // - // Flush the sorted list - // - while ((head = sorted_list.Head ()) != nullptr) { - sorted_list.Remove_Head (); - delete head; - } - - // - // Flush the clean list - // - while ((head = clean_list.Head ()) != nullptr) { - clean_list.Remove_Head (); - delete head; - } - - delete[] temp_index_array; - temp_index_array=nullptr; - temp_index_array_count=0; -} - - -// ---------------------------------------------------------------------------- -// -// Insert a VolumeParticle triangle into the sorting system. -// -// ---------------------------------------------------------------------------- - -void SortingRendererClass::Insert_VolumeParticle( - const SphereClass& bounding_sphere, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count, - unsigned short layerCount) -{ - if (!WW3D::Is_Sorting_Enabled()) { - DX8Wrapper::Draw_Triangles(start_index,polygon_count,min_vertex_index,vertex_count); - return; - } - - //FOR VOLUME_PARTICLE LOGIC: - // WE MUST MULTIPLY THE VERTCOUNT AND POLYCOUNT BY THE VOLUME_PARTICLE DEPTH - DX8_RECORD_SORTING_RENDER( polygon_count * layerCount,vertex_count * layerCount);//THIS IS VOLUME_PARTICLE SPECIFIC - - SortingNodeStruct* state=Get_Sorting_Struct(); - DX8Wrapper::Get_Render_State(state->sorting_state); - - WWASSERT( - ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && - (state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_DYNAMIC_SORTING))); - - state->bounding_sphere=bounding_sphere; - state->start_index=start_index; - state->min_vertex_index=min_vertex_index; - state->polygon_count=polygon_count * layerCount;//THIS IS VOLUME_PARTICLE SPECIFIC - state->vertex_count=vertex_count * layerCount;//THIS IS VOLUME_PARTICLE SPECIFIC - - SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); - WWASSERT(vertex_buffer); - WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); - - // Transform the center point to view space for sorting - - D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; - D3DXVECTOR4 transformed_vec; - D3DXVec3Transform( - &transformed_vec, - &vec, - &mtx); - state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); - - - // BUT WHAT IS THE DEAL WITH THE VERTCOUNT AND POLYCOUNT BEING N BUT TRANSFORMED CENTER COUNT == 1 - - //THE TRANSFORMED CENTER[2] IS THE ZBUFFER DEPTH - - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - SortingNodeStruct* node=sorted_list.Head(); - while (node) { - if (state->transformed_center.Z>node->transformed_center.Z) { - if (sorted_list.Head()==sorted_list.Tail()) - sorted_list.Add_Head(state); - else - state->Insert_Before(node); - break; - } - node=node->Succ(); - } - if (!node) sorted_list.Add_Tail(state); -} diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h deleted file mode 100644 index fec9b565c5b..00000000000 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h +++ /dev/null @@ -1,62 +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 . -*/ - -#pragma once - -#include "always.h" - -class SortingNodeStruct; -class SphereClass; - -class SortingRendererClass -{ - static bool _EnableTriangleDraw; - - static void Flush_Sorting_Pool(); - static void Insert_To_Sorting_Pool(SortingNodeStruct* state); - -public: - static void Insert_Triangles( - const SphereClass& bounding_sphere, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - - static void Insert_Triangles( - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count); - - static void Insert_VolumeParticle( - const SphereClass& bounding_sphere, - unsigned short start_index, - unsigned short polygon_count, - unsigned short min_vertex_index, - unsigned short vertex_count, - unsigned short layerCount); - - static void Flush(); - static void Deinit(); - - static void SetMinVertexBufferSize( unsigned val ); - - static void _Enable_Triangle_Draw(bool enable) { _EnableTriangleDraw=enable; } - static bool _Is_Triangle_Draw_Enabled() { return _EnableTriangleDraw; } -}; diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt index cd6a3a731c1..007136ff040 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt @@ -181,8 +181,8 @@ set(WW3D2_SRC # shdlib.h #snappts.cpp #snapPts.h - sortingrenderer.cpp - sortingrenderer.h +# sortingrenderer.cpp +# sortingrenderer.h #soundlibrarybridge.h #soundrobj.cpp #soundrobj.h diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 936b08844e6..fd18e55be3d 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -545,6 +545,9 @@ def main(): #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") + + #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/sortingrenderer.h", Game.CORE, "Libraries/Source/WWVegas/WW3D2/sortingrenderer.h") + #unify_file_lib(Game.ZEROHOUR, "Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp", Game.CORE, "Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp") return