sortingrenderer.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "sortingrenderer.h"
  19. #include "dx8vertexbuffer.h"
  20. #include "dx8indexbuffer.h"
  21. #include "dx8wrapper.h"
  22. #include "vertmaterial.h"
  23. #include "texture.h"
  24. #include "d3d8.h"
  25. #include "D3dx8math.h"
  26. #include "statistics.h"
  27. #include <wwprofile.h>
  28. bool SortingRendererClass::_EnableTriangleDraw=true;
  29. struct ShortVectorIStruct
  30. {
  31. unsigned short i;
  32. unsigned short j;
  33. unsigned short k;
  34. ShortVectorIStruct(unsigned short i_,unsigned short j_,unsigned short k_) : i(i_),j(j_),k(k_) {}
  35. ShortVectorIStruct() {}
  36. };
  37. struct TempIndexStruct
  38. {
  39. ShortVectorIStruct tri;
  40. unsigned short idx;
  41. TempIndexStruct() {}
  42. TempIndexStruct(const ShortVectorIStruct& tri_, unsigned short idx_)
  43. :
  44. tri(tri_),
  45. idx(idx_)
  46. {
  47. }
  48. };
  49. // ----------------------------------------------------------------------------
  50. //
  51. // InsertionSort (T* array, K *keys, int l, int r)
  52. // Performs insertion sort on array 'array' elements [l-r]. Uses values from array
  53. // 'keys' as sort keys.
  54. //
  55. // ----------------------------------------------------------------------------
  56. template <class T, class K>
  57. void InsertionSort (
  58. T* array, // array to sort
  59. K* keys, // sort keys
  60. int l, // first item
  61. int r) // last item
  62. {
  63. for (int i = l+1; i < r; i++) {
  64. K v=keys[i];
  65. T tv=array[i];
  66. int j=i;
  67. while (keys[j-1] > v) {
  68. keys[j]=keys[j-1];
  69. array[j]=array[j-1];
  70. j--;
  71. if (j == l) break;
  72. };
  73. keys[j]=v;
  74. array[j]=tv;
  75. }
  76. }
  77. // ----------------------------------------------------------------------------
  78. //
  79. // QuickSort (T* array, K* a, int l, int r)
  80. //
  81. // Performs quicksort on array 'array'. Uses values from array 'keys' as sort keys.
  82. //
  83. // Once the length of the array to be sorted is less than 8, the routine calls
  84. // InsertionSort() to perform the actual sorting work.
  85. //
  86. // ----------------------------------------------------------------------------
  87. template <class T, class K>
  88. void QuickSort (
  89. T* array, // array to sort
  90. K* keys, // sort keys
  91. int l, // first element
  92. int r) // last element
  93. {
  94. if (r-l <= 8) {
  95. InsertionSort(array,keys,l,r+1);
  96. return;
  97. }
  98. K t;
  99. K v=keys[r];
  100. T ttemp;
  101. int i=l-1;
  102. int j=r;
  103. do {
  104. do { i++; } while (i<r && keys[i]<v);
  105. do { j--; } while (j>0 && keys[j]>v);
  106. WWASSERT(j>=0);
  107. WWASSERT(i<=r);
  108. ttemp=array[i]; array[i]=array[j]; array[j]=ttemp;
  109. t=keys[i]; keys[i]=keys[j]; keys[j]=t;
  110. } while (j>i);
  111. array[j]=array[i];
  112. array[i]=array[r];
  113. array[r]=ttemp;
  114. keys[j]=keys[i];
  115. keys[i]=keys[r];
  116. keys[r]=t;
  117. if (i-1>l) QuickSort(array,keys,l,i-1);
  118. if (r>i+1) QuickSort(array,keys,i+1,r);
  119. }
  120. // ----------------------------------------------------------------------------
  121. //
  122. // Sorts and array. Uses values from array 'keys' as sort keys.
  123. //
  124. // ----------------------------------------------------------------------------
  125. template <class T, class K>
  126. void Sort (
  127. T* array, // array to sort
  128. K *keys, // sort keys
  129. int count) // array element count
  130. {
  131. bool do_insertion = false;
  132. if (count<=1) return; // only one element.. return..
  133. int c=0; // count number of rise pairs
  134. int i;
  135. for (i = 1; i < count; i++)
  136. if (keys[i] >= keys[i-1]) c++;
  137. if (c+1 == count) return; // array already sorted
  138. if (c<50) do_insertion=true; // array smaller than 50 should use insertion sort
  139. if (c<count/3) { // if array is not rising
  140. T tmp;
  141. K tval;
  142. for (i=0;i<count/2;i++) {
  143. int neg = count-1-i;
  144. tmp=array[i]; array[i]=array[neg]; array[neg]=tmp;
  145. tval=keys[i]; keys[i] = keys[neg]; keys[neg]=tval;
  146. }
  147. if (!c) return;
  148. do_insertion = true;
  149. }
  150. if (do_insertion) InsertionSort(array,keys,0,count);
  151. else QuickSort(array,keys,0,count-1); // quick sort
  152. }
  153. // ----------------------------------------------------------------------------
  154. struct SortingNodeStruct : DLNodeClass<SortingNodeStruct>
  155. {
  156. RenderStateStruct sorting_state;
  157. SphereClass bounding_sphere;
  158. Vector3 transformed_center;
  159. unsigned short start_index; // First index used in the ib
  160. unsigned short polygon_count; // Polygon count to process (3 indices = one polygon)
  161. unsigned short min_vertex_index; // First index used in the vb
  162. unsigned short vertex_count; // Number of vertices used in vb
  163. };
  164. static DLListClass<SortingNodeStruct> sorted_list;
  165. static DLListClass<SortingNodeStruct> clean_list;
  166. static unsigned total_sorting_vertices;
  167. static SortingNodeStruct* Get_Sorting_Struct()
  168. {
  169. SortingNodeStruct* state=clean_list.Head();
  170. if (state) {
  171. state->Remove();
  172. return state;
  173. }
  174. state=new SortingNodeStruct();
  175. return state;
  176. }
  177. // ----------------------------------------------------------------------------
  178. //
  179. // Temporary arrays for the sorting system
  180. //
  181. // ----------------------------------------------------------------------------
  182. static float* vertex_z_array;
  183. static float* polygon_z_array;
  184. static unsigned * node_id_array;
  185. static unsigned * sorted_node_id_array;
  186. static ShortVectorIStruct* polygon_index_array;
  187. static unsigned vertex_z_array_count;
  188. static unsigned polygon_z_array_count;
  189. static unsigned node_id_array_count;
  190. static unsigned sorted_node_id_array_count;
  191. static unsigned polygon_index_array_count;
  192. TempIndexStruct* temp_index_array;
  193. unsigned temp_index_array_count;
  194. static TempIndexStruct* Get_Temp_Index_Array(unsigned count)
  195. {
  196. if (count>temp_index_array_count) {
  197. delete[] temp_index_array;
  198. temp_index_array=new TempIndexStruct[count];
  199. temp_index_array_count=count;
  200. }
  201. return temp_index_array;
  202. }
  203. static float* Get_Vertex_Z_Array(unsigned count)
  204. {
  205. if (count>vertex_z_array_count) {
  206. delete[] vertex_z_array;
  207. vertex_z_array=new float[count];
  208. vertex_z_array_count=count;
  209. }
  210. return vertex_z_array;
  211. }
  212. static float* Get_Polygon_Z_Array(unsigned count)
  213. {
  214. if (count>polygon_z_array_count) {
  215. delete[] polygon_z_array;
  216. polygon_z_array=new float[count];
  217. polygon_z_array_count=count;
  218. }
  219. return polygon_z_array;
  220. }
  221. static unsigned * Get_Node_Id_Array(unsigned count)
  222. {
  223. if (count>node_id_array_count) {
  224. delete[] node_id_array;
  225. node_id_array=new unsigned[count];
  226. node_id_array_count=count;
  227. }
  228. return node_id_array;
  229. }
  230. static unsigned * Get_Sorted_Node_Id_Array(unsigned count)
  231. {
  232. if (count>sorted_node_id_array_count) {
  233. delete[] sorted_node_id_array;
  234. sorted_node_id_array=new unsigned[count];
  235. sorted_node_id_array_count=count;
  236. }
  237. return sorted_node_id_array;
  238. }
  239. static ShortVectorIStruct* Get_Polygon_Index_Array(unsigned count)
  240. {
  241. if (count>polygon_index_array_count) {
  242. delete[] polygon_index_array;
  243. polygon_index_array=new ShortVectorIStruct[count];
  244. polygon_index_array_count=count;
  245. }
  246. return polygon_index_array;
  247. }
  248. // ----------------------------------------------------------------------------
  249. //
  250. // Insert triangles to the sorting system.
  251. //
  252. // ----------------------------------------------------------------------------
  253. void SortingRendererClass::Insert_Triangles(
  254. const SphereClass& bounding_sphere,
  255. unsigned short start_index,
  256. unsigned short polygon_count,
  257. unsigned short min_vertex_index,
  258. unsigned short vertex_count)
  259. {
  260. if (!WW3D::Is_Sorting_Enabled()) {
  261. DX8Wrapper::Draw_Triangles(start_index,polygon_count,min_vertex_index,vertex_count);
  262. return;
  263. }
  264. DX8_RECORD_SORTING_RENDER(polygon_count,vertex_count);
  265. SortingNodeStruct* state=Get_Sorting_Struct();
  266. DX8Wrapper::Get_Render_State(state->sorting_state);
  267. WWASSERT(
  268. ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) &&
  269. (state->sorting_state.vertex_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING)));
  270. state->bounding_sphere=bounding_sphere;
  271. state->start_index=start_index;
  272. state->polygon_count=polygon_count;
  273. state->min_vertex_index=min_vertex_index;
  274. state->vertex_count=vertex_count;
  275. SortingVertexBufferClass* vertex_buffer=static_cast<SortingVertexBufferClass*>(state->sorting_state.vertex_buffer);
  276. WWASSERT(vertex_buffer);
  277. WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count());
  278. // Transform the center point to view space for sorting
  279. D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view;
  280. D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center;
  281. D3DXVECTOR4 transformed_vec;
  282. D3DXVec3Transform(
  283. &transformed_vec,
  284. &vec,
  285. &mtx);
  286. state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]);
  287. SortingNodeStruct* node=sorted_list.Head();
  288. while (node) {
  289. if (state->transformed_center.Z>node->transformed_center.Z) {
  290. if (sorted_list.Head()==sorted_list.Tail())
  291. sorted_list.Add_Head(state);
  292. else
  293. state->Insert_Before(node);
  294. break;
  295. }
  296. node=node->Succ();
  297. }
  298. if (!node) sorted_list.Add_Tail(state);
  299. #ifdef WWDEBUG
  300. unsigned short* indices=NULL;
  301. SortingIndexBufferClass* index_buffer=static_cast<SortingIndexBufferClass*>(state->sorting_state.index_buffer);
  302. WWASSERT(index_buffer);
  303. indices=index_buffer->index_buffer;
  304. WWASSERT(indices);
  305. indices+=state->start_index;
  306. indices+=state->sorting_state.iba_offset;
  307. for (int i=0;i<state->polygon_count;++i) {
  308. unsigned short idx1=indices[i*3]-state->min_vertex_index;
  309. unsigned short idx2=indices[i*3+1]-state->min_vertex_index;
  310. unsigned short idx3=indices[i*3+2]-state->min_vertex_index;
  311. WWASSERT(idx1<state->vertex_count);
  312. WWASSERT(idx2<state->vertex_count);
  313. WWASSERT(idx3<state->vertex_count);
  314. }
  315. #endif
  316. }
  317. // ----------------------------------------------------------------------------
  318. //
  319. // Insert triangles to the sorting system, with no bounding information.
  320. //
  321. // ----------------------------------------------------------------------------
  322. void SortingRendererClass::Insert_Triangles(
  323. unsigned short start_index,
  324. unsigned short polygon_count,
  325. unsigned short min_vertex_index,
  326. unsigned short vertex_count)
  327. {
  328. SphereClass sphere(Vector3(0.0f,0.0f,0.0f),0.0f);
  329. Insert_Triangles(sphere,start_index,polygon_count,min_vertex_index,vertex_count);
  330. }
  331. // ----------------------------------------------------------------------------
  332. //
  333. // Flush all sorting polygons.
  334. //
  335. // ----------------------------------------------------------------------------
  336. void Release_Refs(SortingNodeStruct* state)
  337. {
  338. REF_PTR_RELEASE(state->sorting_state.vertex_buffer);
  339. REF_PTR_RELEASE(state->sorting_state.index_buffer);
  340. REF_PTR_RELEASE(state->sorting_state.material);
  341. for (unsigned i=0;i<MAX_TEXTURE_STAGES;++i) {
  342. REF_PTR_RELEASE(state->sorting_state.Textures[i]);
  343. }
  344. }
  345. static unsigned overlapping_node_count;
  346. static unsigned overlapping_polygon_count;
  347. static unsigned overlapping_vertex_count;
  348. const unsigned MAX_OVERLAPPING_NODES=4096;
  349. static SortingNodeStruct* overlapping_nodes[MAX_OVERLAPPING_NODES];
  350. // ----------------------------------------------------------------------------
  351. void SortingRendererClass::Insert_To_Sorting_Pool(SortingNodeStruct* state)
  352. {
  353. if (overlapping_node_count>=MAX_OVERLAPPING_NODES) {
  354. Release_Refs(state);
  355. WWASSERT(0);
  356. return;
  357. }
  358. overlapping_nodes[overlapping_node_count]=state;
  359. overlapping_vertex_count+=state->vertex_count;
  360. overlapping_polygon_count+=state->polygon_count;
  361. overlapping_node_count++;
  362. }
  363. // ----------------------------------------------------------------------------
  364. static void Apply_Render_State(RenderStateStruct& render_state)
  365. {
  366. /* state->sorting_state.shader.Apply();
  367. */
  368. DX8Wrapper::Set_Shader(render_state.shader);
  369. /* if (render_state.material) render_state.material->Apply();
  370. */
  371. DX8Wrapper::Set_Material(render_state.material);
  372. /* if (render_state.Textures[2]) render_state.Textures[2]->Apply();
  373. if (render_state.Textures[3]) render_state.Textures[3]->Apply();
  374. if (render_state.Textures[4]) render_state.Textures[4]->Apply();
  375. if (render_state.Textures[5]) render_state.Textures[5]->Apply();
  376. if (render_state.Textures[6]) render_state.Textures[6]->Apply();
  377. if (render_state.Textures[7]) render_state.Textures[7]->Apply();
  378. */
  379. for (unsigned i=0;i<MAX_TEXTURE_STAGES;++i) {
  380. DX8Wrapper::Set_Texture(i,render_state.Textures[i]);
  381. }
  382. if (render_state.LightEnable[0]) {
  383. DX8Wrapper::Set_DX8_Light(0,&render_state.Lights[0]);
  384. if (render_state.LightEnable[1]) {
  385. DX8Wrapper::Set_DX8_Light(1,&render_state.Lights[1]);
  386. if (render_state.LightEnable[2]) {
  387. DX8Wrapper::Set_DX8_Light(2,&render_state.Lights[2]);
  388. if (render_state.LightEnable[3]) {
  389. DX8Wrapper::Set_DX8_Light(3,&render_state.Lights[3]);
  390. }
  391. else {
  392. DX8Wrapper::Set_DX8_Light(3,NULL);
  393. }
  394. }
  395. else {
  396. DX8Wrapper::Set_DX8_Light(2,NULL);
  397. }
  398. }
  399. else {
  400. DX8Wrapper::Set_DX8_Light(1,NULL);
  401. }
  402. }
  403. else {
  404. DX8Wrapper::Set_DX8_Light(0,NULL);
  405. }
  406. // Matrix4 mtx;
  407. // mtx=render_state.world.Transpose();
  408. // DX8Wrapper::Set_Transform(D3DTS_WORLD,mtx);
  409. // mtx=render_state.view.Transpose();
  410. // DX8Wrapper::Set_Transform(D3DTS_VIEW,mtx);
  411. DX8Wrapper::_Set_DX8_Transform(D3DTS_WORLD,render_state.world);
  412. DX8Wrapper::_Set_DX8_Transform(D3DTS_VIEW,render_state.view);
  413. }
  414. // ----------------------------------------------------------------------------
  415. void SortingRendererClass::Flush_Sorting_Pool()
  416. {
  417. if (!overlapping_node_count) return;
  418. SNAPSHOT_SAY(("SortingSystem - Flush \n"));
  419. unsigned node_id;
  420. // Fill dynamic index buffer with sorting index buffer vertices
  421. unsigned * node_id_array=Get_Node_Id_Array(overlapping_polygon_count);
  422. float* polygon_z_array=Get_Polygon_Z_Array(overlapping_polygon_count);
  423. ShortVectorIStruct* polygon_idx_array=(ShortVectorIStruct*)Get_Polygon_Index_Array(overlapping_polygon_count);
  424. DynamicVBAccessClass dyn_vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,overlapping_vertex_count);
  425. {
  426. DynamicVBAccessClass::WriteLockClass lock(&dyn_vb_access);
  427. VertexFormatXYZNDUV2* dest_verts=lock.Get_Formatted_Vertex_Array();
  428. unsigned polygon_array_offset=0;
  429. unsigned vertex_array_offset=0;
  430. for (node_id=0;node_id<overlapping_node_count;++node_id) {
  431. SortingNodeStruct* state=overlapping_nodes[node_id];
  432. float* vertex_z_array=Get_Vertex_Z_Array(state->vertex_count);
  433. VertexFormatXYZNDUV2* src_verts=NULL;
  434. SortingVertexBufferClass* vertex_buffer=static_cast<SortingVertexBufferClass*>(state->sorting_state.vertex_buffer);
  435. WWASSERT(vertex_buffer);
  436. src_verts=vertex_buffer->VertexBuffer;
  437. WWASSERT(src_verts);
  438. src_verts+=state->sorting_state.vba_offset;
  439. src_verts+=state->sorting_state.index_base_offset;
  440. src_verts+=state->min_vertex_index;
  441. D3DXMATRIX d3d_mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view;
  442. D3DXMatrixTranspose(&d3d_mtx,&d3d_mtx);
  443. const Matrix4& mtx=(const Matrix4&)d3d_mtx;
  444. for (unsigned i=0;i<state->vertex_count;++i,++src_verts) {
  445. 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]);
  446. //
  447. // If you have a crash in here and "dest_verts" points to illegal memory area,
  448. // it is because D3D is in illegal state, and the only known cure is rebooting.
  449. // This illegal state is usually caused by Quake3-engine powered games such as MOHAA.
  450. *dest_verts++=*src_verts;
  451. }
  452. unsigned short* indices=NULL;
  453. SortingIndexBufferClass* index_buffer=static_cast<SortingIndexBufferClass*>(state->sorting_state.index_buffer);
  454. WWASSERT(index_buffer);
  455. indices=index_buffer->index_buffer;
  456. WWASSERT(indices);
  457. indices+=state->start_index;
  458. indices+=state->sorting_state.iba_offset;
  459. for (i=0;i<state->polygon_count;++i) {
  460. unsigned short idx1=indices[i*3]-state->min_vertex_index;
  461. unsigned short idx2=indices[i*3+1]-state->min_vertex_index;
  462. unsigned short idx3=indices[i*3+2]-state->min_vertex_index;
  463. WWASSERT(idx1<state->vertex_count);
  464. WWASSERT(idx2<state->vertex_count);
  465. WWASSERT(idx3<state->vertex_count);
  466. float z1=vertex_z_array[idx1];
  467. float z2=vertex_z_array[idx2];
  468. float z3=vertex_z_array[idx3];
  469. float z=(z1+z2+z3)/3.0f;
  470. unsigned array_index=i+polygon_array_offset;
  471. WWASSERT(array_index<overlapping_polygon_count);
  472. polygon_z_array[array_index]=z;
  473. node_id_array[array_index]=node_id;
  474. polygon_idx_array[array_index]=ShortVectorIStruct(
  475. idx1+vertex_array_offset,
  476. idx2+vertex_array_offset,
  477. idx3+vertex_array_offset);
  478. }
  479. state->min_vertex_index=vertex_array_offset;
  480. polygon_array_offset+=state->polygon_count;
  481. vertex_array_offset+=state->vertex_count;
  482. }
  483. }
  484. TempIndexStruct* tis=Get_Temp_Index_Array(overlapping_polygon_count);
  485. for (unsigned a=0;a<overlapping_polygon_count;++a) {
  486. tis[a]=TempIndexStruct(polygon_idx_array[a],node_id_array[a]);
  487. }
  488. Sort<TempIndexStruct,float>(tis,polygon_z_array,overlapping_polygon_count);
  489. DynamicIBAccessClass dyn_ib_access(BUFFER_TYPE_DYNAMIC_DX8,overlapping_polygon_count*3);
  490. {
  491. DynamicIBAccessClass::WriteLockClass lock(&dyn_ib_access);
  492. ShortVectorIStruct* sorted_polygon_index_array=(ShortVectorIStruct*)lock.Get_Index_Array();
  493. for (a=0;a<overlapping_polygon_count;++a) {
  494. sorted_polygon_index_array[a]=tis[a].tri;
  495. }
  496. }
  497. // Set index buffer and render!
  498. DX8Wrapper::Set_Index_Buffer(dyn_ib_access,0); // Override with this buffer (do something to prevent need for this!)
  499. DX8Wrapper::Set_Vertex_Buffer(dyn_vb_access); // Override with this buffer (do something to prevent need for this!)
  500. DX8Wrapper::Apply_Render_State_Changes();
  501. bool enable_triangle_draw=DX8Wrapper::_Is_Triangle_Draw_Enabled();
  502. DX8Wrapper::_Enable_Triangle_Draw(_Is_Triangle_Draw_Enabled());
  503. unsigned count_to_render=1;
  504. unsigned start_index=0;
  505. node_id=tis[0].idx;
  506. for (unsigned i=1;i<overlapping_polygon_count;++i) {
  507. if (node_id!=tis[i].idx) {
  508. SortingNodeStruct* state=overlapping_nodes[node_id];
  509. Apply_Render_State(state->sorting_state);
  510. DX8Wrapper::Draw_Triangles(
  511. start_index*3,
  512. count_to_render,
  513. state->min_vertex_index,
  514. state->vertex_count);
  515. count_to_render=0;
  516. start_index=i;
  517. node_id=tis[i].idx;
  518. }
  519. count_to_render++;
  520. }
  521. // Render any remaining polygons...
  522. if (count_to_render) {
  523. SortingNodeStruct* state=overlapping_nodes[node_id];
  524. Apply_Render_State(state->sorting_state);
  525. DX8Wrapper::Draw_Triangles(
  526. start_index*3,
  527. count_to_render,
  528. state->min_vertex_index,
  529. state->vertex_count);
  530. }
  531. // Release all references and return nodes back to the clean list for the frame...
  532. for (node_id=0;node_id<overlapping_node_count;++node_id) {
  533. SortingNodeStruct* state=overlapping_nodes[node_id];
  534. Release_Refs(state);
  535. clean_list.Add_Head(state);
  536. }
  537. overlapping_node_count=0;
  538. overlapping_polygon_count=0;
  539. overlapping_vertex_count=0;
  540. DX8Wrapper::_Enable_Triangle_Draw(enable_triangle_draw);
  541. SNAPSHOT_SAY(("SortingSystem - Done flushing\n"));
  542. }
  543. // ----------------------------------------------------------------------------
  544. void SortingRendererClass::Flush()
  545. {
  546. WWPROFILE("SortingRenderer::Flush");
  547. Matrix4 old_view;
  548. Matrix4 old_world;
  549. DX8Wrapper::Get_Transform(D3DTS_VIEW,old_view);
  550. DX8Wrapper::Get_Transform(D3DTS_WORLD,old_world);
  551. while (SortingNodeStruct* state=sorted_list.Head()) {
  552. state->Remove();
  553. if ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) &&
  554. (state->sorting_state.vertex_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING)) {
  555. Insert_To_Sorting_Pool(state);
  556. }
  557. else {
  558. DX8Wrapper::Set_Render_State(state->sorting_state);
  559. DX8Wrapper::Draw_Triangles(state->start_index,state->polygon_count,state->min_vertex_index,state->vertex_count);
  560. DX8Wrapper::Release_Render_State();
  561. Release_Refs(state);
  562. clean_list.Add_Head(state);
  563. }
  564. }
  565. Flush_Sorting_Pool();
  566. DX8Wrapper::Set_Index_Buffer(0,0);
  567. DX8Wrapper::Set_Vertex_Buffer(0);
  568. total_sorting_vertices=0;
  569. DynamicIBAccessClass::_Reset(false);
  570. DynamicVBAccessClass::_Reset(false);
  571. DX8Wrapper::Set_Transform(D3DTS_VIEW,old_view);
  572. DX8Wrapper::Set_Transform(D3DTS_WORLD,old_world);
  573. }
  574. // ----------------------------------------------------------------------------
  575. void SortingRendererClass::Deinit()
  576. {
  577. SortingNodeStruct *head = NULL;
  578. //
  579. // Flush the sorted list
  580. //
  581. while ((head = sorted_list.Head ()) != NULL) {
  582. sorted_list.Remove_Head ();
  583. delete head;
  584. }
  585. //
  586. // Flush the clean list
  587. //
  588. while ((head = clean_list.Head ()) != NULL) {
  589. clean_list.Remove_Head ();
  590. delete head;
  591. }
  592. delete[] vertex_z_array;
  593. vertex_z_array=NULL;
  594. vertex_z_array_count=0;
  595. delete[] polygon_z_array;
  596. polygon_z_array=NULL;
  597. polygon_z_array_count=0;
  598. delete[] node_id_array;
  599. node_id_array=NULL;
  600. node_id_array_count=0;
  601. delete[] sorted_node_id_array;
  602. sorted_node_id_array=NULL;
  603. sorted_node_id_array_count=0;
  604. delete[] polygon_index_array;
  605. polygon_index_array=NULL;
  606. polygon_index_array_count=0;
  607. delete[] temp_index_array;
  608. temp_index_array=NULL;
  609. temp_index_array_count=0;
  610. }