VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_feedback.c@ 24107

Last change on this file since 24107 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 59.0 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "state.h"
8#include "state_internals.h"
9#include "state/cr_statetypes.h"
10#include "state/cr_feedback.h"
11
12/*
13 * This file is really a complement to the feedbackSPU and as such
14 * has big dependencies upon it. We have to monitor a whole bunch
15 * of state in the feedbackSPU to be able to properly implement
16 * full functionality.
17 *
18 * We have to intercept glColor3f(v)/4f(v) to get state updates on
19 * color properties and also glTexCoord* too, as unlike the tilesortSPU
20 * we don't have a pincher that pulls these out as they're passing
21 * through.
22 *
23 * - Alan.
24 */
25
26
27/*
28 * Selection and feedback
29 *
30 * TODO:
31 * 1. Implement lighting for vertex colors for feedback
32 * 2. Implement user clip planes for points and lines
33 */
34
35
36/**********************************************************************/
37/***** Vertex Transformation and Clipping *****/
38/**********************************************************************/
39
40/*
41 * Transform a point (column vector) by a matrix: Q = M * P
42 */
43#define TRANSFORM_POINT( Q, M, P ) \
44 Q.x = (M).m00 * P.x + (M).m10 * P.y + (M).m20 * P.z + (M).m30 * P.w; \
45 Q.y = (M).m01 * P.x + (M).m11 * P.y + (M).m21 * P.z + (M).m31 * P.w; \
46 Q.z = (M).m02 * P.x + (M).m12 * P.y + (M).m22 * P.z + (M).m32 * P.w; \
47 Q.w = (M).m03 * P.x + (M).m13 * P.y + (M).m23 * P.z + (M).m33 * P.w;
48
49#define TRANSFORM_POINTA( Q, M, P ) \
50 Q.x = (M).m00 * (P)[0] + (M).m10 * (P)[1] + (M).m20 * (P)[2] + (M).m30 * (P)[3]; \
51 Q.y = (M).m01 * (P)[0] + (M).m11 * (P)[1] + (M).m21 * (P)[2] + (M).m31 * (P)[3]; \
52 Q.z = (M).m02 * (P)[0] + (M).m12 * (P)[1] + (M).m22 * (P)[2] + (M).m32 * (P)[3]; \
53 Q.w = (M).m03 * (P)[0] + (M).m13 * (P)[1] + (M).m23 * (P)[2] + (M).m33 * (P)[3];
54
55/*
56 * clip coord to window coord mapping
57 */
58#define MAP_POINT( Q, P, VP ) \
59 Q.x = (GLfloat) (((P.x / P.w) + 1.0) * VP.viewportW / 2.0 + VP.viewportX); \
60 Q.y = (GLfloat) (((P.y / P.w) + 1.0) * VP.viewportH / 2.0 + VP.viewportY); \
61 Q.z = (GLfloat) (((P.z / P.w) + 1.0) * (VP.farClip - VP.nearClip) / 2.0 + VP.nearClip);\
62 Q.w = (GLfloat) P.w;
63
64
65/*
66 * Linear interpolation:
67 */
68#define INTERPOLATE(T, A, B) ((A) + ((B) - (A)) * (T))
69
70
71/*
72 * Interpolate vertex position, color, texcoords, etc.
73 */
74static void
75interpolate_vertex(GLfloat t,
76 const CRVertex *v0, const CRVertex *v1,
77 CRVertex *vOut)
78{
79 vOut->eyePos.x = INTERPOLATE(t, v0->eyePos.x, v1->eyePos.x);
80 vOut->eyePos.y = INTERPOLATE(t, v0->eyePos.y, v1->eyePos.y);
81 vOut->eyePos.z = INTERPOLATE(t, v0->eyePos.z, v1->eyePos.z);
82 vOut->eyePos.w = INTERPOLATE(t, v0->eyePos.w, v1->eyePos.w);
83
84 vOut->clipPos.x = INTERPOLATE(t, v0->clipPos.x, v1->clipPos.x);
85 vOut->clipPos.y = INTERPOLATE(t, v0->clipPos.y, v1->clipPos.y);
86 vOut->clipPos.z = INTERPOLATE(t, v0->clipPos.z, v1->clipPos.z);
87 vOut->clipPos.w = INTERPOLATE(t, v0->clipPos.w, v1->clipPos.w);
88
89 vOut->attrib[VERT_ATTRIB_COLOR0][0] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_COLOR0][0], v1->attrib[VERT_ATTRIB_COLOR0][0]);
90 vOut->attrib[VERT_ATTRIB_COLOR0][1] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_COLOR0][1], v1->attrib[VERT_ATTRIB_COLOR0][1]);
91 vOut->attrib[VERT_ATTRIB_COLOR0][2] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_COLOR0][2], v1->attrib[VERT_ATTRIB_COLOR0][2]);
92 vOut->attrib[VERT_ATTRIB_COLOR0][3] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_COLOR0][3], v1->attrib[VERT_ATTRIB_COLOR0][3]);
93
94 vOut->colorIndex = INTERPOLATE(t, v0->colorIndex, v1->colorIndex);
95
96 vOut->attrib[VERT_ATTRIB_TEX0][0] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_TEX0][0], v1->attrib[VERT_ATTRIB_TEX0][0]);
97 vOut->attrib[VERT_ATTRIB_TEX0][1] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_TEX0][1], v1->attrib[VERT_ATTRIB_TEX0][0]);
98 vOut->attrib[VERT_ATTRIB_TEX0][2] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_TEX0][2], v1->attrib[VERT_ATTRIB_TEX0][0]);
99 vOut->attrib[VERT_ATTRIB_TEX0][3] = INTERPOLATE(t, v0->attrib[VERT_ATTRIB_TEX0][3], v1->attrib[VERT_ATTRIB_TEX0][0]);
100}
101
102
103
104
105/* clip bit codes */
106#define CLIP_LEFT 1
107#define CLIP_RIGHT 2
108#define CLIP_BOTTOM 4
109#define CLIP_TOP 8
110#define CLIP_NEAR 16
111#define CLIP_FAR 32
112#define CLIP_USER0 64
113#define CLIP_USER1 128
114
115
116/*
117 * Apply clip testing to a point.
118 * Return: 0 - visible
119 * non-zero - clip code mask (or of above CLIP_ bits)
120 */
121static GLuint
122clip_point(const CRVertex *v)
123{
124 CRContext *g = GetCurrentContext();
125 GLuint mask = 0;
126 GLuint i;
127
128 /* user-defined clip planes */
129 for (i = 0; i < g->limits.maxClipPlanes; i++)
130 {
131 if (g->transform.clip[i])
132 {
133 const GLvectord *plane = g->transform.clipPlane + i;
134 if (plane->x * v->eyePos.x +
135 plane->y * v->eyePos.y +
136 plane->z * v->eyePos.z +
137 plane->w * v->eyePos.w < 0.0)
138 mask |= (CLIP_USER0 << i);
139 }
140 }
141
142 /* view volume clipping */
143 if (v->clipPos.x > v->clipPos.w)
144 mask |= CLIP_RIGHT;
145 if (v->clipPos.x < -v->clipPos.w)
146 mask |= CLIP_LEFT;
147 if (v->clipPos.y > v->clipPos.w)
148 mask |= CLIP_TOP;
149 if (v->clipPos.y < -v->clipPos.w)
150 mask |= CLIP_BOTTOM;
151 if (v->clipPos.z > v->clipPos.w)
152 mask |= CLIP_FAR;
153 if (v->clipPos.z < -v->clipPos.w)
154 mask |= CLIP_NEAR;
155 return mask;
156}
157
158
159/*
160 * Apply clipping to a line segment.
161 * Input: v0, v1 - incoming vertices
162 * Output: v0out, v1out - result/clipped vertices
163 * Return: GL_TRUE: visible
164 * GL_FALSE: totally clipped
165 */
166static GLboolean
167clip_line(const CRVertex *v0in, const CRVertex *v1in,
168 CRVertex *v0new, CRVertex *v1new)
169{
170 CRVertex v0, v1, vNew;
171 GLfloat dx, dy, dz, dw, t;
172 GLuint code0, code1;
173
174 /* XXX need to do user-clip planes */
175
176 code0 = clip_point(v0in);
177 code1 = clip_point(v1in);
178 if (code0 & code1)
179 return GL_FALSE; /* totally clipped */
180
181 *v0new = *v0in;
182 *v1new = *v1in;
183 if (code0 == 0 && code1 == 0)
184 return GL_TRUE; /* no clipping needed */
185
186 v0 = *v0in;
187 v1 = *v1in;
188
189
190/*
191 * We use 6 instances of this code to clip agains the 6 planes.
192 * For each plane, we define the OUTSIDE and COMPUTE_INTERSECTION
193 * macros apprpriately.
194 */
195#define GENERAL_CLIP \
196 if (OUTSIDE(v0)) { \
197 if (OUTSIDE(v1)) { \
198 /* both verts are outside ==> return 0 */ \
199 return 0; \
200 } \
201 else { \
202 /* v0 is outside, v1 is inside ==> clip */ \
203 COMPUTE_INTERSECTION( v1, v0, vNew ) \
204 interpolate_vertex(t, &v1, &v0, &vNew); \
205 v0 = vNew; \
206 } \
207 } \
208 else { \
209 if (OUTSIDE(v1)) { \
210 /* v0 is inside, v1 is outside ==> clip */ \
211 COMPUTE_INTERSECTION( v0, v1, vNew ) \
212 interpolate_vertex(t, &v0, &v1, &vNew); \
213 v1 = vNew; \
214 } \
215 /* else both verts are inside ==> do nothing */ \
216 }
217
218 /*** Clip against +X side ***/
219#define OUTSIDE(V) (V.clipPos.x > V.clipPos.w)
220#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
221 dx = OUT.clipPos.x - IN.clipPos.x; \
222 dw = OUT.clipPos.w - IN.clipPos.w; \
223 t = (IN.clipPos.x - IN.clipPos.w) / (dw-dx);
224 GENERAL_CLIP
225#undef OUTSIDE
226#undef COMPUTE_INTERSECTION
227
228 /*** Clip against -X side ***/
229#define OUTSIDE(V) (V.clipPos.x < -(V.clipPos.w))
230#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
231 dx = OUT.clipPos.x - IN.clipPos.x; \
232 dw = OUT.clipPos.w - IN.clipPos.w; \
233 t = -(IN.clipPos.x + IN.clipPos.w) / (dw+dx);
234 GENERAL_CLIP
235#undef OUTSIDE
236#undef COMPUTE_INTERSECTION
237
238 /*** Clip against +Y side ***/
239#define OUTSIDE(V) (V.clipPos.y > V.clipPos.w)
240#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
241 dy = OUT.clipPos.y - IN.clipPos.y; \
242 dw = OUT.clipPos.w - IN.clipPos.w; \
243 t = (IN.clipPos.y - IN.clipPos.w) / (dw-dy);
244 GENERAL_CLIP
245#undef OUTSIDE
246#undef COMPUTE_INTERSECTION
247
248 /*** Clip against -Y side ***/
249#define OUTSIDE(V) (V.clipPos.y < -(V.clipPos.w))
250#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
251 dy = OUT.clipPos.y - IN.clipPos.y; \
252 dw = OUT.clipPos.w - IN.clipPos.w; \
253 t = -(IN.clipPos.y + IN.clipPos.w) / (dw+dy);
254 GENERAL_CLIP
255#undef OUTSIDE
256#undef COMPUTE_INTERSECTION
257
258 /*** Clip against +Z side ***/
259#define OUTSIDE(V) (V.clipPos.z > V.clipPos.w)
260#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
261 dz = OUT.clipPos.z - IN.clipPos.z; \
262 dw = OUT.clipPos.w - IN.clipPos.w; \
263 t = (IN.clipPos.z - IN.clipPos.w) / (dw-dz);
264 GENERAL_CLIP
265#undef OUTSIDE
266#undef COMPUTE_INTERSECTION
267
268 /*** Clip against -Z side ***/
269#define OUTSIDE(V) (V.clipPos.z < -(V.clipPos.w))
270#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
271 dz = OUT.clipPos.z - IN.clipPos.z; \
272 dw = OUT.clipPos.w - IN.clipPos.w; \
273 t = -(IN.clipPos.z + IN.clipPos.w) / (dw+dz);
274 GENERAL_CLIP
275#undef OUTSIDE
276#undef COMPUTE_INTERSECTION
277
278#undef GENERAL_CLIP
279
280 *v0new = v0;
281 *v1new = v1;
282 return GL_TRUE;
283}
284
285
286
287/*
288 * Apply clipping to a polygon.
289 * Input: vIn - array of input vertices
290 * inCount - number of input vertices
291 * Output: vOut - new vertices
292 * Return: number of vertices in vOut
293 */
294static GLuint
295clip_polygon(const CRVertex *vIn, unsigned int inCount,
296 CRVertex *vOut)
297{
298 CRVertex inlist[20], outlist[20];
299 GLfloat dx, dy, dz, dw, t;
300 GLuint incount, outcount, previ, curri, result;
301 const CRVertex *currVert, *prevVert;
302 CRVertex *newVert;
303
304 /* XXX need to do user-clip planes */
305
306#define GENERAL_CLIP(INCOUNT, INLIST, OUTCOUNT, OUTLIST) \
307 if (INCOUNT < 3) \
308 return GL_FALSE; \
309 previ = INCOUNT - 1; /* let previous = last vertex */ \
310 prevVert = INLIST + previ; \
311 OUTCOUNT = 0; \
312 for (curri = 0; curri < INCOUNT; curri++) { \
313 currVert = INLIST + curri; \
314 if (INSIDE(currVert)) { \
315 if (INSIDE(prevVert)) { \
316 /* both verts are inside ==> copy current to outlist */ \
317 OUTLIST[OUTCOUNT] = *currVert; \
318 OUTCOUNT++; \
319 } \
320 else { \
321 newVert = OUTLIST + OUTCOUNT; \
322 /* current is inside and previous is outside ==> clip */ \
323 COMPUTE_INTERSECTION( currVert, prevVert, newVert ) \
324 OUTCOUNT++; \
325 /* Output current */ \
326 OUTLIST[OUTCOUNT] = *currVert; \
327 OUTCOUNT++; \
328 } \
329 } \
330 else { \
331 if (INSIDE(prevVert)) { \
332 newVert = OUTLIST + OUTCOUNT; \
333 /* current is outside and previous is inside ==> clip */ \
334 COMPUTE_INTERSECTION( prevVert, currVert, newVert ); \
335 OUTLIST[OUTCOUNT] = *newVert; \
336 OUTCOUNT++; \
337 } \
338 /* else both verts are outside ==> do nothing */ \
339 } \
340 /* let previous = current */ \
341 previ = curri; \
342 prevVert = currVert; \
343 }
344
345/*
346 * Clip against +X
347 */
348#define INSIDE(V) (V->clipPos.x <= V->clipPos.w)
349#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
350 dx = OUT->clipPos.x - IN->clipPos.x; \
351 dw = OUT->clipPos.w - IN->clipPos.w; \
352 t = (IN->clipPos.x - IN->clipPos.w) / (dw - dx); \
353 interpolate_vertex(t, IN, OUT, NEW );
354
355 GENERAL_CLIP(inCount, vIn, outcount, outlist)
356
357#undef INSIDE
358#undef COMPUTE_INTERSECTION
359
360/*
361 * Clip against -X
362 */
363#define INSIDE(V) (V->clipPos.x >= -V->clipPos.w)
364#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
365 dx = OUT->clipPos.x - IN->clipPos.x; \
366 dw = OUT->clipPos.w - IN->clipPos.w; \
367 t = -(IN->clipPos.x + IN->clipPos.w) / (dw + dx); \
368 interpolate_vertex(t, IN, OUT, NEW );
369
370 GENERAL_CLIP(outcount, outlist, incount, inlist)
371
372#undef INSIDE
373#undef COMPUTE_INTERSECTION
374
375/*
376 * Clip against +Y
377 */
378#define INSIDE(V) (V->clipPos.y <= V->clipPos.w)
379#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
380 dy = OUT->clipPos.y - IN->clipPos.y; \
381 dw = OUT->clipPos.w - IN->clipPos.w; \
382 t = (IN->clipPos.y - IN->clipPos.w) / (dw - dy); \
383 interpolate_vertex(t, IN, OUT, NEW );
384
385 GENERAL_CLIP(incount, inlist, outcount, outlist)
386
387#undef INSIDE
388#undef COMPUTE_INTERSECTION
389
390/*
391 * Clip against -Y
392 */
393#define INSIDE(V) (V->clipPos.y >= -V->clipPos.w)
394#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
395 dy = OUT->clipPos.y - IN->clipPos.y; \
396 dw = OUT->clipPos.w - IN->clipPos.w; \
397 t = -(IN->clipPos.y + IN->clipPos.w) / (dw + dy); \
398 interpolate_vertex(t, IN, OUT, NEW );
399
400 GENERAL_CLIP(outcount, outlist, incount, inlist)
401
402#undef INSIDE
403#undef COMPUTE_INTERSECTION
404
405/*
406 * Clip against +Z
407 */
408#define INSIDE(V) (V->clipPos.z <= V->clipPos.w)
409#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
410 dz = OUT->clipPos.z - IN->clipPos.z; \
411 dw = OUT->clipPos.w - IN->clipPos.w; \
412 t = (IN->clipPos.z - IN->clipPos.w) / (dw - dz); \
413 interpolate_vertex(t, IN, OUT, NEW );
414
415 GENERAL_CLIP(incount, inlist, outcount, outlist)
416
417#undef INSIDE
418#undef COMPUTE_INTERSECTION
419
420/*
421 * Clip against -Z
422 */
423#define INSIDE(V) (V->clipPos.z >= -V->clipPos.w)
424#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
425 dz = OUT->clipPos.z - IN->clipPos.z; \
426 dw = OUT->clipPos.w - IN->clipPos.w; \
427 t = -(IN->clipPos.z + IN->clipPos.w) / (dw + dz); \
428 interpolate_vertex(t, IN, OUT, NEW );
429
430 GENERAL_CLIP(outcount, outlist, result, vOut)
431
432#undef INSIDE
433#undef COMPUTE_INTERSECTION
434
435#undef GENERAL_CLIP
436
437 return result;
438}
439
440
441/**********************************************************************/
442/***** Feedback *****/
443/**********************************************************************/
444
445
446#define FB_3D 0x01
447#define FB_4D 0x02
448#define FB_INDEX 0x04
449#define FB_COLOR 0x08
450#define FB_TEXTURE 0X10
451
452#define FEEDBACK_TOKEN( T ) \
453 do { \
454 if (f->count < f->bufferSize) { \
455 f->buffer[f->count] = (GLfloat) (T); \
456 } \
457 f->count++; \
458 } while (0)
459
460/*
461 * Put a vertex into the feedback buffer.
462 */
463static void
464feedback_vertex(const CRVertex *v)
465{
466 CRContext *g = GetCurrentContext();
467 CRFeedbackState *f = &(g->feedback);
468 CRTransformState *t = &(g->transform);
469
470 FEEDBACK_TOKEN(v->winPos.x);
471 FEEDBACK_TOKEN(v->winPos.y);
472
473 if (f->mask & FB_3D)
474 {
475 FEEDBACK_TOKEN(v->winPos.z);
476 }
477
478 if (f->mask & FB_4D)
479 {
480 FEEDBACK_TOKEN(v->winPos.w);
481 }
482
483 /* We don't deal with color index in Chromium */
484 if (f->mask & FB_INDEX)
485 {
486 FEEDBACK_TOKEN(v->colorIndex);
487 }
488
489 if (f->mask & FB_COLOR)
490 {
491 FEEDBACK_TOKEN(v->attrib[VERT_ATTRIB_COLOR0][0]);
492 FEEDBACK_TOKEN(v->attrib[VERT_ATTRIB_COLOR0][1]);
493 FEEDBACK_TOKEN(v->attrib[VERT_ATTRIB_COLOR0][2]);
494 FEEDBACK_TOKEN(v->attrib[VERT_ATTRIB_COLOR0][3]);
495 }
496
497 if (f->mask & FB_TEXTURE)
498 {
499 GLvectorf coord, transCoord;
500 /* Ugh, copy (s,t,r,q) to (x,y,z,w) */
501 coord.x = v->attrib[VERT_ATTRIB_TEX0][0];
502 coord.y = v->attrib[VERT_ATTRIB_TEX0][1];
503 coord.z = v->attrib[VERT_ATTRIB_TEX0][2];
504 coord.w = v->attrib[VERT_ATTRIB_TEX0][3];
505 TRANSFORM_POINT(transCoord, *(t->textureStack[0].top), coord);
506 FEEDBACK_TOKEN(transCoord.x);
507 FEEDBACK_TOKEN(transCoord.y);
508 FEEDBACK_TOKEN(transCoord.z);
509 FEEDBACK_TOKEN(transCoord.w);
510 }
511}
512
513
514
515static void
516feedback_rasterpos(void)
517{
518 CRContext *g = GetCurrentContext();
519 CRVertex *tv = g->vBuffer + g->vCount;
520 CRVertex v;
521
522 v.winPos.x = g->current.rasterAttrib[VERT_ATTRIB_POS][0];
523 v.winPos.y = g->current.rasterAttrib[VERT_ATTRIB_POS][1];
524 v.winPos.z = g->current.rasterAttrib[VERT_ATTRIB_POS][2];
525 v.winPos.w = g->current.rasterAttrib[VERT_ATTRIB_POS][3];
526 COPY_4V(v.attrib[VERT_ATTRIB_COLOR0] , g->current.rasterAttrib[VERT_ATTRIB_COLOR0]); /* XXX need to apply lighting */
527 COPY_4V(v.attrib[VERT_ATTRIB_COLOR1] , g->current.rasterAttrib[VERT_ATTRIB_COLOR1]);
528 v.colorIndex = (GLfloat) g->current.rasterIndex;
529
530 /* Don't do this, we're capturing TexCoord ourselves and
531 * we'd miss the conversion in RasterPosUpdate */
532 /* v.texCoord[0] = g->current.rasterTexture; */
533
534 /* So we do this instead, and pluck it from the current vertex */
535 COPY_4V(v.attrib[VERT_ATTRIB_TEX0] , tv->attrib[VERT_ATTRIB_TEX0]);
536
537 feedback_vertex(&v);
538}
539
540
541static void
542feedback_point(const CRVertex *v)
543{
544 CRContext *g = GetCurrentContext();
545 CRFeedbackState *f = &(g->feedback);
546 if (clip_point(v) == 0)
547 {
548 CRVertex c = *v;
549 MAP_POINT(c.winPos, c.clipPos, g->viewport);
550 FEEDBACK_TOKEN((GLfloat) GL_POINT_TOKEN);
551 feedback_vertex(&c);
552 }
553}
554
555
556static void
557feedback_line(const CRVertex *v0, const CRVertex *v1, GLboolean reset)
558{
559 CRContext *g = GetCurrentContext();
560 CRFeedbackState *f = &(g->feedback);
561 CRVertex c0, c1;
562 if (clip_line(v0, v1, &c0, &c1))
563 {
564 MAP_POINT(c0.winPos, c0.clipPos, g->viewport);
565 MAP_POINT(c1.winPos, c1.clipPos, g->viewport);
566 if (reset)
567 FEEDBACK_TOKEN((GLfloat) GL_LINE_RESET_TOKEN);
568 else
569 FEEDBACK_TOKEN((GLfloat) GL_LINE_TOKEN);
570 feedback_vertex(&c0);
571 feedback_vertex(&c1);
572 }
573}
574
575
576static void
577feedback_triangle(const CRVertex *v0, const CRVertex *v1, const CRVertex *v2)
578{
579 CRContext *g = GetCurrentContext();
580 CRFeedbackState *f = &(g->feedback);
581 CRVertex vlist[3], vclipped[8];
582 GLuint i, n;
583
584 vlist[0] = *v0;
585 vlist[1] = *v1;
586 vlist[2] = *v2;
587 n = clip_polygon(vlist, 3, vclipped);
588 FEEDBACK_TOKEN( (GLfloat) GL_POLYGON_TOKEN );
589 FEEDBACK_TOKEN( (GLfloat) n );
590 for (i = 0; i < n; i++) {
591 MAP_POINT(vclipped[i].winPos, vclipped[i].clipPos, g->viewport);
592 feedback_vertex(vclipped + i);
593 }
594}
595
596
597void STATE_APIENTRY
598crStateFeedbackVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
599{
600 CRContext *g = GetCurrentContext();
601 CRTransformState *t = &(g->transform);
602 CRPolygonState *p = &(g->polygon);
603 CRVertex *v = g->vBuffer + g->vCount;
604
605 /* store the vertex */
606 v->attrib[VERT_ATTRIB_POS][0] = x;
607 v->attrib[VERT_ATTRIB_POS][1] = y;
608 v->attrib[VERT_ATTRIB_POS][2] = z;
609 v->attrib[VERT_ATTRIB_POS][3] = w;
610 COPY_4V(v->attrib[VERT_ATTRIB_COLOR0] , g->current.vertexAttrib[VERT_ATTRIB_COLOR0]); /* XXX need to apply lighting */
611 v->colorIndex = g->current.colorIndex; /* XXX need to apply lighting */
612 /* Don't do this, we're capturing TexCoord ourselves as
613 * we don't have a pincher like the tilesortSPU */
614 /* v->texCoord[0] = g->current.texCoord[0]; */
615
616 /* transform to eye space, then clip space */
617 TRANSFORM_POINTA(v->eyePos, *(t->modelViewStack.top), v->attrib[VERT_ATTRIB_POS]);
618 TRANSFORM_POINT(v->clipPos, *(t->projectionStack.top), v->eyePos);
619
620 switch (g->current.mode) {
621 case GL_POINTS:
622 CRASSERT(g->vCount == 0);
623 feedback_point(v);
624 break;
625 case GL_LINES:
626 if (g->vCount == 0)
627 {
628 g->vCount = 1;
629 }
630 else
631 {
632 CRASSERT(g->vCount == 1);
633 feedback_line(g->vBuffer + 0, g->vBuffer + 1, g->lineReset);
634 g->vCount = 0;
635 }
636 break;
637 case GL_LINE_STRIP:
638 if (g->vCount == 0)
639 {
640 g->vCount = 1;
641 }
642 else
643 {
644 CRASSERT(g->vCount == 1);
645 feedback_line(g->vBuffer + 0, g->vBuffer + 1, g->lineReset);
646 g->vBuffer[0] = g->vBuffer[1];
647 g->lineReset = GL_FALSE;
648 /* leave g->vCount at 1 */
649 }
650 break;
651 case GL_LINE_LOOP:
652 if (g->vCount == 0)
653 {
654 g->lineLoop = GL_FALSE;
655 g->vCount = 1;
656 }
657 else if (g->vCount == 1)
658 {
659 feedback_line(g->vBuffer + 0, g->vBuffer + 1, g->lineReset);
660 g->lineReset = GL_FALSE;
661 g->lineLoop = GL_TRUE;
662 g->vCount = 2;
663 }
664 else
665 {
666 CRASSERT(g->vCount == 2);
667 CRASSERT(g->lineReset == GL_FALSE);
668 g->lineLoop = GL_FALSE;
669 feedback_line(g->vBuffer + 1, g->vBuffer + 2, g->lineReset);
670 g->vBuffer[1] = g->vBuffer[2];
671 /* leave g->vCount at 2 */
672 }
673 break;
674 case GL_TRIANGLES:
675 if (g->vCount == 0 || g->vCount == 1)
676 {
677 g->vCount++;
678 }
679 else
680 {
681 CRASSERT(g->vCount == 2);
682 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
683 g->vCount = 0;
684 }
685 break;
686 case GL_TRIANGLE_STRIP:
687 if (g->vCount == 0 || g->vCount == 1)
688 {
689 g->vCount++;
690 }
691 else if (g->vCount == 2)
692 {
693 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
694 g->vCount = 3;
695 }
696 else
697 {
698 CRASSERT(g->vCount == 3);
699 feedback_triangle(g->vBuffer + 1, g->vBuffer + 3, g->vBuffer + 2);
700 g->vBuffer[0] = g->vBuffer[2];
701 g->vBuffer[1] = g->vBuffer[3];
702 g->vCount = 2;
703 }
704 break;
705 case GL_TRIANGLE_FAN:
706 if (g->vCount == 0 || g->vCount == 1)
707 {
708 g->vCount++;
709 }
710 else
711 {
712 CRASSERT(g->vCount == 2);
713 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
714 g->vBuffer[1] = g->vBuffer[2];
715 /* leave g->vCount = 2 */
716 }
717 break;
718 case GL_QUADS:
719 if (g->vCount < 3)
720 {
721 g->vCount++;
722 }
723 else
724 {
725 CRASSERT(g->vCount == 3);
726 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
727 feedback_triangle(g->vBuffer + 0, g->vBuffer + 2, g->vBuffer + 3);
728 g->vCount = 0;
729 }
730 break;
731 case GL_QUAD_STRIP:
732 if (g->vCount < 3)
733 {
734 g->vCount++;
735 }
736 else
737 {
738 CRASSERT(g->vCount == 3);
739 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
740 feedback_triangle(g->vBuffer + 1, g->vBuffer + 3, g->vBuffer + 2);
741 g->vBuffer[0] = g->vBuffer[2];
742 g->vBuffer[1] = g->vBuffer[3];
743 g->vCount = 2;
744 }
745 break;
746 case GL_POLYGON:
747 /* XXX need to observe polygon mode for the above TRI/QUAD prims */
748 switch (p->frontMode) {
749 case GL_POINT:
750 CRASSERT(g->vCount == 0);
751 feedback_point(v);
752 break;
753 case GL_LINE:
754 if (g->vCount == 0)
755 {
756 g->lineLoop = GL_FALSE;
757 g->vCount = 1;
758 }
759 else if (g->vCount == 1)
760 {
761 feedback_line(g->vBuffer + 0, g->vBuffer + 1, g->lineReset);
762 g->lineReset = GL_FALSE;
763 g->lineLoop = GL_TRUE;
764 g->vCount = 2;
765 }
766 else
767 {
768 CRASSERT(g->vCount == 2);
769 CRASSERT(g->lineReset == GL_FALSE);
770 g->lineLoop = GL_FALSE;
771 feedback_line(g->vBuffer + 1, g->vBuffer + 2, g->lineReset);
772 g->vBuffer[1] = g->vBuffer[2];
773 /* leave g->vCount at 2 */
774 }
775 break;
776 case GL_FILL:
777 /* draw as a tri-fan */
778 if (g->vCount == 0 || g->vCount == 1)
779 {
780 g->vCount++;
781 }
782 else
783 {
784 CRASSERT(g->vCount == 2);
785 feedback_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
786 g->vBuffer[1] = g->vBuffer[2];
787 /* leave g->vCount = 2 */
788 }
789 break;
790 default:
791 ; /* impossible */
792 }
793 break;
794 default:
795 ; /* impossible */
796 }
797}
798
799
800void STATE_APIENTRY
801crStateFeedbackBegin(GLenum mode)
802{
803 CRContext *g = GetCurrentContext();
804
805 crStateBegin(mode);
806
807 g->vCount = 0;
808 g->lineReset = GL_TRUE;
809 g->lineLoop = GL_FALSE;
810}
811
812
813void STATE_APIENTRY
814crStateFeedbackEnd(void)
815{
816 CRContext *g = GetCurrentContext();
817
818 if ( (g->current.mode == GL_LINE_LOOP ||
819 (g->current.mode == GL_POLYGON && g->polygon.frontMode == GL_LINE))
820 && g->vCount == 2 )
821 {
822 /* draw the last line segment */
823 if (g->lineLoop)
824 feedback_line(g->vBuffer + 1, g->vBuffer + 0, GL_FALSE);
825 else
826 feedback_line(g->vBuffer + 2, g->vBuffer + 0, GL_FALSE);
827 }
828
829 crStateEnd();
830}
831
832
833void STATE_APIENTRY
834crStateFeedbackBuffer(GLsizei size, GLenum type, GLfloat * buffer)
835{
836 CRContext *g = GetCurrentContext();
837 CRFeedbackState *f = &(g->feedback);
838
839 if (g->current.inBeginEnd)
840 {
841 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
842 "FeedbackBuffer called in begin/end");
843 return;
844 }
845
846 if (g->renderMode == GL_FEEDBACK)
847 {
848 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
849 "Invalid Operation GL_FEEDBACK");
850 return;
851 }
852 if (size < 0)
853 {
854 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
855 "Invalid Value size < 0");
856 return;
857 }
858 if (!buffer)
859 {
860 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
861 "Invalid Value buffer = NULL");
862 f->bufferSize = 0;
863 return;
864 }
865
866 FLUSH();
867
868 switch (type)
869 {
870 case GL_2D:
871 f->mask = 0;
872 break;
873 case GL_3D:
874 f->mask = FB_3D;
875 break;
876 case GL_3D_COLOR:
877 f->mask = (FB_3D | FB_COLOR); /* FB_INDEX ?? */
878 break;
879 case GL_3D_COLOR_TEXTURE:
880 f->mask = (FB_3D | FB_COLOR | FB_TEXTURE); /* FB_INDEX ?? */
881 break;
882 case GL_4D_COLOR_TEXTURE:
883 f->mask = (FB_3D | FB_4D | FB_COLOR | FB_TEXTURE); /* FB_INDEX ?? */
884 break;
885 default:
886 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "invalid type");
887 return;
888 }
889
890 f->type = type;
891 f->bufferSize = size;
892 f->buffer = buffer;
893 f->count = 0;
894}
895
896
897void STATE_APIENTRY
898crStatePassThrough(GLfloat token)
899{
900 CRContext *g = GetCurrentContext();
901 CRFeedbackState *f = &(g->feedback);
902
903 if (g->current.inBeginEnd)
904 {
905 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
906 "PassThrough called in begin/end");
907 return;
908 }
909
910 FLUSH();
911
912 if (g->renderMode == GL_FEEDBACK)
913 {
914 FEEDBACK_TOKEN((GLfloat) (GLint) GL_PASS_THROUGH_TOKEN);
915 FEEDBACK_TOKEN(token);
916 }
917}
918
919
920/*
921 * Although these functions are used by the feedbackSPU alone,
922 * I've left them here as they interface to the other functions.....
923 */
924void STATE_APIENTRY
925crStateFeedbackGetBooleanv(GLenum pname, GLboolean * params)
926{
927 CRContext *g = GetCurrentContext();
928
929 switch (pname)
930 {
931
932 case GL_FEEDBACK_BUFFER_SIZE:
933 params[0] = (GLboolean) (g->feedback.bufferSize != 0);
934 break;
935 case GL_FEEDBACK_BUFFER_TYPE:
936 params[0] = (GLboolean) (g->feedback.type != 0);
937 break;
938 case GL_SELECTION_BUFFER_SIZE:
939 params[0] = (GLboolean) (g->selection.bufferSize != 0);
940 break;
941 default:
942 break;
943 }
944}
945
946
947void STATE_APIENTRY
948crStateFeedbackGetDoublev(GLenum pname, GLdouble * params)
949{
950 CRContext *g = GetCurrentContext();
951
952 switch (pname)
953 {
954
955 case GL_FEEDBACK_BUFFER_SIZE:
956 params[0] = (GLdouble) g->feedback.bufferSize;
957 break;
958 case GL_FEEDBACK_BUFFER_TYPE:
959 params[0] = (GLdouble) g->feedback.type;
960 break;
961 case GL_SELECTION_BUFFER_SIZE:
962 params[0] = (GLdouble) g->selection.bufferSize;
963 break;
964 default:
965 break;
966 }
967}
968
969
970void STATE_APIENTRY
971crStateFeedbackGetFloatv(GLenum pname, GLfloat * params)
972{
973 CRContext *g = GetCurrentContext();
974
975 switch (pname)
976 {
977
978 case GL_FEEDBACK_BUFFER_SIZE:
979 params[0] = (GLfloat) g->feedback.bufferSize;
980 break;
981 case GL_FEEDBACK_BUFFER_TYPE:
982 params[0] = (GLfloat) g->feedback.type;
983 break;
984 case GL_SELECTION_BUFFER_SIZE:
985 params[0] = (GLfloat) g->selection.bufferSize;
986 break;
987 default:
988 break;
989 }
990}
991
992
993void STATE_APIENTRY
994crStateFeedbackGetIntegerv(GLenum pname, GLint * params)
995{
996 CRContext *g = GetCurrentContext();
997
998 switch (pname)
999 {
1000
1001 case GL_FEEDBACK_BUFFER_SIZE:
1002 params[0] = (GLint) g->feedback.bufferSize;
1003 break;
1004 case GL_FEEDBACK_BUFFER_TYPE:
1005 params[0] = (GLint) g->feedback.type;
1006 break;
1007 case GL_SELECTION_BUFFER_SIZE:
1008 params[0] = (GLint) g->selection.bufferSize;
1009 break;
1010 default:
1011 break;
1012 }
1013}
1014
1015
1016void STATE_APIENTRY
1017crStateFeedbackDrawPixels(GLsizei width, GLsizei height, GLenum format,
1018 GLenum type, const GLvoid * pixels)
1019{
1020 CRContext *g = GetCurrentContext();
1021 CRFeedbackState *f = &(g->feedback);
1022
1023 (void) width;
1024 (void) height;
1025 (void) format;
1026 (void) type;
1027 (void) pixels;
1028
1029 FEEDBACK_TOKEN((GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN);
1030
1031 feedback_rasterpos();
1032}
1033
1034void STATE_APIENTRY
1035crStateFeedbackCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1036 GLenum type)
1037{
1038 CRContext *g = GetCurrentContext();
1039 CRFeedbackState *f = &(g->feedback);
1040
1041 (void) x;
1042 (void) y;
1043 (void) width;
1044 (void) height;
1045 (void) type;
1046
1047 FEEDBACK_TOKEN((GLfloat) (GLint) GL_COPY_PIXEL_TOKEN);
1048 feedback_rasterpos();
1049}
1050
1051void STATE_APIENTRY
1052crStateFeedbackBitmap(GLsizei width, GLsizei height, GLfloat xorig,
1053 GLfloat yorig, GLfloat xmove, GLfloat ymove,
1054 const GLubyte * bitmap)
1055{
1056 CRContext *g = GetCurrentContext();
1057 CRFeedbackState *f = &(g->feedback);
1058
1059 (void) width;
1060 (void) height;
1061 (void) bitmap;
1062 (void) xorig;
1063 (void) yorig;
1064
1065 FEEDBACK_TOKEN((GLfloat) (GLint) GL_BITMAP_TOKEN);
1066
1067 feedback_rasterpos();
1068
1069 if (g->current.rasterValid)
1070 {
1071 g->current.rasterAttrib[VERT_ATTRIB_POS][0] += xmove;
1072 g->current.rasterAttrib[VERT_ATTRIB_POS][1] += ymove;
1073 }
1074}
1075
1076
1077void STATE_APIENTRY
1078crStateFeedbackVertex4fv(const GLfloat * v)
1079{
1080 crStateFeedbackVertex4f(v[0], v[1], v[2], v[3]);
1081}
1082
1083void STATE_APIENTRY
1084crStateFeedbackVertex4s(GLshort v0, GLshort v1, GLshort v2, GLshort v3)
1085{
1086 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2,
1087 (GLfloat) v3);
1088}
1089
1090void STATE_APIENTRY
1091crStateFeedbackVertex4sv(const GLshort * v)
1092{
1093 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
1094 (GLfloat) v[3]);
1095}
1096
1097void STATE_APIENTRY
1098crStateFeedbackVertex4i(GLint v0, GLint v1, GLint v2, GLint v3)
1099{
1100 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2,
1101 (GLfloat) v3);
1102}
1103
1104void STATE_APIENTRY
1105crStateFeedbackVertex4iv(const GLint * v)
1106{
1107 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
1108 (GLfloat) v[3]);
1109}
1110
1111void STATE_APIENTRY
1112crStateFeedbackVertex4d(GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)
1113{
1114 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2,
1115 (GLfloat) v3);
1116}
1117
1118void STATE_APIENTRY
1119crStateFeedbackVertex4dv(const GLdouble * v)
1120{
1121 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
1122 (GLfloat) v[3]);
1123}
1124
1125void STATE_APIENTRY
1126crStateFeedbackVertex2i(GLint v0, GLint v1)
1127{
1128 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, 0.0f, 1.0f);
1129}
1130
1131void STATE_APIENTRY
1132crStateFeedbackVertex2iv(const GLint * v)
1133{
1134 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0f, 1.0f);
1135}
1136
1137void STATE_APIENTRY
1138crStateFeedbackVertex2s(GLshort v0, GLshort v1)
1139{
1140 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, 0.0f, 1.0f);
1141}
1142
1143void STATE_APIENTRY
1144crStateFeedbackVertex2sv(const GLshort * v)
1145{
1146 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0f, 1.0f);
1147}
1148
1149void STATE_APIENTRY
1150crStateFeedbackVertex2f(GLfloat v0, GLfloat v1)
1151{
1152 crStateFeedbackVertex4f(v0, v1, 0.0f, 1.0f);
1153}
1154
1155void STATE_APIENTRY
1156crStateFeedbackVertex2fv(const GLfloat * v)
1157{
1158 crStateFeedbackVertex4f(v[0], v[1], 0.0f, 1.0f);
1159}
1160
1161void STATE_APIENTRY
1162crStateFeedbackVertex2d(GLdouble v0, GLdouble v1)
1163{
1164 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, 0.0f, 1.0f);
1165}
1166
1167void STATE_APIENTRY
1168crStateFeedbackVertex2dv(const GLdouble * v)
1169{
1170 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0f, 1.0f);
1171}
1172
1173void STATE_APIENTRY
1174crStateFeedbackVertex3i(GLint v0, GLint v1, GLint v2)
1175{
1176 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2, 1.0f);
1177}
1178
1179void STATE_APIENTRY
1180crStateFeedbackVertex3iv(const GLint * v)
1181{
1182 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0f);
1183}
1184
1185void STATE_APIENTRY
1186crStateFeedbackVertex3s(GLshort v0, GLshort v1, GLshort v2)
1187{
1188 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2, 1.0f);
1189}
1190
1191void STATE_APIENTRY
1192crStateFeedbackVertex3sv(const GLshort * v)
1193{
1194 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
1195 1.0f);
1196}
1197
1198void STATE_APIENTRY
1199crStateFeedbackVertex3f(GLfloat v0, GLfloat v1, GLfloat v2)
1200{
1201 crStateFeedbackVertex4f(v0, v1, v2, 1.0f);
1202}
1203
1204void STATE_APIENTRY
1205crStateFeedbackVertex3fv(const GLfloat * v)
1206{
1207 crStateFeedbackVertex4f(v[0], v[1], v[2], 1.0f);
1208}
1209
1210void STATE_APIENTRY
1211crStateFeedbackVertex3d(GLdouble v0, GLdouble v1, GLdouble v2)
1212{
1213 crStateFeedbackVertex4f((GLfloat) v0, (GLfloat) v1, (GLfloat) v2, 1.0f);
1214}
1215
1216void STATE_APIENTRY
1217crStateFeedbackVertex3dv(const GLdouble * v)
1218{
1219 crStateFeedbackVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
1220 1.0f);
1221}
1222
1223void STATE_APIENTRY
1224crStateFeedbackTexCoord4f( GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 )
1225{
1226 CRContext *g = GetCurrentContext();
1227 CRVertex *v = g->vBuffer + g->vCount;
1228
1229 /* store the texCoord in the current vertex */
1230 v->attrib[VERT_ATTRIB_TEX0][0] = v0;
1231 v->attrib[VERT_ATTRIB_TEX0][1] = v1;
1232 v->attrib[VERT_ATTRIB_TEX0][2] = v2;
1233 v->attrib[VERT_ATTRIB_TEX0][3] = v3;
1234}
1235
1236void STATE_APIENTRY
1237crStateFeedbackTexCoord4fv( const GLfloat *v )
1238{
1239 crStateFeedbackTexCoord4f( v[0], v[1], v[2], v[3] );
1240}
1241
1242void STATE_APIENTRY
1243crStateFeedbackTexCoord4s( GLshort v0, GLshort v1, GLshort v2, GLshort v3 )
1244{
1245 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, (GLfloat)v3 );
1246}
1247
1248void STATE_APIENTRY
1249crStateFeedbackTexCoord4sv( const GLshort *v )
1250{
1251 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3] );
1252}
1253
1254void STATE_APIENTRY
1255crStateFeedbackTexCoord4i( GLint v0, GLint v1, GLint v2, GLint v3 )
1256{
1257 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, (GLfloat)v3 );
1258}
1259
1260void STATE_APIENTRY
1261crStateFeedbackTexCoord4iv( const GLint *v )
1262{
1263 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3] );
1264}
1265
1266void STATE_APIENTRY
1267crStateFeedbackTexCoord4d( GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3 )
1268{
1269 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, (GLfloat)v3 );
1270}
1271
1272void STATE_APIENTRY
1273crStateFeedbackTexCoord4dv( const GLdouble *v )
1274{
1275 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3] );
1276}
1277
1278void STATE_APIENTRY
1279crStateFeedbackTexCoord1i( GLint v0 )
1280{
1281 crStateFeedbackTexCoord4f( (GLfloat)v0, 0.0f, 0.0f, 1.0f );
1282}
1283
1284void STATE_APIENTRY
1285crStateFeedbackTexCoord1iv( const GLint *v )
1286{
1287 crStateFeedbackTexCoord4f( (GLfloat)v[0], 0.0f, 0.0f, 1.0f );
1288}
1289
1290void STATE_APIENTRY
1291crStateFeedbackTexCoord1s( GLshort v0 )
1292{
1293 crStateFeedbackTexCoord4f( (GLfloat)v0, 0.0f, 0.0f, 1.0f );
1294}
1295
1296void STATE_APIENTRY
1297crStateFeedbackTexCoord1sv( const GLshort *v )
1298{
1299 crStateFeedbackTexCoord4f( (GLfloat)v[0], 0.0f, 0.0f, 1.0f );
1300}
1301
1302void STATE_APIENTRY
1303crStateFeedbackTexCoord1f( GLfloat v0 )
1304{
1305 crStateFeedbackTexCoord4f( v0, 0.0f, 0.0f, 1.0f );
1306}
1307
1308void STATE_APIENTRY
1309crStateFeedbackTexCoord1fv( const GLfloat *v )
1310{
1311 crStateFeedbackTexCoord4f( v[0], 0.0f, 0.0f, 1.0f );
1312}
1313
1314void STATE_APIENTRY
1315crStateFeedbackTexCoord1d( GLdouble v0 )
1316{
1317 crStateFeedbackTexCoord4f( (GLfloat)v0, 0.0f, 0.0f, 1.0f );
1318}
1319
1320void STATE_APIENTRY
1321crStateFeedbackTexCoord1dv( const GLdouble *v )
1322{
1323 crStateFeedbackTexCoord4f( (GLfloat)v[0], 0.0f, 0.0f, 1.0f );
1324}
1325
1326void STATE_APIENTRY
1327crStateFeedbackTexCoord2i( GLint v0, GLint v1 )
1328{
1329 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, 0.0f, 1.0f );
1330}
1331
1332void STATE_APIENTRY
1333crStateFeedbackTexCoord2iv( const GLint *v )
1334{
1335 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], 0.0f, 1.0f );
1336}
1337
1338void STATE_APIENTRY
1339crStateFeedbackTexCoord2s( GLshort v0, GLshort v1 )
1340{
1341 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, 0.0f, 1.0f );
1342}
1343
1344void STATE_APIENTRY
1345crStateFeedbackTexCoord2sv( const GLshort *v )
1346{
1347 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], 0.0f, 1.0f );
1348}
1349
1350void STATE_APIENTRY
1351crStateFeedbackTexCoord2f( GLfloat v0, GLfloat v1 )
1352{
1353 crStateFeedbackTexCoord4f( v0, v1, 0.0f, 1.0f );
1354}
1355
1356void STATE_APIENTRY
1357crStateFeedbackTexCoord2fv( const GLfloat *v )
1358{
1359 crStateFeedbackTexCoord4f( v[0], v[1], 0.0f, 1.0f );
1360}
1361
1362void STATE_APIENTRY
1363crStateFeedbackTexCoord2d( GLdouble v0, GLdouble v1 )
1364{
1365 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, 0.0f, 1.0f );
1366}
1367
1368void STATE_APIENTRY
1369crStateFeedbackTexCoord2dv( const GLdouble *v )
1370{
1371 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], 0.0f, 1.0f );
1372}
1373
1374void STATE_APIENTRY
1375crStateFeedbackTexCoord3i( GLint v0, GLint v1, GLint v2 )
1376{
1377 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, 1.0f );
1378}
1379
1380void STATE_APIENTRY
1381crStateFeedbackTexCoord3iv( const GLint *v )
1382{
1383 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], 0.0f, 1.0f );
1384}
1385
1386void STATE_APIENTRY
1387crStateFeedbackTexCoord3s( GLshort v0, GLshort v1, GLshort v2 )
1388{
1389 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, 1.0f );
1390}
1391
1392void STATE_APIENTRY
1393crStateFeedbackTexCoord3sv( const GLshort *v )
1394{
1395 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], 1.0f );
1396}
1397
1398void STATE_APIENTRY
1399crStateFeedbackTexCoord3f( GLfloat v0, GLfloat v1, GLfloat v2 )
1400{
1401 crStateFeedbackTexCoord4f( v0, v1, v2, 1.0f );
1402}
1403
1404void STATE_APIENTRY
1405crStateFeedbackTexCoord3fv( const GLfloat *v )
1406{
1407 crStateFeedbackTexCoord4f( v[0], v[1], v[2], 1.0f );
1408}
1409
1410void STATE_APIENTRY
1411crStateFeedbackTexCoord3d( GLdouble v0, GLdouble v1, GLdouble v2 )
1412{
1413 crStateFeedbackTexCoord4f( (GLfloat)v0, (GLfloat)v1, (GLfloat)v2, 1.0f );
1414}
1415
1416void STATE_APIENTRY
1417crStateFeedbackTexCoord3dv( const GLdouble *v )
1418{
1419 crStateFeedbackTexCoord4f( (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], 1.0f );
1420}
1421
1422void STATE_APIENTRY
1423crStateFeedbackRectf(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1)
1424{
1425 crStateFeedbackBegin(GL_QUADS);
1426 crStateFeedbackVertex2f(x0, y0);
1427 crStateFeedbackVertex2f(x0, y1);
1428 crStateFeedbackVertex2f(x1, y1);
1429 crStateFeedbackVertex2f(x1, y0);
1430 crStateFeedbackEnd();
1431}
1432
1433void STATE_APIENTRY
1434crStateFeedbackRecti(GLint x0, GLint y0, GLint x1, GLint y1)
1435{
1436 crStateFeedbackRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
1437}
1438
1439void STATE_APIENTRY
1440crStateFeedbackRectd(GLdouble x0, GLdouble y0, GLdouble x1, GLdouble y1)
1441{
1442 crStateFeedbackRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
1443}
1444
1445void STATE_APIENTRY
1446crStateFeedbackRects(GLshort x0, GLshort y0, GLshort x1, GLshort y1)
1447{
1448 crStateFeedbackRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
1449}
1450
1451void STATE_APIENTRY
1452crStateFeedbackRectiv(const GLint *v0, const GLint *v1)
1453{
1454 crStateFeedbackRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
1455}
1456
1457void STATE_APIENTRY
1458crStateFeedbackRectfv(const GLfloat *v0, const GLfloat *v1)
1459{
1460 crStateFeedbackRectf(v0[0], v0[1], v1[0], v1[1]);
1461}
1462
1463void STATE_APIENTRY
1464crStateFeedbackRectdv(const GLdouble *v0, const GLdouble *v1)
1465{
1466 crStateFeedbackRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
1467}
1468
1469void STATE_APIENTRY
1470crStateFeedbackRectsv(const GLshort *v0, const GLshort *v1)
1471{
1472 crStateFeedbackRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
1473}
1474
1475/**********************************************************************/
1476/***** Selection *****/
1477/**********************************************************************/
1478
1479
1480void STATE_APIENTRY
1481crStateSelectBuffer(GLsizei size, GLuint * buffer)
1482{
1483 CRContext *g = GetCurrentContext();
1484 CRSelectionState *se = &(g->selection);
1485
1486 if (g->current.inBeginEnd)
1487 {
1488 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1489 "SelectBuffer called in begin/end");
1490 return;
1491 }
1492
1493 if (g->renderMode == GL_SELECT)
1494 {
1495 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1496 "SelectBuffer called with RenderMode = GL_SELECT");
1497 return;
1498 }
1499
1500 FLUSH();
1501
1502 se->buffer = buffer;
1503 se->bufferSize = size;
1504 se->bufferCount = 0;
1505 se->hitFlag = GL_FALSE;
1506 se->hitMinZ = 1.0;
1507 se->hitMaxZ = 0.0;
1508}
1509
1510
1511#define WRITE_RECORD( V ) \
1512 if (se->bufferCount < se->bufferSize) { \
1513 se->buffer[se->bufferCount] = (V); \
1514 } \
1515 se->bufferCount++;
1516
1517
1518static void
1519write_hit_record(CRSelectionState * se)
1520{
1521 GLuint i;
1522 GLuint zmin, zmax, zscale = (~0u);
1523
1524 /* hitMinZ and hitMaxZ are in [0,1]. Multiply these values by */
1525 /* 2^32-1 and round to nearest unsigned integer. */
1526
1527 zmin = (GLuint) ((GLfloat) zscale * se->hitMinZ);
1528 zmax = (GLuint) ((GLfloat) zscale * se->hitMaxZ);
1529
1530 WRITE_RECORD(se->nameStackDepth);
1531 WRITE_RECORD(zmin);
1532 WRITE_RECORD(zmax);
1533 for (i = 0; i < se->nameStackDepth; i++)
1534 {
1535 WRITE_RECORD(se->nameStack[i]);
1536 }
1537
1538 se->hits++;
1539 se->hitFlag = GL_FALSE;
1540 se->hitMinZ = 1.0;
1541 se->hitMaxZ = -1.0;
1542}
1543
1544
1545
1546void STATE_APIENTRY
1547crStateInitNames(void)
1548{
1549 CRContext *g = GetCurrentContext();
1550 CRSelectionState *se = &(g->selection);
1551
1552 if (g->current.inBeginEnd)
1553 {
1554 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1555 "InitNames called in begin/end");
1556 return;
1557 }
1558
1559 FLUSH();
1560
1561 /* Record the hit before the hitFlag is wiped out again. */
1562 if (g->renderMode == GL_SELECT)
1563 {
1564 if (se->hitFlag)
1565 {
1566 write_hit_record(se);
1567 }
1568 }
1569
1570 se->nameStackDepth = 0;
1571 se->hitFlag = GL_FALSE;
1572 se->hitMinZ = 1.0;
1573 se->hitMaxZ = 0.0;
1574}
1575
1576
1577void STATE_APIENTRY
1578crStateLoadName(GLuint name)
1579{
1580 CRContext *g = GetCurrentContext();
1581 CRSelectionState *se = &(g->selection);
1582
1583 if (g->current.inBeginEnd)
1584 {
1585 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1586 "LoadName called in begin/end");
1587 return;
1588 }
1589
1590
1591 if (g->renderMode != GL_SELECT)
1592 {
1593 return;
1594 }
1595
1596 if (se->nameStackDepth == 0)
1597 {
1598 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1599 "nameStackDepth = 0");
1600 return;
1601 }
1602
1603 FLUSH();
1604
1605 if (se->hitFlag)
1606 {
1607 write_hit_record(se);
1608 }
1609 if (se->nameStackDepth < MAX_NAME_STACK_DEPTH)
1610 {
1611 se->nameStack[se->nameStackDepth - 1] = name;
1612 }
1613 else
1614 {
1615 se->nameStack[MAX_NAME_STACK_DEPTH - 1] = name;
1616 }
1617}
1618
1619
1620void STATE_APIENTRY
1621crStatePushName(GLuint name)
1622{
1623 CRContext *g = GetCurrentContext();
1624 CRSelectionState *se = &(g->selection);
1625
1626 if (g->current.inBeginEnd)
1627 {
1628 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1629 "PushName called in begin/end");
1630 return;
1631 }
1632
1633
1634 if (g->renderMode != GL_SELECT)
1635 {
1636 return;
1637 }
1638
1639 FLUSH();
1640
1641 if (se->hitFlag)
1642 {
1643 write_hit_record(se);
1644 }
1645 if (se->nameStackDepth >= MAX_NAME_STACK_DEPTH)
1646 {
1647 crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW,
1648 "nameStackDepth overflow");
1649 }
1650 else
1651 se->nameStack[se->nameStackDepth++] = name;
1652}
1653
1654void STATE_APIENTRY
1655crStatePopName(void)
1656{
1657 CRContext *g = GetCurrentContext();
1658 CRSelectionState *se = &(g->selection);
1659
1660 if (g->current.inBeginEnd)
1661 {
1662 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1663 "PopName called in begin/end");
1664 return;
1665 }
1666
1667 if (g->renderMode != GL_SELECT)
1668 {
1669 return;
1670 }
1671
1672 FLUSH();
1673
1674 if (se->hitFlag)
1675 {
1676 write_hit_record(se);
1677 }
1678
1679 if (se->nameStackDepth == 0)
1680 {
1681 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW,
1682 "nameStackDepth underflow");
1683 }
1684 else
1685 se->nameStackDepth--;
1686}
1687
1688
1689static void
1690update_hitflag(GLfloat z)
1691{
1692 CRContext *g = GetCurrentContext();
1693 CRSelectionState *se = &(g->selection);
1694
1695 se->hitFlag = GL_TRUE;
1696
1697 if (z < se->hitMinZ)
1698 se->hitMinZ = z;
1699
1700 if (z > se->hitMaxZ)
1701 se->hitMaxZ = z;
1702}
1703
1704
1705static void
1706select_rasterpos(void)
1707{
1708 CRContext *g = GetCurrentContext();
1709
1710 if (g->current.rasterValid)
1711 update_hitflag(g->current.rasterAttrib[VERT_ATTRIB_POS][2]);
1712}
1713
1714static void
1715select_point(const CRVertex *v)
1716{
1717 CRContext *g = GetCurrentContext();
1718 if (clip_point(v) == 0)
1719 {
1720 CRVertex c = *v;
1721 MAP_POINT(c.winPos, c.clipPos, g->viewport);
1722 update_hitflag(c.winPos.z);
1723 }
1724}
1725
1726
1727static void
1728select_line(const CRVertex *v0, const CRVertex *v1)
1729{
1730 CRContext *g = GetCurrentContext();
1731 CRVertex c0, c1;
1732 if (clip_line(v0, v1, &c0, &c1))
1733 {
1734 MAP_POINT(c0.winPos, c0.clipPos, g->viewport);
1735 MAP_POINT(c1.winPos, c1.clipPos, g->viewport);
1736 update_hitflag(c0.winPos.z);
1737 update_hitflag(c1.winPos.z);
1738 }
1739}
1740
1741
1742static void
1743select_triangle(const CRVertex *v0,
1744 const CRVertex *v1,
1745 const CRVertex *v2)
1746{
1747 CRContext *g = GetCurrentContext();
1748 CRVertex vlist[3], vclipped[8];
1749 GLuint i, n;
1750
1751 vlist[0] = *v0;
1752 vlist[1] = *v1;
1753 vlist[2] = *v2;
1754 n = clip_polygon(vlist, 3, vclipped);
1755 for (i = 0; i < n; i++) {
1756 MAP_POINT(vclipped[i].winPos, vclipped[i].clipPos, g->viewport);
1757 update_hitflag(vclipped[i].winPos.z);
1758 }
1759}
1760
1761
1762void STATE_APIENTRY
1763crStateSelectVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1764{
1765 CRContext *g = GetCurrentContext();
1766 CRTransformState *t = &(g->transform);
1767 CRVertex *v = g->vBuffer + g->vCount;
1768
1769 /* store the vertex */
1770 v->attrib[VERT_ATTRIB_POS][0] = x;
1771 v->attrib[VERT_ATTRIB_POS][1] = y;
1772 v->attrib[VERT_ATTRIB_POS][2] = z;
1773 v->attrib[VERT_ATTRIB_POS][3] = w;
1774 COPY_4V(v->attrib[VERT_ATTRIB_COLOR0] , g->current.vertexAttrib[VERT_ATTRIB_COLOR0]); /* XXX need to apply lighting */
1775 v->colorIndex = g->current.colorIndex; /* XXX need to apply lighting */
1776 /* Don't do this, we're capturing TexCoord ourselves as
1777 * we don't have a pincher like the tilesortSPU */
1778 /* v->texCoord[0] = g->current.texCoord[0]; */
1779
1780 /* transform to eye space, then clip space */
1781 TRANSFORM_POINTA(v->eyePos, *(t->modelViewStack.top), v->attrib[VERT_ATTRIB_POS]);
1782 TRANSFORM_POINT(v->clipPos, *(t->projectionStack.top), v->eyePos);
1783
1784 switch (g->current.mode) {
1785 case GL_POINTS:
1786 CRASSERT(g->vCount == 0);
1787 select_point(v);
1788 break;
1789 case GL_LINES:
1790 if (g->vCount == 0)
1791 {
1792 g->vCount = 1;
1793 }
1794 else
1795 {
1796 CRASSERT(g->vCount == 1);
1797 select_line(g->vBuffer + 0, g->vBuffer + 1);
1798 g->vCount = 0;
1799 }
1800 break;
1801 case GL_LINE_STRIP:
1802 if (g->vCount == 0)
1803 {
1804 g->vCount = 1;
1805 }
1806 else
1807 {
1808 CRASSERT(g->vCount == 1);
1809 select_line(g->vBuffer + 0, g->vBuffer + 1);
1810 g->vBuffer[0] = g->vBuffer[1];
1811 /* leave g->vCount at 1 */
1812 }
1813 break;
1814 case GL_LINE_LOOP:
1815 if (g->vCount == 0)
1816 {
1817 g->vCount = 1;
1818 g->lineLoop = GL_FALSE;
1819 }
1820 else if (g->vCount == 1)
1821 {
1822 select_line(g->vBuffer + 0, g->vBuffer + 1);
1823 g->lineLoop = GL_TRUE;
1824 g->vCount = 2;
1825 }
1826 else
1827 {
1828 CRASSERT(g->vCount == 2);
1829 g->lineLoop = GL_FALSE;
1830 select_line(g->vBuffer + 1, g->vBuffer + 2);
1831 g->vBuffer[1] = g->vBuffer[2];
1832 /* leave g->vCount at 2 */
1833 }
1834 break;
1835 case GL_TRIANGLES:
1836 if (g->vCount == 0 || g->vCount == 1)
1837 {
1838 g->vCount++;
1839 }
1840 else
1841 {
1842 CRASSERT(g->vCount == 2);
1843 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1844 g->vCount = 0;
1845 }
1846 break;
1847 case GL_TRIANGLE_STRIP:
1848 if (g->vCount == 0 || g->vCount == 1)
1849 {
1850 g->vCount++;
1851 }
1852 else if (g->vCount == 2)
1853 {
1854 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1855 g->vCount = 3;
1856 }
1857 else
1858 {
1859 CRASSERT(g->vCount == 3);
1860 select_triangle(g->vBuffer + 1, g->vBuffer + 3, g->vBuffer + 2);
1861 g->vBuffer[0] = g->vBuffer[2];
1862 g->vBuffer[1] = g->vBuffer[3];
1863 g->vCount = 2;
1864 }
1865 break;
1866 case GL_TRIANGLE_FAN:
1867 if (g->vCount == 0 || g->vCount == 1)
1868 {
1869 g->vCount++;
1870 }
1871 else
1872 {
1873 CRASSERT(g->vCount == 2);
1874 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1875 g->vBuffer[1] = g->vBuffer[2];
1876 /* leave g->vCount = 2 */
1877 }
1878 break;
1879 case GL_QUADS:
1880 if (g->vCount < 3)
1881 {
1882 g->vCount++;
1883 }
1884 else
1885 {
1886 CRASSERT(g->vCount == 3);
1887 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1888 select_triangle(g->vBuffer + 0, g->vBuffer + 2, g->vBuffer + 3);
1889 g->vCount = 0;
1890 }
1891 break;
1892 case GL_QUAD_STRIP:
1893 if (g->vCount < 3)
1894 {
1895 g->vCount++;
1896 }
1897 else
1898 {
1899 CRASSERT(g->vCount == 3);
1900 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1901 select_triangle(g->vBuffer + 1, g->vBuffer + 3, g->vBuffer + 2);
1902 g->vBuffer[0] = g->vBuffer[2];
1903 g->vBuffer[1] = g->vBuffer[3];
1904 g->vCount = 2;
1905 }
1906 break;
1907 case GL_POLYGON:
1908 /* draw as a tri-fan */
1909 if (g->vCount == 0 || g->vCount == 1)
1910 {
1911 g->vCount++;
1912 }
1913 else
1914 {
1915 CRASSERT(g->vCount == 2);
1916 select_triangle(g->vBuffer + 0, g->vBuffer + 1, g->vBuffer + 2);
1917 g->vBuffer[1] = g->vBuffer[2];
1918 /* leave g->vCount = 2 */
1919 }
1920 break;
1921 default:
1922 ; /* impossible */
1923 }
1924}
1925
1926void STATE_APIENTRY
1927crStateSelectRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1928{
1929 crStateRasterPos4f( x, y, z, w );
1930
1931 select_rasterpos();
1932}
1933
1934void STATE_APIENTRY
1935crStateSelectBegin(GLenum mode)
1936{
1937 CRContext *g = GetCurrentContext();
1938
1939 crStateBegin(mode);
1940
1941 g->vCount = 0;
1942 g->lineReset = GL_TRUE;
1943 g->lineLoop = GL_FALSE;
1944}
1945
1946
1947void STATE_APIENTRY
1948crStateSelectEnd(void)
1949{
1950 CRContext *g = GetCurrentContext();
1951
1952 if (g->current.mode == GL_LINE_LOOP && g->vCount == 2)
1953 {
1954 /* draw the last line segment */
1955 select_line(g->vBuffer + 1, g->vBuffer + 0);
1956 }
1957
1958 crStateEnd();
1959}
1960
1961void STATE_APIENTRY
1962crStateSelectVertex2d(GLdouble x, GLdouble y)
1963{
1964 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
1965}
1966
1967void STATE_APIENTRY
1968crStateSelectVertex2dv(const GLdouble * v)
1969{
1970 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
1971}
1972
1973void STATE_APIENTRY
1974crStateSelectVertex2f(GLfloat x, GLfloat y)
1975{
1976 crStateSelectVertex4f(x, y, 0.0, 1.0);
1977}
1978
1979void STATE_APIENTRY
1980crStateSelectVertex2fv(const GLfloat * v)
1981{
1982 crStateSelectVertex4f(v[0], v[1], 0.0, 1.0);
1983}
1984
1985void STATE_APIENTRY
1986crStateSelectVertex2i(GLint x, GLint y)
1987{
1988 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
1989}
1990
1991void STATE_APIENTRY
1992crStateSelectVertex2iv(const GLint * v)
1993{
1994 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
1995}
1996
1997void STATE_APIENTRY
1998crStateSelectVertex2s(GLshort x, GLshort y)
1999{
2000 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
2001}
2002
2003void STATE_APIENTRY
2004crStateSelectVertex2sv(const GLshort * v)
2005{
2006 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
2007}
2008
2009void STATE_APIENTRY
2010crStateSelectVertex3d(GLdouble x, GLdouble y, GLdouble z)
2011{
2012 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2013}
2014
2015void STATE_APIENTRY
2016crStateSelectVertex3dv(const GLdouble * v)
2017{
2018 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0);
2019}
2020
2021void STATE_APIENTRY
2022crStateSelectVertex3f(GLfloat x, GLfloat y, GLfloat z)
2023{
2024 crStateSelectVertex4f(x, y, z, 1.0);
2025}
2026
2027void STATE_APIENTRY
2028crStateSelectVertex3fv(const GLfloat * v)
2029{
2030 crStateSelectVertex4f(v[0], v[1], v[2], 1.0);
2031}
2032
2033void STATE_APIENTRY
2034crStateSelectVertex3i(GLint x, GLint y, GLint z)
2035{
2036 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2037}
2038
2039void STATE_APIENTRY
2040crStateSelectVertex3iv(const GLint * v)
2041{
2042 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0);
2043}
2044
2045void STATE_APIENTRY
2046crStateSelectVertex3s(GLshort x, GLshort y, GLshort z)
2047{
2048 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2049}
2050
2051void STATE_APIENTRY
2052crStateSelectVertex3sv(const GLshort * v)
2053{
2054 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0);
2055}
2056
2057void STATE_APIENTRY
2058crStateSelectVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
2059{
2060 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2061}
2062
2063void STATE_APIENTRY
2064crStateSelectVertex4dv(const GLdouble * v)
2065{
2066 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
2067}
2068
2069void STATE_APIENTRY
2070crStateSelectVertex4fv(const GLfloat * v)
2071{
2072 crStateSelectVertex4f(v[0], v[1], v[2], v[3]);
2073}
2074
2075void STATE_APIENTRY
2076crStateSelectVertex4i(GLint x, GLint y, GLint z, GLint w)
2077{
2078 crStateSelectVertex4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2079}
2080
2081void STATE_APIENTRY
2082crStateSelectVertex4iv(const GLint * v)
2083{
2084 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
2085}
2086
2087void STATE_APIENTRY
2088crStateSelectVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
2089{
2090 crStateSelectVertex4f(x, y, z, w);
2091}
2092
2093void STATE_APIENTRY
2094crStateSelectVertex4sv(const GLshort * v)
2095{
2096 crStateSelectVertex4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
2097}
2098
2099void STATE_APIENTRY
2100crStateSelectRasterPos2d(GLdouble x, GLdouble y)
2101{
2102 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
2103}
2104
2105void STATE_APIENTRY
2106crStateSelectRasterPos2dv(const GLdouble * v)
2107{
2108 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
2109}
2110
2111void STATE_APIENTRY
2112crStateSelectRasterPos2f(GLfloat x, GLfloat y)
2113{
2114 crStateSelectRasterPos4f(x, y, 0.0, 1.0);
2115}
2116
2117void STATE_APIENTRY
2118crStateSelectRasterPos2fv(const GLfloat * v)
2119{
2120 crStateSelectRasterPos4f(v[0], v[1], 0.0, 1.0);
2121}
2122
2123void STATE_APIENTRY
2124crStateSelectRasterPos2i(GLint x, GLint y)
2125{
2126 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
2127}
2128
2129void STATE_APIENTRY
2130crStateSelectRasterPos2iv(const GLint * v)
2131{
2132 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
2133}
2134
2135void STATE_APIENTRY
2136crStateSelectRasterPos2s(GLshort x, GLshort y)
2137{
2138 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, 0.0, 1.0);
2139}
2140
2141void STATE_APIENTRY
2142crStateSelectRasterPos2sv(const GLshort * v)
2143{
2144 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0, 1.0);
2145}
2146
2147void STATE_APIENTRY
2148crStateSelectRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
2149{
2150 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2151}
2152
2153void STATE_APIENTRY
2154crStateSelectRasterPos3dv(const GLdouble * v)
2155{
2156 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , 1.0);
2157}
2158
2159void STATE_APIENTRY
2160crStateSelectRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
2161{
2162 crStateSelectRasterPos4f(x, y, z, 1.0);
2163}
2164
2165void STATE_APIENTRY
2166crStateSelectRasterPos3fv(const GLfloat * v)
2167{
2168 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , 1.0);
2169}
2170
2171void STATE_APIENTRY
2172crStateSelectRasterPos3i(GLint x, GLint y, GLint z)
2173{
2174 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2175}
2176
2177void STATE_APIENTRY
2178crStateSelectRasterPos3iv(const GLint * v)
2179{
2180 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , 1.0);
2181}
2182
2183void STATE_APIENTRY
2184crStateSelectRasterPos3s(GLshort x, GLshort y, GLshort z)
2185{
2186 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0);
2187}
2188
2189void STATE_APIENTRY
2190crStateSelectRasterPos3sv(const GLshort * v)
2191{
2192 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , 1.0);
2193}
2194
2195void STATE_APIENTRY
2196crStateSelectRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
2197{
2198 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2199}
2200
2201void STATE_APIENTRY
2202crStateSelectRasterPos4dv(const GLdouble * v)
2203{
2204 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , (GLfloat) v[3]);
2205}
2206
2207void STATE_APIENTRY
2208crStateSelectRasterPos4fv(const GLfloat * v)
2209{
2210 crStateSelectRasterPos4f(v[0], v[1], v[2], v[3]);
2211}
2212
2213void STATE_APIENTRY
2214crStateSelectRasterPos4i(GLint x, GLint y, GLint z, GLint w)
2215{
2216 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2217}
2218
2219void STATE_APIENTRY
2220crStateSelectRasterPos4iv(const GLint * v)
2221{
2222 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
2223}
2224
2225void STATE_APIENTRY
2226crStateSelectRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
2227{
2228 crStateSelectRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
2229}
2230
2231void STATE_APIENTRY
2232crStateSelectRasterPos4sv(const GLshort * v)
2233{
2234 crStateSelectRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] , (GLfloat) v[3]);
2235}
2236
2237void STATE_APIENTRY
2238crStateSelectRectf(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1)
2239{
2240 crStateSelectBegin(GL_QUADS);
2241 crStateSelectVertex2f(x0, y0);
2242 crStateSelectVertex2f(x0, y1);
2243 crStateSelectVertex2f(x1, y1);
2244 crStateSelectVertex2f(x1, y0);
2245 crStateSelectEnd();
2246}
2247
2248void STATE_APIENTRY
2249crStateSelectRecti(GLint x0, GLint y0, GLint x1, GLint y1)
2250{
2251 crStateSelectRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
2252}
2253
2254void STATE_APIENTRY
2255crStateSelectRectd(GLdouble x0, GLdouble y0, GLdouble x1, GLdouble y1)
2256{
2257 crStateSelectRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
2258}
2259
2260void STATE_APIENTRY
2261crStateSelectRects(GLshort x0, GLshort y0, GLshort x1, GLshort y1)
2262{
2263 crStateSelectRectf((GLfloat) x0, (GLfloat) y0, (GLfloat) x1, (GLfloat) y1);
2264}
2265
2266void STATE_APIENTRY
2267crStateSelectRectiv(const GLint *v0, const GLint *v1)
2268{
2269 crStateSelectRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
2270}
2271
2272void STATE_APIENTRY
2273crStateSelectRectfv(const GLfloat *v0, const GLfloat *v1)
2274{
2275 crStateSelectRectf(v0[0], v0[1], v1[0], v1[1]);
2276}
2277
2278void STATE_APIENTRY
2279crStateSelectRectdv(const GLdouble *v0, const GLdouble *v1)
2280{
2281 crStateSelectRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
2282}
2283
2284void STATE_APIENTRY
2285crStateSelectRectsv(const GLshort *v0, const GLshort *v1)
2286{
2287 crStateSelectRectf((GLfloat) v0[0], (GLfloat) v0[1], (GLfloat) v1[0], (GLfloat) v1[1]);
2288}
2289
2290
2291GLint STATE_APIENTRY
2292crStateRenderMode(GLenum mode)
2293{
2294 CRContext *g = GetCurrentContext();
2295 CRFeedbackState *f = &(g->feedback);
2296 CRSelectionState *se = &(g->selection);
2297 GLint result;
2298
2299 if (g->current.inBeginEnd)
2300 {
2301 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
2302 "RenderMode called in begin/end");
2303 return 0;
2304 }
2305
2306 FLUSH();
2307
2308 switch (g->renderMode)
2309 {
2310 case GL_RENDER:
2311 result = 0;
2312 break;
2313 case GL_SELECT:
2314 if (se->hitFlag)
2315 {
2316 write_hit_record(se);
2317 }
2318
2319 if (se->bufferCount > se->bufferSize)
2320 {
2321 /* overflow */
2322 result = -1;
2323 }
2324 else
2325 {
2326 result = se->hits;
2327 }
2328 se->bufferCount = 0;
2329 se->hits = 0;
2330 se->nameStackDepth = 0;
2331 break;
2332 case GL_FEEDBACK:
2333 if (f->count > f->bufferSize)
2334 {
2335 /* overflow */
2336 result = -1;
2337 }
2338 else
2339 {
2340 result = f->count;
2341 }
2342 f->count = 0;
2343 break;
2344 default:
2345 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "invalid rendermode");
2346 return 0;
2347 }
2348
2349 switch (mode)
2350 {
2351 case GL_RENDER:
2352 break;
2353 case GL_SELECT:
2354 if (se->bufferSize == 0)
2355 {
2356 /* haven't called glSelectBuffer yet */
2357 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
2358 "buffersize = 0");
2359 }
2360 break;
2361 case GL_FEEDBACK:
2362 if (f->bufferSize == 0)
2363 {
2364 /* haven't called glFeedbackBuffer yet */
2365 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
2366 "buffersize = 0");
2367 }
2368 break;
2369 default:
2370 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "invalid rendermode");
2371 return 0;
2372 }
2373
2374 g->renderMode = mode;
2375
2376 return result;
2377}
2378
2379
2380void STATE_APIENTRY
2381crStateSelectDrawPixels(GLsizei width, GLsizei height, GLenum format,
2382 GLenum type, const GLvoid * pixels)
2383{
2384 (void) width;
2385 (void) height;
2386 (void) format;
2387 (void) type;
2388 (void) pixels;
2389 select_rasterpos();
2390}
2391
2392void STATE_APIENTRY
2393crStateSelectCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2394 GLenum type)
2395{
2396 (void) x;
2397 (void) y;
2398 (void) width;
2399 (void) height;
2400 (void) type;
2401 select_rasterpos();
2402}
2403
2404void STATE_APIENTRY
2405crStateSelectBitmap(GLsizei width, GLsizei height, GLfloat xorig,
2406 GLfloat yorig, GLfloat xmove, GLfloat ymove,
2407 const GLubyte * bitmap)
2408{
2409 CRContext *g = GetCurrentContext();
2410 (void) width;
2411 (void) height;
2412 (void) xorig;
2413 (void) yorig;
2414 (void) bitmap;
2415
2416 select_rasterpos();
2417 if (g->current.rasterValid)
2418 {
2419 g->current.rasterAttrib[VERT_ATTRIB_POS][0] += xmove;
2420 g->current.rasterAttrib[VERT_ATTRIB_POS][1] += ymove;
2421 }
2422}
2423
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette