2 * \file radeon_subset_select.c
7 * Mesa 3-D graphics library
10 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 /* $Id: radeon_subset_select.c,v 1.2 2003/08/22 20:11:45 brianp Exp $ */
36 /*#include "mmath.h"*/
42 #include "radeon_context.h"
43 #include "radeon_subset.h"
49 struct { GLfloat x
, y
, z
, w
; } pos
; /**< \brief position */
50 struct { GLfloat x
, y
, z
, w
; } eyePos
; /**< \brief position, eye coordinates */
51 struct { GLfloat x
, y
, z
, w
; } clipPos
; /**< \brief clipped coordinates */
52 struct { GLfloat x
, y
, z
, w
; } winPos
; /**< \brief position, windows coordinates */
53 struct { GLfloat s
, t
; } texCoord
; /**< \brief texture coordinates */
54 struct { GLfloat r
, g
, b
, a
; } color
; /**< \brief color */
59 * \brief Vertex buffer.
61 static struct select_vb_t
{
62 GLuint vCount
; /**< \brief vertex count */
63 vertex vBuffer
[4]; /**< \brief vertex buffer */
65 GLboolean partialLineLoop
; /**< \brief whether we are in a middle of a line loop */
71 /**********************************************************************/
72 /** \name Vertex Transformation and Clipping */
73 /**********************************************************************/
77 * \brief Transform a point (column vector) by a matrix: Q = M * P.
79 * \param Q destination point.
80 * \param P source point.
81 * \param M transformation matrix.
83 #define TRANSFORM_POINT( Q, M, P ) \
84 Q.x = M[0] * P.x + M[4] * P.y + M[8] * P.z + M[12] * P.w; \
85 Q.y = M[1] * P.x + M[5] * P.y + M[9] * P.z + M[13] * P.w; \
86 Q.z = M[2] * P.x + M[6] * P.y + M[10] * P.z + M[14] * P.w; \
87 Q.w = M[3] * P.x + M[7] * P.y + M[11] * P.z + M[15] * P.w;
90 * \brief Clip coord to window coord mapping.
92 * \param Q destination point.
93 * \param P source point.
94 * \param VP view port.
96 #define MAP_POINT( Q, P, VP ) \
97 Q.x = (GLfloat) (((P.x / P.w) + 1.0) * VP.Width / 2.0 + VP.X); \
98 Q.y = (GLfloat) (((P.y / P.w) + 1.0) * VP.Height / 2.0 + VP.Y); \
99 Q.z = (GLfloat) (((P.z / P.w) + 1.0) * (VP.Far - VP.Near) / 2.0 + VP.Near);\
104 * \brief Linear interpolation: (1 - T) * A + T * B.
106 * \param T interpolation factor.
107 * \param A first value.
108 * \param B second value.
109 * \result interpolated value.
111 #define INTERPOLATE(T, A, B) ((A) + ((B) - (A)) * (T))
116 * \brief Interpolate vertex position, color, texcoords, etc.
118 * \param t interpolation factor.
119 * \param v0 first vertex.
120 * \param v1 second vertex.
121 * \param vOut output vertex.
123 * Uses the #INTERPOLATE macro for all the interpolation of all elements.
126 interpolate_vertex(GLfloat t
, const vertex
*v0
, const vertex
*v1
,
129 vOut
->eyePos
.x
= INTERPOLATE(t
, v0
->eyePos
.x
, v1
->eyePos
.x
);
130 vOut
->eyePos
.y
= INTERPOLATE(t
, v0
->eyePos
.y
, v1
->eyePos
.y
);
131 vOut
->eyePos
.z
= INTERPOLATE(t
, v0
->eyePos
.z
, v1
->eyePos
.z
);
132 vOut
->eyePos
.w
= INTERPOLATE(t
, v0
->eyePos
.w
, v1
->eyePos
.w
);
134 vOut
->clipPos
.x
= INTERPOLATE(t
, v0
->clipPos
.x
, v1
->clipPos
.x
);
135 vOut
->clipPos
.y
= INTERPOLATE(t
, v0
->clipPos
.y
, v1
->clipPos
.y
);
136 vOut
->clipPos
.z
= INTERPOLATE(t
, v0
->clipPos
.z
, v1
->clipPos
.z
);
137 vOut
->clipPos
.w
= INTERPOLATE(t
, v0
->clipPos
.w
, v1
->clipPos
.w
);
139 vOut
->color
.r
= INTERPOLATE(t
, v0
->color
.r
, v1
->color
.r
);
140 vOut
->color
.g
= INTERPOLATE(t
, v0
->color
.g
, v1
->color
.g
);
141 vOut
->color
.b
= INTERPOLATE(t
, v0
->color
.b
, v1
->color
.b
);
142 vOut
->color
.a
= INTERPOLATE(t
, v0
->color
.a
, v1
->color
.a
);
144 vOut
->texCoord
.s
= INTERPOLATE(t
, v0
->texCoord
.s
, v1
->texCoord
.s
);
145 vOut
->texCoord
.t
= INTERPOLATE(t
, v0
->texCoord
.t
, v1
->texCoord
.t
);
156 #define CLIP_BOTTOM 4
163 * \brief Apply view volume clip testing to a point.
165 * \param v point to test.
166 * \return zero if visible, or the clip code mask, i.e., binary OR of a
167 * combination of the #CLIP_LEFT, #CLIP_RIGHT, #CLIP_BOTTOM, #CLIP_TOP, #CLIP_NEAR,
168 * #CLIP_FAR clip bit codes.
171 clip_point(const vertex
*v
)
174 if (v
->clipPos
.x
> v
->clipPos
.w
) mask
|= CLIP_RIGHT
;
175 if (v
->clipPos
.x
< -v
->clipPos
.w
) mask
|= CLIP_LEFT
;
176 if (v
->clipPos
.y
> v
->clipPos
.w
) mask
|= CLIP_TOP
;
177 if (v
->clipPos
.y
< -v
->clipPos
.w
) mask
|= CLIP_BOTTOM
;
178 if (v
->clipPos
.z
> v
->clipPos
.w
) mask
|= CLIP_FAR
;
179 if (v
->clipPos
.z
< -v
->clipPos
.w
) mask
|= CLIP_NEAR
;
186 * \brief Clipping utility macro.
188 * We use 6 instances of this code in each of the clip_line() and
189 * clip_polygon() to clip against the 6 planes. For each plane, we define the
190 * #OUTSIDE and #COMPUTE_INTERSECTION macros appropriately.
195 * \brief Apply clipping to a line segment.
197 * \param v0in input start vertex
198 * \param v1in input end vertesx
199 * \param v0new output start vertex
200 * \param v1new output end vertex
202 * \return GL_TRUE if the line segment is visible, or GL_FALSE if it is totally
208 clip_line(const vertex
*v0in
, const vertex
*v1in
,
209 vertex
*v0new
, vertex
*v1new
)
212 GLfloat dx
, dy
, dz
, dw
, t
;
215 code0
= clip_point(v0in
);
216 code1
= clip_point(v1in
);
218 return GL_FALSE
; /* totally clipped */
222 if (code0
== 0 && code1
== 0)
223 return GL_TRUE
; /* no clipping needed */
229 #define GENERAL_CLIP \
232 /* both verts are outside ==> return 0 */ \
236 /* v0 is outside, v1 is inside ==> clip */ \
237 COMPUTE_INTERSECTION( v1, v0, vNew ) \
238 interpolate_vertex(t, &v1, &v0, &vNew); \
244 /* v0 is inside, v1 is outside ==> clip */ \
245 COMPUTE_INTERSECTION( v0, v1, vNew ) \
246 interpolate_vertex(t, &v0, &v1, &vNew); \
249 /* else both verts are inside ==> do nothing */ \
252 /* Clip against +X side */
253 #define OUTSIDE(V) (V.clipPos.x > V.clipPos.w)
254 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
255 dx = OUT.clipPos.x - IN.clipPos.x; \
256 dw = OUT.clipPos.w - IN.clipPos.w; \
257 t = (IN.clipPos.x - IN.clipPos.w) / (dw-dx);
260 #undef COMPUTE_INTERSECTION
262 /* Clip against -X side */
263 #define OUTSIDE(V) (V.clipPos.x < -(V.clipPos.w))
264 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
265 dx = OUT.clipPos.x - IN.clipPos.x; \
266 dw = OUT.clipPos.w - IN.clipPos.w; \
267 t = -(IN.clipPos.x + IN.clipPos.w) / (dw+dx);
270 #undef COMPUTE_INTERSECTION
272 /* Clip against +Y side */
273 #define OUTSIDE(V) (V.clipPos.y > V.clipPos.w)
274 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
275 dy = OUT.clipPos.y - IN.clipPos.y; \
276 dw = OUT.clipPos.w - IN.clipPos.w; \
277 t = (IN.clipPos.y - IN.clipPos.w) / (dw-dy);
280 #undef COMPUTE_INTERSECTION
282 /* Clip against -Y side */
283 #define OUTSIDE(V) (V.clipPos.y < -(V.clipPos.w))
284 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
285 dy = OUT.clipPos.y - IN.clipPos.y; \
286 dw = OUT.clipPos.w - IN.clipPos.w; \
287 t = -(IN.clipPos.y + IN.clipPos.w) / (dw+dy);
290 #undef COMPUTE_INTERSECTION
292 /* Clip against +Z side */
293 #define OUTSIDE(V) (V.clipPos.z > V.clipPos.w)
294 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
295 dz = OUT.clipPos.z - IN.clipPos.z; \
296 dw = OUT.clipPos.w - IN.clipPos.w; \
297 t = (IN.clipPos.z - IN.clipPos.w) / (dw-dz);
300 #undef COMPUTE_INTERSECTION
302 /* Clip against -Z side */
303 #define OUTSIDE(V) (V.clipPos.z < -(V.clipPos.w))
304 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
305 dz = OUT.clipPos.z - IN.clipPos.z; \
306 dw = OUT.clipPos.w - IN.clipPos.w; \
307 t = -(IN.clipPos.z + IN.clipPos.w) / (dw+dz);
310 #undef COMPUTE_INTERSECTION
322 * \brief Apply clipping to a polygon.
324 * \param vIn array of input vertices.
325 * \param inCount number of input vertices
326 * \param vOut array of output vertices.
328 * \return number of vertices in \p vOut.
333 clip_polygon(const vertex
*vIn
, unsigned int inCount
, vertex
*vOut
)
335 vertex inlist
[20], outlist
[20];
336 GLfloat dx
, dy
, dz
, dw
, t
;
337 GLuint incount
, outcount
, previ
, curri
, result
;
338 const vertex
*currVert
, *prevVert
;
342 #define GENERAL_CLIP(INCOUNT, INLIST, OUTCOUNT, OUTLIST) \
345 previ = INCOUNT - 1; /* let previous = last vertex */ \
346 prevVert = INLIST + previ; \
348 for (curri = 0; curri < INCOUNT; curri++) { \
349 currVert = INLIST + curri; \
350 if (INSIDE(currVert)) { \
351 if (INSIDE(prevVert)) { \
352 /* both verts are inside ==> copy current to outlist */ \
353 OUTLIST[OUTCOUNT] = *currVert; \
357 newVert = OUTLIST + OUTCOUNT; \
358 /* current is inside and previous is outside ==> clip */ \
359 COMPUTE_INTERSECTION( currVert, prevVert, newVert ) \
361 /* Output current */ \
362 OUTLIST[OUTCOUNT] = *currVert; \
367 if (INSIDE(prevVert)) { \
368 newVert = OUTLIST + OUTCOUNT; \
369 /* current is outside and previous is inside ==> clip */ \
370 COMPUTE_INTERSECTION( prevVert, currVert, newVert ); \
371 OUTLIST[OUTCOUNT] = *newVert; \
374 /* else both verts are outside ==> do nothing */ \
376 /* let previous = current */ \
378 prevVert = currVert; \
384 #define INSIDE(V) (V->clipPos.x <= V->clipPos.w)
385 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
386 dx = OUT->clipPos.x - IN->clipPos.x; \
387 dw = OUT->clipPos.w - IN->clipPos.w; \
388 t = (IN->clipPos.x - IN->clipPos.w) / (dw - dx); \
389 interpolate_vertex(t, IN, OUT, NEW );
391 GENERAL_CLIP(inCount
, vIn
, outcount
, outlist
)
394 #undef COMPUTE_INTERSECTION
399 #define INSIDE(V) (V->clipPos.x >= -V->clipPos.w)
400 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
401 dx = OUT->clipPos.x - IN->clipPos.x; \
402 dw = OUT->clipPos.w - IN->clipPos.w; \
403 t = -(IN->clipPos.x + IN->clipPos.w) / (dw + dx); \
404 interpolate_vertex(t, IN, OUT, NEW );
406 GENERAL_CLIP(outcount
, outlist
, incount
, inlist
)
409 #undef COMPUTE_INTERSECTION
414 #define INSIDE(V) (V->clipPos.y <= V->clipPos.w)
415 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
416 dy = OUT->clipPos.y - IN->clipPos.y; \
417 dw = OUT->clipPos.w - IN->clipPos.w; \
418 t = (IN->clipPos.y - IN->clipPos.w) / (dw - dy); \
419 interpolate_vertex(t, IN, OUT, NEW );
421 GENERAL_CLIP(incount
, inlist
, outcount
, outlist
)
424 #undef COMPUTE_INTERSECTION
429 #define INSIDE(V) (V->clipPos.y >= -V->clipPos.w)
430 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
431 dy = OUT->clipPos.y - IN->clipPos.y; \
432 dw = OUT->clipPos.w - IN->clipPos.w; \
433 t = -(IN->clipPos.y + IN->clipPos.w) / (dw + dy); \
434 interpolate_vertex(t, IN, OUT, NEW );
436 GENERAL_CLIP(outcount
, outlist
, incount
, inlist
)
439 #undef COMPUTE_INTERSECTION
444 #define INSIDE(V) (V->clipPos.z <= V->clipPos.w)
445 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
446 dz = OUT->clipPos.z - IN->clipPos.z; \
447 dw = OUT->clipPos.w - IN->clipPos.w; \
448 t = (IN->clipPos.z - IN->clipPos.w) / (dw - dz); \
449 interpolate_vertex(t, IN, OUT, NEW );
451 GENERAL_CLIP(incount
, inlist
, outcount
, outlist
)
454 #undef COMPUTE_INTERSECTION
459 #define INSIDE(V) (V->clipPos.z >= -V->clipPos.w)
460 #define COMPUTE_INTERSECTION( IN, OUT, NEW ) \
461 dz = OUT->clipPos.z - IN->clipPos.z; \
462 dw = OUT->clipPos.w - IN->clipPos.w; \
463 t = -(IN->clipPos.z + IN->clipPos.w) / (dw + dz); \
464 interpolate_vertex(t, IN, OUT, NEW );
466 GENERAL_CLIP(outcount
, outlist
, result
, vOut
)
469 #undef COMPUTE_INTERSECTION
480 /**********************************************************************/
481 /** \name Selection */
482 /**********************************************************************/
486 * \brief Select point.
490 * If the clipped point is visible then maps the vertex into window coordinates
491 * and calls _mesa_update_hitflag().
494 select_point(const vertex
*v
)
496 GET_CURRENT_CONTEXT(ctx
);
497 if (clip_point(v
) == 0)
500 MAP_POINT(c
.winPos
, c
.clipPos
, ctx
->Viewport
);
501 _mesa_update_hitflag(ctx
, c
.winPos
.z
);
506 * \brief Select line.
508 * \param v0 first vertex.
509 * \param v1 second vertex.
511 * If the clipped line is visible then maps the vertices into window coordinates
512 * and calls _mesa_update_hitflag().
515 select_line(const vertex
*v0
, const vertex
*v1
)
517 GET_CURRENT_CONTEXT(ctx
);
519 if (clip_line(v0
, v1
, &c0
, &c1
))
521 MAP_POINT(c0
.winPos
, c0
.clipPos
, ctx
->Viewport
);
522 MAP_POINT(c1
.winPos
, c1
.clipPos
, ctx
->Viewport
);
523 _mesa_update_hitflag(ctx
, c0
.winPos
.z
);
524 _mesa_update_hitflag(ctx
, c1
.winPos
.z
);
529 * \brief Select line.
531 * \param v0 first vertex.
532 * \param v1 second vertex.
533 * \param v2 third vertex.
535 * If the clipped polygon is visible then maps the vertices into window
536 * coordinates and calls _mesa_update_hitflag().
539 select_triangle(const vertex
*v0
,
543 GET_CURRENT_CONTEXT(ctx
);
544 vertex vlist
[3], vclipped
[8];
550 n
= clip_polygon(vlist
, 3, vclipped
);
551 for (i
= 0; i
< n
; i
++) {
552 MAP_POINT(vclipped
[i
].winPos
, vclipped
[i
].clipPos
, ctx
->Viewport
);
553 _mesa_update_hitflag(ctx
, vclipped
[i
].winPos
.z
);
558 * \brief Set current vertex coordinates.
560 * \param x x vertex coordinate.
561 * \param y y vertex coordinate.
562 * \param z z vertex coordinate.
563 * \param w homogeneous coordinate.
565 * Stores the vertex and current attributes in ::vb, transforms it into eye space and then clip space.
567 * If a sufficient number of vertices is stored calls one of select_point(),
568 * select_line() or select_triangle(), according to the current primitive.
571 radeon_select_Vertex4f(GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
573 GET_CURRENT_CONTEXT(ctx
);
574 struct gl_polygon_attrib
*p
= &(ctx
->Polygon
);
575 vertex
*v
= vb
.vBuffer
+ vb
.vCount
;
577 /* store the vertex */
582 v
->color
.r
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][0];
583 v
->color
.g
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][1];
584 v
->color
.b
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][2];
585 v
->color
.a
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
][3];
586 v
->texCoord
.s
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][0];
587 v
->texCoord
.t
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
][1];
589 /* transform to eye space, then clip space */
590 TRANSFORM_POINT(v
->eyePos
, ctx
->ModelviewMatrixStack
.Top
->m
, v
->pos
);
591 TRANSFORM_POINT(v
->clipPos
, ctx
->ProjectionMatrixStack
.Top
->m
, v
->eyePos
);
593 switch (ctx
->Driver
.CurrentExecPrimitive
) {
595 assert(vb
.vCount
== 0);
605 assert(vb
.vCount
== 1);
606 select_line(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1);
617 assert(vb
.vCount
== 1);
618 select_line(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1);
619 vb
.vBuffer
[0] = vb
.vBuffer
[1];
620 /* leave vb.vCount at 1 */
627 vb
.partialLineLoop
= GL_FALSE
;
629 else if (vb
.vCount
== 1)
631 select_line(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1);
632 vb
.partialLineLoop
= GL_TRUE
;
637 assert(vb
.vCount
== 2);
638 vb
.partialLineLoop
= GL_FALSE
;
639 select_line(vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
640 vb
.vBuffer
[1] = vb
.vBuffer
[2];
641 /* leave vb.vCount at 2 */
645 if (vb
.vCount
== 0 || vb
.vCount
== 1)
651 assert(vb
.vCount
== 2);
652 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
656 case GL_TRIANGLE_STRIP
:
657 if (vb
.vCount
== 0 || vb
.vCount
== 1)
661 else if (vb
.vCount
== 2)
663 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
668 assert(vb
.vCount
== 3);
669 select_triangle(vb
.vBuffer
+ 1, vb
.vBuffer
+ 3, vb
.vBuffer
+ 2);
670 vb
.vBuffer
[0] = vb
.vBuffer
[2];
671 vb
.vBuffer
[1] = vb
.vBuffer
[3];
675 case GL_TRIANGLE_FAN
:
676 if (vb
.vCount
== 0 || vb
.vCount
== 1)
682 assert(vb
.vCount
== 2);
683 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
684 vb
.vBuffer
[1] = vb
.vBuffer
[2];
685 /* leave vb.vCount = 2 */
695 assert(vb
.vCount
== 3);
696 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
697 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 2, vb
.vBuffer
+ 3);
708 assert(vb
.vCount
== 3);
709 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
710 select_triangle(vb
.vBuffer
+ 1, vb
.vBuffer
+ 3, vb
.vBuffer
+ 2);
711 vb
.vBuffer
[0] = vb
.vBuffer
[2];
712 vb
.vBuffer
[1] = vb
.vBuffer
[3];
717 switch (p
->FrontMode
) {
719 assert(vb
.vCount
== 0);
726 vb
.partialLineLoop
= GL_FALSE
;
728 else if (vb
.vCount
== 1)
730 select_line(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1);
731 vb
.partialLineLoop
= GL_TRUE
;
736 assert(vb
.vCount
== 2);
737 vb
.partialLineLoop
= GL_FALSE
;
738 select_line(vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
739 vb
.vBuffer
[1] = vb
.vBuffer
[2];
740 /* leave vb.vCount at 2 */
744 /* draw as a tri-fan */
745 if (vb
.vCount
== 0 || vb
.vCount
== 1)
751 assert(vb
.vCount
== 2);
752 select_triangle(vb
.vBuffer
+ 0, vb
.vBuffer
+ 1, vb
.vBuffer
+ 2);
753 vb
.vBuffer
[1] = vb
.vBuffer
[2];
754 /* leave vb.vCount = 2 */
762 ; /* outside begin/end -- no action required */
767 * \brief Calls radeon_select_Vertex4f().
769 static void radeon_select_Vertex2f(GLfloat x
, GLfloat y
)
771 radeon_select_Vertex4f(x
, y
, 0.0, 1.0);
775 * \brief Calls radeon_select_Vertex4f().
777 static void radeon_select_Vertex2fv(const GLfloat
* v
)
779 radeon_select_Vertex4f(v
[0], v
[1], 0.0, 1.0);
783 * \brief Calls radeon_select_Vertex4f().
785 static void radeon_select_Vertex3f(GLfloat x
, GLfloat y
, GLfloat z
)
787 radeon_select_Vertex4f(x
, y
, z
, 1.0);
791 * \brief Calls radeon_select_Vertex4f().
793 static void radeon_select_Vertex3fv(const GLfloat
* v
)
795 radeon_select_Vertex4f(v
[0], v
[1], v
[2], 1.0);
800 * \brief Set current vertex color.
802 * \param r red color component.
803 * \param g gree color component.
804 * \param b blue color component.
805 * \param a alpha color component.
807 * Updates the GL context's current vertex color.
809 static void radeon_select_Color4f( GLfloat r
, GLfloat g
,
810 GLfloat b
, GLfloat a
)
812 GET_CURRENT_CONTEXT(ctx
);
813 GLfloat
*dest
= ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
821 * \brief Calls radeon_select_Color4f().
823 static void radeon_select_Color4fv( const GLfloat
*v
)
825 radeon_select_Color4f( v
[0], v
[1], v
[2], v
[3] );
829 * \brief Calls radeon_select_Color4f().
831 static void radeon_select_Color3f( GLfloat r
, GLfloat g
, GLfloat b
)
833 radeon_select_Color4f( r
, g
, b
, 1.0 );
837 * \brief Calls radeon_select_Color4f().
839 static void radeon_select_Color3fv( const GLfloat
*v
)
841 radeon_select_Color4f( v
[0], v
[1], v
[2], 1.0 );
845 * \brief Set current vertex texture coordinates.
847 * \param s texture coordinate.
848 * \param t texture coordinate.
850 * Updates the GL context's current vertex texture coordinates.
852 static __inline__
void radeon_select_TexCoord2f( GLfloat s
, GLfloat t
)
854 GET_CURRENT_CONTEXT(ctx
);
855 GLfloat
*dest
= ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
861 * \brief Calls radeon_select_TexCoord2f().
863 static void radeon_select_TexCoord2fv( const GLfloat
*v
)
865 radeon_select_TexCoord2f( v
[0], v
[1] );
870 * \brief Process glBegin().
872 * \param mode primitive.
874 static void radeon_select_Begin(GLenum mode
)
876 GET_CURRENT_CONTEXT(ctx
);
878 if (mode
> GL_POLYGON
) {
879 _mesa_error( ctx
, GL_INVALID_ENUM
, "glBegin" );
883 if (ctx
->Driver
.CurrentExecPrimitive
!= GL_POLYGON
+1) {
884 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glBegin" );
888 ctx
->Driver
.CurrentExecPrimitive
= mode
;
891 vb
.lineReset
= GL_TRUE
;
892 vb
.partialLineLoop
= GL_FALSE
;
896 * \brief Process glEnd().
898 static void radeon_select_End(void)
900 GET_CURRENT_CONTEXT(ctx
);
902 if ( (ctx
->Driver
.CurrentExecPrimitive
== GL_LINE_LOOP
||
903 (ctx
->Driver
.CurrentExecPrimitive
== GL_POLYGON
&&
904 ctx
->Polygon
.FrontMode
== GL_LINE
))
907 /* draw the last line segment */
908 if (vb
.partialLineLoop
)
909 select_line(vb
.vBuffer
+ 1, vb
.vBuffer
+ 0);
911 select_line(vb
.vBuffer
+ 2, vb
.vBuffer
+ 0);
914 ctx
->Driver
.CurrentExecPrimitive
= GL_POLYGON
+1;
919 * \brief Flush vertices.
921 * \param ctx GL context.
922 * \param flags not used.
924 * Nothing much to do here, besides marking the vertices as flushed, as we
925 * don't buffer anything.
927 static void radeonSelectFlushVertices( GLcontext
*ctx
, GLuint flags
)
929 ctx
->Driver
.NeedFlush
= 0;
933 * \brief Install the select callbacks.
935 * \param ctx GL context.
937 * Installs the glBegin()/glEnd() associated select callbacks into the glapi
940 void radeon_select_Install( GLcontext
*ctx
)
942 struct _glapi_table
*exec
= ctx
->Exec
;
944 exec
->Color3f
= radeon_select_Color3f
;
945 exec
->Color3fv
= radeon_select_Color3fv
;
946 exec
->Color4f
= radeon_select_Color4f
;
947 exec
->Color4fv
= radeon_select_Color4fv
;
948 exec
->TexCoord2f
= radeon_select_TexCoord2f
;
949 exec
->TexCoord2fv
= radeon_select_TexCoord2fv
;
950 exec
->Vertex2f
= radeon_select_Vertex2f
;
951 exec
->Vertex2fv
= radeon_select_Vertex2fv
;
952 exec
->Vertex3f
= radeon_select_Vertex3f
;
953 exec
->Vertex3fv
= radeon_select_Vertex3fv
;
954 exec
->Begin
= radeon_select_Begin
;
955 exec
->End
= radeon_select_End
;
957 ctx
->Driver
.FlushVertices
= radeonSelectFlushVertices
;
964 * \brief Set rasterization mode.
966 * \param ctx GL context.
967 * \param mode rasterization mode. Supports GL_RENDER or
969 * If mode is GL_RENDER, calls either radeonVtxfmtInit() or
970 * radeon_noop_Install depending on whether the application has focus
971 * (i.e., a fullscreen-cliprect) or not. If mode is GL_SELECT, calls
972 * radeon_select_Install().
974 static void radeonRenderMode( GLcontext
*ctx
, GLenum mode
)
978 radeonVtxfmtInit( ctx
);
981 radeon_select_Install( ctx
);
989 * \brief Setup the GL context driver callbacks.
991 * \param ctx GL context.
993 * \sa Called by radeonCreateContext().
995 void radeonInitSelect( GLcontext
*ctx
)
997 ctx
->Driver
.RenderMode
= radeonRenderMode
;