W3DBibBuffer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. ** Command & Conquer Generals(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. VertexFormatXYZDUV1 *vb;
  90. UnsignedShort *ib;
  91. // Lock the buffers.
  92. DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBib);
  93. DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexBib);
  94. vb=(VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array();
  95. ib = lockIdxBuffer.Get_Index_Array();
  96. // Add to the index buffer & vertex buffer.
  97. UnsignedShort *curIb = ib;
  98. VertexFormatXYZDUV1 *curVb = vb;
  99. Int curBib;
  100. // Calculate a static lighting value to use for all the bibs.
  101. Real shadeR, shadeG, shadeB;
  102. shadeR = TheGlobalData->m_terrainAmbient[0].red;
  103. shadeG = TheGlobalData->m_terrainAmbient[0].green;
  104. shadeB = TheGlobalData->m_terrainAmbient[0].blue;
  105. shadeR += TheGlobalData->m_terrainDiffuse[0].red;
  106. shadeG += TheGlobalData->m_terrainDiffuse[0].green;
  107. shadeB += TheGlobalData->m_terrainDiffuse[0].blue;
  108. if (shadeR>1.0f) shadeR=1.0f;
  109. if (shadeG>1.0f) shadeG=1.0f;
  110. if (shadeB>1.0f) shadeB=1.0f;
  111. shadeR*=255.0f;
  112. shadeG*=255.0f;
  113. shadeB*=255.0f;
  114. Int diffuse = (REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | (255 << 24));
  115. Int doHighlight;
  116. for (doHighlight=0; doHighlight<=1; doHighlight++)
  117. {
  118. if (doHighlight==1)
  119. {
  120. m_curNumNormalBibIndices = m_curNumBibIndices;
  121. m_curNumNormalBibVertex = m_curNumBibVertices;
  122. }
  123. for (curBib=0; curBib<m_numBibs; curBib++) {
  124. if (m_bibs[curBib].m_unused) continue;
  125. if (m_bibs[curBib].m_highlight != (Bool)doHighlight) continue;
  126. Int startVertex = m_curNumBibVertices;
  127. Int i;
  128. Int numVertex = 4;
  129. if (m_curNumBibVertices+numVertex+2>= m_vertexBibSize) {
  130. break;
  131. }
  132. Int numIndex = 6;
  133. if (m_curNumBibIndices+numIndex+6 >= m_indexBibSize) {
  134. break;
  135. }
  136. for (i=0; i<numVertex; i++) {
  137. // Update the uv values. The W3D models each have their own texture, and
  138. // we use one texture with all images in one, so we have to change the uvs to
  139. // match.
  140. Real U, V;
  141. Vector3 vLoc=m_bibs[curBib].m_corners[i];
  142. switch (i) {
  143. case 0 :
  144. U=0;V=1;
  145. break;
  146. case 1:
  147. U=1;V=1;
  148. break;
  149. case 2:
  150. U=1;V=0;
  151. break;
  152. case 3:
  153. U=0;V=0;
  154. break;
  155. }
  156. curVb->u1 = U;
  157. curVb->v1 = V;
  158. curVb->x = vLoc.X;
  159. curVb->y = vLoc.Y;
  160. curVb->z = vLoc.Z;
  161. curVb->diffuse = diffuse;
  162. curVb++;
  163. m_curNumBibVertices++;
  164. }
  165. *curIb++ = startVertex + 0;
  166. *curIb++ = startVertex + 1;
  167. *curIb++ = startVertex + 2;
  168. *curIb++ = startVertex + 0;
  169. *curIb++ = startVertex + 2;
  170. *curIb++ = startVertex + 3;
  171. m_curNumBibIndices+=6;
  172. }
  173. }
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Public Functions
  177. //-----------------------------------------------------------------------------
  178. //=============================================================================
  179. // W3DBibBuffer::~W3DBibBuffer
  180. //=============================================================================
  181. /** Destructor. Releases w3d assets. */
  182. //=============================================================================
  183. W3DBibBuffer::~W3DBibBuffer(void)
  184. {
  185. freeBibBuffers();
  186. REF_PTR_RELEASE(m_bibTexture);
  187. REF_PTR_RELEASE(m_highlightBibTexture);
  188. }
  189. //=============================================================================
  190. // W3DBibBuffer::W3DBibBuffer
  191. //=============================================================================
  192. /** Constructor. Sets m_initialized to true if it finds the w3d models it needs
  193. for the bibs. */
  194. //=============================================================================
  195. W3DBibBuffer::W3DBibBuffer(void)
  196. {
  197. m_initialized = false;
  198. m_vertexBib = NULL;
  199. m_indexBib = NULL;
  200. m_bibTexture = NULL;
  201. m_curNumBibVertices=0;
  202. m_curNumBibIndices=0;
  203. clearAllBibs();
  204. m_indexBibSize = INITIAL_BIB_INDEX;
  205. m_vertexBibSize = INITIAL_BIB_VERTEX;
  206. allocateBibBuffers();
  207. m_bibTexture = NEW_REF(TextureClass, ("TBBib.tga"));
  208. m_highlightBibTexture = NEW_REF(TextureClass, ("TBRedBib.tga"));
  209. m_bibTexture->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  210. m_bibTexture->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  211. m_highlightBibTexture->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  212. m_highlightBibTexture->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  213. m_initialized = true;
  214. }
  215. //=============================================================================
  216. // W3DBibBuffer::freeBibBuffers
  217. //=============================================================================
  218. /** Frees the index and vertex buffers. */
  219. //=============================================================================
  220. void W3DBibBuffer::freeBibBuffers(void)
  221. {
  222. REF_PTR_RELEASE(m_vertexBib);
  223. REF_PTR_RELEASE(m_indexBib);
  224. }
  225. //=============================================================================
  226. // W3DBibBuffer::allocateBibBuffers
  227. //=============================================================================
  228. /** Allocates the index and vertex buffers. */
  229. //=============================================================================
  230. void W3DBibBuffer::allocateBibBuffers(void)
  231. {
  232. m_vertexBib=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_vertexBibSize+4,DX8VertexBufferClass::USAGE_DYNAMIC));
  233. m_indexBib=NEW_REF(DX8IndexBufferClass,(m_indexBibSize+4, DX8IndexBufferClass::USAGE_DYNAMIC));
  234. m_curNumBibVertices=0;
  235. m_curNumBibIndices=0;
  236. }
  237. //=============================================================================
  238. // W3DBibBuffer::clearAllBibs
  239. //=============================================================================
  240. /** Removes all bibs. */
  241. //=============================================================================
  242. void W3DBibBuffer::clearAllBibs(void)
  243. {
  244. m_numBibs=0;
  245. m_anythingChanged = true;
  246. /* test bib
  247. Vector3 corners[4];
  248. corners[0].Set(0, 0, 20);
  249. corners[1].Set(100, 0, 20);
  250. corners[2].Set(100,100,20);
  251. corners[3].Set(0,100,20);
  252. addBib(corners, 1, false);
  253. */
  254. }
  255. //=============================================================================
  256. // W3DBibBuffer::removeHighlighting
  257. //=============================================================================
  258. /** Clears highlighting flag. */
  259. //=============================================================================
  260. void W3DBibBuffer::removeHighlighting(void)
  261. {
  262. Int bibIndex;
  263. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  264. m_bibs[bibIndex].m_highlight = false;
  265. }
  266. }
  267. //=============================================================================
  268. // W3DBibBuffer::addBib
  269. //=============================================================================
  270. /** Adds a bib. */
  271. //=============================================================================
  272. void W3DBibBuffer::addBib(Vector3 corners[4], ObjectID id, Bool highlight)
  273. {
  274. Int bibIndex;
  275. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  276. if (!m_bibs[bibIndex].m_unused && m_bibs[bibIndex].m_objectID == id) {
  277. break;
  278. }
  279. }
  280. if (bibIndex==m_numBibs) {
  281. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  282. if (m_bibs[bibIndex].m_unused) {
  283. break;
  284. }
  285. }
  286. }
  287. if (bibIndex==m_numBibs) {
  288. if (m_numBibs >= MAX_BIBS) {
  289. return;
  290. }
  291. m_numBibs++;
  292. }
  293. m_anythingChanged = true;
  294. m_bibs[bibIndex].m_corners[0] = corners[0];
  295. m_bibs[bibIndex].m_corners[1] = corners[1];
  296. m_bibs[bibIndex].m_corners[2] = corners[2];
  297. m_bibs[bibIndex].m_corners[3] = corners[3];
  298. m_bibs[bibIndex].m_highlight = highlight;
  299. m_bibs[bibIndex].m_color = 0; // for now.
  300. m_bibs[bibIndex].m_unused = false; // for now.
  301. m_bibs[bibIndex].m_objectID = id;
  302. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  303. }
  304. //=============================================================================
  305. // W3DBibBuffer::addBib
  306. //=============================================================================
  307. /** Adds a bib. */
  308. //=============================================================================
  309. void W3DBibBuffer::addBibDrawable(Vector3 corners[4], DrawableID id, Bool highlight)
  310. {
  311. Int bibIndex;
  312. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  313. if (!m_bibs[bibIndex].m_unused && m_bibs[bibIndex].m_drawableID == id) {
  314. break;
  315. }
  316. }
  317. if (bibIndex==m_numBibs) {
  318. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  319. if (m_bibs[bibIndex].m_unused) {
  320. break;
  321. }
  322. }
  323. }
  324. if (bibIndex==m_numBibs) {
  325. if (m_numBibs >= MAX_BIBS) {
  326. return;
  327. }
  328. m_numBibs++;
  329. }
  330. m_anythingChanged = true;
  331. m_bibs[bibIndex].m_corners[0] = corners[0];
  332. m_bibs[bibIndex].m_corners[1] = corners[1];
  333. m_bibs[bibIndex].m_corners[2] = corners[2];
  334. m_bibs[bibIndex].m_corners[3] = corners[3];
  335. m_bibs[bibIndex].m_highlight = highlight;
  336. m_bibs[bibIndex].m_color = 0; // for now.
  337. m_bibs[bibIndex].m_unused = false; // for now.
  338. m_bibs[bibIndex].m_objectID = INVALID_ID;
  339. m_bibs[bibIndex].m_drawableID = id;
  340. }
  341. //=============================================================================
  342. // W3DBibBuffer::removeBib
  343. //=============================================================================
  344. /** Removes a bib. */
  345. //=============================================================================
  346. void W3DBibBuffer::removeBib(ObjectID id)
  347. {
  348. Int bibIndex;
  349. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  350. if (m_bibs[bibIndex].m_objectID == id) {
  351. m_bibs[bibIndex].m_unused = true;
  352. m_bibs[bibIndex].m_objectID = INVALID_ID;
  353. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  354. m_anythingChanged = true;
  355. }
  356. }
  357. }
  358. //=============================================================================
  359. // W3DBibBuffer::removeBib
  360. //=============================================================================
  361. /** Removes a bib. */
  362. //=============================================================================
  363. void W3DBibBuffer::removeBibDrawable(DrawableID id)
  364. {
  365. Int bibIndex;
  366. for (bibIndex=0; bibIndex<m_numBibs; bibIndex++) {
  367. if (m_bibs[bibIndex].m_drawableID == id) {
  368. m_bibs[bibIndex].m_unused = true;
  369. m_bibs[bibIndex].m_objectID = INVALID_ID;
  370. m_bibs[bibIndex].m_drawableID = INVALID_DRAWABLE_ID;
  371. m_anythingChanged = true;
  372. }
  373. }
  374. }
  375. //=============================================================================
  376. // W3DBibBuffer::drawBibs
  377. //=============================================================================
  378. /** Draws the bibs. Uses camera to cull. */
  379. //=============================================================================
  380. void W3DBibBuffer::renderBibs()
  381. {
  382. loadBibsInVertexAndIndexBuffers();
  383. if (m_curNumBibIndices == 0) {
  384. return;
  385. }
  386. // Setup the vertex buffer, shader & texture.
  387. DX8Wrapper::Set_Index_Buffer(m_indexBib,0);
  388. DX8Wrapper::Set_Vertex_Buffer(m_vertexBib);
  389. DX8Wrapper::Set_Shader(detailAlphaShader);
  390. if (m_curNumNormalBibIndices) {
  391. DX8Wrapper::Set_Texture(0,m_bibTexture);
  392. DX8Wrapper::Draw_Triangles( 0, m_curNumNormalBibIndices/3, 0, m_curNumNormalBibVertex);
  393. }
  394. if (m_curNumBibIndices>m_curNumNormalBibIndices) {
  395. DX8Wrapper::Set_Texture(0,m_highlightBibTexture);
  396. DX8Wrapper::Draw_Triangles( m_curNumNormalBibIndices, (m_curNumBibIndices-m_curNumNormalBibIndices)/3,
  397. m_curNumNormalBibVertex, m_curNumBibVertices-m_curNumNormalBibVertex);
  398. }
  399. }