Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OpenGLMesh.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. /*!
  2. * \file OpenGLMesh.cpp
  3. * \brief OpenGL Mesh
  4. *
  5. * Defining UNIT_TEST_OPENGLMESH builds OpenGLMesh class as a console unit test
  6. *
  7. * \author Mongoose
  8. */
  9. #ifdef __APPLE__
  10. #include <OpenGL/gl.h>
  11. #else
  12. #include <GL/gl.h>
  13. #endif
  14. #include "OpenGLMesh.h"
  15. ////////////////////////////////////////////////////////////
  16. // Constructors
  17. ////////////////////////////////////////////////////////////
  18. OpenGLMesh::OpenGLMesh()
  19. {
  20. mNumVertices = 0;
  21. mVertices = 0x0;
  22. mNumNormals = 0;
  23. mNormals = 0x0;
  24. mNumColors = 0;
  25. mColors = 0x0;
  26. mNumTris = 0;
  27. mTris = 0x0;
  28. mNumQuads = 0;
  29. mQuads = 0x0;
  30. mVertexArray = 0x0;
  31. mNormalArray = 0x0;
  32. mColorArray = 0x0;
  33. mTriangleCount = 0;
  34. mTriangleTextures = 0x0;
  35. mTriangleIndices = 0x0;
  36. mTriangleFlags = 0x0;
  37. mTriangleTexCoordArray = 0x0;
  38. mFlags = 0;
  39. mMode = OpenGLMeshModeTexture;
  40. }
  41. OpenGLMesh::~OpenGLMesh()
  42. {
  43. unsigned int i;
  44. if (mVertices)
  45. {
  46. delete [] mVertices;
  47. }
  48. if (mNormals)
  49. {
  50. delete [] mNormals;
  51. }
  52. if (mColors)
  53. {
  54. delete [] mColors;
  55. }
  56. if (mTris)
  57. {
  58. for (i = 0; i < mNumTris; ++i)
  59. {
  60. if (mTris[i].triangles)
  61. delete [] mTris[i].triangles;
  62. if (mTris[i].alpha_triangles)
  63. delete [] mTris[i].alpha_triangles;
  64. if (mTris[i].texcoors)
  65. delete [] mTris[i].texcoors;
  66. if (mTris[i].texcoors2)
  67. delete [] mTris[i].texcoors2;
  68. }
  69. delete [] mTris;
  70. }
  71. if (mQuads)
  72. {
  73. for (i = 0; i < mNumQuads; ++i)
  74. {
  75. if (mQuads[i].quads)
  76. delete [] mQuads[i].quads;
  77. if (mQuads[i].alpha_quads)
  78. delete [] mQuads[i].alpha_quads;
  79. if (mQuads[i].texcoors)
  80. delete [] mQuads[i].texcoors;
  81. if (mQuads[i].texcoors2)
  82. delete [] mQuads[i].texcoors2;
  83. }
  84. delete [] mQuads;
  85. }
  86. if (mVertexArray)
  87. {
  88. delete [] mVertexArray;
  89. }
  90. if (mNormalArray)
  91. {
  92. delete [] mNormalArray;
  93. }
  94. if (mColorArray)
  95. {
  96. delete [] mColorArray;
  97. }
  98. if (mTriangleTextures)
  99. {
  100. delete [] mTriangleTextures;
  101. }
  102. if (mTriangleIndices)
  103. {
  104. delete [] mTriangleIndices;
  105. }
  106. if (mTriangleFlags)
  107. {
  108. delete [] mTriangleFlags;
  109. }
  110. if (mTriangleTexCoordArray)
  111. {
  112. delete [] mTriangleTexCoordArray;
  113. }
  114. }
  115. ////////////////////////////////////////////////////////////
  116. // Public Accessors
  117. ////////////////////////////////////////////////////////////
  118. void OpenGLMesh::drawAlpha()
  119. {
  120. unsigned int i, j, k, index;
  121. // Render quadralaterals
  122. for (mQuads ? i = 0 : i = mNumQuads; i < mNumQuads; ++i)
  123. {
  124. switch (mMode)
  125. {
  126. case OpenGLMeshModeWireframe:
  127. glColor3f(0.0, 0.0, 1.0);
  128. case OpenGLMeshModeSolid:
  129. // Bind WHITE texture for solid colors
  130. glBindTexture(GL_TEXTURE_2D, 0);
  131. break;
  132. default:
  133. // Bind texture id for textures
  134. glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
  135. }
  136. glBegin(GL_QUADS);
  137. for (j = 0; j < mQuads[i].num_alpha_quads; ++j)
  138. {
  139. for (k = 0; k < 4; ++k)
  140. {
  141. index = mQuads[i].alpha_quads[j*4+k];
  142. glTexCoord2fv(mQuads[i].texcoors2[j*4+k]);
  143. glColor4fv(mColors[index]);
  144. glVertex3fv(mVertices[index]);
  145. }
  146. }
  147. glEnd();
  148. }
  149. // Render triangles
  150. for (mTris ? i = 0 : i = mNumTris; i < mNumTris; ++i)
  151. {
  152. switch (mMode)
  153. {
  154. case OpenGLMeshModeWireframe:
  155. glColor3f(0.0, 1.0, 0.0);
  156. case OpenGLMeshModeSolid:
  157. // Bind WHITE texture for solid colors
  158. glBindTexture(GL_TEXTURE_2D, 0);
  159. break;
  160. default:
  161. // Bind texture id for textures
  162. glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
  163. }
  164. glBegin(GL_TRIANGLES);
  165. for (j = 0; j < mTris[i].num_alpha_triangles; ++j)
  166. {
  167. for (k = 0; k < 3; ++k)
  168. {
  169. index = mTris[i].alpha_triangles[j*3+k];
  170. glTexCoord2fv(mTris[i].texcoors2[j*3+k]);
  171. glColor4fv(mColors[index]);
  172. glVertex3fv(mVertices[index]);
  173. }
  174. }
  175. glEnd();
  176. }
  177. }
  178. void OpenGLMesh::drawSolid()
  179. {
  180. unsigned int i, j, k, index;
  181. if (mFlags & fOpenGLMesh_UseVertexArray)
  182. {
  183. //glEnableClientState(GL_VERTEX_ARRAY);
  184. //glVertexPointer(3, GL_FLOAT, 0, mVertexArray);
  185. glPointSize(2.0f);
  186. glColor3f(1.0f, 1.0f, 1.0f);
  187. glBegin(GL_TRIANGLES);
  188. for (i = 0; i < mTriangleCount*3; ++i)
  189. {
  190. //glArrayElement(mTriangleIndices[i]);
  191. glVertex3fv(mVertexArray+mTriangleIndices[i]);
  192. }
  193. glEnd();
  194. glPointSize(1.0f);
  195. return; // FIXME
  196. for (j = 0; j < mQuads[i].num_quads; ++j)
  197. {
  198. for (k = 0; k < 4; ++k)
  199. {
  200. index = mQuads[i].quads[j*4+k];
  201. glTexCoord2fv(mQuads[i].texcoors[j*4+k]);
  202. glArrayElement(mQuads[i].quads[j*4+k]);
  203. }
  204. }
  205. return;
  206. }
  207. // Render quadralaterals
  208. for (mQuads ? i = 0 : i = mNumQuads; i < mNumQuads; ++i)
  209. {
  210. switch (mMode)
  211. {
  212. case OpenGLMeshModeSolid:
  213. glColor3f(0.0, 0.0, 0.0);
  214. break;
  215. case OpenGLMeshModeWireframe:
  216. // Bind WHITE texture for solid colors
  217. glBindTexture(GL_TEXTURE_2D, 0);
  218. break;
  219. #ifdef MULTITEXTURE
  220. case OpenGLMeshModeMultiTexture:
  221. glActiveTextureARB(GL_TEXTURE0_ARB);
  222. glEnable(GL_TEXTURE_2D);
  223. glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
  224. glActiveTextureARB(GL_TEXTURE1_ARB);
  225. glEnable(GL_TEXTURE_2D);
  226. glBindTexture(GL_TEXTURE_2D, mQuads[i].bumpmap+1);
  227. break;
  228. #endif
  229. default:
  230. // Bind texture id for textures
  231. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  232. glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
  233. }
  234. glBegin(GL_QUADS);
  235. for (j = 0; j < mQuads[i].num_quads; ++j)
  236. {
  237. for (k = 0; k < 4; ++k)
  238. {
  239. index = mQuads[i].quads[j*4+k];
  240. glColor4fv(mColors[index]);
  241. #ifdef MULTITEXTURE
  242. if (mMode == OpenGLMeshModeMultiTexture)
  243. {
  244. glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,
  245. mQuads[i].texcoors[j*4+k]);
  246. glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,
  247. mQuads[i].texcoors[j*4+k]);
  248. }
  249. else
  250. #endif
  251. glTexCoord2fv(mQuads[i].texcoors[j*4+k]);
  252. glVertex3fv(mVertices[index]);
  253. }
  254. }
  255. glEnd();
  256. }
  257. // Render triangles
  258. for (mTris ? i = 0 : i = mNumTris; i < mNumTris; ++i)
  259. {
  260. switch (mMode)
  261. {
  262. case OpenGLMeshModeSolid:
  263. glColor3f(1.0, 0.0, 0.0);
  264. break;
  265. case OpenGLMeshModeWireframe:
  266. // Bind WHITE texture for solid colors
  267. glBindTexture(GL_TEXTURE_2D, 0);
  268. break;
  269. #ifdef MULTITEXTURE
  270. case OpenGLMeshModeMultiTexture:
  271. glActiveTextureARB(GL_TEXTURE0_ARB);
  272. glEnable(GL_TEXTURE_2D);
  273. glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
  274. glActiveTextureARB(GL_TEXTURE1_ARB);
  275. glEnable(GL_TEXTURE_2D);
  276. glBindTexture(GL_TEXTURE_2D, mTris[i].bumpmap+1);
  277. break;
  278. #endif
  279. default:
  280. // Bind texture id for textures
  281. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  282. glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
  283. }
  284. glBegin(GL_TRIANGLES);
  285. for (j = 0; j < mTris[i].num_triangles; ++j)
  286. {
  287. for (k = 0; k < 3; ++k)
  288. {
  289. index = mTris[i].triangles[j*3+k];
  290. #ifdef MULTITEXTURE
  291. if (mMode == OpenGLMeshModeMultiTexture)
  292. {
  293. glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,
  294. mTris[i].texcoors[j*3+k]);
  295. glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,
  296. mTris[i].texcoors[j*3+k]);
  297. }
  298. else
  299. #endif
  300. glTexCoord2fv(mTris[i].texcoors[j*3+k]);
  301. glColor4fv(mColors[index]);
  302. glVertex3fv(mVertices[index]);
  303. }
  304. }
  305. glEnd();
  306. }
  307. #ifdef MULTITEXTURE
  308. if (mMode == OpenGLMeshModeMultiTexture)
  309. {
  310. glDisable(GL_TEXTURE_2D);
  311. glActiveTextureARB(GL_TEXTURE0_ARB);
  312. }
  313. #endif
  314. }
  315. ////////////////////////////////////////////////////////////
  316. // Public Mutators
  317. ////////////////////////////////////////////////////////////
  318. void OpenGLMesh::allocateColors(unsigned int n)
  319. {
  320. if (mColors)
  321. {
  322. mNumColors = 0;
  323. delete [] mColors;
  324. }
  325. if (!n)
  326. {
  327. return;
  328. }
  329. mNumColors = n;
  330. mColors = new vec4_t[mNumColors];
  331. }
  332. void OpenGLMesh::allocateNormals(unsigned int n)
  333. {
  334. if (mNormals)
  335. {
  336. mNumNormals = 0;
  337. delete [] mNormals;
  338. }
  339. if (!n)
  340. {
  341. return;
  342. }
  343. mNumNormals = n;
  344. mNormals = new vec3_t[mNumNormals];
  345. }
  346. void OpenGLMesh::allocateRectangles(unsigned int n)
  347. {
  348. if (mQuads)
  349. {
  350. mNumQuads = 0;
  351. delete [] mQuads;
  352. }
  353. if (!n)
  354. {
  355. return;
  356. }
  357. mNumQuads = n;
  358. mQuads = new rect_t[mNumQuads];
  359. }
  360. void OpenGLMesh::allocateTriangles(unsigned int n)
  361. {
  362. if (mTris)
  363. {
  364. mNumTris = 0;
  365. delete [] mTris;
  366. }
  367. if (!n)
  368. {
  369. return;
  370. }
  371. mNumTris = n;
  372. mTris = new tris_t[mNumTris];
  373. }
  374. void OpenGLMesh::allocateVertices(unsigned int n)
  375. {
  376. if (mVertices)
  377. {
  378. mNumVertices = 0;
  379. delete [] mVertices;
  380. }
  381. if (!n)
  382. {
  383. return;
  384. }
  385. mNumVertices = n;
  386. mVertices = new vec3_t[mNumVertices];
  387. }
  388. void OpenGLMesh::bufferColorArray(unsigned int colorCount, vec_t *colors,
  389. unsigned int colorWidth)
  390. {
  391. if (mColors)
  392. {
  393. mNumColors = 0;
  394. delete [] mColors;
  395. }
  396. if (!colorCount)
  397. {
  398. return;
  399. }
  400. //mColorWidth = colorWidth; // for now assume 4 always
  401. mNumColors = colorCount;
  402. mColorArray = colors;
  403. }
  404. void OpenGLMesh::bufferNormalArray(unsigned int normalCount, vec_t *normals)
  405. {
  406. if (mNormals)
  407. {
  408. mNumNormals = 0;
  409. delete [] mNormals;
  410. }
  411. if (!normalCount)
  412. {
  413. return;
  414. }
  415. mNumNormals = normalCount;
  416. mNormalArray = normals;
  417. }
  418. void OpenGLMesh::bufferTriangles(unsigned int count,
  419. unsigned int *indices, vec_t *texCoords,
  420. int *textures, unsigned int *flags)
  421. {
  422. mTriangleCount = count;
  423. mTriangleTextures = textures;
  424. mTriangleIndices = indices;
  425. mTriangleFlags = flags;
  426. mTriangleTexCoordArray = texCoords;
  427. // FIXME: sortTrianglesByTexture();
  428. }
  429. void OpenGLMesh::bufferVertexArray(unsigned int vertexCount, vec_t *vertices)
  430. {
  431. if (mVertices)
  432. {
  433. mNumVertices = 0;
  434. delete [] mVertices;
  435. }
  436. if (!vertexCount)
  437. {
  438. return;
  439. }
  440. mNumVertices = vertexCount;
  441. mVertexArray = vertices;
  442. mFlags |= fOpenGLMesh_UseVertexArray;
  443. }
  444. void OpenGLMesh::setColor(unsigned int index,
  445. float r, float g, float b, float a)
  446. {
  447. if (index > mNumColors)
  448. {
  449. return;
  450. }
  451. mColors[index][0] = r;
  452. mColors[index][1] = g;
  453. mColors[index][2] = b;
  454. mColors[index][3] = a;
  455. }
  456. void OpenGLMesh::setColor(unsigned int index, float rgba[4])
  457. {
  458. if (index > mNumColors)
  459. {
  460. return;
  461. }
  462. mColors[index][0] = rgba[0];
  463. mColors[index][1] = rgba[1];
  464. mColors[index][2] = rgba[2];
  465. mColors[index][3] = rgba[3];
  466. }
  467. void OpenGLMesh::setNormal(unsigned int index, float i, float j, float k)
  468. {
  469. if (index > mNumNormals)
  470. {
  471. return;
  472. }
  473. mNormals[index][0] = i;
  474. mNormals[index][1] = j;
  475. mNormals[index][2] = k;
  476. }
  477. void OpenGLMesh::setVertex(unsigned int index, float x, float y, float z)
  478. {
  479. if (index > mNumVertices)
  480. {
  481. return;
  482. }
  483. mVertices[index][0] = x;
  484. mVertices[index][1] = y;
  485. mVertices[index][2] = z;
  486. }
  487. ////////////////////////////////////////////////////////////
  488. // Private Accessors
  489. ////////////////////////////////////////////////////////////
  490. ////////////////////////////////////////////////////////////
  491. // Private Mutators
  492. ////////////////////////////////////////////////////////////
  493. ////////////////////////////////////////////////////////////
  494. // Unit Test code
  495. ////////////////////////////////////////////////////////////
  496. #ifdef UNIT_TEST_OPENGLMESH
  497. int runOpenGLMeshUnitTest(int argc, char *argv[])
  498. {
  499. return 0;
  500. }
  501. int main(int argc, char *argv[])
  502. {
  503. OpenGLMesh test;
  504. printf("[OpenGLMesh class test]\n");
  505. return runOpenGLMeshUnitTest(argc, argv);
  506. }
  507. #endif