prim3d.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. /*=============================================================================
  2. Name : prim3d.h
  3. Purpose : Draw 3d primitives.
  4. Created 7/1/1997 by lmoloney
  5. Copyright Relic Entertainment, Inc. All rights reserved.
  6. =============================================================================*/
  7. #define WIN32_LEAN_AND_MEAN
  8. #include <math.h>
  9. #include <stdlib.h>
  10. #include <windows.h>
  11. #include "debug.h"
  12. #include "glinc.h"
  13. #include "linkedlist.h"
  14. #include "memory.h"
  15. #include "prim3d.h"
  16. #include "render.h"
  17. #include "texreg.h"
  18. #include "types.h"
  19. #include "vector.h"
  20. #include "glcaps.h"
  21. #include "devstats.h"
  22. #define sizeofverticearray(x) sizeof(vertice_array) + (sizeof(vector) * (x-1))
  23. typedef struct
  24. {
  25. Node node;
  26. udword num_vertices;
  27. uword axis;
  28. vector vertice[1];
  29. } vertice_array;
  30. //globals
  31. LinkedList CircleList;
  32. /*=============================================================================
  33. Functions:
  34. =============================================================================*/
  35. /*-----------------------------------------------------------------------------
  36. Name : primLine3
  37. Description : Draw a line in 3D using having a thickness of 1 pixel
  38. Inputs : p1, p2 - end points of line segment to draw
  39. c - color to draw it in.
  40. Outputs :
  41. Return : void
  42. ----------------------------------------------------------------------------*/
  43. void primLine3(vector *p1, vector *p2, color c)
  44. {
  45. bool blendon;
  46. if (glCapFeatureExists(GL_LINE_SMOOTH))
  47. {
  48. blendon = glIsEnabled(GL_BLEND);
  49. if (!blendon) glEnable(GL_BLEND);
  50. glEnable(GL_LINE_SMOOTH);
  51. rndAdditiveBlends(FALSE);
  52. }
  53. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  54. glBegin(GL_LINES);
  55. glVertex3fv((const GLfloat *)p1);
  56. glVertex3fv((const GLfloat *)p2);
  57. glEnd();
  58. if (glCapFeatureExists(GL_LINE_SMOOTH))
  59. {
  60. if (!blendon) glDisable(GL_BLEND);
  61. glDisable(GL_LINE_SMOOTH);
  62. }
  63. }
  64. /*-----------------------------------------------------------------------------
  65. Name : primCircleSolid3
  66. Description : Draw a solid circle on the z = centre->z plane
  67. Inputs : centre - centre point (in 3D coords) of the circle
  68. radius - radius of circle (actually, distance
  69. from centre to vertices)
  70. nSlices - number of polygons to draw
  71. c - color of circle
  72. Outputs : ..
  73. Return : void
  74. ----------------------------------------------------------------------------*/
  75. void primCircleSolid3(vector *centre, real32 radius, sdword nSlices, color c)
  76. {
  77. sdword index;
  78. GLfloat v[3];
  79. double theta;
  80. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  81. v[0] = centre->x;
  82. v[1] = centre->y;
  83. v[2] = centre->z;
  84. glBegin(GL_TRIANGLE_FAN);
  85. glVertex3fv(v); //centre vertex
  86. for (index = 0, theta = 0.0; index < nSlices; index++)
  87. {
  88. v[0] = centre->x + (real32)(sin(theta)) * radius;
  89. v[1] = centre->y + (real32)(cos(theta)) * radius;
  90. theta += 2.0 * PI / (double)nSlices;
  91. glVertex3fv(v); //vertex on outer rim
  92. }
  93. v[0] = centre->x;
  94. v[1] = centre->y + radius;
  95. glVertex3fv(v); //final vertex on outer rim
  96. glEnd();
  97. }
  98. void primCircleSolid3Fade(vector *centre, real32 radius, sdword nSlices, color c, real32 fade)
  99. {
  100. sdword index;
  101. GLfloat v[3];
  102. double theta;
  103. GLboolean blend = glIsEnabled(GL_BLEND);
  104. if (!blend)
  105. {
  106. glEnable(GL_BLEND);
  107. rndAdditiveBlends(FALSE);
  108. }
  109. glColor4ub(colRed(c), colGreen(c), colBlue(c), (ubyte)(fade * 255.0f));
  110. v[0] = centre->x;
  111. v[1] = centre->y;
  112. v[2] = centre->z;
  113. glBegin(GL_TRIANGLE_FAN);
  114. glVertex3fv(v); //centre vertex
  115. for (index = 0, theta = 0.0; index < nSlices; index++)
  116. {
  117. v[0] = centre->x + (real32)(sin(theta)) * radius;
  118. v[1] = centre->y + (real32)(cos(theta)) * radius;
  119. theta += 2.0 * PI / (double)nSlices;
  120. glVertex3fv(v); //vertex on outer rim
  121. }
  122. v[0] = centre->x;
  123. v[1] = centre->y + radius;
  124. glVertex3fv(v); //final vertex on outer rim
  125. glEnd();
  126. if (!blend)
  127. {
  128. glDisable(GL_BLEND);
  129. }
  130. }
  131. /*-----------------------------------------------------------------------------
  132. Name : primCreateNewCircleVerticeArray
  133. Description : Creates a set of vertices defining a unit circle around the axis given
  134. Inputs : nSlices - the number of polygons in the unit circle,
  135. axis - the axis around which the circle is drawn
  136. Outputs : Allocates some memory and stuff
  137. Return : the new vertice array
  138. ----------------------------------------------------------------------------*/
  139. vertice_array *primCreateNewCircleVerticeArray(sdword nSlices, uword axis)
  140. {
  141. udword i;
  142. double theta = 0.0;
  143. vertice_array *vertices = (vertice_array *)memAlloc(sizeofverticearray(nSlices+1), "circle_vertices", NonVolatile);
  144. vertices->num_vertices = nSlices + 1;
  145. vertices->axis = axis;
  146. for (i = 0; i < vertices->num_vertices; i++)
  147. {
  148. switch (axis)
  149. {
  150. case X_AXIS:
  151. vertices->vertice[i].x = 0.0;
  152. vertices->vertice[i].y = (real32)(cos(theta));
  153. vertices->vertice[i].z = (real32)(sin(theta));
  154. break;
  155. case Y_AXIS:
  156. vertices->vertice[i].x = (real32)(sin(theta));
  157. vertices->vertice[i].y = 0.0;
  158. vertices->vertice[i].z = (real32)(cos(theta));
  159. break;
  160. case Z_AXIS:
  161. vertices->vertice[i].x = (real32)(sin(theta));
  162. vertices->vertice[i].y = (real32)(cos(theta));
  163. vertices->vertice[i].z = 0.0;
  164. break;
  165. }
  166. theta += 2.0 * PI / (double)nSlices;
  167. }
  168. listAddNode(&CircleList, &vertices->node, vertices);
  169. return vertices;
  170. }
  171. /*-----------------------------------------------------------------------------
  172. Name : primCircleOutline3
  173. Description : Draw a solid circle on the z = centre->z plane
  174. Inputs : centre - centre point (in 3D coords) of the circle
  175. radius - radius of circle (actually, distance
  176. from centre to vertices)
  177. nSlices - number of polygons to draw
  178. nSpokes - number of 'spokes' which actually get drawn.
  179. nSlices should integer divide by this with no remainder.
  180. color - color of circle
  181. axis - axis on which to draw the circle
  182. Outputs : ..
  183. Return : void
  184. ----------------------------------------------------------------------------*/
  185. void primCircleOutline3(vector *centre, real32 radius, sdword nSlices,
  186. sdword nSpokes, color color, uword axis)
  187. {
  188. Node *node;
  189. vertice_array *vertices;
  190. register vector *vec_ptr;
  191. sdword index;
  192. GLfloat c[3], rim[3];
  193. // find the vertice list containing the unit circle that has the same
  194. // number of slices and is aligned along the same axis as the circle to be drawn
  195. node = CircleList.head;
  196. while (node != NULL)
  197. {
  198. vertices = (vertice_array *)listGetStructOfNode(node);
  199. if ((vertices->num_vertices == (nSlices + 1)) && (vertices->axis == axis))
  200. {
  201. //found the correct unit circle
  202. break;
  203. }
  204. node = node->next;
  205. }
  206. //if the unit circle isn't found, generate a new one
  207. if (node == NULL)
  208. {
  209. vertices = primCreateNewCircleVerticeArray(nSlices, axis);
  210. }
  211. if (nSpokes != 0)
  212. {
  213. nSpokes = nSlices / nSpokes;
  214. }
  215. glColor3ub(colRed(color), colGreen(color), colBlue(color));
  216. c[0] = centre->x; //compute centre point
  217. c[1] = centre->y;
  218. c[2] = centre->z;
  219. glShadeModel(GL_SMOOTH);
  220. if (glCapFeatureExists(GL_LINE_SMOOTH))
  221. {
  222. glEnable(GL_BLEND);
  223. glEnable(GL_LINE_SMOOTH);
  224. rndAdditiveBlends(FALSE);
  225. }
  226. vec_ptr = &vertices->vertice[0];
  227. switch (axis)
  228. {
  229. case X_AXIS:
  230. rim[0] = centre->x + vec_ptr->x * radius;
  231. //draw the circle
  232. glBegin(GL_LINE_LOOP);
  233. for (index = 0; index <= nSlices; index++, vec_ptr++)
  234. {
  235. rim[1] = centre->y + vec_ptr->y * radius;
  236. rim[2] = centre->z + vec_ptr->z * radius;
  237. glVertex3fv(rim); //vertex on rim
  238. }
  239. glEnd();
  240. //now draw the spokes
  241. if (nSpokes)
  242. {
  243. vec_ptr = &vertices->vertice[0];
  244. glBegin(GL_LINES);
  245. for (index = 0; index <= nSlices; index += nSpokes, vec_ptr += nSpokes)
  246. {
  247. rim[1] = centre->y + vec_ptr->y * radius;
  248. rim[2] = centre->z + vec_ptr->z * radius;
  249. glVertex3fv(c);
  250. glVertex3fv(rim);
  251. }
  252. glEnd();
  253. }
  254. break;
  255. case Y_AXIS:
  256. rim[1] = centre->y + vec_ptr->y * radius;
  257. //draw the circle
  258. glBegin(GL_LINE_LOOP);
  259. for (index = 0; index <= nSlices; index++, vec_ptr++)
  260. {
  261. rim[0] = centre->x + vec_ptr->x * radius;
  262. rim[2] = centre->z + vec_ptr->z * radius;
  263. glVertex3fv(rim); //vertex on rim
  264. }
  265. glEnd();
  266. //draw the spokes
  267. if (nSpokes)
  268. {
  269. vec_ptr = &vertices->vertice[0];
  270. glBegin(GL_LINES);
  271. for (index = 0; index <= nSlices; index += nSpokes, vec_ptr += nSpokes)
  272. {
  273. rim[0] = centre->x + vec_ptr->x * radius;
  274. rim[2] = centre->z + vec_ptr->z * radius;
  275. glVertex3fv(c);
  276. glVertex3fv(rim);
  277. }
  278. glEnd();
  279. }
  280. break;
  281. case Z_AXIS:
  282. rim[2] = centre->z + vec_ptr->z * radius;
  283. //draw the circle
  284. glBegin(GL_LINE_LOOP);
  285. for (index = 0; index <= nSlices; index++, vec_ptr++)
  286. {
  287. rim[0] = centre->x + vec_ptr->x * radius;
  288. rim[1] = centre->y + vec_ptr->y * radius;
  289. glVertex3fv(rim); //vertex on rim
  290. }
  291. glEnd();
  292. //draw the spokes
  293. if (nSpokes)
  294. {
  295. vec_ptr = &vertices->vertice[0];
  296. glBegin(GL_LINES);
  297. for (index = 0; index <= nSlices; index += nSpokes, vec_ptr += nSpokes)
  298. {
  299. rim[0] = centre->x + vec_ptr->x * radius;
  300. rim[1] = centre->y + vec_ptr->y * radius;
  301. glVertex3fv(c);
  302. glVertex3fv(rim);
  303. }
  304. glEnd();
  305. }
  306. break;
  307. default:
  308. break;
  309. }
  310. if (glCapFeatureExists(GL_LINE_SMOOTH))
  311. {
  312. glDisable(GL_BLEND);
  313. glDisable(GL_LINE_SMOOTH);
  314. }
  315. }
  316. /*-----------------------------------------------------------------------------
  317. Name : primCircleOutlineZ
  318. Description : Similar to the previous function, except that it has no spokes
  319. and is optimized for circles aligned to the Z-axis.
  320. Inputs : centre - where to draw it.
  321. radius - obvious
  322. nSegments - number of line segments to make up the circle
  323. c - color to draw in
  324. Outputs :
  325. Return :
  326. ----------------------------------------------------------------------------*/
  327. void primCircleOutlineZ(vector *centre, real32 radius, sdword nSegments, color c)
  328. {
  329. //now that primCircleOutline3 has been optimized, it is faster than this one
  330. //this one can probably still be tweaked even further, so I'll leave it here
  331. primCircleOutline3(centre, radius, nSegments, 0, c, Z_AXIS);
  332. /*
  333. GLfloat rim[3];
  334. double theta, thetaDelta;
  335. real32 x, y;
  336. theta = 0.0f;
  337. thetaDelta = 2.0 * PI / (double)nSegments;
  338. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  339. rndGLStateLog("primCircleOutlineZ");
  340. x = centre->x;
  341. y = centre->y;
  342. rim[2] = centre->z;
  343. glBegin(GL_LINE_STRIP);
  344. for (; nSegments >= 0; nSegments--)
  345. {
  346. rim[0] = x + (real32)sin(theta) * radius;
  347. rim[1] = y + (real32)cos(theta) * radius;
  348. glVertex3fv(rim);
  349. theta += thetaDelta;
  350. }
  351. glEnd();
  352. */
  353. }
  354. /*-----------------------------------------------------------------------------
  355. Name : primEllipseOutlineZ
  356. Description : Draw an axis-aligned ellipse centred about a specified point on the Z plane
  357. Inputs : centre - centre of the ellipse
  358. rx - x - axis radius
  359. ry - y - axis radius
  360. nSegments - number of segments
  361. c - color of ellipse
  362. Outputs :
  363. Return :
  364. ----------------------------------------------------------------------------*/
  365. void primEllipseOutlineZ(vector *centre, real32 rx, real32 ry, sdword nSegments, color c)
  366. {
  367. GLfloat rim[3];
  368. double theta, thetaDelta;
  369. real32 x, y;
  370. theta = 0.0f;
  371. thetaDelta = 2.0 * PI / (double)nSegments;
  372. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  373. x = centre->x;
  374. y = centre->y;
  375. rim[2] = centre->z;
  376. glBegin(GL_LINE_STRIP);
  377. for (; nSegments >= 0; nSegments--)
  378. {
  379. rim[0] = x + (real32)sin(theta) * rx;
  380. rim[1] = y + (real32)cos(theta) * ry;
  381. glVertex3fv(rim);
  382. theta += thetaDelta;
  383. }
  384. glEnd();
  385. }
  386. /*-----------------------------------------------------------------------------
  387. Name : primPoint3
  388. Description : Draw a 3D point
  389. Inputs : p1 - location of point
  390. c - color of point
  391. Outputs :
  392. Return : void
  393. ----------------------------------------------------------------------------*/
  394. void primPoint3(vector *p1, color c)
  395. {
  396. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  397. glBegin(GL_POINTS);
  398. glVertex3f(p1->x, p1->y, p1->z); //!!! no size
  399. glEnd();
  400. }
  401. static bool gFastBlends;
  402. static bool gWasBlending;
  403. /*-----------------------------------------------------------------------------
  404. Name : primBeginPointSize3Fade
  405. Description : begin drawing multiple 3D points
  406. Inputs : size - size of point (ie. 1.0f, 2.0f, ...)
  407. Outputs :
  408. Return :
  409. ----------------------------------------------------------------------------*/
  410. void primBeginPointSize3Fade(real32 size)
  411. {
  412. if (glCapFeatureExists(GL_POINT_SIZE))
  413. {
  414. glPointSize(size);
  415. }
  416. gFastBlends = glCapFastFeature(GL_BLEND);
  417. if (gFastBlends)
  418. {
  419. gWasBlending = glIsEnabled(GL_BLEND);
  420. if (!gWasBlending)
  421. {
  422. glEnable(GL_BLEND);
  423. }
  424. rndAdditiveBlends(FALSE);
  425. }
  426. glBegin(GL_POINTS);
  427. }
  428. /*-----------------------------------------------------------------------------
  429. Name : primNextPointSize3Fade
  430. Description : render a 3D point (call from inside Begin/End block only)
  431. Inputs : p1 - location of point
  432. c - color of point
  433. fade - fadeness of point (1.0f == no fade, 0.0f == faded to black)
  434. Outputs :
  435. Return :
  436. ----------------------------------------------------------------------------*/
  437. void primNextPointSize3Fade(vector* p1, color c, real32 fade)
  438. {
  439. sdword ifade = (sdword)(fade * 255.0f);
  440. if (gFastBlends)
  441. {
  442. glColor4ub((GLubyte)colRed(c),
  443. (GLubyte)colGreen(c),
  444. (GLubyte)colBlue(c),
  445. (GLubyte)ifade);
  446. }
  447. else
  448. {
  449. glColor3ub((GLubyte)(((sdword)colRed(c) * ifade) >> 8),
  450. (GLubyte)(((sdword)colGreen(c) * ifade) >> 8),
  451. (GLubyte)(((sdword)colBlue(c) * ifade) >> 8));
  452. }
  453. }
  454. /*-----------------------------------------------------------------------------
  455. Name : primEndPointSize3Fade
  456. Description : end multiple point mode
  457. Inputs :
  458. Outputs :
  459. Return :
  460. ----------------------------------------------------------------------------*/
  461. void primEndPointSize3Fade(void)
  462. {
  463. glEnd();
  464. if (gFastBlends && !gWasBlending)
  465. {
  466. glDisable(GL_BLEND);
  467. }
  468. }
  469. /*-----------------------------------------------------------------------------
  470. Name : primPointSize3
  471. Description : Draw a 3D point with size
  472. Inputs : p1 - location of point
  473. size - physical size of point
  474. c - color of point
  475. Outputs :
  476. Return : void
  477. ----------------------------------------------------------------------------*/
  478. void primPointSize3(vector *p1, real32 size, color c)
  479. {
  480. glPointSize(size);
  481. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  482. glBegin(GL_POINTS);
  483. glVertex3f(p1->x, p1->y, p1->z); //!!! no size
  484. glEnd();
  485. glPointSize(1.0f);
  486. }
  487. void primPointSize3Fade(vector *p1, real32 size, color c, real32 fade)
  488. {
  489. GLboolean blend = glIsEnabled(GL_BLEND);
  490. if (!blend)
  491. {
  492. glEnable(GL_BLEND);
  493. }
  494. glPointSize(size);
  495. glColor4ub(colRed(c), colGreen(c), colBlue(c), (ubyte)(fade * 255.0f));
  496. glBegin(GL_POINTS);
  497. glVertex3f(p1->x, p1->y, p1->z); //!!! no size
  498. glEnd();
  499. glPointSize(1.0f);
  500. if (!blend)
  501. {
  502. glDisable(GL_BLEND);
  503. }
  504. }
  505. static void primSolidTexture3_multi(vector* p1, real32 size, color c, trhandle tex)
  506. {
  507. real32 halfsize;
  508. texreg* reg;
  509. extern udword gDevcaps;
  510. halfsize = 0.5f * size;
  511. rndTextureEnable(TRUE);
  512. trMakeCurrent(tex);
  513. reg = trStructureGet(tex);
  514. if (bitTest(reg->flags, TRF_Alpha))
  515. {
  516. glEnable(GL_BLEND);
  517. glDisable(GL_ALPHA_TEST);
  518. rndAdditiveBlends(TRUE);
  519. }
  520. glBegin(GL_QUADS);
  521. glColor3ub(colRed(c), colGreen(c), colBlue(c));
  522. glTexCoord2f(0.0f, 0.0f);
  523. glVertex3f(p1->x-halfsize, p1->y-halfsize, 0.0f);
  524. glTexCoord2f(1.0f, 0.0f);
  525. glVertex3f(p1->x+halfsize, p1->y-halfsize, 0.0f);
  526. glTexCoord2f(1.0f, 1.0f);
  527. glVertex3f(p1->x+halfsize, p1->y+halfsize, 0.0f);
  528. glTexCoord2f(0.0f, 1.0f);
  529. glVertex3f(p1->x-halfsize, p1->y+halfsize, 0.0f);
  530. if (!bitTest(gDevcaps, DEVSTAT_NO_GETTEXIMAGE))
  531. {
  532. glColor3ub(172, 172, 172);
  533. glTexCoord2f(0.0f, 0.0f);
  534. glVertex3f(p1->x-halfsize, p1->y-halfsize, 0.0f);
  535. glTexCoord2f(1.0f, 0.0f);
  536. glVertex3f(p1->x+halfsize, p1->y-halfsize, 0.0f);
  537. glTexCoord2f(1.0f, 1.0f);
  538. glVertex3f(p1->x+halfsize, p1->y+halfsize, 0.0f);
  539. glTexCoord2f(0.0f, 1.0f);
  540. glVertex3f(p1->x-halfsize, p1->y+halfsize, 0.0f);
  541. }
  542. glEnd();
  543. glDisable(GL_BLEND);
  544. rndAdditiveBlends(FALSE);
  545. }
  546. /*-----------------------------------------------------------------------------
  547. Name : primSolidTexture3
  548. Description : Draw a 3D point with size
  549. Inputs : p1 - location of point
  550. size - physical size of point
  551. c - color of point
  552. Outputs :
  553. Return : void
  554. ----------------------------------------------------------------------------*/
  555. void primSolidTexture3(vector *p1, real32 size, color c, trhandle tex)
  556. {
  557. real32 halfsize;
  558. real32 biasRed, biasGreen, biasBlue;
  559. texreg* reg;
  560. if (!glCapFeatureExists(RGL_COLOROP_ADD))
  561. {
  562. //multi-pass render to approximate a missing feature
  563. primSolidTexture3_multi(p1, size, c, tex);
  564. return;
  565. }
  566. halfsize = 0.5f * size;
  567. rndTextureEnable(TRUE);
  568. // glDepthMask(GL_FALSE);
  569. trMakeCurrent(tex);
  570. reg = trStructureGet(tex);
  571. if (bitTest(reg->flags, TRF_Alpha))
  572. {
  573. glEnable(GL_BLEND);
  574. glDisable(GL_ALPHA_TEST);
  575. rndAdditiveBlends(TRUE);
  576. }
  577. biasRed = colReal32(colRed(c));
  578. biasGreen = colReal32(colGreen(c));
  579. biasBlue = colReal32(colBlue(c));
  580. if (RGL)
  581. {
  582. glPixelTransferf(GL_RED_BIAS, biasRed);
  583. glPixelTransferf(GL_GREEN_BIAS, biasGreen);
  584. glPixelTransferf(GL_BLUE_BIAS, biasBlue);
  585. }
  586. glColor3f(biasRed, biasGreen, biasBlue);
  587. glBegin(GL_QUADS);
  588. glTexCoord2f(0.0f, 0.0f);
  589. glVertex3f(p1->x-halfsize, p1->y-halfsize, 0.0f);
  590. glTexCoord2f(1.0f, 0.0f);
  591. glVertex3f(p1->x+halfsize, p1->y-halfsize, 0.0f);
  592. glTexCoord2f(1.0f, 1.0f);
  593. glVertex3f(p1->x+halfsize, p1->y+halfsize, 0.0f);
  594. glTexCoord2f(0.0f, 1.0f);
  595. glVertex3f(p1->x-halfsize, p1->y+halfsize, 0.0f);
  596. glEnd();
  597. if (RGL)
  598. {
  599. glPixelTransferf(GL_RED_BIAS, 0.0f);
  600. glPixelTransferf(GL_GREEN_BIAS, 0.0f);
  601. glPixelTransferf(GL_BLUE_BIAS, 0.0f);
  602. }
  603. glDisable(GL_BLEND);
  604. // glDepthMask(GL_TRUE);
  605. rndAdditiveBlends(FALSE);
  606. }
  607. void primSolidTexture3Fade(vector *p1, real32 size, color c, trhandle tex, real32 fade)
  608. {
  609. real32 halfsize = size / 2;
  610. real32 biasRed, biasGreen, biasBlue;
  611. texreg* reg;
  612. rndTextureEnable(TRUE);
  613. trMakeCurrent(tex);
  614. reg = trStructureGet(tex);
  615. if (bitTest(reg->flags, TRF_Alpha))
  616. {
  617. glEnable(GL_BLEND);
  618. glDisable(GL_ALPHA_TEST);
  619. rndAdditiveBlends(TRUE);
  620. }
  621. biasRed = colReal32(colRed(c));
  622. biasGreen = colReal32(colGreen(c));
  623. biasBlue = colReal32(colBlue(c));
  624. if (RGL)
  625. {
  626. glPixelTransferf(GL_RED_BIAS, biasRed);
  627. glPixelTransferf(GL_GREEN_BIAS, biasGreen);
  628. glPixelTransferf(GL_BLUE_BIAS, biasBlue);
  629. }
  630. glColor4f(biasRed, biasGreen, biasBlue, fade);
  631. glBegin(GL_QUADS);
  632. glTexCoord2f(0.0f, 0.0f);
  633. glVertex3f(p1->x-halfsize, p1->y-halfsize, 0.0f);
  634. glTexCoord2f(1.0f, 0.0f);
  635. glVertex3f(p1->x+halfsize, p1->y-halfsize, 0.0f);
  636. glTexCoord2f(1.0f, 1.0f);
  637. glVertex3f(p1->x+halfsize, p1->y+halfsize, 0.0f);
  638. glTexCoord2f(0.0f, 1.0f);
  639. glVertex3f(p1->x-halfsize, p1->y+halfsize, 0.0f);
  640. glEnd();
  641. if (RGL)
  642. {
  643. glPixelTransferf(GL_RED_BIAS, 0.0f);
  644. glPixelTransferf(GL_GREEN_BIAS, 0.0f);
  645. glPixelTransferf(GL_BLUE_BIAS, 0.0f);
  646. }
  647. glDisable(GL_BLEND);
  648. rndAdditiveBlends(FALSE);
  649. }
  650. /*-----------------------------------------------------------------------------
  651. Name : prim3dStartup
  652. Description : Initializes some 3d drawing structures
  653. Inputs :
  654. Outputs : Initializes the circle vertice list
  655. Return : void
  656. ----------------------------------------------------------------------------*/
  657. void prim3dStartup(void)
  658. {
  659. listInit(&CircleList);
  660. }
  661. /*-----------------------------------------------------------------------------
  662. Name : prim3dShutdown
  663. Description : Performs shutdown on 3d drawing structures
  664. Inputs :
  665. Outputs : Deallocates the circle vertice list
  666. Return : void
  667. ----------------------------------------------------------------------------*/
  668. void prim3dShutdown(void)
  669. {
  670. listDeleteAll(&CircleList);
  671. }