W3DBibBuffer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DBibBuffer.cpp ////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: W3DBibBuffer.cpp
  36. //
  37. // Created: John Ahlquist, May 2001
  38. //
  39. // Desc: Draw buffer to handle all the bibs in a scene.
  40. //
  41. //-----------------------------------------------------------------------------
  42. //-----------------------------------------------------------------------------
  43. // Includes
  44. //-----------------------------------------------------------------------------
  45. #include "W3DDevice/GameClient/W3DBibBuffer.h"
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <assetmgr.h>
  49. #include <texture.h>
  50. #include "common/GlobalData.h"
  51. #include "common/RandomValue.h"
  52. #include "W3DDevice/GameClient/TerrainTex.h"
  53. #include "W3DDevice/GameClient/HeightMap.h"
  54. #include "W3DDevice/GameClient/W3DDynamicLight.h"
  55. #include "WW3D2/Camera.h"
  56. #include "WW3D2/DX8Wrapper.h"
  57. #include "WW3D2/DX8Renderer.h"
  58. #include "WW3D2/Mesh.h"
  59. #include "WW3D2/MeshMdl.h"
  60. //-----------------------------------------------------------------------------
  61. // Private Data
  62. //-----------------------------------------------------------------------------
  63. // A W3D shader that does alpha, texturing, tests zbuffer, doesn't update zbuffer.
  64. #define SC_ALPHA_DETAIL ( SHADE_CNST(ShaderClass::PASS_ALWAYS, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_SRC_ALPHA, \
  65. ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \
  66. ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \
  67. ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
  68. static ShaderClass detailAlphaShader(SC_ALPHA_DETAIL);
  69. //-----------------------------------------------------------------------------
  70. // Private Functions
  71. //-----------------------------------------------------------------------------
  72. //=============================================================================
  73. // W3DBibBuffer::loadBibsInVertexAndIndexBuffers
  74. //=============================================================================
  75. /** Loads the bibs into the vertex buffer for drawing. */
  76. //=============================================================================
  77. void W3DBibBuffer::loadBibsInVertexAndIndexBuffers(void)
  78. {
  79. if (!m_indexBib || !m_vertexBib || !m_initialized) {
  80. return;
  81. }
  82. if (!m_anythingChanged) {
  83. return;
  84. }
  85. m_curNumBibVertices = 0;
  86. m_curNumBibIndices = 0;
  87. m_curNumNormalBibIndices = 0;
  88. m_curNumNormalBibVertex = 0;
  89. if (m_numBibs==0) {
  90. return;
  91. }
  92. VertexFormatXYZDUV1 *vb;
  93. UnsignedShort *ib;
  94. // Lock the buffers.
  95. DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBib, D3DLOCK_DISCARD);
  96. DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexBib, D3DLOCK_DISCARD);
  97. vb=(VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
  98. ib = lockIdxBuffer.Get_Index_Array();
  99. // Add to the index buffer & vertex buffer.
  100. UnsignedShort *curIb = ib;
  101. VertexFormatXYZDUV1 *curVb = vb;
  102. Int curBib;
  103. // Calculate a static lighting value to use for all the bibs.
  104. Real shadeR, shadeG, shadeB;
  105. shadeR = TheGlobalData->m_terrainAmbient[0].red;
  106. shadeG = TheGlobalData->m_terrainAmbient[0].green;
  107. shadeB = TheGlobalData->m_terrainAmbient[0].blue;
  108. shadeR += TheGlobalData->m_terrainDiffuse[0].red;
  109. shadeG += TheGlobalData->m_terrainDiffuse[0].green;
  110. shadeB += TheGlobalData->m_terrainDiffuse[0].blue;
  111. if (shadeR>1.0f) shadeR=1.0f;
  112. if (shadeG>1.0f) shadeG=1.0f;
  113. if (shadeB>1.0f) shadeB=1.0f;
  114. shadeR*=255.0f;
  115. shadeG*=255.0f;
  116. shadeB*=255.0f;
  117. Int diffuse = (REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | (255 << 24));
  118. Int doHighlight;
  119. try {
  120. for (doHighlight=0; doHighlight<=1; doHighlight++)
  121. {
  122. if (doHighlight==1)
  123. {
  124. m_curNumNormalBibIndices = m_curNumBibIndices;
  125. m_curNumNormalBibVertex = m_curNumBibVertices;
  126. }
  127. for (curBib=0; curBib<m_numBibs; curBib++) {
  128. if (m_bibs[curBib].m_unused) continue;
  129. if (m_bibs[curBib].m_highlight != (Bool)doHighlight) continue;
  130. Int startVertex = m_curNumBibVertices;
  131. Int i;
  132. Int numVertex = 4;
  133. if (m_curNumBibVertices+numVertex+2>= m_vertexBibSize) {
  134. break;
  135. }
  136. Int numIndex = 6;
  137. if (m_curNumBibIndices+numIndex+6 >= m_indexBibSize) {
  138. break;
  139. }
  140. for (i=0; i<numVertex; i++) {
  141. // Update the uv values. The W3D models each have their own texture, and
  142. // we use one texture with all images in one, so we have to change the uvs to
  143. // match.
  144. Real U, V;
  145. Vector3 vLoc=m_bibs[curBib].m_corners[i];
  146. switch (i) {
  147. case 0 :
  148. U=0;V=1;
  149. break;
  150. case 1:
  151. U=1;V=1;
  152. break;
  153. case 2:
  154. U=1;V=0;
  155. break;
  156. case 3:
  157. U=0;V=0;
  158. break;
  159. }
  160. curVb->u1 = U;
  161. curVb->v1 = V;
  162. curVb->x = vLoc.X;
  163. curVb->y = vLoc.Y;
  164. curVb->z = vLoc.Z;
  165. curVb->diffuse = diffuse;
  166. curVb++;
  167. m_curNumBibVertices++;
  168. }
  169. *curIb++ = startVertex + 0;
  170. *curIb++ = startVertex + 1;
  171. *curIb++ = startVertex + 2;
  172. *curIb++ = startVertex + 0;
  173. *curIb++ = startVertex + 2;
  174. *curIb++ = startVertex + 3;
  175. m_curNumBibIndices+=6;
  176. }
  177. }
  178. IndexBufferExceptionFunc();
  179. } catch(...) {
  180. IndexBufferExceptionFunc();
  181. }
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Public Functions
  185. //-----------------------------------------------------------------------------
  186. //=============================================================================
  187. // W3DBibBuffer::~W3DBibBuffer
  188. //=============================================================================
  189. /** Destructor. Releases w3d assets. */
  190. //=============================================================================
  191. W3DBibBuffer::~W3DBibBuffer(void)
  192. {
  193. freeBibBuffers();
  194. REF_PTR_RELEASE(m_bibTexture);
  195. REF_PTR_RELEASE(m_highlightBibTexture);
  196. }
  197. //=============================================================================
  198. // W3DBibBuffer::W3DBibBuffer
  199. //=============================================================================
  200. /** Constructor. Sets m_initialized to true if it finds the w3d models it needs
  201. for the bibs. */
  202. //=============================================================================
  203. W3DBibBuffer::W3DBibBuffer(void)
  204. {
  205. m_initialized = false;
  206. m_vertexBib = NULL;
  207. m_indexBib = NULL;
  208. m_bibTexture = NULL;
  209. m_curNumBibVertices=0;
  210. m_curNumBibIndices=0;
  211. clearAllBibs();
  212. m_indexBibSize = INITIAL_BIB_INDEX;
  213. m_vertexBibSize = INITIAL_BIB_VERTEX;
  214. allocateBibBuffers();
  215. m_bibTexture = NEW_REF(TextureClass, ("TBBib.tga"));
  216. m_highlightBibTexture = NEW_REF(TextureClass, ("TBRedBib.tga"));
  217. m_bibTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
  218. m_bibTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
  219. m_highlightBibTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
  220. m_highlightBibTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
  221. m_initialized = true;
  222. }
  223. //=============================================================================
  224. // W3DBibBuffer::freeBibBuffers
  225. //=============================================================================
  226. /** Frees the index and vertex buffers. */
  227. //=============================================================================
  228. void W3DBibBuffer::freeBibBuffers(void)
  229. {
  230. REF_PTR_RELEASE(m_vertexBib);
  231. REF_PTR_RELEASE(m_indexBib);
  232. }
  233. //=============================================================================
  234. // W3DBibBuffer::allocateBibBuffers
  235. //=============================================================================
  236. /** Allocates the index and vertex buffers. */
  237. //=============================================================================
  238. void W3DBibBuffer::allocateBibBuffers(void)
  239. {
  240. m_vertexBib=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_vertexBibSize+4,DX8VertexBufferClass::USAGE_DYNAMIC));
  241. m_indexBib=NEW_REF(DX8IndexBufferClass,(m_indexBibSize+4, DX8IndexBufferClass::USAGE_DYNAMIC));
  242. m_curNumBibVertices=0;
  243. m_curNumBibIndices=0;
  244. }
  245. //=============================================================================
  246. // W3DBibBuffer::clearAllBibs
  247. //=============================================================================
  248. /** Removes all bibs. */
  249. //=============================================================================
  250. void W3DBibBuffer::clearAllBibs(void)
  251. {
  252. m_numBibs=0;
  253. m_anythingChanged = true;
  254. /* test bib
  255. Vector3 corners[4];
  256. corners[0].Set(0, 0, 20);
  257. corners[1].Set(100, 0, 20);
  258. corners[2].Set(100,100,20);
  259. corners[3].Set(0,100,20);
  260. addBib(corners, 1, false);
  261. */
  262. }
  263. //=============================================================================
  264. // W3DBibBuffer::removeHighlighting
  265. //=============================================================================
  266. /** Clears highlighting flag. */
  267. //=============================================================================
  268. void W3DBibBuffer::removeHighlighting(void)
  269. {
  270. Int bibIndex;
  271. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  272. m_bibs[bibIndex].m_highlight = false;
  273. }
  274. }
  275. //=============================================================================
  276. // W3DBibBuffer::addBib
  277. //=============================================================================
  278. /** Adds a bib. */
  279. //=============================================================================
  280. void W3DBibBuffer::addBib(Vector3 corners[4], ObjectID id, Bool highlight)
  281. {
  282. Int bibIndex;
  283. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  284. if (!m_bibs[bibIndex].m_unused && m_bibs[bibIndex].m_objectID == id) {
  285. break;
  286. }
  287. }
  288. if (bibIndex==m_numBibs) {
  289. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  290. if (m_bibs[bibIndex].m_unused) {
  291. break;
  292. }
  293. }
  294. }
  295. if (bibIndex==m_numBibs) {
  296. if (m_numBibs >= MAX_BIBS) {
  297. return;
  298. }
  299. m_numBibs++;
  300. }
  301. m_anythingChanged = true;
  302. m_bibs[bibIndex].m_corners[0] = corners[0];
  303. m_bibs[bibIndex].m_corners[1] = corners[1];
  304. m_bibs[bibIndex].m_corners[2] = corners[2];
  305. m_bibs[bibIndex].m_corners[3] = corners[3];
  306. m_bibs[bibIndex].m_highlight = highlight;
  307. m_bibs[bibIndex].m_color = 0; // for now.
  308. m_bibs[bibIndex].m_unused = false; // for now.
  309. m_bibs[bibIndex].m_objectID = id;
  310. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  311. }
  312. //=============================================================================
  313. // W3DBibBuffer::addBib
  314. //=============================================================================
  315. /** Adds a bib. */
  316. //=============================================================================
  317. void W3DBibBuffer::addBibDrawable(Vector3 corners[4], DrawableID id, Bool highlight)
  318. {
  319. Int bibIndex;
  320. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  321. if (!m_bibs[bibIndex].m_unused && m_bibs[bibIndex].m_drawableID == id) {
  322. break;
  323. }
  324. }
  325. if (bibIndex==m_numBibs) {
  326. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  327. if (m_bibs[bibIndex].m_unused) {
  328. break;
  329. }
  330. }
  331. }
  332. if (bibIndex==m_numBibs) {
  333. if (m_numBibs >= MAX_BIBS) {
  334. return;
  335. }
  336. m_numBibs++;
  337. }
  338. m_anythingChanged = true;
  339. m_bibs[bibIndex].m_corners[0] = corners[0];
  340. m_bibs[bibIndex].m_corners[1] = corners[1];
  341. m_bibs[bibIndex].m_corners[2] = corners[2];
  342. m_bibs[bibIndex].m_corners[3] = corners[3];
  343. m_bibs[bibIndex].m_highlight = highlight;
  344. m_bibs[bibIndex].m_color = 0; // for now.
  345. m_bibs[bibIndex].m_unused = false; // for now.
  346. m_bibs[bibIndex].m_objectID = INVALID_ID;
  347. m_bibs[bibIndex].m_drawableID = id;
  348. }
  349. //=============================================================================
  350. // W3DBibBuffer::removeBib
  351. //=============================================================================
  352. /** Removes a bib. */
  353. //=============================================================================
  354. void W3DBibBuffer::removeBib(ObjectID id)
  355. {
  356. Int bibIndex;
  357. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  358. if (m_bibs[bibIndex].m_objectID == id) {
  359. m_bibs[bibIndex].m_unused = true;
  360. m_bibs[bibIndex].m_objectID = INVALID_ID;
  361. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  362. m_anythingChanged = true;
  363. }
  364. }
  365. }
  366. //=============================================================================
  367. // W3DBibBuffer::removeBib
  368. //=============================================================================
  369. /** Removes a bib. */
  370. //=============================================================================
  371. void W3DBibBuffer::removeBibDrawable(DrawableID id)
  372. {
  373. Int bibIndex;
  374. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  375. if (m_bibs[bibIndex].m_drawableID == id) {
  376. m_bibs[bibIndex].m_unused = true;
  377. m_bibs[bibIndex].m_objectID = INVALID_ID;
  378. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  379. m_anythingChanged = true;
  380. }
  381. }
  382. }
  383. //=============================================================================
  384. // W3DBibBuffer::drawBibs
  385. //=============================================================================
  386. /** Draws the bibs. Uses camera to cull. */
  387. //=============================================================================
  388. void W3DBibBuffer::renderBibs()
  389. {
  390. loadBibsInVertexAndIndexBuffers();
  391. if (m_curNumBibIndices == 0) {
  392. return;
  393. }
  394. // Setup the vertex buffer, shader & texture.
  395. DX8Wrapper::Set_Index_Buffer(m_indexBib,0);
  396. DX8Wrapper::Set_Vertex_Buffer(m_vertexBib);
  397. DX8Wrapper::Set_Shader(detailAlphaShader);
  398. if (m_curNumNormalBibIndices) {
  399. DX8Wrapper::Set_Texture(0,m_bibTexture);
  400. DX8Wrapper::Draw_Triangles( 0, m_curNumNormalBibIndices/3, 0, m_curNumNormalBibVertex);
  401. }
  402. if (m_curNumBibIndices>m_curNumNormalBibIndices) {
  403. DX8Wrapper::Set_Texture(0,m_highlightBibTexture);
  404. DX8Wrapper::Draw_Triangles( m_curNumNormalBibIndices, (m_curNumBibIndices-m_curNumNormalBibIndices)/3,
  405. m_curNumNormalBibVertex, m_curNumBibVertices-m_curNumNormalBibVertex);
  406. }
  407. }