2 PrtView plugin for GtkRadiant
\r
3 Copyright (C) 2001 Geoffrey Dewan, Loki software and qeradiant.com
\r
5 This library is free software; you can redistribute it and/or
\r
6 modify it under the terms of the GNU Lesser General Public
\r
7 License as published by the Free Software Foundation; either
\r
8 version 2.1 of the License, or (at your option) any later version.
\r
10 This library is distributed in the hope that it will be useful,
\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
13 Lesser General Public License for more details.
\r
15 You should have received a copy of the GNU Lesser General Public
\r
16 License along with this library; if not, write to the Free Software
\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
28 #define LINE_BUF 1000
\r
31 CPortalsRender render;
\r
33 int compare( const void *arg1, const void *arg2 )
\r
36 if(portals.portal[*((int *)arg1)].dist > portals.portal[*((int *)arg2)].dist)
\r
38 else if(portals.portal[*((int *)arg1)].dist < portals.portal[*((int *)arg2)].dist)
\r
45 CBspPortal::CBspPortal()
\r
47 memset(this, 0, sizeof(CBspPortal));
\r
50 CBspPortal::~CBspPortal()
\r
53 delete[] inner_point;
\r
56 qboolean CBspPortal::Build(char *def)
\r
63 if(portals.hint_flags)
\r
65 res_cnt = sscanf(def, "%u %d %d %d", &point_count, &dummy1, &dummy2, (int *)&hint);
\r
69 sscanf(def, "%u", &point_count);
\r
73 if(point_count < 3 || (portals.hint_flags && res_cnt < 4))
\r
76 point = new CBspPoint[point_count];
\r
77 inner_point = new CBspPoint[point_count];
\r
79 for(n = 0; n < point_count; n++)
\r
81 for(; *c != 0 && *c != '('; c++);
\r
88 sscanf(c, "%f %f %f", point[n].p, point[n].p+1, point[n].p+2);
\r
90 center.p[0] += point[n].p[0];
\r
91 center.p[1] += point[n].p[1];
\r
92 center.p[2] += point[n].p[2];
\r
96 for(i = 0; i < 3; i++)
\r
98 min[i] = point[n].p[i];
\r
99 max[i] = point[n].p[i];
\r
104 for(i = 0; i < 3; i++)
\r
106 if(min[i] > point[n].p[i])
\r
107 min[i] = point[n].p[i];
\r
108 if(max[i] < point[n].p[i])
\r
109 max[i] = point[n].p[i];
\r
114 center.p[0] /= (float)point_count;
\r
115 center.p[1] /= (float)point_count;
\r
116 center.p[2] /= (float)point_count;
\r
118 for(n = 0; n < point_count; n++)
\r
120 inner_point[n].p[0] = (0.01f * center.p[0]) + (0.99f * point[n].p[0]);
\r
121 inner_point[n].p[1] = (0.01f * center.p[1]) + (0.99f * point[n].p[1]);
\r
122 inner_point[n].p[2] = (0.01f * center.p[2]) + (0.99f * point[n].p[2]);
\r
125 fp_color_random[0] = (float)(rand() & 0xff) / 255.0f;
\r
126 fp_color_random[1] = (float)(rand() & 0xff) / 255.0f;
\r
127 fp_color_random[2] = (float)(rand() & 0xff) / 255.0f;
\r
128 fp_color_random[3] = 1.0f;
\r
133 CPortals::CPortals()
\r
135 memset(this, 0, sizeof(CPortals));
\r
138 CPortals::~CPortals()
\r
143 void CPortals::Purge()
\r
146 delete[] portal_sort;
\r
148 portal_sort = NULL;
\r
158 void CPortals::Load()
\r
160 char buf[LINE_BUF+1];
\r
162 memset(buf, 0, LINE_BUF + 1);
\r
166 Sys_Printf(MSG_PREFIX "Loading portal file %s.\n", fn);
\r
170 in = fopen(fn, "rt");
\r
174 Sys_Printf(" ERROR - could not open file.\n");
\r
179 if(!fgets(buf, LINE_BUF, in))
\r
183 Sys_Printf(" ERROR - File ended prematurely.\n");
\r
188 if(strncmp("PRT1", buf, 4) != 0)
\r
192 Sys_Printf(" ERROR - File header indicates wrong file type (should be \"PRT1\").\n");
\r
197 if(!fgets(buf, LINE_BUF, in))
\r
201 Sys_Printf(" ERROR - File ended prematurely.\n");
\r
206 sscanf(buf, "%u", &node_count);
\r
208 if(node_count > 0xFFFF)
\r
214 Sys_Printf(" ERROR - Extreme number of nodes, aborting.\n");
\r
220 if(!fgets(buf, LINE_BUF, in))
\r
226 Sys_Printf(" ERROR - File ended prematurely.\n");
\r
231 sscanf(buf, "%u", &portal_count);
\r
233 if(portal_count > 0xFFFF)
\r
240 Sys_Printf(" ERROR - Extreme number of portals, aborting.\n");
\r
245 if(portal_count < 0)
\r
252 Sys_Printf(" ERROR - number of portals equals 0, aborting.\n");
\r
257 // node = new CBspNode[node_count];
\r
258 portal = new CBspPortal[portal_count];
\r
259 portal_sort = new int[portal_count];
\r
262 qboolean first = TRUE;
\r
263 unsigned test_vals_1, test_vals_2;
\r
265 hint_flags = FALSE;
\r
267 for(n = 0; n < portal_count; )
\r
269 if(!fgets(buf, LINE_BUF, in))
\r
275 Sys_Printf(" ERROR - Could not find information for portal number %d of %d.\n", n + 1, portal_count);
\r
280 if(!portal[n].Build(buf))
\r
282 if(first && sscanf(buf, "%d %d", &test_vals_1, &test_vals_2) == 1) // skip additional counts of later data, not needed
\r
284 // We can count on hint flags being in the file
\r
295 Sys_Printf(" ERROR - Information for portal number %d of %d is not formatted correctly.\n", n + 1, portal_count);
\r
305 Sys_Printf(" %u portals read in.\n", node_count, portal_count);
\r
308 void CPortals::FixColors()
\r
310 fp_color_2d[0] = (float)GetRValue(color_2d) / 255.0f;
\r
311 fp_color_2d[1] = (float)GetGValue(color_2d) / 255.0f;
\r
312 fp_color_2d[2] = (float)GetBValue(color_2d) / 255.0f;
\r
313 fp_color_2d[3] = 1.0f;
\r
315 fp_color_3d[0] = (float)GetRValue(color_3d) / 255.0f;
\r
316 fp_color_3d[1] = (float)GetGValue(color_3d) / 255.0f;
\r
317 fp_color_3d[2] = (float)GetBValue(color_3d) / 255.0f;
\r
318 fp_color_3d[3] = 1.0f;
\r
320 fp_color_fog[0] = 0.0f;//(float)GetRValue(color_fog) / 255.0f;
\r
321 fp_color_fog[1] = 0.0f;//(float)GetGValue(color_fog) / 255.0f;
\r
322 fp_color_fog[2] = 0.0f;//(float)GetBValue(color_fog) / 255.0f;
\r
323 fp_color_fog[3] = 1.0f;
\r
326 CPortalsRender::CPortalsRender()
\r
331 CPortalsRender::~CPortalsRender()
\r
335 void CPortalsRender::Register()
\r
337 g_QglTable.m_pfnHookGL2DWindow( this );
\r
338 g_QglTable.m_pfnHookGL3DWindow( this );
\r
341 void CPortalsRender::Draw2D( VIEWTYPE vt )
\r
343 if(!portals.show_2d || portals.portal_count < 1)
\r
346 g_QglTable.m_pfn_qglPushAttrib(GL_ALL_ATTRIB_BITS);
\r
350 g_QglTable.m_pfn_qglEnable(GL_BLEND);
\r
351 g_QglTable.m_pfn_qglEnable(GL_LINE_SMOOTH);
\r
355 g_QglTable.m_pfn_qglDisable(GL_BLEND);
\r
356 g_QglTable.m_pfn_qglEnable(GL_LINE_SMOOTH);
\r
364 g_QglTable.m_pfn_qglRotatef(270.0f, 1.0f, 0.0f, 0.0f);
\r
367 g_QglTable.m_pfn_qglRotatef(270.0f, 1.0f, 0.0f, 0.0f);
\r
368 g_QglTable.m_pfn_qglRotatef(270.0f, 0.0f, 0.0f, 1.0f);
\r
372 g_QglTable.m_pfn_qglLineWidth(portals.width_2d * 0.5f);
\r
374 g_QglTable.m_pfn_qglColor4fv(portals.fp_color_2d);
\r
378 for(n = 0; n < portals.portal_count; n++)
\r
380 g_QglTable.m_pfn_qglBegin(GL_LINE_LOOP);
\r
382 for(p = 0; p < portals.portal[n].point_count; p++)
\r
383 g_QglTable.m_pfn_qglVertex3fv(portals.portal[n].point[p].p);
\r
385 g_QglTable.m_pfn_qglEnd();
\r
388 g_QglTable.m_pfn_qglPopAttrib();
\r
392 * Transform a point (column vector) by a 4x4 matrix. I.e. out = m * in
\r
393 * Input: m - the 4x4 matrix
\r
394 * in - the 4x1 vector
\r
395 * Output: out - the resulting 4x1 vector.
\r
397 static void transform_point( GLdouble out[4], const GLdouble m[16],
\r
398 const GLdouble in[4] )
\r
400 #define M(row,col) m[col*4+row]
\r
401 out[0] = M(0,0) * in[0] + M(0,1) * in[1] + M(0,2) * in[2] + M(0,3) * in[3];
\r
402 out[1] = M(1,0) * in[0] + M(1,1) * in[1] + M(1,2) * in[2] + M(1,3) * in[3];
\r
403 out[2] = M(2,0) * in[0] + M(2,1) * in[1] + M(2,2) * in[2] + M(2,3) * in[3];
\r
404 out[3] = M(3,0) * in[0] + M(3,1) * in[1] + M(3,2) * in[2] + M(3,3) * in[3];
\r
412 * Perform a 4x4 matrix multiplication (product = a x b).
\r
413 * Input: a, b - matrices to multiply
\r
414 * Output: product - product of a and b
\r
416 static void matmul( GLdouble *product, const GLdouble *a, const GLdouble *b )
\r
418 /* This matmul was contributed by Thomas Malik */
\r
422 #define A(row,col) a[(col<<2)+row]
\r
423 #define B(row,col) b[(col<<2)+row]
\r
424 #define T(row,col) temp[(col<<2)+row]
\r
427 for (i = 0; i < 4; i++)
\r
429 T(i, 0) = A(i, 0) * B(0, 0) + A(i, 1) * B(1, 0) + A(i, 2) * B(2, 0) + A(i, 3) * B(3, 0);
\r
430 T(i, 1) = A(i, 0) * B(0, 1) + A(i, 1) * B(1, 1) + A(i, 2) * B(2, 1) + A(i, 3) * B(3, 1);
\r
431 T(i, 2) = A(i, 0) * B(0, 2) + A(i, 1) * B(1, 2) + A(i, 2) * B(2, 2) + A(i, 3) * B(3, 2);
\r
432 T(i, 3) = A(i, 0) * B(0, 3) + A(i, 1) * B(1, 3) + A(i, 2) * B(2, 3) + A(i, 3) * B(3, 3);
\r
438 memcpy ( product, temp, 16*sizeof(GLdouble) );
\r
444 * Compute inverse of 4x4 transformation matrix.
\r
445 * Code contributed by Jacques Leroy jle@star.be
\r
446 * Return GL_TRUE for success, GL_FALSE for failure (singular matrix)
\r
448 static GLboolean invert_matrix( const GLdouble *m, GLdouble *out )
\r
450 /* NB. OpenGL Matrices are COLUMN major. */
\r
451 #define SWAP_ROWS(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; }
\r
452 #define MAT(m,r,c) (m)[(c)*4+(r)]
\r
454 GLdouble wtmp[4][8];
\r
455 GLdouble m0, m1, m2, m3, s;
\r
456 GLdouble *r0, *r1, *r2, *r3;
\r
458 r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
\r
460 r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
\r
461 r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
\r
462 r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
\r
464 r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
\r
465 r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
\r
466 r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
\r
468 r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
\r
469 r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
\r
470 r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
\r
472 r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
\r
473 r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
\r
474 r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
\r
476 /* choose pivot - or die */
\r
477 if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
\r
478 if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
\r
479 if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
\r
480 if (0.0 == r0[0]) return GL_FALSE;
\r
482 /* eliminate first variable */
\r
483 m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
\r
484 s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
\r
485 s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
\r
486 s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
\r
488 if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
\r
490 if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
\r
492 if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
\r
494 if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
\r
496 /* choose pivot - or die */
\r
497 if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
\r
498 if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
\r
499 if (0.0 == r1[1]) return GL_FALSE;
\r
501 /* eliminate second variable */
\r
502 m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
\r
503 r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
\r
504 r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
\r
505 s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
\r
506 s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
\r
507 s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
\r
508 s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
\r
510 /* choose pivot - or die */
\r
511 if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
\r
512 if (0.0 == r2[2]) return GL_FALSE;
\r
514 /* eliminate third variable */
\r
516 r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
\r
517 r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
\r
518 r3[7] -= m3 * r2[7];
\r
521 if (0.0 == r3[3]) return GL_FALSE;
\r
523 s = 1.0/r3[3]; /* now back substitute row 3 */
\r
524 r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
\r
526 m2 = r2[3]; /* now back substitute row 2 */
\r
528 r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
\r
529 r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
\r
531 r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
\r
532 r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
\r
534 r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
\r
535 r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
\r
537 m1 = r1[2]; /* now back substitute row 1 */
\r
539 r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
\r
540 r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
\r
542 r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
\r
543 r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
\r
545 m0 = r0[1]; /* now back substitute row 0 */
\r
547 r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
\r
548 r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
\r
550 MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5],
\r
551 MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7],
\r
552 MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5],
\r
553 MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7],
\r
554 MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5],
\r
555 MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7],
\r
556 MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5],
\r
557 MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7];
\r
565 GLint UnProject(GLdouble winx,GLdouble winy,GLdouble winz,
\r
566 const GLdouble model[16],const GLdouble proj[16],
\r
567 const GLint viewport[4],
\r
568 GLdouble *objx,GLdouble *objy,GLdouble *objz)
\r
570 /* matrice de transformation */
\r
571 GLdouble m[16], A[16];
\r
572 GLdouble in[4],out[4];
\r
574 /* transformation coordonnees normalisees entre -1 et 1 */
\r
575 in[0]=(winx-viewport[0])*2/viewport[2] - 1.0;
\r
576 in[1]=(winy-viewport[1])*2/viewport[3] - 1.0;
\r
577 in[2]=2*winz - 1.0;
\r
580 /* calcul transformation inverse */
\r
581 matmul(A,proj,model);
\r
582 invert_matrix(A,m);
\r
584 /* d'ou les coordonnees objets */
\r
585 transform_point(out,m,in);
\r
588 *objx=out[0]/out[3];
\r
589 *objy=out[1]/out[3];
\r
590 *objz=out[2]/out[3];
\r
594 void CPortalsRender::Draw3D()
\r
596 if(!portals.show_3d || portals.portal_count < 1)
\r
599 g_QglTable.m_pfn_qglPushAttrib(GL_ALL_ATTRIB_BITS);
\r
603 double model_m[16];
\r
604 float min_check[3];
\r
605 float max_check[3];
\r
606 float trans = (100.0f - portals.trans_3d) / 100.0f;
\r
609 g_QglTable.m_pfn_qglGetDoublev(GL_PROJECTION_MATRIX, proj_m);
\r
610 g_QglTable.m_pfn_qglGetDoublev(GL_MODELVIEW_MATRIX, model_m);
\r
611 g_QglTable.m_pfn_qglGetIntegerv(GL_VIEWPORT, view);
\r
613 UnProject(0.5 * (double)view[2], 0.5 * (double)view[3], 0.0, model_m, proj_m, view, cam, cam+1, cam+2);
\r
615 min_check[0] = (float)cam[0] + (portals.clip_range * 64.0f);
\r
616 min_check[1] = (float)cam[1] + (portals.clip_range * 64.0f);
\r
617 min_check[2] = (float)cam[2] + (portals.clip_range * 64.0f);
\r
618 max_check[0] = (float)cam[0] - (portals.clip_range * 64.0f);
\r
619 max_check[1] = (float)cam[1] - (portals.clip_range * 64.0f);
\r
620 max_check[2] = (float)cam[2] - (portals.clip_range * 64.0f);
\r
622 g_QglTable.m_pfn_qglHint(GL_FOG_HINT, GL_NICEST);
\r
624 g_QglTable.m_pfn_qglDisable(GL_CULL_FACE);
\r
626 g_QglTable.m_pfn_qglDisable(GL_LINE_SMOOTH);
\r
627 g_QglTable.m_pfn_qglDisable(GL_POLYGON_SMOOTH);
\r
629 g_QglTable.m_pfn_qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
\r
631 g_QglTable.m_pfn_qglShadeModel(GL_SMOOTH);
\r
633 g_QglTable.m_pfn_qglEnable(GL_BLEND);
\r
634 g_QglTable.m_pfn_qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
\r
635 g_QglTable.m_pfn_qglEnable(GL_POLYGON_SMOOTH);
\r
638 g_QglTable.m_pfn_qglEnable(GL_LINE_SMOOTH);
\r
640 g_QglTable.m_pfn_qglDisable(GL_LINE_SMOOTH);
\r
644 g_QglTable.m_pfn_qglEnable(GL_FOG);
\r
646 g_QglTable.m_pfn_qglFogi(GL_FOG_MODE, GL_EXP);
\r
647 g_QglTable.m_pfn_qglFogf(GL_FOG_DENSITY, 0.001f);
\r
648 g_QglTable.m_pfn_qglFogf(GL_FOG_START, 10.0f);
\r
649 g_QglTable.m_pfn_qglFogf(GL_FOG_END, 10000.0f);
\r
650 g_QglTable.m_pfn_qglFogi(GL_FOG_INDEX, 0);
\r
651 g_QglTable.m_pfn_qglFogfv(GL_FOG_COLOR, portals.fp_color_fog);
\r
655 g_QglTable.m_pfn_qglDisable(GL_FOG);
\r
658 switch(portals.zbuffer)
\r
661 g_QglTable.m_pfn_qglEnable(GL_DEPTH_TEST);
\r
662 g_QglTable.m_pfn_qglDepthMask(GL_FALSE);
\r
665 g_QglTable.m_pfn_qglDisable(GL_DEPTH_TEST);
\r
668 g_QglTable.m_pfn_qglEnable(GL_DEPTH_TEST);
\r
669 g_QglTable.m_pfn_qglDepthMask(GL_TRUE);
\r
672 g_QglTable.m_pfn_qglLineWidth(portals.width_3d * 0.5f);
\r
676 if(portals.polygons)
\r
678 if(portals.zbuffer != 0)
\r
682 for(n = 0; n < portals.portal_count; n++)
\r
684 d = (float)cam[0] - portals.portal[n].center.p[0];
\r
685 portals.portal[n].dist = d * d;
\r
687 d = (float)cam[1] - portals.portal[n].center.p[1];
\r
688 portals.portal[n].dist += d * d;
\r
690 d = (float)cam[2] - portals.portal[n].center.p[2];
\r
691 portals.portal[n].dist += d * d;
\r
693 portals.portal_sort[n] = n;
\r
696 qsort(portals.portal_sort, portals.portal_count, 4, compare);
\r
698 for(n = 0; n < portals.portal_count; n++)
\r
700 if(portals.polygons == 2 && !portals.portal[portals.portal_sort[n]].hint)
\r
705 if(min_check[0] < portals.portal[portals.portal_sort[n]].min[0])
\r
707 else if(min_check[1] < portals.portal[portals.portal_sort[n]].min[1])
\r
709 else if(min_check[2] < portals.portal[portals.portal_sort[n]].min[2])
\r
711 else if(max_check[0] > portals.portal[portals.portal_sort[n]].max[0])
\r
713 else if(max_check[1] > portals.portal[portals.portal_sort[n]].max[1])
\r
715 else if(max_check[2] > portals.portal[portals.portal_sort[n]].max[2])
\r
719 g_QglTable.m_pfn_qglColor4f(portals.portal[portals.portal_sort[n]].fp_color_random[0], portals.portal[portals.portal_sort[n]].fp_color_random[1],
\r
720 portals.portal[portals.portal_sort[n]].fp_color_random[2], trans);
\r
722 g_QglTable.m_pfn_qglBegin(GL_POLYGON);
\r
724 for(p = 0; p < portals.portal[portals.portal_sort[n]].point_count; p++)
\r
725 g_QglTable.m_pfn_qglVertex3fv(portals.portal[portals.portal_sort[n]].point[p].p);
\r
727 g_QglTable.m_pfn_qglEnd();
\r
732 for(n = 0; n < portals.portal_count; n++)
\r
734 if(portals.polygons == 2 && !portals.portal[n].hint)
\r
739 if(min_check[0] < portals.portal[n].min[0])
\r
741 else if(min_check[1] < portals.portal[n].min[1])
\r
743 else if(min_check[2] < portals.portal[n].min[2])
\r
745 else if(max_check[0] > portals.portal[n].max[0])
\r
747 else if(max_check[1] > portals.portal[n].max[1])
\r
749 else if(max_check[2] > portals.portal[n].max[2])
\r
753 g_QglTable.m_pfn_qglColor4f(portals.portal[n].fp_color_random[0], portals.portal[n].fp_color_random[1],
\r
754 portals.portal[n].fp_color_random[2], trans);
\r
756 g_QglTable.m_pfn_qglBegin(GL_POLYGON);
\r
758 for(p = 0; p < portals.portal[n].point_count; p++)
\r
759 g_QglTable.m_pfn_qglVertex3fv(portals.portal[n].point[p].p);
\r
761 g_QglTable.m_pfn_qglEnd();
\r
768 g_QglTable.m_pfn_qglColor4fv(portals.fp_color_3d);
\r
770 for(n = 0; n < portals.portal_count; n++)
\r
772 if(portals.lines == 2 && !portals.portal[n].hint)
\r
777 if(min_check[0] < portals.portal[n].min[0])
\r
779 else if(min_check[1] < portals.portal[n].min[1])
\r
781 else if(min_check[2] < portals.portal[n].min[2])
\r
783 else if(max_check[0] > portals.portal[n].max[0])
\r
785 else if(max_check[1] > portals.portal[n].max[1])
\r
787 else if(max_check[2] > portals.portal[n].max[2])
\r
791 g_QglTable.m_pfn_qglBegin(GL_LINE_LOOP);
\r
793 for(p = 0; p < portals.portal[n].point_count; p++)
\r
794 g_QglTable.m_pfn_qglVertex3fv(portals.portal[n].inner_point[p].p);
\r
796 g_QglTable.m_pfn_qglEnd();
\r
800 g_QglTable.m_pfn_qglPopAttrib();
\r