1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25 /*
26 * $Id: rmdraw2.c,v 1.20 2005/07/02 17:48:45 wes Exp $
27 * Version: $Name: OpenRM-1-6-0-2-RC2 $
28 * $Revision: 1.20 $
29 * $Log: rmdraw2.c,v $
30 * Revision 1.20 2005/07/02 17:48:45 wes
31 * Updated rasterpos offset code for sprites to support 3D as well as 2D.
32 * Some minor z-coordinate buglets remain for 3D sprite positioning - see
33 * the comments in code for details.
34 *
35 * Revision 1.19 2005/06/26 18:50:11 wes
36 * Numerous updates:
37 * (1) Correct computation of viewport matrix, stuff into RMstate.
38 * (2) Refine code that repositions the glRasterPosition for RM_SPRITE primitives;
39 * works well in 2D, still needs a little help for 3D.
40 * (3) Update RM_SPRITE draw code to take into account text justification parms.
41 *
42 * Revision 1.18 2005/06/06 02:04:29 wes
43 * Lots of small additions to clean up compiler warnings.
44 *
45 * Revision 1.17 2005/05/28 16:25:57 wes
46 * Fixed bug where the pickable quad associated with bitmap-based
47 * primitives (RM_BITMAP, RM_TEXT, etc.) was incorrectly placed when
48 * text justification attributes RM_CENTER or RM_RIGHT were in effect.
49 *
50 * Revision 1.16 2005/05/16 01:01:37 wes
51 * Update some primitive draw routines to use private_rmSetGLTexCoordFunc
52 * to obtain the correct OpenGL texture coordinate function.
53 *
54 * Revision 1.15 2005/05/15 15:20:42 wes
55 * New internal routine to set the appropriate OpenGL texture coordinate function
56 * as a function of RMprimitive TC data characteristics.
57 *
58 * Revision 1.14 2005/05/06 16:35:26 wes
59 * Fixed buglet whereby prims specified with 0 verts would generate an
60 * incomplete OpenGL display list, thereby causing a domino-effect
61 * of errors.
62 *
63 * Revision 1.13 2005/03/16 16:43:17 wes
64 * Fixed a text rendering bug introduced during code merge.
65 *
66 * Revision 1.12 2005/02/27 19:34:04 wes
67 * Added support for application supplied texture object IDs and display lists.
68 *
69 * Revision 1.11 2005/02/19 16:23:56 wes
70 * Distro sync and consolidation.
71 * Added support for multitexturing.
72 *
73 * Revision 1.10 2005/02/12 00:54:50 wes
74 * Preliminary multitexturing support for RMprimitives: qmesh, quads, tstrip,
75 * triangles, and indexed triangles.
76 *
77 * Revision 1.9 2005/01/23 17:00:22 wes
78 * Copyright updated to 2005.
79 *
80 * Revision 1.8 2004/09/28 00:45:13 wes
81 * Modified rmQuads to support per-face colors and/or normals. Moved
82 * rmQuads from rmdraw1.c to rmdraw2.c
83 *
84 * Revision 1.7 2004/03/10 01:47:06 wes
85 * Added rendering code for RM_INDEXED_QUAD_STRIP prim type.
86 *
87 * Revision 1.6 2004/02/23 03:04:32 wes
88 * New primitives: RM_QUAD_STRIP, RM_INDEXED_TRIANGLES, RM_INDEXED_QUADS,
89 * RM_INDEXED_TRIANGLE_STRIP.
90 *
91 * Revision 1.5 2004/01/16 16:44:05 wes
92 * Updated copyright line for 2004.
93 *
94 * Revision 1.4 2003/10/03 19:21:17 wes
95 * Improved error checking and reporting in the rmText rendering function.
96 *
97 * Revision 1.3 2003/07/20 14:44:41 wes
98 * Modified some declarations for RM support routines to support per-line
99 * color in the disjoint lines primitives.
100 *
101 * Revision 1.2 2003/02/02 02:07:15 wes
102 * Updated copyright to 2003.
103 *
104 * Revision 1.1.1.1 2003/01/28 02:15:23 wes
105 * Manual rebuild of rm150 repository.
106 *
107 * Revision 1.17 2003/01/16 22:21:17 wes
108 * Updated all source files to reflect new organization of header files:
109 * all header files formerly located in include/rmaux, include/rmi, include/rmv
110 * are now located in include/rm.
111 *
112 * Revision 1.16 2002/12/02 16:24:56 wes
113 * Bug fixes:
114 * (1) fixed memory leak in rmPrimitiveSetText;
115 * (2) fixed problem with textProps not being applied to 2nd and later
116 * strings in an RM_TEXT text primitive.
117 *
118 * Revision 1.15 2002/11/14 15:34:51 wes
119 * Minor editing for beautification.
120 *
121 * Revision 1.14 2002/08/29 22:20:32 wes
122 *
123 * Massive upgrade to accommodate dynamic object reallocation within
124 * the component manager, and within the context cache. Use the
125 * debug #define DEBUG_LEVEL DEBUG_REALLOC_TRACE to get a printf
126 * whenever a realloc occurs. With this upgrade, there are no
127 * OpenRM limits on the size of the scene graph. There will be external
128 * limits, such as the amount of RAM and the amount of space available
129 * to your OpenGL implementation.
130 *
131 * Revision 1.13 2002/06/17 00:57:01 wes
132 * Fixed numerical problem related to calcuation of quad used when doing
133 * GL_SELECT on bitmaps, sprites and text. Condensed the code used to
134 * compute and draw those pickable quads; the new routines make use of
135 * the internal routine private_rmNewWCfromDCOffset rather than compute
136 * it separately. Added SHOW_PICKABLE_QUADS #define to draw the pickable
137 * quads during normal rendering for visual reality check.
138 *
139 * Revision 1.12 2002/06/02 15:14:18 wes
140 *
141 * Added RMstateCache code to help eliminate the number of state changes
142 * made during the render traversal. The RMstateCache tracks
143 * the actual OpenGL rendering state w/o the need for querying OpenGL
144 * directly, and is queried by draw code that then decides if any
145 * real state changes are required given the configuration of data
146 * within an RMprimitive.
147 *
148 * Revision 1.11 2002/04/30 19:31:22 wes
149 * Fixed a bug in the display of indexed text/bitmap primitives.
150 *
151 * Revision 1.10 2001/10/15 00:04:53 wes
152 * Changed dispatching of characters in rmText from single char at a time
153 * to string at a time. The older code had some debug stuff in it that
154 * checked the raster position after the glVertex2/3f() call, but before
155 * the glBitmap() call. That calling sequence seems to cause problems for
156 * Win32.
157 *
158 * Added an RMstate parm to the parm list for the setup funcs inside
159 * draw routines for lines, text and images. This will cause lighting
160 * to be enabled or disabled as a function of whether or not fogging
161 * is active. It would be nice if fogging could be enabled, but lighting
162 * disabled.
163 *
164 * Revision 1.9 2001/05/26 14:35:49 wes
165 * Added error checking code to rmSprite().
166 *
167 * Revision 1.8 2001/03/31 17:12:38 wes
168 * v1.4.0-alpha-2 checkin.
169 *
170 * Revision 1.7 2000/12/05 03:01:59 wes
171 * Fixed problem with rmText in which default text properties were
172 * malloc'ed, but never free'd.
173 *
174 * Revision 1.6 2000/12/03 22:34:37 wes
175 * Mods for thread safety- RMpipe added as parm to display list
176 * calls.
177 *
178 * Revision 1.5 2000/08/31 02:07:11 wes
179 * No significant changes.
180 *
181 * Revision 1.4 2000/08/23 23:24:21 wes
182 * DO_LISTS define moved from rmogl.c to rmprivat.h. All display
183 * list code removed from rmBitmap (will be reinserted later).
184 *
185 * Revision 1.3 2000/08/19 14:58:29 wes
186 * Culled unused code.
187 *
188 * Revision 1.2 2000/04/20 16:29:47 wes
189 * Documentation additions/enhancements, some code rearragement.
190 *
191 * Revision 1.1.1.1 2000/02/28 21:29:40 wes
192 * OpenRM 1.2 Checkin
193 *
194 * Revision 1.1.1.1 2000/02/28 17:18:48 wes
195 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
196 *
197 */
198
199 #include <rm/rm.h>
200 #include "rmprivat.h"
201 #include "rmprivatps.h"
202
203 /*
204 * 6/12/02 wes
205 * for debugging purposes, you can set SHOW_PICKABLE_QUADS to a
206 * non-zero value. this will cause the pickable quads associated with
207 * rmText, rmBitmap and rmSprite primitives to be drawn *in addition to*
208 * the source bitmap, text or sprite. usually, * these "helper" objects
209 * are not drawn except during selection mode.
210 */
211 #define SHOW_PICKABLE_QUADS 0
212 /*#define SHOW_PICKABLE_QUADS 1 */
213
214
215 /*
216 * this file contains RMprimitive "draw" routines for those
217 * primitives that DO NOT easily map to OpenGL vertex arrays.
218 */
219
220 extern void rmuCone(void (*colorfunc)(const float *), float *color, RMvertex3D *p1, RMvertex3D *p2, float radius1 ,int subdivisions, RMpipe *p);
221
222 /*
223 * Begin glVertex* and pals macro/function layer
224 *
225 * win-32 notes:
226 *
227 * un*x treats glVertex* and cousins as a normal function (pointer).
228 * therefore, it is possible to access those functions through a pointer.
229 * in MS VC, the glVertex* and pals have a verbose declaration which renders
230 * indirect access (via a pointer) next to impossible.
231 *
232 * in order to remedy this situation, we use either macros (UNIX) or
233 * a subroutine layer (win-32) to temporarily work around this problem.
234 *
235 */
236
237 #ifdef RM_WIN
238
239 void
rmglVertex3fv(const GLfloat * v)240 rmglVertex3fv (const GLfloat *v)
241 {
242 glVertex3fv(v);
243 }
244
245 void
rmglVertex2fv(const GLfloat * v)246 rmglVertex2fv (const GLfloat *v)
247 {
248 glVertex2fv(v);
249 }
250
251 void
rmglNormal3fv(const GLfloat * v)252 rmglNormal3fv (const GLfloat *v)
253 {
254 glNormal3fv(v);
255 }
256
257 void
rmglColor3fv(const GLfloat * a)258 rmglColor3fv (const GLfloat *a)
259 {
260 glColor3fv(a);
261 }
262
263 void
rmglColor4fv(const GLfloat * a)264 rmglColor4fv (const GLfloat *a)
265 {
266 glColor4fv(a);
267 }
268
269 void
rmglRasterPos2fv(const GLfloat * v)270 rmglRasterPos2fv (const GLfloat *v)
271 {
272 glRasterPos2fv(v);
273 }
274
275 void
rmglRasterPos3fv(const GLfloat * v)276 rmglRasterPos3fv (const GLfloat *v)
277 {
278 glRasterPos3fv(v);
279 }
280
281 void
rmglTexCoord1fv(const GLfloat * v)282 rmglTexCoord1fv (const GLfloat *v)
283 {
284 glTexCoord1fv(v);
285 }
286
287 void
rmglTexCoord2fv(const GLfloat * v)288 rmglTexCoord2fv (const GLfloat *v)
289 {
290 glTexCoord2fv(v);
291 }
292
293 void
rmglTexCoord3fv(const GLfloat * v)294 rmglTexCoord3fv (const GLfloat *v)
295 {
296 glTexCoord3fv(v);
297 }
298
299 #endif
300
301 /* PRIVATE */
302 void
glNoOp(const float * f)303 glNoOp (const float *f)
304 {
305 /* do nothing */
306 f = NULL; /* foil compiler warning */
307 }
308
309
310 /* PRIVATE */
311 void
private_rmSetGLColorFunc(int cvecsize,int ncolors,void (** cfuncptr)(const float *))312 private_rmSetGLColorFunc (int cvecsize,
313 int ncolors,
314 void (**cfuncptr)(const float *))
315 {
316 /* set OpenGL color routine as a function of the color vector length */
317 if (ncolors == 0 || cvecsize == 0)
318 *cfuncptr = glNoOp;
319 else
320 {
321 if (cvecsize == 3)
322 *cfuncptr = rmglColor3fv;
323 else
324 {
325 if (cvecsize == 4)
326 *cfuncptr = rmglColor4fv;
327 else
328 *cfuncptr = glNoOp; /* warning? */
329 }
330 }
331 }
332
333 /* PRIVATE */
334 void
private_rmSetGLTexCoordFunc(int tcvecsize,int ntc,void (** tcfuncptr)(const float *))335 private_rmSetGLTexCoordFunc (int tcvecsize,
336 int ntc,
337 void (**tcfuncptr)(const float *))
338 {
339 /* set OpenGL texture coord routine as a function of tc vector length */
340 if (ntc == 0 || tcvecsize == 0)
341 *tcfuncptr = glNoOp;
342 else
343 {
344 switch(tcvecsize)
345 {
346 case 2:
347 *tcfuncptr = rmglTexCoord2fv;
348 break;
349 case 3:
350 *tcfuncptr = rmglTexCoord3fv;
351 break;
352 case 1:
353 *tcfuncptr = rmglTexCoord1fv;
354 break;
355 default:
356 rmError("private_rmSetGLTexCoordFunc error: input tcveclen != 1,2, or 3 yet ntc != 0. Please file a bug report. ");
357 break;
358 }
359 }
360 }
361
362
363 /* PRIVATE */
364 void
private_rmStateGetTextJustify(const RMstate * s,RMenum * hjustify,RMenum * vjustify)365 private_rmStateGetTextJustify (const RMstate *s,
366 RMenum *hjustify,
367 RMenum *vjustify)
368 {
369 extern RMenum RM_DEFAULT_HJUSTIFY, RM_DEFAULT_VJUSTIFY;
370
371 if (s->textProps == NULL)
372 {
373 *hjustify = RM_DEFAULT_HJUSTIFY;
374 *vjustify = RM_DEFAULT_VJUSTIFY;
375 }
376 else
377 {
378 *hjustify = s->textProps->hJustify;
379 *vjustify = s->textProps->vJustify;
380 }
381 }
382
383
384 /* precomputed trig tables */
385 #define TRIG_RES 360
386 double cos_table[TRIG_RES], sin_table[TRIG_RES];
387
388 /* PRIVATE */
389 void
private_initTrigTables(void)390 private_initTrigTables (void)
391 {
392 int i;
393 double t, dt;
394
395 t = 0.0;
396 dt = RM_TWO_PI / (double)TRIG_RES;
397
398 for (i = 0; i < TRIG_RES; i++, t += dt)
399 {
400 cos_table[i] = cos(t);
401 sin_table[i] = sin(t);
402 }
403 }
404
405
406 /* PRIVATE */
407 static void
rmuCircle2d(int subdivisions)408 rmuCircle2d (int subdivisions)
409 {
410 int i;
411 float t, dt;
412 float v[2];
413
414 /* draw a unit convex polygon at (0,0) */
415 if (subdivisions > TRIG_RES)
416 subdivisions = TRIG_RES;
417
418 t = 0.0;
419 dt = (float)(TRIG_RES) / (float)(subdivisions);
420
421 glBegin(GL_POLYGON);
422 for (i = 0; i < subdivisions; i++, t += dt)
423 {
424 v[0] = cos_table[(int)t];
425 v[1] = sin_table[(int)t];
426 glVertex2fv(v);
427 }
428 glEnd();
429 }
430
431
432 /* PRIVATE */
433 static void
rmuEllipse2d(int subdivisions,float a,float b)434 rmuEllipse2d (int subdivisions,
435 float a, /* vertical scale */
436 float b) /* horizontal scale */
437 {
438 int i;
439 float t, dt;
440 float v[2];
441
442 /* draw a unit convex polygon at (0,0) with the desired scaling */
443 if (subdivisions > TRIG_RES)
444 subdivisions = TRIG_RES;
445
446 t = 0.0;
447 dt = (float)(TRIG_RES) / (float)(subdivisions);
448
449 glBegin(GL_POLYGON);
450 for (i = 0; i < subdivisions; i++, t += dt)
451 {
452 v[0] = cos_table[(int)t] * b;
453 v[1] = sin_table[(int)t] * a;
454 glVertex2fv(v);
455 }
456 glEnd();
457 }
458
459 /* PRIVATE */
460 static void
private_rmSetupBitmapPickMatrices(RMstate * s,RMmatrix * vpm,RMmatrix * vpm_inv,RMmatrix * forward,RMmatrix * inv)461 private_rmSetupBitmapPickMatrices (RMstate *s,
462 RMmatrix *vpm,
463 RMmatrix *vpm_inv,
464 RMmatrix *forward,
465 RMmatrix *inv)
466 {
467 RMmatrix m;
468
469 rmMatrixIdentity(vpm);
470
471 private_rmComputeViewportMatrix(s->vp, (float)s->w, (float)s->h, vpm);
472
473 rmMatrixInverse(vpm, vpm_inv);
474
475 rmMatrixMultiply(&(s->modelView), &(s->projection), &m);
476 *forward = m;
477
478 rmMatrixInverse(&m, inv);
479 }
480
481 /* PRIVATE */
482 static void
private_rmDrawBitmapPickableQuads(RMmatrix * vpm,RMmatrix * vpm_invOrig,RMmatrix * forwardOrig,RMmatrix * inv,RMvertex3D * v,int horigin,int vorigin,int bitmap_width,int bitmap_height)483 private_rmDrawBitmapPickableQuads (RMmatrix *vpm,
484 RMmatrix *vpm_invOrig,
485 RMmatrix *forwardOrig,
486 RMmatrix *inv,
487 RMvertex3D *v,
488 int horigin,
489 int vorigin,
490 int bitmap_width,
491 int bitmap_height)
492 {
493 RMvertex3D vnew[4];
494
495 private_rmNewWCfromDCOffset(v, -horigin, -vorigin, vnew,
496 vpm, vpm_invOrig, forwardOrig, inv);
497 private_rmNewWCfromDCOffset(v, bitmap_width-horigin, -vorigin, vnew+1,
498 vpm, vpm_invOrig, forwardOrig, inv);
499 private_rmNewWCfromDCOffset(v, bitmap_width-horigin, bitmap_height-vorigin, vnew+2,
500 vpm, vpm_invOrig, forwardOrig, inv);
501 private_rmNewWCfromDCOffset(v, -horigin, bitmap_height-vorigin, vnew+3,
502 vpm, vpm_invOrig, forwardOrig, inv);
503
504 glBegin(GL_QUADS);
505 glVertex3fv((float *)(vnew));
506 glVertex3fv((float *)(vnew+1));
507 glVertex3fv((float *)(vnew+2));
508 glVertex3fv((float *)(vnew+3));
509 glEnd();
510 }
511
512 /* PRIVATE
513 * draw routine for the app-provided display list primitive
514 */
515 void
OGLPRIMPARMLIST()516 rmAppDisplayList OGLPRIMPARMLIST()
517 {
518
519 #if (DEBUG_LEVEL & DEBUG_GLERRORCHECK)
520 rmGLGetError("rmAppDisplayList() - before calling app display list");
521 #endif
522
523 glCallList(p->flags1);
524
525 /* foil compiler warning */
526 r = NULL;
527 s = NULL;
528 renderPipe = NULL;
529 rsc = NULL;
530
531 #if (DEBUG_LEVEL & DEBUG_GLERRORCHECK)
532 rmGLGetError("rmAppDisplayList() - after calling app display list");
533 #endif
534 }
535
536 /* PRIVATE
537 *
538 * draw routine for quadmesh routines
539 */
540 void
OGLPRIMPARMLIST()541 rmQuadmesh OGLPRIMPARMLIST()
542 {
543 float *nrow0=NULL, *nrow1=NULL;
544 float *vrow0=NULL, *vrow1=NULL;
545 float *crow0=NULL, *crow1=NULL;
546 float *tcrow0 = NULL, *tcrow1 = NULL;
547 int usize, vsize;
548 int *dims;
549 int iv, iu;
550
551 /* for verts */
552 float *v;
553 int vstride, nverts, vveclen;
554
555 /* color data */
556 float *c = NULL;
557 int cstride, ncolors, cveclen;
558
559 /* texture coord data */
560 float *tc = NULL;
561 int tcstride;
562 int ntc, tcveclen;
563
564 /* normals */
565 float *n;
566 int nstride, nveclen, nnormals;
567 int listStat;
568
569 /* vertex, normal, color, tc functions */
570 void (*vertexfunc)(const float *);
571 void (*normalfunc)(const float *);
572 void (*colorfunc)(const float *);
573 void (*tcfunc)(const float *);
574
575 int haveMTCs = 0;
576
577 #if (DEBUG_LEVEL & DEBUG_GLSTATECHECK)
578 private_glStateCheck(s);
579 #endif
580
581 private_colorMaterialStateManip(p, s, rsc);
582 private_lightingStateManip(p, s, rsc, RM_FALSE);
583
584 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
585 if (listStat == 0)
586 return;
587
588 r = NULL; /* foil compile warning */
589
590 /* get vertex data */
591 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
592
593 /* get color data */
594 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
595
596 /* get texture coord data */
597 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
598
599 /* get normals info */
600 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
601
602 /* get the size info for the qmesh */
603 private_rmGetBlobData(BLOB_QMESHDIMS_INDEX, p, NULL, NULL, (void *)&dims, NULL);
604
605 if (p->multiTextureCoordBlobsMask != 0)
606 haveMTCs = 1;
607
608 vrow0 = v;
609 nrow0 = n;
610 crow0 = c;
611 tcrow0 = tc;
612
613 usize = dims[0];
614 vsize = dims[1];
615
616 if (vveclen == 3)
617 vertexfunc = rmglVertex3fv;
618 else
619 vertexfunc = rmglVertex2fv;
620 vrow1 = vrow0 + usize*vstride;
621
622 if (nrow0 != NULL)
623 {
624 nrow1 = nrow0 + usize*nstride;
625 normalfunc = rmglNormal3fv;
626 }
627 else
628 {
629 nrow0 = nrow1 = NULL;
630 normalfunc = glNoOp;
631 }
632
633 if ((ncolors != usize*vsize) && (cstride != 0))
634 {
635 rmWarning(" only per-vertex colors are supported with the quadmesh. use quads as an alternative. drawing the quadmesh without colors.");
636 cstride = 0;
637 colorfunc = glNoOp;
638 }
639 else
640 {
641 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
642 crow1 = crow0 + (usize * cstride);
643 }
644
645 if (ntc == 0)
646 tcfunc = glNoOp;
647 else
648 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
649
650 tcrow1 = tcrow0 + (usize * tcstride);
651
652 for (iv = 0; iv < (vsize - 1); iv++)
653 {
654 glBegin(GL_QUAD_STRIP);
655
656 for (iu = 0; iu < usize; iu++)
657 {
658 (*colorfunc)((float *)(crow1 + (iu * cstride)));
659 (*tcfunc)((float *)(tcrow1 + (iu * tcstride)));
660 (*normalfunc)((float *)(nrow1 + (iu * nstride)));
661 if (haveMTCs)
662 private_dispatchMTCs(renderPipe, p, (iv+1) * usize + iu);
663
664 (*vertexfunc)((float *)(vrow1 + (iu * vstride)));
665
666 (*colorfunc)((float *)(crow0 + (iu * cstride)));
667 (*tcfunc)((float *)(tcrow0 + (iu * tcstride)));
668 (*normalfunc)((float *)(nrow0 + (iu * nstride)));
669
670 if (haveMTCs)
671 private_dispatchMTCs(renderPipe, p, iv * usize + iu);
672
673 (*vertexfunc)((float *)(vrow0 + (iu * vstride)));
674 }
675
676 glEnd();
677
678 vrow0 = vrow1;
679 vrow1 += usize * vstride;
680
681 nrow0 = nrow1;
682 nrow1 += usize * nstride;
683
684 crow0 = crow1;
685 crow1 += usize * cstride;
686
687 tcrow0 = tcrow1;
688 tcrow1 += usize * tcstride;
689 }
690 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
691 }
692
693
694 /* PRIVATE */
695 void
OGLPRIMPARMLIST()696 rmSpheres OGLPRIMPARMLIST()
697 {
698 /* for verts */
699 float *v;
700 int vstride, nverts, vveclen;
701
702 /* color data */
703 float *c = NULL;
704 int cstride, ncolors, cveclen;
705
706 /* radius data */
707 float *radii = NULL;
708 int rstride, nradii, rveclen;
709
710 int i, listStat;
711 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
712 float dummy_radius = 0.0;
713
714 private_lightingStateManip(p, s, rsc, RM_TRUE);
715 private_colorMaterialStateManip(p, s, rsc);
716
717 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
718 if (listStat == 0)
719 return;
720
721 r = NULL; /* foil compiler warning */
722
723 /* get vertex data */
724 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
725
726 /* get color data */
727 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
728
729 /* get radius data */
730 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &rstride, &nradii, (void **)&radii, &rveclen);
731
732 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
733
734 if (vveclen == 3)
735 vertexfunc = rmglVertex3fv;
736 else if (vveclen == 2)
737 vertexfunc = rmglVertex2fv;
738
739 if (nradii == 0)
740 {
741 radii = &dummy_radius;
742 rstride = 0;
743 }
744
745 for (i = 0; i < nverts; i++, v += vstride, radii += rstride, c += cstride)
746 {
747 void rmuSphere(void (*colorfunc) (const float *), float *color, RMvertex3D *p1, float radius, int model_switch, RMpipe *p);
748
749 if (*radii != 0.0F)
750 {
751 #if 0
752 /* tmp hack to test improved rendering when transparent. */
753 /* this actually works surprisingly well..need to promote
754 this approach to a higher level. */
755
756 if (s->renderpass == RM_RENDERPASS_TRANSPARENT)
757 {
758 glEnable(GL_CULL_FACE);
759 glCullFace(GL_FRONT);
760 rmuSphere(colorfunc, c, (RMvertex3D *)v, *radii,
761 rmPrimitiveGetModelFlag(p), renderPipe);
762 glCullFace(GL_BACK);
763 rmuSphere(colorfunc, c, (RMvertex3D *)v, *radii,
764 rmPrimitiveGetModelFlag(p), renderPipe);
765 glDisable(GL_CULL_FACE);
766 }
767 else
768 #endif
769 rmuSphere(colorfunc, c, (RMvertex3D *)v, *radii,
770 rmPrimitiveGetModelFlag(p), renderPipe);
771 }
772 else
773 {
774 /* we should be able to detect that the radius values
775 for the entire prim are null and to deal with them differently
776 (more efficiently) than doing them one-by-one here. */
777
778 glBegin(GL_POINTS);
779 (*colorfunc)(c);
780 (*vertexfunc)(v);
781 glEnd();
782 }
783 }
784 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
785 }
786
787
788 /* PRIVATE */
789 void
OGLPRIMPARMLIST()790 rmCones OGLPRIMPARMLIST()
791 {
792 /* for verts */
793 int vstride, nverts, vveclen;
794 float *v;
795
796 /* color data */
797 int cstride, ncolors, cveclen;
798 float *c = NULL;
799
800 /* radius data */
801 int rstride, nradii, rveclen;
802 float *radii = NULL;
803
804 /* cones */
805 int i, ncones, listStat;
806 float dummy_radius = 0.0;
807 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
808
809 private_lightingStateManip(p, s, rsc, RM_TRUE);
810 private_colorMaterialStateManip(p, s, rsc);
811
812 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
813 if (listStat == 0)
814 return;
815
816 r = NULL; /* foil compiler warning */
817
818 /* get vertex data */
819 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
820
821 ncones = nverts >> 1; /* each vertex pair defines a cone (base,top) */
822 /* get color data */
823 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
824
825 /* get radius data */
826 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &rstride, &nradii, (void **)&radii, &rveclen);
827
828 if (vveclen == 3)
829 vertexfunc = rmglVertex3fv;
830 else
831 vertexfunc = rmglVertex2fv;
832
833 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
834
835 if (radii == NULL)
836 {
837 dummy_radius = 0.0;
838 radii = &dummy_radius;
839 rstride = 0;
840 }
841
842 for (i = 0; i < ncones; i++, v += 2 * vstride, c += cstride, radii += rstride)
843 {
844 RMvertex3D *p1, *p2;
845
846 p1 = (RMvertex3D *)v;
847 p2 = (RMvertex3D *)(v + vstride);
848
849 rmuCone(colorfunc, c, p1, p2, *radii, rmPrimitiveGetModelFlag(p), renderPipe);
850 }
851 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
852 }
853
854
855 /* PRIVATE */
856 void
OGLPRIMPARMLIST()857 rmCylinders OGLPRIMPARMLIST()
858 {
859 /* for verts */
860 float *v;
861 int vstride, nverts, vveclen;
862
863 /* color data */
864 float *c = NULL;
865 int cstride, ncolors, cveclen;
866
867 /* radius data */
868 float *radii = NULL;
869 int rstride, nradii, rveclen;
870
871 int i, listStat, ncylinders;
872 void (*colorfunc)(const float *);
873 float dummy_radius;
874
875 private_lightingStateManip(p, s, rsc, RM_TRUE);
876 private_colorMaterialStateManip(p, s, rsc);
877
878 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
879 if (listStat == 0)
880 return;
881
882 r = NULL; /* foil compiler warning */
883
884 /* get vertex data */
885 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
886
887 ncylinders = nverts >> 1; /* each vertex pair defines a cone (base,top) */
888
889 /* get color data */
890 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
891
892 /* get radius data */
893 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &rstride, &nradii, (void **)&radii, &rveclen);
894
895 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
896
897 /* for now, assume 1 radius value per cylinder..so that they're
898 straight (non-tapered) cylinders. also, we assume the layout of
899 vertices is like that of disjoint lines..so that if we have
900 n vertices, we'll render n/2 cylinders. */
901
902 if (radii == NULL)
903 {
904 dummy_radius = 0.;
905 radii = &dummy_radius;
906 rstride = 0;
907 }
908
909 for (i = 0; i < ncylinders; i++, v += 2 * vstride, c += cstride, radii += rstride)
910 {
911 RMvertex3D *p1, *p2;
912
913 void rmuCylinder(void (*colorfunc)(const float *), float *color, RMvertex3D *p1, RMvertex3D *p2,float radius1, int subdivisions, RMpipe *p);
914
915 p1 = (RMvertex3D *)v;
916 p2 = (RMvertex3D *)(v + vstride);
917
918 rmuCylinder(colorfunc, c, p1, p2, *radii, rmPrimitiveGetModelFlag(p), renderPipe);
919 }
920 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
921 }
922
923
924 /* PRIVATE */
925 void
OGLPRIMPARMLIST()926 rmMarkers2D OGLPRIMPARMLIST()
927 {
928 /* for verts */
929 float *v;
930 int vstride, nverts, vveclen;
931
932 /* color data */
933 float *c = NULL;
934 int cstride, ncolors, cveclen;
935
936 /* scale data */
937 float *scales;
938 int sstride, nscales, sveclen;
939
940 int i, j;
941 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
942
943 RMinternalMarker2D *m;
944 int nmarker_prims;
945 RMmatrix mx;
946
947 float m00, m10, m01, m11, m30, m31;
948
949 /*
950 * 5/11/02
951 * this code not yet tested - no demo programs that exercise 2d markers.
952 */
953 private_colorMaterialStateManip(p, s, rsc);
954 private_lightingStateManip(p, s, rsc, RM_FALSE);
955
956 /* get vertex data */
957 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
958 if (nverts == 0)
959 return;
960
961 r = NULL; /* foil compiler warning */
962 renderPipe = NULL; /* foil compiler warning */
963
964 /* get color data */
965 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
966
967 /* get radius data */
968 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &sstride, &nscales, (void **)&scales, &sveclen);
969
970 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
971
972 /* we could check to make sure only 2d vertices are permitted here... */
973 if (vveclen == 3)
974 vertexfunc = rmglVertex3fv;
975 else
976 vertexfunc = rmglVertex2fv;
977
978 private_rmPrimitiveGetItem(p, RM_PRIMITIVE_MARKERS2D_PRIM, &nmarker_prims, (void **)&m);
979 rmMatrixIdentity(&mx);
980
981 /* need to use render state interface here. */
982 {
983 RMmatrix m;
984 rmMatrixMultiply(&(s->modelView), &(s->projection), &m);
985 rmMatrixInverse(&m, &m);
986
987 mx.m[0][0] = 1. / m.m[1][1];
988 mx.m[1][1] = s->aspect_ratio / m.m[0][0];
989 }
990
991 m00 = s->model.m[0][0];
992 m10 = s->model.m[1][0];
993 m01 = s->model.m[0][1];
994 m11 = s->model.m[1][1];
995 m30 = s->model.m[3][0];
996 m31 = s->model.m[3][1];
997
998 if (nmarker_prims != 1)
999 {
1000 rmWarning("rmMarkers2D() error: at this time, only one markerprim per RMprimitive is permitted. This restriction will be removed in a future release. Drawing only the first one.");
1001 }
1002
1003 /* temp - we assume that nmarker_prims == 1. */
1004 for (i = 0; i < nverts; i++, v += vstride, c += cstride, scales += sstride)
1005 {
1006 float *v2, v3[3];
1007
1008 glPushMatrix();
1009
1010 /* translate to the proper x/y location. this translation
1011 accounts for scale, etc in the model-view-projection matrix.
1012 the markers
1013 will be positioned correctly, but will be rotation-invariant. */
1014
1015 mx.m[3][0] = v[0] * m00 + v[1] * m10 + m30;
1016 mx.m[3][1] = v[0] * m01 + v[1] * m11 + m31;
1017
1018 glMultMatrixf(&(mx.m[0][0]));
1019
1020 (*colorfunc)(c);
1021
1022 v2 = (float *)(rmInternalMarker2DGetVerts(m));
1023
1024 glBegin( rmInternalMarker2DGetBFlag(m) );
1025
1026 for (j = 0; j < rmInternalMarker2DGetNpts(m); j++, v2 += 2)
1027 {
1028 v3[0] = v2[0] * *scales ;
1029 v3[1] = v2[1] * *scales ;
1030 (*vertexfunc)(v3);
1031 }
1032 glEnd();
1033
1034 glPopMatrix();
1035 }
1036 }
1037
1038
1039 /* unit cube geometry */
1040 static RMvertex3D ibox[6][4] =
1041 {
1042 {{1.0, 0.0, 0.0}, {1.0, 0.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 0.0}}, /* +x face */
1043 {{0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 1.0}}, /* -x face */
1044 {{0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}, {1.0, 1.0, 1.0}, {0.0, 1.0, 1.0}}, /* +y face */
1045 {{0.0, 0.0, 1.0}, {1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}, /* -y face */
1046 {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}}, /* front face */
1047 {{1.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 1.0}, {1.0, 1.0, 1.0}} /* back face */
1048 };
1049
1050 /* unit cube normals */
1051 static RMvertex3D iboxnorms[6] =
1052 {
1053 {1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 0.0, 1.0}
1054 };
1055
1056
1057 /* PRIVATE */
1058 void
OGLPRIMPARMLIST()1059 rmBox3d OGLPRIMPARMLIST()
1060 {
1061 /* for verts */
1062 float *v;
1063 int vstride, nverts, vveclen;
1064
1065 /* color data */
1066 float *c = NULL;
1067 int cstride, ncolors, cveclen;
1068
1069 int i, j, k, listStat;
1070 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
1071 RMvertex3D *rv;
1072 RMvertex3D tbox[6][4];
1073
1074 private_lightingStateManip(p, s, rsc, RM_TRUE);
1075 private_colorMaterialStateManip(p, s, rsc);
1076 private_textureStateManip(p, s, rsc);
1077
1078 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
1079 if (listStat == 0)
1080 return;
1081
1082 r = NULL; /* foil compiler warning */
1083
1084 /* get vertex data */
1085 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1086
1087 /* get color data */
1088 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1089
1090 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1091
1092 if (vveclen == 3)
1093 vertexfunc = rmglVertex3fv;
1094 else /* an error */
1095 {
1096 rmError("rmBox3D() error: box3d primitives MUST have 3d vertices. \n");
1097 return;
1098 }
1099
1100 rv = (RMvertex3D *)v;
1101
1102 for (i = 0; i < (nverts / 2); i++, rv += 2, c += cstride)
1103 {
1104 float sx, sy, sz;
1105
1106 sx = rv[1].x - rv[0].x;
1107 sy = rv[1].y - rv[0].y;
1108 sz = rv[1].z - rv[0].z;
1109
1110 for (k = 0; k < 6; k++)
1111 {
1112 for (j = 0; j < 4; j++)
1113 {
1114 tbox[k][j].x = ibox[k][j].x * sx;
1115 tbox[k][j].y = ibox[k][j].y * sy;
1116 tbox[k][j].z = ibox[k][j].z * sz;
1117 }
1118 }
1119
1120 glPushMatrix();
1121 glTranslatef(rv->x,rv->y,rv->z); /* won't work with 2d vertices */
1122
1123 glBegin(GL_QUADS);
1124 (*colorfunc)(c);
1125 for (j = 0; j < 6; j++)
1126 {
1127 /* glColor3fv((float *)&(debug_colors[j])); */ /* debug */
1128 glNormal3fv((float *)&(iboxnorms[j]));
1129 for (k = 3; k >= 0; k--)
1130 {
1131 (*vertexfunc)((float *)&(tbox[j][k]));
1132 }
1133 }
1134 glEnd();
1135
1136 glPopMatrix();
1137 }
1138 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
1139 }
1140
1141
1142 /* PRIVATE */
1143 void
OGLPRIMPARMLIST()1144 rmBox3dWire OGLPRIMPARMLIST()
1145 {
1146 /* for verts */
1147 int vstride, nverts, vveclen;
1148 float *v;
1149
1150 /* color data */
1151 int cstride, ncolors, cveclen;
1152 float *c = NULL;
1153
1154 /* box */
1155 int i, listStat;
1156 RMvertex3D *rv;
1157 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
1158
1159 private_colorMaterialStateManip(p, s, rsc);
1160 private_lightingStateManip(p, s, rsc, RM_FALSE);
1161 private_textureStateManip(p, s, rsc);
1162
1163 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
1164 if (listStat == 0)
1165 return;
1166
1167 r = NULL; /* foil compiler warning */
1168
1169 /* vertex data */
1170 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1171
1172 /* get color data */
1173 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1174
1175 private_rmSetGLColorFunc(cveclen,ncolors, &colorfunc);
1176
1177 if (vveclen == 3)
1178 vertexfunc = rmglVertex3fv;
1179 else /* an error */
1180 {
1181 rmError("rmBox3DWire() error: box3dwire primitives MUST have 3d vertices. \n");
1182 return;
1183 }
1184
1185 rv = (RMvertex3D *)v;
1186
1187 for (i = 0; i < (nverts / 2); i++, rv += 2, c += cstride)
1188 {
1189 float sx, sy, sz;
1190
1191 sx = rv[1].x - rv[0].x;
1192 sy = rv[1].y - rv[0].y;
1193 sz = rv[1].z - rv[0].z;
1194
1195 glPushMatrix();
1196 glTranslatef(rv->x, rv->y, rv->z); /* won't work with 2d vertices */
1197
1198 glBegin(GL_LINE_STRIP);
1199 (*colorfunc)(c);
1200
1201 glVertex3f(0.0F, 0.0F ,0.0F);
1202 glVertex3f(sx, 0.0F, 0.0F);
1203 glVertex3f(sx, sy, 0.0F);
1204 glVertex3f(0.0F, sy, 0.0F);
1205
1206 glVertex3f(0.0F, 0.0F, 0.0F);
1207 glVertex3f(0.0F, 0.0F, sz);
1208 glVertex3f(0.0F, sy, sz);
1209 glVertex3f(0.0F, sy, 0.0F);
1210
1211 glVertex3f(0.0F, sy, sz);
1212 glVertex3f(sx, sy, sz);
1213 glVertex3f(sx, sy, 0.0F);
1214 glVertex3f(sx, 0.0F, 0.0F);
1215
1216 glVertex3f(sx, 0.0F, sz);
1217 glVertex3f(sx, sy, sz);
1218 glVertex3f(sx, 0.0F, sz);
1219 glVertex3f(0.0F, 0.0F, sz);
1220
1221 glEnd();
1222
1223 glPopMatrix();
1224 }
1225 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
1226 }
1227
1228
1229 /* PRIVATE */
1230 void
OGLPRIMPARMLIST()1231 rmCircle2d OGLPRIMPARMLIST()
1232 {
1233 /*
1234 * TODO: 12/5/99
1235 * circles need to have display-list code added.
1236 *
1237 * ------ general info
1238 * for each of verts, color & texture, we need
1239 * 1. stride, for memory accessing
1240 * 2. veclen, for proper gl function call
1241 *
1242 * the main delivery loop is over vertices. we check the number of
1243 * colors, norms & textures to ensure that we have either none or
1244 * per-vertex of each.
1245 */
1246 int i;
1247 void (*colorfunc)(const float *);
1248 float dummy = 1.0, scale;
1249
1250 /* for verts */
1251 float *v;
1252 int vstride, nverts, vveclen;
1253
1254 /* color data */
1255 float *c = NULL;
1256 int cstride, ncolors, cveclen;
1257
1258 /* for radius data */
1259 float *radii= NULL;
1260 int rstride, rveclen, nradii;
1261
1262 RMmatrix m;
1263
1264 private_colorMaterialStateManip(p, s, rsc);
1265 private_lightingStateManip(p, s, rsc, RM_FALSE);
1266
1267 /* get vertex data */
1268 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1269
1270 /* get color data */
1271 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1272
1273 /* get radius info */
1274 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &rstride, &nradii, (void **)&radii, &rveclen);
1275 if (radii == NULL)
1276 {
1277 radii = &dummy;
1278 rstride = 0;
1279 nradii = 0;
1280 }
1281
1282 /*
1283 * do validity checking:
1284 * 1. ncolors must be 0 or equal to nverts/2
1285 * 2. ntcoords must be 0 or equal to nverts/2
1286 */
1287 if (ncolors != 0 && ncolors != nverts)
1288 {
1289 rmError("error: rmCircle2D() only per-circle color is supported. \n");
1290 return;
1291 }
1292
1293 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1294
1295 rmMatrixMultiply(&(s->model), &(s->projection), &m);
1296 rmMatrixMultiply(&m, &(s->vpm), &m);
1297
1298 scale = RM_MIN(m.m[0][0], m.m[1][1]);
1299
1300 for (i = 0; i < nverts; i++, v += vstride, c+= cstride, radii += rstride)
1301 {
1302 int subdivisions = 9;
1303 RMmatrix m;
1304
1305 glPushMatrix();
1306 rmMatrixIdentity(&m);
1307
1308 m.m[0][0] = m.m[1][1] = m.m[2][2] = *radii;
1309 m.m[3][0] = v[0];
1310 m.m[3][1] = v[1];
1311 m.m[3][2] = 0.0F;
1312 glMultMatrixf((const GLfloat *)&(m.m[0][0]));
1313 (*colorfunc)(c);
1314
1315 subdivisions = *radii * scale; /* this formulation results in line segments which are about 3 pixels long */
1316
1317 rmuCircle2d(subdivisions);
1318
1319 glPopMatrix();
1320 }
1321 r = NULL; /* foil compiler warning */
1322 renderPipe = NULL; /* foil compiler warning */
1323 }
1324
1325
1326 /* PRIVATE
1327 *
1328 * because we use glRect() for drawing 2D boxes, the use of texture coords is not supported
1329 */
1330 void
OGLPRIMPARMLIST()1331 rmBox2d OGLPRIMPARMLIST()
1332 {
1333 /* for verts */
1334 int vstride, nverts, vveclen;
1335 float *v, *v2;
1336
1337 /* color data */
1338 int cstride, ncolors, cveclen;
1339 int i, nboxes, listStat;
1340 float *c = NULL;
1341 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
1342
1343 private_colorMaterialStateManip(p, s, rsc);
1344 private_lightingStateManip(p, s, rsc, RM_FALSE);
1345
1346 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
1347 if (listStat == 0)
1348 return;
1349
1350 r = NULL; /* foil compiler warning */
1351
1352 /* vertex data */
1353 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1354
1355 /* get color data */
1356 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1357
1358 /*
1359 * do validity checking:
1360 * 1. ncolors must be 0 or equal to nverts/2
1361 */
1362 if ((ncolors != 0) && (ncolors != (nverts/2)))
1363 {
1364 rmError("error: rmBox2D() only per-box color is supported. \n");
1365 return;
1366 }
1367
1368 if (vveclen == 3) /* why check for 3D vertices on 2D boxes? */
1369 vertexfunc = rmglVertex3fv;
1370 else /* assume vveclen == 2 */
1371 vertexfunc = rmglVertex2fv;
1372
1373 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1374
1375 nboxes = nverts / 2;
1376 v2 = v + vstride;
1377
1378 for (i = 0; i < nboxes; i++, c += cstride)
1379 {
1380 (*colorfunc)(c);
1381 glRectfv((GLfloat *)(v), (GLfloat *)(v2));
1382
1383 v = v2 += vstride;
1384 v2 += vstride;
1385 }
1386
1387 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
1388 }
1389
1390
1391 /* PRIVATE */
1392 void
OGLPRIMPARMLIST()1393 rmEllipse2d OGLPRIMPARMLIST()
1394 {
1395 /* for verts */
1396 float *v;
1397 int vstride, nverts, vveclen;
1398
1399 /* color data */
1400 float *c = NULL;
1401 int cstride, ncolors, cveclen;
1402
1403 /* for radius data */
1404 float *radii = NULL;
1405 int rstride, rveclen, nradii;
1406
1407 /* for rotation data */
1408 float *rotdata;
1409 int rotstride, rotveclen, nrots;
1410
1411 int i;
1412 float scale;
1413 RMmatrix m;
1414 void (*colorfunc)(const float *);
1415 float dummy_rotate = 0.0;
1416
1417 private_colorMaterialStateManip(p, s, rsc);
1418 private_lightingStateManip(p, s, rsc, RM_FALSE);
1419
1420 /* get vertex data */
1421 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1422
1423 /* get color data */
1424 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1425
1426 /* get radius info */
1427 private_rmGetBlobData(BLOB_SCALE_INDEX, p, &rstride, &nradii, (void **)&radii, &rveclen);
1428
1429 /* rotation data is stuffed into the blob otherwise used
1430 for indices. if we ever want to do indexed ellipses (?), then
1431 we'll have to use a different data blob. */
1432
1433 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &rotstride, &nrots, (void **)&rotdata, &rotveclen);
1434
1435 if (rotdata == NULL)
1436 {
1437 rotdata = &dummy_rotate;
1438 rotstride = 0;
1439 }
1440
1441 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1442
1443 rmMatrixMultiply(&(s->model), &(s->projection), &m);
1444 rmMatrixMultiply(&m, &(s->vpm), &m);
1445
1446 scale = RM_MIN(m.m[0][0], m.m[1][1]);
1447
1448 /* careful on rveclen: we assume radius pairs w/o having to explicitly set veclen on the blob */
1449 for (i = 0; i < nverts; i++, v += vstride, c+= cstride, radii += 2, rotdata += rotstride)
1450 {
1451 RMmatrix m;
1452 int subdivisions;
1453 float rval;
1454 float cval, sval;
1455
1456 glPushMatrix();
1457
1458 /* assume input in degrees */
1459 {
1460 int idegrees;
1461 /*
1462 * input rotation value is expressed in terms of 10th's
1463 * of degrees. our cos/sin table resolution is 1 degree, so
1464 * we just throw away the additional resolution by dividing
1465 * by 10.
1466 */
1467 idegrees = (int)(*rotdata * 0.10F);
1468 idegrees = idegrees % 360;
1469 idegrees = (idegrees < 0) ? idegrees + 360 : idegrees;
1470
1471 cval = cos_table[idegrees];
1472 sval = sin_table[idegrees];
1473 }
1474
1475 rmMatrixIdentity(&m);
1476
1477 m.m[0][0] = m.m[1][1] = cval;
1478 m.m[0][1] = sval;
1479 m.m[1][0] = -sval;
1480
1481 m.m[3][0] = v[0];
1482 m.m[3][1] = v[1];
1483 m.m[3][2] = 0.0F;
1484 glMultMatrixf((const GLfloat *)&(m.m[0][0]));
1485 (*colorfunc)(c);
1486
1487 rval = RM_MAX(radii[0], radii[1]); /* radii must be defined */
1488 subdivisions = rval * scale; /* this formulation results in line segments which are about 3 pixels long */
1489
1490
1491 rmuEllipse2d(subdivisions, radii[0], radii[1]);
1492
1493
1494 glPopMatrix();
1495 }
1496
1497 r = NULL; /* foil compiler warning */
1498 renderPipe = NULL; /* foil compiler warning */
1499 }
1500
1501
1502 /* PRIVATE */
1503 void
OGLPRIMPARMLIST()1504 rmSprite OGLPRIMPARMLIST()
1505 {
1506 /*
1507 * display listing is handled a little differently for sprites &
1508 * bitmaps. the display list is associated with the RMimage object,
1509 * not the RMprimitive based upon the observation that the image
1510 * data itself is a higher-payload object than a vertex or two,
1511 * and to allow for this code to deal with weird raster position
1512 * placement issues that come up in OpenGL when drawing image
1513 * based data.
1514 */
1515
1516 /* for verts */
1517 float *v;
1518 int vstride, nverts, vveclen;
1519 void (*vertexfunc)(const float *);
1520
1521 int i;
1522 RMimage **sprite_list, *sprite;
1523 RMmatrix vpm, vpm_inv, forward, inv;
1524 float horigin = 0.0F, vorigin = 0.0F;
1525 GLenum format, gltype;
1526
1527 RMenum hjustify, vjustify;
1528
1529 /* get vertex data */
1530 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1531
1532 private_lightingStateManip(p, s, rsc, RM_FALSE);
1533
1534 if (vveclen == 2)
1535 vertexfunc = rmglRasterPos2fv;
1536 else /* assume vincr = 3 */
1537 vertexfunc = rmglRasterPos3fv;
1538
1539 /* get justification settings specified for text */
1540 private_rmStateGetTextJustify(s, &hjustify, &vjustify);
1541
1542 /*
1543 * now, grab the sprites. note that indexed sprites are not
1544 * currently supported.
1545 */
1546 private_rmPrimitiveGetItem(p, RM_PRIMITIVE_SPRITES, &i, (void **)&sprite_list);
1547
1548 private_rmSetupBitmapPickMatrices(s, &vpm, &vpm_inv, &forward, &inv);
1549
1550 for (i = 0; i < nverts; i++, v += vstride)
1551 {
1552 float xzoom, yzoom;
1553
1554 sprite = sprite_list[i];
1555
1556 if (sprite == NULL)
1557 rmError("error in rmSprite() - NULL image pointer encountered in an RM_SPRITE primitive. \n");
1558
1559 rmImageGetPixelZoom(sprite, &xzoom, &yzoom);
1560
1561 horigin = 0.0F;
1562 if (hjustify == RM_CENTER)
1563 horigin = (float)sprite->w * xzoom * 0.5F;
1564 else if (hjustify == RM_RIGHT)
1565 horigin = (float)sprite->w * xzoom;
1566
1567 vorigin = 0.0F;
1568 if (vjustify == RM_CENTER)
1569 vorigin = (float)sprite->h * yzoom * 0.5F;
1570 else if (vjustify == RM_TOP)
1571 vorigin = (float)sprite->h * yzoom;
1572
1573 if (s->rendermode == GL_SELECT || SHOW_PICKABLE_QUADS)
1574 {
1575 /*
1576 * in pick mode, we have to generate some pickable geometry
1577 * since glDrawPixels doesn't generate anything we can pick.
1578 * This hunk of code draws pickable geometry.
1579 */
1580 int w, h;
1581 RMvertex3D t;
1582
1583 w = sprite->w * xzoom;
1584 h = sprite->h * yzoom;
1585
1586 t.x = v[0];
1587 t.y = v[1];
1588 t.z = (vveclen == 2) ? 0.0F : v[2];
1589
1590 private_rmDrawBitmapPickableQuads(&vpm, &vpm_inv, &forward,&inv,
1591 &t, horigin, vorigin, w, h);
1592 }
1593
1594 if ((s->rendermode != GL_SELECT) || (SHOW_PICKABLE_QUADS))
1595 {
1596 /*
1597 * In rendering mode, compute the pixel location of the
1598 * vertex value associated with the sprite. The final pixel
1599 * coordinate will reflect the transformation of world
1600 * coordinates to pixel coordinates as well as the offset
1601 * resulting from the requested justification.
1602 */
1603 RMvertex3D dc;
1604 RMvertex3D drawVertex;
1605 RMvertex3D t;
1606 float xmove=0.0F, ymove=0.0F;
1607 int adjustRasterpos = 0;
1608
1609 t.x = v[0];
1610 t.y = v[1];
1611 t.z = (vveclen == 2) ? 0.0F : v[2];
1612
1613 if (vveclen == 2)
1614 private_rmDCFromWC2(&t, &dc, 1, s);
1615 else
1616 private_rmDCFromWC3(&t, &dc, 1, s);
1617
1618 dc.x -= horigin;
1619 dc.y -= vorigin;
1620
1621 /* check to see if the requested vertex position is outside
1622 the viewport. */
1623
1624 if ((dc.x <= 0.0F) || (dc.y <= 0.0F) || /* off to left or bottom */
1625 (dc.x >= s->w) || (dc.y >= s->h)) /* off to top or right */
1626 {
1627 RMvertex3D newDC;
1628 float dx, dy;
1629
1630 /* put the new vertex at the center of the screen */
1631 newDC.x = (float)(s->w) * 0.5;
1632 newDC.y = (float)(s->h) * 0.5;
1633 newDC.z = dc.z;
1634
1635 /* what is the pixel delta from current vertex location in
1636 pixel coordinates to pixel coordinates of proposed
1637 new vertex? */
1638 dx = newDC.x - dc.x;
1639 dy = newDC.y - dc.y;
1640
1641 /*
1642 * compute the new world coordinate. This approach produces
1643 * the correct projected screen location, but the z-coordinate
1644 * isn't exactly correct. If you have fog turned on, you may
1645 * see a discontinous shade change when the sprite crosses
1646 * over the left or bottom window boundary.
1647 */
1648 private_rmNewWCfromDCOffset((RMvertex3D *)v, dx, dy,
1649 &drawVertex,
1650 &vpm, &vpm_inv, &forward, &inv);
1651 xmove = -1.0F * dx;
1652 ymove = -1.0F * dy;
1653
1654 adjustRasterpos = 1;
1655 }
1656 else
1657 {
1658 /*
1659 * the vertex with justification lies within the viewport.
1660 * compute a new world coordinate for use in drawing
1661 * the sprite.
1662 */
1663 private_rmNewWCfromDCOffset(&t, -horigin, -vorigin,
1664 &drawVertex,
1665 &vpm, &vpm_inv, &forward, &inv);
1666 adjustRasterpos = 0;
1667 }
1668
1669
1670 (*vertexfunc)((GLfloat *)&drawVertex);
1671
1672 /* warning!! generates a bitmap feedback token!! */
1673 if (adjustRasterpos == 1)
1674 glBitmap(0, 0, 0, 0, (GLfloat)xmove, (GLfloat)ymove, NULL);
1675
1676 glPixelZoom ((GLfloat)xzoom, (GLfloat)yzoom);
1677
1678 format = private_rmImageGetOGLFormat(sprite);
1679 gltype = private_rmImageGetOGLType(sprite);
1680
1681 private_glDrawPixels(private_rmImageGetWidth(sprite), private_rmImageGetHeight(sprite), format, gltype, (const GLvoid *)(private_rmImageGetPixelData(sprite)), sprite);
1682
1683 /* all sprite/image display list stuff was ripped out
1684 during the SBIR work. */
1685 #if 0
1686 /* try to build a display list for this image */
1687 if (private_rmImageGetDirtyFlag(sprite) == RM_TRUE)
1688 {
1689 private_rmImageSetDirtyFlag(sprite,RM_FALSE);
1690 if (sprite->d1 != -1)
1691 {
1692 glDeleteLists(sprite->d1, 1);
1693 sprite->d1 = -1;
1694 }
1695 }
1696
1697 if (sprite->d1 == -1)
1698 {
1699
1700 #if DO_LISTS
1701 sprite->d1 = glGenLists(1);
1702
1703 glNewList(sprite->d1, GL_COMPILE_AND_EXECUTE);
1704 #endif
1705
1706
1707 /* enable pixel transfer mode if there's a vismap present */
1708 private_glDrawPixels(private_rmImageGetWidth(sprite), private_rmImageGetHeight(sprite), format, gltype, (const GLvoid *)(private_rmImageGetPixelData(sprite)), sprite);
1709
1710
1711
1712 /* 10/5/200 all RMimage display list stuff removed during
1713 SBIR work.*/
1714 #if DO_LISTS
1715 glEndList();
1716 #endif
1717
1718 }
1719 else
1720 glCallList(sprite->d1);
1721 #endif
1722 }
1723 }
1724 r = NULL; /* foil compiler warning */
1725 renderPipe = NULL; /* foil compiler warning */
1726 }
1727
1728
1729 /* PRIVATE */
1730 void
OGLPRIMPARMLIST()1731 rmBitmap OGLPRIMPARMLIST()
1732 {
1733 /* for verts */
1734 float *v;
1735 int vstride, nverts, vveclen;
1736
1737 /* color data */
1738 float *c = NULL;
1739 int cstride, ncolors, cveclen;
1740
1741 int i;
1742
1743 void (*vertexfunc)(const float *);
1744 void (*colorfunc)(const float *);
1745
1746 RMmatrix vpm, vpm_inv, forward, inv;
1747 RMenum hjustify, vjustify;
1748 GLfloat horigin, vorigin;
1749 int nbitmaps;
1750
1751 RMbitmap **bmp_list, *bmp;
1752
1753 /* get vertex data */
1754 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1755
1756 /* get color data */
1757 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1758
1759 private_colorMaterialStateManip(p, s, rsc);
1760 private_lightingStateManip(p, s, rsc, RM_FALSE);
1761
1762 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1763
1764 if (vveclen == 2)
1765 vertexfunc = rmglRasterPos2fv;
1766 else /* assume vincr = 3 */
1767 vertexfunc = rmglRasterPos3fv;
1768
1769 private_rmStateGetTextJustify(s, &hjustify, &vjustify);
1770
1771 private_rmPrimitiveGetItem(p, RM_PRIMITIVE_BITMAPS, &nbitmaps, (void **)&bmp_list);
1772
1773 if (nbitmaps != nverts)
1774 {
1775 rmError(" the number of bitmaps is not the same as the number of vertices in a bitmap primitive. \n");
1776 return;
1777 }
1778
1779 if (s->rendermode == GL_SELECT || SHOW_PICKABLE_QUADS)
1780 {
1781 /*
1782 * in select mode, we're going to draw a bunch of quads rather
1783 * than text bitmaps: bitmaps are not pickable, whereas quads
1784 * are. in order to do that, we need some matrices.
1785 */
1786 private_rmSetupBitmapPickMatrices(s, &vpm, &vpm_inv, &forward, &inv);
1787 }
1788
1789 for (i = 0; i < nverts; i++, v += vstride, c += cstride)
1790 {
1791 int bw, bh, bytes;
1792
1793 bmp = bmp_list[i];
1794 rmBitmapGetSize(bmp, &bw, &bh, &bytes);
1795
1796 if (c)
1797 (*colorfunc)(c);
1798
1799 horigin = 0.0F;
1800 if (hjustify == RM_CENTER)
1801 horigin = (GLfloat)(bw >> 1);
1802 else
1803 if (hjustify == RM_RIGHT)
1804 horigin = (GLfloat)(bw);
1805
1806 vorigin = 0.0F;
1807
1808 if (vjustify == RM_CENTER)
1809 vorigin = (GLfloat)(bh >> 1);
1810 else if (vjustify == RM_TOP)
1811 vorigin = (GLfloat)(bh);
1812
1813 if (s->rendermode == GL_SELECT || SHOW_PICKABLE_QUADS)
1814 {
1815 /* in select mode, draw quads using the matrices we computed earlier */
1816 RMvertex3D t;
1817 t.x = v[0];
1818 t.y = v[1];
1819 if (vveclen == 2)
1820 t.z = 0.0F;
1821 else
1822 t.z = v[2];
1823
1824 private_rmDrawBitmapPickableQuads(&vpm, &vpm_inv, &forward, &inv,
1825 &t, horigin, vorigin, bw, bh);
1826 }
1827 if ((s->rendermode != GL_SELECT) || (SHOW_PICKABLE_QUADS))
1828 {
1829 /* otherwise, we're in normal draw mode. spit out the bitmaps */
1830 (*colorfunc)((float *)c);
1831 (*vertexfunc)((float *)v);
1832 glBitmap((GLsizei)(bw), (GLsizei)(bh), horigin, vorigin, (GLfloat) 0.0F, (GLfloat)0.0F, (const GLubyte *)(private_rmBitmapGetPixelData(bmp)));
1833 }
1834 }
1835
1836 r = NULL; /* foil compiler warning */
1837 renderPipe = NULL; /* foil compiler warning */
1838 }
1839
1840
1841 /* PRIVATE */
1842 void
OGLPRIMPARMLIST()1843 rmIndexedBitmap OGLPRIMPARMLIST()
1844 {
1845 /*
1846 * todo: display list stuff.
1847 */
1848 rmError(" rmIndexedBitmap is broken. \n");
1849
1850 /* foil compiler warning */
1851 r = NULL;
1852 p = NULL;
1853 s = NULL;
1854 renderPipe = NULL;
1855 rsc = NULL;
1856 }
1857
1858
1859 /* PRIVATE
1860 *
1861 * draw routine for indexed text prims
1862 */
1863 void
OGLPRIMPARMLIST()1864 rmIndexedText OGLPRIMPARMLIST()
1865 {
1866 rmText(p, r, s, renderPipe, rsc);
1867 }
1868
1869
1870 /* PRIVATE
1871 *
1872 * draw routine for text prims
1873 */
1874 void
OGLPRIMPARMLIST()1875 rmText OGLPRIMPARMLIST()
1876 {
1877 /* for verts */
1878 float *v;
1879 int vstride, nverts, vveclen;
1880
1881 /* color data */
1882 float *c = NULL;
1883 int cstride, ncolors, cveclen;
1884
1885 /* index data */
1886 int *indices, istride, nindices, iveclen;
1887 int i, j;
1888
1889 void (*vertexfunc)(const float *);
1890 void (*colorfunc)(const float *);
1891
1892 RMenum hjustify, vjustify;
1893 int do_indices;
1894
1895 RMtextPrim *parray;
1896 int numtextprims;
1897 RMtextProps *tp;
1898 RMfontRegistry *fr;
1899
1900 int usingTempTextProps = 0;
1901
1902 RMmatrix vpm, vpm_inv, forward, inv;
1903
1904 private_colorMaterialStateManip(p, s, rsc);
1905
1906 private_lightingStateManip(p, s, rsc, RM_FALSE);
1907
1908 /* get vertex data */
1909 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
1910
1911 /* get color data */
1912 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
1913
1914 /* get index data */
1915 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
1916
1917 if (indices != NULL)
1918 do_indices = 1;
1919 else
1920 do_indices = 0;
1921
1922 if (vveclen == 3)
1923 vertexfunc = rmglRasterPos3fv;
1924 else
1925 vertexfunc = rmglRasterPos2fv;
1926
1927 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
1928
1929 if (private_rmPrimitiveGetText(p, &numtextprims, &parray) == RM_WHACKED)
1930 {
1931 rmWarning(" rmText() rendering function error: the input primitive has no text strings defined. \n");
1932 return; /* 9/29/03 - need to verify that a simple return here is OK. */
1933 }
1934
1935 /* loop to verify that we have proper width & height info
1936 using the current RMtextProps info. */
1937 tp = s->textProps;
1938
1939 if (tp == NULL)
1940 {
1941 tp = private_rmDefaultTextProps(renderPipe);
1942 usingTempTextProps = 1;
1943 }
1944
1945 /*
1946 * 10/2000 - thread-safety work:
1947 * 1. private_rmPrepareBitmapFont will conditionally build display
1948 * lists for the English alphabet using the requested font and style
1949 * 2. get the rmFontRegistry handle for that font family on the
1950 * named RMpipe - it contains display list indices used for
1951 * drawing bitmaps.
1952 */
1953 private_rmPrepareBitmapFont(tp, renderPipe); /* build display lists */
1954
1955 fr = private_rmFontRegistryEntry(tp->fontEnum, tp->sizeEnum, tp->italicEnum, tp->boldEnum, renderPipe->contextCache->pipeFontRegistry);
1956
1957 /* assertion check on "fr" here? */
1958
1959
1960 for (i = 0; i < numtextprims; i++)
1961 {
1962
1963 /*
1964 * 10/2000 TODO
1965 * the following routine computes the character width
1966 * and height of a character string when rendered given
1967 * font family and style info. this info is needed for
1968 * picking (selection) and for justification. in an
1969 * earlier (non thread-safe) version of OpenRM, we cached
1970 * some info in the RMtextPrim. we need to update this
1971 * code so that we need not recompute character width
1972 * and height during each frame rendering.
1973 */
1974 int indx;
1975
1976 if (do_indices == 1)
1977 indx = indices[i];
1978 else
1979 indx = i;
1980
1981 private_rmTextPrimComputeCW(parray + indx, fr, renderPipe);
1982 }
1983
1984 private_rmStateGetTextJustify(s, &hjustify, &vjustify);
1985
1986 /* need w,h of the bitmaps in order to do justification & picking */
1987 if (s->rendermode == GL_SELECT || SHOW_PICKABLE_QUADS)
1988 {
1989 private_rmSetupBitmapPickMatrices(s, &vpm, &vpm_inv, &forward, &inv);
1990 }
1991
1992 for (i = 0, j = 0; i < nverts; i++, v += vstride, c += cstride)
1993 {
1994 int bw, bh;
1995 int horigin = 0, vorigin = 0;
1996 RMtextPrim *pt;
1997
1998 if (do_indices == 1)
1999 pt = parray + indices[i];
2000 else
2001 pt = parray + i;
2002 bw = pt->bw;
2003 bh = pt->bh;
2004
2005 horigin = 0.0F;
2006 if (hjustify == RM_CENTER)
2007 horigin = (GLfloat)(bw >> 1);
2008 else
2009 if (hjustify == RM_RIGHT)
2010 horigin = (GLfloat)(bw);
2011
2012 vorigin = 0.0F;
2013 if (vjustify == RM_CENTER)
2014 vorigin = (GLfloat)(bh >> 1);
2015 else
2016 if (vjustify == RM_TOP)
2017 vorigin = (GLfloat)(bh);
2018
2019 if (s->rendermode == GL_SELECT || SHOW_PICKABLE_QUADS)
2020 {
2021 RMvertex3D tv;
2022
2023 tv.x = v[0];
2024 tv.y = v[1];
2025
2026 /* 6/12/02 add code so that src z-coord is used if
2027 present. this fixes a picking bug. */
2028
2029 if (vveclen == 2)
2030 tv.z = 0.0;
2031 else
2032 tv.z = v[2];
2033
2034 private_rmDrawBitmapPickableQuads(&vpm, &vpm_inv, &forward, &inv,
2035 &tv, horigin, vorigin, bw, bh);
2036
2037 } /* end selection mode */
2038 if ((s->rendermode == GL_RENDER) || SHOW_PICKABLE_QUADS)
2039 {
2040 char *str;
2041
2042 (*colorfunc)(c);
2043 (*vertexfunc)(v);
2044
2045 str = pt->string;
2046
2047 {
2048 if (horigin != 0 || vorigin != 0)
2049 {
2050 glBitmap(0, 0, 0, 0, -horigin, -vorigin, NULL);
2051 }
2052
2053 glPushAttrib(GL_LIST_BIT);
2054 glListBase(fr->listbase - 32);
2055
2056 glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
2057 glPopAttrib();
2058 }
2059 }
2060
2061 if (do_indices == 1)
2062 j++;
2063 } /* loop over nverts */
2064
2065 if (usingTempTextProps == 1)
2066 rmTextPropsDelete(tp);
2067
2068 r = NULL; /* foil compiler warning */
2069 }
2070
2071
2072 /* PRIVATE */
2073 void
OGLPRIMPARMLIST()2074 rmIndexedTriangleFan OGLPRIMPARMLIST()
2075 {
2076 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
2077 void (*tcfunc)(const float *), (*normalfunc)(const float *);
2078
2079 /* for verts */
2080 float *v;
2081 int vstride, nverts, vveclen;
2082
2083 /* color data */
2084 float *c = NULL;
2085 int cstride, ncolors, cveclen;
2086
2087 /* texture coord data */
2088 float *tc = NULL;
2089 int tcstride;
2090 int ntc, tcveclen;
2091
2092 /* normals */
2093 float *n;
2094 int nstride, nveclen, nnormals;
2095
2096 /* indices */
2097 int *indices;
2098 int nindices, iveclen, istride;
2099
2100 int i, listStat;
2101
2102 /* get vertex data */
2103 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2104
2105 /* get indices */
2106 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
2107
2108 if ((nindices == 0) || (nverts == 0)) /* check for early termination */
2109 return;
2110
2111 private_colorMaterialStateManip(p, s, rsc);
2112 private_lightingStateManip(p, s, rsc, RM_FALSE);
2113
2114 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
2115 if (listStat == 0)
2116 return;
2117
2118 r = NULL; /* foil compiler warning */
2119
2120 /* get color data */
2121 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2122
2123 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2124
2125 /* get normals info */
2126 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2127
2128 if (vveclen == 3)
2129 vertexfunc = rmglVertex3fv;
2130 else /* assume vveclen == 2 */
2131 vertexfunc = rmglVertex2fv;
2132
2133 if (n != NULL) /* assume normals are in R3*/
2134 normalfunc = rmglNormal3fv;
2135 else
2136 normalfunc = glNoOp;
2137
2138 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2139
2140 if (ntc == 0)
2141 tcfunc = glNoOp;
2142 else
2143 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2144
2145 glBegin(GL_TRIANGLE_FAN);
2146 for (i = 0; i < nindices; i++)
2147 {
2148 int indx = indices[i];
2149
2150 (*colorfunc)(c + (indx * cstride));
2151 (*normalfunc)(n + (indx * nstride));
2152 (*tcfunc)(tc + (indx * tcstride));
2153 (*vertexfunc)(v + (indx * vstride));
2154 }
2155 glEnd();
2156
2157 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2158 }
2159
2160 /* PRIVATE */
2161 void
OGLPRIMPARMLIST()2162 rmIndexedQuads OGLPRIMPARMLIST()
2163 {
2164 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
2165 void (*tcfunc)(const float *), (*normalfunc)(const float *);
2166
2167 /* for verts */
2168 float *v;
2169 int vstride, nverts, vveclen;
2170
2171 /* color data */
2172 float *c = NULL;
2173 int cstride, ncolors, cveclen;
2174
2175 /* texture coord data */
2176 float *tc = NULL;
2177 int tcstride;
2178 int ntc, tcveclen;
2179
2180 /* normals */
2181 float *n;
2182 int nstride, nveclen, nnormals;
2183
2184 /* indices */
2185 int *indices;
2186 int nindices, iveclen, istride;
2187
2188 int i, listStat;
2189
2190
2191 /* get indices */
2192 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
2193
2194 /* get vertex data */
2195 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2196 if ((nindices == 0) || (nverts == 0)) /* check for early termination */
2197 return;
2198
2199 private_colorMaterialStateManip(p, s, rsc);
2200 private_lightingStateManip(p, s, rsc, RM_FALSE);
2201
2202 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
2203 if (listStat == 0)
2204 return;
2205
2206 r = NULL; /* foil compiler warning */
2207
2208 /* get color data */
2209 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2210
2211 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2212
2213 /* get normals info */
2214 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2215
2216 if (vveclen == 3)
2217 vertexfunc = rmglVertex3fv;
2218 else /* assume vveclen == 2 */
2219 vertexfunc = rmglVertex2fv;
2220
2221 if (n != NULL) /* assume normals are in R3*/
2222 normalfunc = rmglNormal3fv;
2223 else
2224 normalfunc = glNoOp;
2225
2226 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2227
2228 if (ntc == 0)
2229 tcfunc = glNoOp;
2230 else
2231 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2232
2233 glBegin(GL_QUADS);
2234 for (i = 0; i < nindices; i++)
2235 {
2236 int indx = indices[i];
2237
2238 (*colorfunc)(c + (indx * cstride));
2239 (*normalfunc)(n + (indx * nstride));
2240 (*tcfunc)(tc + (indx * tcstride));
2241 (*vertexfunc)(v + (indx * vstride));
2242 }
2243 glEnd();
2244
2245 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2246 }
2247
2248 /* PRIVATE */
2249 void
OGLPRIMPARMLIST()2250 rmIndexedTriangles OGLPRIMPARMLIST()
2251 {
2252 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
2253 void (*tcfunc)(const float *), (*normalfunc)(const float *);
2254
2255 /* for verts */
2256 float *v;
2257 int vstride, nverts, vveclen;
2258
2259 /* color data */
2260 float *c = NULL;
2261 int cstride, ncolors, cveclen;
2262
2263 /* texture coord data */
2264 float *tc = NULL;
2265 int tcstride;
2266 int ntc, tcveclen;
2267
2268 /* normals */
2269 float *n;
2270 int nstride, nveclen, nnormals;
2271
2272 /* indices */
2273 int *indices;
2274 int nindices, iveclen, istride;
2275
2276 /* multitexturing */
2277 int haveMTCs = 0;
2278
2279 int i, listStat;
2280
2281 /* get indices */
2282 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
2283
2284 /* get vertex data */
2285 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2286 if ((nverts == 0) || (nindices == 0)) /* check for early termination */
2287 return;
2288
2289 r = NULL; /* foil compiler warning */
2290
2291 private_colorMaterialStateManip(p, s, rsc);
2292 private_lightingStateManip(p, s, rsc, RM_FALSE);
2293
2294 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
2295 if (listStat == 0)
2296 return;
2297
2298 /* get color data */
2299 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2300
2301 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2302
2303 /* get normals info */
2304 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2305
2306 if (vveclen == 3)
2307 vertexfunc = rmglVertex3fv;
2308 else /* assume vveclen == 2 */
2309 vertexfunc = rmglVertex2fv;
2310
2311 if (n != NULL) /* assume normals are in R3 */
2312 normalfunc = rmglNormal3fv;
2313 else
2314 normalfunc = glNoOp;
2315
2316 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2317
2318 if (ntc == 0)
2319 tcfunc = glNoOp;
2320 else
2321 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2322
2323 if (p->multiTextureCoordBlobsMask != 0)
2324 haveMTCs = 1;
2325
2326 glBegin(GL_TRIANGLES);
2327 for (i = 0; i < nindices; i++)
2328 {
2329 int indx = indices[i];
2330
2331 (*colorfunc)(c + (indx * cstride));
2332 (*normalfunc)(n + (indx * nstride));
2333 (*tcfunc)(tc + (indx * tcstride));
2334 if (haveMTCs)
2335 private_dispatchMTCs(renderPipe, p, indx);
2336 (*vertexfunc)(v + (indx * vstride));
2337 }
2338 glEnd();
2339
2340 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2341 }
2342
2343 /* PRIVATE */
2344 void
OGLPRIMPARMLIST()2345 rmIndexedQuadStrip OGLPRIMPARMLIST()
2346 {
2347 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
2348 void (*tcfunc)(const float *), (*normalfunc)(const float *);
2349
2350 /* for verts */
2351 float *v;
2352 int vstride, nverts, vveclen;
2353
2354 /* color data */
2355 float *c = NULL;
2356 int cstride, ncolors, cveclen;
2357
2358 /* texture coord data */
2359 float *tc = NULL;
2360 int tcstride;
2361 int ntc, tcveclen;
2362
2363 /* normals */
2364 float *n;
2365 int nstride, nveclen, nnormals;
2366
2367 /* indices */
2368 int *indices;
2369 int nindices, iveclen, istride;
2370
2371 int i, listStat;
2372
2373 /* get indices */
2374 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
2375
2376 /* get vertex data */
2377 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2378 if ((nverts == 0) || (nindices == 0)) /* check for early termination */
2379 return;
2380
2381 private_colorMaterialStateManip(p, s, rsc);
2382 private_lightingStateManip(p, s, rsc, RM_FALSE);
2383
2384 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
2385 if (listStat == 0)
2386 return;
2387
2388 r = NULL; /* foil compiler warning */
2389
2390 /* get color data */
2391 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2392
2393 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2394
2395 /* get normals info */
2396 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2397
2398 if (vveclen == 3)
2399 vertexfunc = rmglVertex3fv;
2400 else /* assume vveclen == 2 */
2401 vertexfunc = rmglVertex2fv;
2402
2403 if (n != NULL) /* assume normals are in R3 */
2404 normalfunc = rmglNormal3fv;
2405 else
2406 normalfunc = glNoOp;
2407
2408 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2409
2410 if (ntc == 0)
2411 tcfunc = glNoOp;
2412 else
2413 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2414
2415 glBegin(GL_QUAD_STRIP);
2416 for (i = 0; i < nindices; i++)
2417 {
2418 int indx = indices[i];
2419
2420 (*colorfunc)(c + (indx * cstride));
2421 (*normalfunc)(n + (indx * nstride));
2422 (*tcfunc)(tc + (indx * tcstride));
2423 (*vertexfunc)(v + (indx * vstride));
2424 }
2425 glEnd();
2426
2427 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2428 }
2429
2430 /* PRIVATE */
2431 void
OGLPRIMPARMLIST()2432 rmIndexedTriangleStrip OGLPRIMPARMLIST()
2433 {
2434 void (*vertexfunc)(const float *), (*colorfunc)(const float *);
2435 void (*tcfunc)(const float *), (*normalfunc)(const float *);
2436
2437 /* for verts */
2438 float *v;
2439 int vstride, nverts, vveclen;
2440
2441 /* color data */
2442 float *c = NULL;
2443 int cstride, ncolors, cveclen;
2444
2445 /* texture coord data */
2446 float *tc = NULL;
2447 int tcstride;
2448 int ntc, tcveclen;
2449
2450 /* normals */
2451 float *n;
2452 int nstride, nveclen, nnormals;
2453
2454 /* indices */
2455 int *indices;
2456 int nindices, iveclen, istride;
2457
2458 int i, listStat;
2459
2460 /* get indices */
2461 private_rmGetBlobData(BLOB_INDEX_INDEX, p, &istride, &nindices, (void **)&indices, &iveclen);
2462
2463 /* get vertex data */
2464 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2465 if ((nverts == 0) || (nindices == 0)) /* check for early termination */
2466 return;
2467
2468 private_colorMaterialStateManip(p, s, rsc);
2469 private_lightingStateManip(p, s, rsc, RM_FALSE);
2470
2471 listStat = private_rmPrimitiveDisplayListBegin(renderPipe, p);
2472 if (listStat == 0)
2473 return;
2474
2475 r = NULL; /* foil compiler warning */
2476
2477 /* get color data */
2478 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2479
2480 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2481
2482 /* get normals info */
2483 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2484
2485 if (vveclen == 3)
2486 vertexfunc = rmglVertex3fv;
2487 else /* assume vveclen == 2 */
2488 vertexfunc = rmglVertex2fv;
2489
2490 if (n != NULL) /* assume normals are in R3 */
2491 normalfunc = rmglNormal3fv;
2492 else
2493 normalfunc = glNoOp;
2494
2495 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2496
2497 if (ntc == 0)
2498 tcfunc = glNoOp;
2499 else
2500 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2501
2502 glBegin(GL_TRIANGLE_STRIP);
2503 for (i = 0; i < nindices; i++)
2504 {
2505 int indx = indices[i];
2506
2507 (*colorfunc)(c + (indx * cstride));
2508 (*normalfunc)(n + (indx * nstride));
2509 (*tcfunc)(tc + (indx * tcstride));
2510 (*vertexfunc)(v + (indx * vstride));
2511 }
2512 glEnd();
2513
2514 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2515 }
2516
2517 /* PRIVATE
2518 *
2519 * 8/14/04 - updated code to accommodate per-face colors, normals, etc.
2520 * When optional data items (colors, normals) are specified per-vertex,
2521 * then we use vertex arrays. Otherwise, we use a slower path through
2522 * OpenGL.
2523 */
2524 void
OGLPRIMPARMLIST()2525 rmQuads OGLPRIMPARMLIST()
2526 {
2527 /* for verts */
2528 float *v;
2529 int vstride, nverts, vveclen;
2530
2531 /* color data */
2532 float *c = NULL;
2533 int cstride, ncolors, cveclen;
2534
2535 /* texture coord data */
2536 float *tc = NULL;
2537 int tcstride;
2538 int ntc, tcveclen;
2539
2540 /* normals */
2541 float *n;
2542 int nstride, nveclen, nnormals;
2543
2544 int listStat;
2545
2546 int perVertexColor=0, perFaceColor=0;
2547 int perVertexNormals=0, perFaceNormals=0;
2548 int useVertexArrays=1;
2549
2550 int haveMTCs = 0;
2551
2552 private_lightingStateManip(p,s, rsc, RM_FALSE);
2553 private_colorMaterialStateManip(p,s, rsc);
2554
2555 listStat = private_rmPrimitiveDisplayListBegin(renderPipe,p);
2556
2557 if (listStat == 0)
2558 return;
2559
2560 r = NULL; /* foil compiler warning */
2561
2562 /* get vertex data */
2563 private_rmGetBlobData(BLOB_VERTEX_INDEX, p, &vstride, &nverts, (void **)&v, &vveclen);
2564
2565 /* get color data */
2566 private_rmGetBlobData(BLOB_COLOR_INDEX, p, &cstride, &ncolors, (void **)&c, &cveclen);
2567
2568 /* get texture coord data - NOTE: (2/2000) tc's & quads not tested */
2569 private_rmGetBlobData(BLOB_TC_INDEX, p, &tcstride, &ntc, (void **)&tc, &tcveclen);
2570
2571 /* get normals info */
2572 private_rmGetBlobData(BLOB_NORMAL_INDEX, p, &nstride, &nnormals, (void **)&n, &nveclen);
2573
2574 /*
2575 * check to see which code path to use
2576 */
2577 if (ncolors != 0)
2578 {
2579 if (ncolors == nverts)
2580 perVertexColor = 1;
2581 else if ((ncolors << 2) == nverts)
2582 {
2583 perFaceColor = 1;
2584 useVertexArrays = 0;
2585 }
2586 }
2587
2588 if (nnormals != 0)
2589 {
2590 if (nnormals == nverts)
2591 perVertexNormals = 1;
2592 else if ((nnormals << 2) == nverts)
2593 {
2594 perFaceNormals = 1;
2595 useVertexArrays = 0;
2596 }
2597 }
2598
2599 if (p->multiTextureCoordBlobsMask != 0)
2600 {
2601 useVertexArrays = 0; /* slow path until we figure out how to
2602 use vertex arrays with MTCs. */
2603 haveMTCs = 1;
2604 }
2605
2606 if (useVertexArrays == 1)
2607 {
2608 private_rmEnableVertexArrays(nverts, ncolors, nnormals, ntc, 0, 0);
2609
2610 glVertexPointer(vveclen, GL_FLOAT, sizeof(float) * vstride, (const GLvoid *)v);
2611
2612 if (ncolors != 0)
2613 glColorPointer(cveclen, GL_FLOAT, sizeof(float) * cstride, (const GLvoid *)c);
2614
2615 if (ntc != 0)
2616 glTexCoordPointer(tcveclen, GL_FLOAT,sizeof(float) * tcstride, (const GLvoid *)tc);
2617
2618 if (nnormals != 0)
2619 glNormalPointer(GL_FLOAT, sizeof(float) * nstride, (const GLvoid *)n);
2620
2621 glDrawArrays(GL_QUADS, 0, nverts);
2622 }
2623 else
2624 {
2625 /* vertex, normal, color, tc functions */
2626 void (*vertexfunc)(const float *);
2627 void (*normalfunc)(const float *);
2628 void (*colorfunc)(const float *);
2629 void (*tcfunc)(const float *);
2630 int i;
2631
2632 if (vveclen == 3)
2633 vertexfunc = rmglVertex3fv;
2634 else
2635 vertexfunc = rmglVertex2fv;
2636
2637 if (nnormals != 0)
2638 normalfunc = rmglNormal3fv;
2639 else
2640 normalfunc = glNoOp;
2641
2642 if (ncolors != 0)
2643 private_rmSetGLColorFunc(cveclen, ncolors, &colorfunc);
2644 else
2645 colorfunc = glNoOp;
2646
2647 if (ntc == 0)
2648 tcfunc = glNoOp;
2649 else
2650 private_rmSetGLTexCoordFunc(tcveclen, ntc, &tcfunc);
2651
2652 glBegin(GL_QUADS);
2653
2654 for (i=0; i < nverts; i++)
2655 {
2656 if (nnormals != 0)
2657 (*normalfunc)(n), n += nstride;
2658 if (ncolors != 0)
2659 (*colorfunc)(c), c += cstride;
2660 if (ntc != 0)
2661 (*tcfunc)(tc), tc += tcstride;
2662 if (haveMTCs)
2663 private_dispatchMTCs(renderPipe, p, i);
2664
2665 (*vertexfunc)(v);
2666 i++;
2667 v += vstride;
2668
2669 if (nnormals != 0)
2670 (*normalfunc)(n), n += nstride;
2671 if (perVertexColor)
2672 (*colorfunc)(c), c += cstride;
2673 if (ntc != 0)
2674 (*tcfunc)(tc), tc += tcstride;
2675 if (haveMTCs)
2676 private_dispatchMTCs(renderPipe, p, i);
2677
2678 (*vertexfunc)(v);
2679 i++;
2680 v += vstride;
2681
2682 if (nnormals != 0)
2683 (*normalfunc)(n), n += nstride;
2684 if (perVertexColor)
2685 (*colorfunc)(c), c += cstride;
2686 if (ntc != 0)
2687 (*tcfunc)(tc), tc += tcstride;
2688 if (haveMTCs)
2689 private_dispatchMTCs(renderPipe, p, i);
2690
2691 (*vertexfunc)(v);
2692 i++;
2693 v += vstride;
2694
2695 if (nnormals != 0)
2696 (*normalfunc)(n), n += nstride;
2697 if (perVertexColor)
2698 (*colorfunc)(c), c += cstride;
2699 if (ntc != 0)
2700 (*tcfunc)(tc), tc += tcstride;
2701 if (haveMTCs)
2702 private_dispatchMTCs(renderPipe, p, i);
2703
2704 (*vertexfunc)(v);
2705 i++;
2706 v += vstride;
2707 }
2708
2709 glEnd();
2710 }
2711
2712
2713 private_rmPrimitiveDisplayListEnd(renderPipe, p, listStat);
2714 }
2715
2716 /* PRIVATE */
2717 /*
2718 * dispatch
2719 */
2720 void
private_dispatchMTCs(RMpipe * pipe,RMprimitive * prim,int vertexIndx)2721 private_dispatchMTCs(RMpipe *pipe,
2722 RMprimitive *prim,
2723 int vertexIndx)
2724 {
2725 int i;
2726 int offset;
2727 int mask;
2728 RMprimitiveDataBlob *b;
2729
2730 mask = prim->multiTextureCoordBlobsMask;
2731 for (i=0; (i < RM_MAX_MULTITEXTURES) && (mask != 0); i++)
2732 {
2733 if (mask & 0x1)
2734 {
2735 GLint target = GL_TEXTURE0_ARB + i;
2736 float *f;
2737
2738 b = prim->multiTextureCoordBlobs + i;
2739 offset = private_rmBlobGetStride(b) / sizeof(float) * vertexIndx;
2740 f = (float *)private_rmBlobGetData(b) + offset;
2741
2742 switch (private_rmBlobGetVeclen(b))
2743 {
2744 case 1:
2745 (*(pipe->caps->multiTexCoord1fvARB))(target, f);
2746 break;
2747 case 2:
2748 (*(pipe->caps->multiTexCoord2fvARB))(target, f);
2749 break;
2750 case 3:
2751 (*(pipe->caps->multiTexCoord3fvARB))(target, f);
2752 break;
2753 default:
2754 printf(" private_dispatchMTS - blob vector length is not 1, 2 or 3. \n");
2755 break;
2756 }
2757 }
2758 mask = mask >> 1;
2759 }
2760 }
2761
2762 /* EOF */
2763