source: trunk/src/opengl/mesa/vbrender.c@ 2938

Last change on this file since 2938 was 2938, checked in by sandervl, 25 years ago

created

File size: 18.4 KB
Line 
1/* $Id: vbrender.c,v 1.1 2000-02-29 00:50:14 sandervl Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Render points, lines, and polygons. The only entry point to this
30 * file is the gl_render_vb() function. This function is called after
31 * the vertex buffer has filled up or a state change has occurred.
32 *
33 * This file basically only makes calls to the clipping functions and
34 * the point, line and triangle rasterizers via the function pointers.
35 * context->Driver.PointsFunc()
36 * context->Driver.LineFunc()
37 * context->Driver.TriangleFunc()
38 */
39
40
41#ifdef PC_HEADER
42#include "all.h"
43#else
44#ifndef XFree86Server
45#include <stdio.h>
46#else
47#include "GL/xf86glx.h"
48#endif
49#include "clip.h"
50#include "context.h"
51#include "light.h"
52#include "lines.h"
53#include "macros.h"
54#include "matrix.h"
55#include "pb.h"
56#include "points.h"
57#include "pipeline.h"
58#include "stages.h"
59#include "types.h"
60#include "vb.h"
61#include "vbcull.h"
62#include "vbrender.h"
63#include "vbindirect.h"
64#include "xform.h"
65#endif
66
67
68/*
69 * This file implements rendering of points, lines and polygons defined by
70 * vertices in the vertex buffer.
71 */
72
73/*
74 * Render a line segment from VB[v1] to VB[v2] when either one or both
75 * endpoints must be clipped.
76 */
77void gl_render_clipped_line( GLcontext *ctx, GLuint v1, GLuint v2 )
78{
79 GLuint pv = v2;
80 struct vertex_buffer *VB = ctx->VB;
81 GLubyte mask = (GLubyte) (VB->ClipMask[v1] | VB->ClipMask[v2]);
82/* GLubyte andmask = VB->ClipMask[v1] & VB->ClipMask[v2]; */
83
84 if ((ctx->line_clip_tab[VB->ClipPtr->size])( VB, &v1, &v2, mask ))
85 ctx->Driver.LineFunc( ctx, v1, v2, pv );
86}
87
88static INLINE void gl_render_clipped_line2( GLcontext *ctx,
89 GLuint v1, GLuint v2 )
90{
91 GLuint pv = v2;
92 struct vertex_buffer *VB = ctx->VB;
93 GLubyte mask = (GLubyte) (VB->ClipMask[v1] | VB->ClipMask[v2]);
94
95 if (!mask || (ctx->line_clip_tab[VB->ClipPtr->size])( VB, &v1, &v2, mask ))
96 ctx->Driver.LineFunc( ctx, v1, v2, pv );
97}
98
99
100
101/*
102 * Compute Z offsets for a polygon with plane defined by (A,B,C,D)
103 * D is not needed.
104 */
105static void offset_polygon( GLcontext *ctx, GLfloat a, GLfloat b, GLfloat c )
106{
107 GLfloat ac, bc, m;
108 GLfloat offset;
109
110 if (c<0.001F && c>-0.001F) {
111 /* to prevent underflow problems */
112 offset = 0.0F;
113 }
114 else {
115 ac = a / c;
116 bc = b / c;
117 if (ac<0.0F) ac = -ac;
118 if (bc<0.0F) bc = -bc;
119 m = MAX2( ac, bc );
120 /* m = sqrt( ac*ac + bc*bc ); */
121
122 offset = m * ctx->Polygon.OffsetFactor + ctx->Polygon.OffsetUnits;
123 }
124
125 ctx->PointZoffset = ctx->Polygon.OffsetPoint ? offset : 0.0F;
126 ctx->LineZoffset = ctx->Polygon.OffsetLine ? offset : 0.0F;
127 ctx->PolygonZoffset = ctx->Polygon.OffsetFill ? offset : 0.0F;
128}
129
130#define FLUSH_PRIM(prim) \
131do { \
132 if (ctx->PB->primitive != prim) { \
133 gl_reduced_prim_change( ctx, prim ); \
134 } \
135} while(0)
136
137
138/*
139 * When glPolygonMode() is used to specify that the front/back rendering
140 * mode for polygons is not GL_FILL we end up calling this function.
141 */
142static void unfilled_polygon( GLcontext *ctx,
143 GLuint n, GLuint vlist[],
144 GLuint pv, GLuint facing )
145{
146 GLenum mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
147 struct vertex_buffer *VB = ctx->VB;
148 GLubyte *edge_ptr = (GLubyte *)VB->EdgeFlagPtr->data;
149
150 FLUSH_PRIM(mode);
151
152 if (mode==GL_POINT) {
153 GLuint i, j;
154 for (i=0;i<n;i++) {
155 j = vlist[i];
156 if (edge_ptr[j] & 0x3) {
157 edge_ptr[j] &= ~0x3;
158 (*ctx->Driver.PointsFunc)( ctx, j, j );
159 }
160 }
161 }
162 else if (mode==GL_LINE) {
163 GLuint i, j0, j1;
164
165 /* draw the edges */
166 for (i=0;i<n-1;i++) {
167 j0 = vlist[i];
168 j1 = vlist[i+1];
169
170 if (edge_ptr[j0] & 0x1) {
171 edge_ptr[j0] &= ~1;
172 (*ctx->Driver.LineFunc)( ctx, j0, j1, pv );
173 }
174 }
175
176 /* last edge is special */
177 j0 = vlist[i];
178 j1 = vlist[0];
179
180 if (edge_ptr[j0] & 0x2) {
181 edge_ptr[j0] &= ~2;
182 (*ctx->Driver.LineFunc)( ctx, j0, j1, pv );
183 }
184 }
185 else {
186 /* Fill the polygon */
187 GLuint j0, i;
188 j0 = vlist[0];
189 for (i=2;i<n;i++) {
190 (*ctx->Driver.TriangleFunc)( ctx, j0, vlist[i-1], vlist[i], pv );
191 }
192 }
193}
194
195
196
197
198/*
199 * Render a polygon in which at least one vertex has to be clipped.
200 * Input: n - number of vertices
201 * vlist - list of vertices in the polygon.
202 * CCW order = front facing.
203 */
204void gl_render_clipped_triangle( GLcontext *ctx, GLuint n, GLuint vlist[],
205 GLuint pv )
206{
207 struct vertex_buffer *VB = ctx->VB;
208 GLubyte mask = 0;
209 GLuint i;
210
211 for (i = 0 ; i < n ; i++)
212 mask |= VB->ClipMask[vlist[i]];
213
214 n = (ctx->poly_clip_tab[VB->ClipPtr->size])( VB, n, vlist, mask );
215
216 for (i=2;i<n;i++)
217 ctx->TriangleFunc( ctx, *vlist, vlist[i-1], vlist[i], pv );
218}
219
220
221static INLINE void gl_render_clipped_triangle2( GLcontext *ctx,
222 GLuint v1, GLuint v2, GLuint v3,
223 GLuint pv )
224{
225 struct vertex_buffer *VB = ctx->VB;
226 GLubyte mask = (GLubyte) (VB->ClipMask[v1] | VB->ClipMask[v2] | VB->ClipMask[v3]);
227 GLuint vlist[VB_MAX_CLIPPED_VERTS];
228 GLuint i, n;
229
230 if (!mask) {
231 ctx->TriangleFunc( ctx, v1, v2, v3, pv );
232 return;
233 }
234
235 if (CLIP_ALL_BITS & VB->ClipMask[v1] & VB->ClipMask[v2] & VB->ClipMask[v3])
236 return;
237
238 ASSIGN_3V(vlist, v1, v2, v3 );
239 n = (ctx->poly_clip_tab[VB->ClipPtr->size])( VB, 3, vlist, mask );
240
241 for (i=2;i<n;i++)
242 ctx->TriangleFunc( ctx, *vlist, vlist[i-1], vlist[i], pv );
243}
244
245
246/* Implements triangle_rendering when (IndirectTriangles & DD_SW_SETUP)
247 * is non-zero.
248 */
249static void render_triangle( GLcontext *ctx,
250 GLuint v0, GLuint v1, GLuint v2, GLuint pv )
251{
252 struct vertex_buffer *VB = ctx->VB;
253 GLfloat (*win)[4] = VB->Win.data;
254 GLfloat ex = win[v1][0] - win[v0][0];
255 GLfloat ey = win[v1][1] - win[v0][1];
256 GLfloat fx = win[v2][0] - win[v0][0];
257 GLfloat fy = win[v2][1] - win[v0][1];
258 GLfloat c = ex*fy-ey*fx;
259 GLuint facing;
260 GLuint tricaps;
261
262 if (c * ctx->backface_sign > 0)
263 return;
264
265 facing = (c<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
266 tricaps = ctx->IndirectTriangles;
267
268 if (tricaps & DD_TRI_OFFSET) {
269 /* finish computing plane equation of polygon, compute offset */
270 GLfloat fz = win[v2][2] - win[v0][2];
271 GLfloat ez = win[v1][2] - win[v0][2];
272 GLfloat a = ey*fz-ez*fy;
273 GLfloat b = ez*fx-ex*fz;
274 offset_polygon( ctx, a, b, c );
275 }
276
277 if (tricaps & DD_TRI_LIGHT_TWOSIDE) {
278 VB->Specular = VB->Spec[facing];
279 VB->ColorPtr = VB->Color[facing];
280 VB->IndexPtr = VB->Index[facing];
281 }
282
283 if (tricaps & DD_TRI_UNFILLED) {
284 GLuint vlist[3];
285 vlist[0] = v0;
286 vlist[1] = v1;
287 vlist[2] = v2;
288 unfilled_polygon( ctx, 3, vlist, pv, facing );
289 }
290 else {
291 (*ctx->Driver.TriangleFunc)( ctx, v0, v1, v2, pv );
292 }
293}
294
295
296
297/* Implements triangle_rendering when (IndirectTriangles & DD_SW_SETUP)
298 * is non-zero.
299 */
300static void render_quad( GLcontext *ctx, GLuint v0, GLuint v1,
301 GLuint v2, GLuint v3, GLuint pv )
302{
303 struct vertex_buffer *VB = ctx->VB;
304 GLfloat (*win)[4] = VB->Win.data;
305 GLfloat ex = win[v2][0] - win[v0][0];
306 GLfloat ey = win[v2][1] - win[v0][1];
307 GLfloat fx = win[v3][0] - win[v1][0];
308 GLfloat fy = win[v3][1] - win[v1][1];
309 GLfloat c = ex*fy-ey*fx;
310 GLuint facing;
311 GLuint tricaps;
312
313 if (c * ctx->backface_sign > 0)
314 return;
315
316 facing = (c<0.0F) ^ (ctx->Polygon.FrontFace==GL_CW);
317 tricaps = ctx->IndirectTriangles;
318 (void) tricaps; /* not needed? */
319
320 if (ctx->IndirectTriangles & DD_TRI_OFFSET) {
321 GLfloat ez = win[v2][2] - win[v0][2];
322 GLfloat fz = win[v3][2] - win[v1][2];
323 GLfloat a = ey*fz-ez*fy;
324 GLfloat b = ez*fx-ex*fz;
325 offset_polygon( ctx, a, b, c );
326 }
327
328
329 if (ctx->IndirectTriangles & DD_TRI_LIGHT_TWOSIDE) {
330 VB->Specular = VB->Spec[facing];
331 VB->ColorPtr = VB->Color[facing];
332 VB->IndexPtr = VB->Index[facing];
333 }
334
335
336 /* Render the quad! */
337 if (ctx->IndirectTriangles & DD_TRI_UNFILLED) {
338 GLuint vlist[4];
339 vlist[0] = v0;
340 vlist[1] = v1;
341 vlist[2] = v2;
342 vlist[3] = v3;
343 unfilled_polygon( ctx, 4, vlist, pv, facing );
344 }
345 else {
346 (*ctx->Driver.QuadFunc)( ctx, v0, v1, v2, v3, pv );
347 }
348}
349
350
351
352
353
354extern const char *gl_prim_name[];
355
356
357/*
358 * Either the vertex buffer is full (VB->Count==VB_MAX) or glEnd() has been
359 * called. Render the primitives defined by the vertices and reset the
360 * buffer.
361 *
362 * This function won't be called if the device driver implements a
363 * RenderVB() function.
364 */
365
366#define NEED_EDGEFLAG_SETUP (ctx->TriangleCaps & DD_TRI_UNFILLED)
367
368#define EDGEFLAG_TRI( i2, i1, i, pv, parity) \
369do { \
370 GLuint e1=i1, e0=i; \
371 if (parity) { GLuint t=e1; e1=e0; e0=t; } \
372 eflag[i2] = eflag[e1] = 1; eflag[e0] = 2; \
373} while (0)
374
375#define EDGEFLAG_QUAD( i3, i2, i1, i, pv) \
376do { \
377 eflag[i3] = eflag[i2] = eflag[i1] = 1; eflag[i] = 2; \
378} while (0)
379
380
381/* Culled and possibly clipped primitives.
382 */
383#define RENDER_POINTS( start, count ) \
384 (void) cullmask; \
385 (*ctx->Driver.PointsFunc)( ctx, start, count-1 );
386
387
388#define RENDER_LINE( i1, i ) \
389do { \
390 const GLubyte flags = cullmask[i]; \
391 \
392 if (!(flags & PRIM_NOT_CULLED)) \
393 continue; \
394 \
395 if (flags & PRIM_ANY_CLIP) \
396 gl_render_clipped_line( ctx, i1, i ); \
397 else \
398 ctx->Driver.LineFunc( ctx, i1, i, i ); \
399} while (0)
400
401
402
403#define RENDER_TRI( i2, i1, i, pv, parity) \
404do { \
405 const GLubyte flags = cullmask[i]; \
406 \
407 if (!(flags & PRIM_NOT_CULLED)) \
408 continue; \
409 \
410 if (flags & PRIM_ANY_CLIP) { \
411 if (parity) { \
412 vlist[0] = i1; \
413 vlist[1] = i2; \
414 vlist[2] = i; \
415 } else { \
416 vlist[0] = i2; \
417 vlist[1] = i1; \
418 vlist[2] = i; \
419 } \
420 gl_render_clipped_triangle( ctx, 3, vlist, pv ); \
421 } else if (parity) \
422 ctx->TriangleFunc( ctx, i1, i2, i, pv ); \
423 else \
424 ctx->TriangleFunc( ctx, i2, i1, i, pv ); \
425 \
426} while (0)
427
428
429#define RENDER_QUAD( i3, i2, i1, i, pv) \
430do { \
431 const GLubyte flags = cullmask[i]; \
432 \
433 if (!(flags & PRIM_NOT_CULLED)) \
434 continue; \
435 \
436 if (flags&PRIM_ANY_CLIP) { \
437 vlist[0] = i3; \
438 vlist[1] = i2; \
439 vlist[2] = i1; \
440 vlist[3] = i; \
441 gl_render_clipped_triangle( ctx, 4, vlist, pv ); \
442 } else \
443 ctx->QuadFunc( ctx, i3, i2, i1, i, pv ); \
444} while (0)
445
446
447#define LOCAL_VARS \
448 GLcontext *ctx = VB->ctx; \
449 const GLubyte *cullmask = VB->CullMask; \
450 GLuint vlist[VB_SIZE]; \
451 GLubyte *eflag = VB->EdgeFlagPtr->data; \
452 GLuint *stipplecounter = &VB->ctx->StippleCounter; \
453 (void) vlist; (void) eflag; (void) stipplecounter;
454
455#define TAG(x) x##_cull
456#define INIT(x) FLUSH_PRIM(x)
457#define RESET_STIPPLE *stipplecounter = 0
458#include "render_tmp.h"
459
460
461
462
463
464
465
466/* Direct, no clipping or culling.
467 */
468#define RENDER_POINTS( start, count ) \
469 (*ctx->Driver.PointsFunc)( ctx, start, count-1 )
470
471#define RENDER_LINE( i1, i ) \
472 (*ctx->Driver.LineFunc)( ctx, i1, i, i )
473
474#define RENDER_TRI( i2, i1, i, pv, parity ) \
475do { \
476 if (parity) \
477 ctx->TriangleFunc( ctx, i1, i2, i, pv ); \
478 else \
479 ctx->TriangleFunc( ctx, i2, i1, i, pv ); \
480} while (0)
481
482
483#define RENDER_QUAD( i3, i2, i1, i, pv ) \
484 ctx->QuadFunc( ctx, i3, i2, i1, i, i );
485
486#define TAG(x) x##_raw
487
488#define LOCAL_VARS \
489 GLcontext *ctx = VB->ctx; \
490 GLubyte *eflag = VB->EdgeFlagPtr->data; \
491 GLuint *stipplecounter = &VB->ctx->StippleCounter; \
492 (void) eflag; (void) stipplecounter;
493
494#define INIT(x) FLUSH_PRIM(x);
495#define RESET_STIPPLE *stipplecounter = 0
496#include "render_tmp.h"
497
498
499
500
501/* Direct, with the possibility of clipping.
502 */
503#define RENDER_POINTS( start, count ) \
504 (*ctx->Driver.PointsFunc)( ctx, start, count-1 )
505
506#define RENDER_LINE( i1, i ) \
507 gl_render_clipped_line2( ctx, i1, i )
508
509#define RENDER_TRI( i2, i1, i, pv, parity) \
510do { \
511 GLuint e1=i1, e0=i; \
512 if (parity) { GLuint t=e1; e1=e0; e0=t; } \
513 gl_render_clipped_triangle2(ctx,i2,e1,e0,pv); \
514} while (0)
515
516#define RENDER_QUAD( i3, i2, i1, i, pv) \
517do { \
518 gl_render_clipped_triangle2(ctx,i3,i2,i1,pv); \
519 gl_render_clipped_triangle2(ctx,i3,i1,i,pv); \
520} while (0)
521
522/* gl_render_clipped_triangle2(ctx,i3,i2,i,pv); */
523/* gl_render_clipped_triangle2(ctx,i2,i1,i,pv); */
524
525
526#define LOCAL_VARS \
527 GLcontext *ctx = VB->ctx; \
528 GLubyte *eflag = VB->EdgeFlagPtr->data; \
529 GLuint *stipplecounter = &VB->ctx->StippleCounter; \
530 (void) eflag; (void) stipplecounter;
531
532#define INIT(x) FLUSH_PRIM(x);
533#define TAG(x) x##_clipped
534#define RESET_STIPPLE *stipplecounter = 0
535
536#include "render_tmp.h"
537
538/* Bits:
539 * 0x1 - draw this edge if it is first or second in a triangle.
540 * 0x2 - draw this edge if it is last in a triangle.
541 * 0x4 - placeholder for multipass rendering.
542 *
543 * Bits 0x1 and 0x2 are cleared after they are used. Bit 0x4 is used
544 * to stop these values going to zero in multipass rendering.
545 *
546 * Clipping introduces vertices on outgoing edges with edgeflag 0x1.
547 * Incoming edges retain the value of the clipped vertex, with the following
548 * masks:
549 * - If the incoming edge originates from the last vertex in the
550 * clipped primitive (triangle or quad), the introduced vertex
551 * retains both bits (0x3) of the original flag.
552 * - All other introduced vertices retain only bit 1 (0x1).
553 *
554 * In a horrible hack I've had to push tristrips, fans & quadstrip handling
555 * into render_tmp.h...
556 *
557 * Keith.
558 */
559void gl_setup_edgeflag( struct vertex_buffer *VB,
560 GLenum prim,
561 GLuint start,
562 GLuint count,
563 GLuint parity )
564{
565 GLubyte *flag = VB->EdgeFlagPtr->data + start;
566 GLuint n = count - start;
567 GLuint i;
568 (void) parity;
569
570 switch (prim) {
571 case GL_TRIANGLES:
572 for (i = 0 ; i < n-2 ; i+=3) {
573 if (flag[i]) flag[i] = 0x5;
574 if (flag[i+1]) flag[i+1] = 0x5;
575 if (flag[i+2]) flag[i+2] = 0x6;
576 }
577 break;
578 case GL_QUADS:
579 for (i = 0 ; i < n-3 ; i+=4) {
580 if (flag[i]) flag[i] = 0x5;
581 if (flag[i+1]) flag[i+1] = 0x5;
582 if (flag[i+2]) flag[i+2] = 0x5;
583 if (flag[i+3]) flag[i+3] = 0x6;
584 }
585 break;
586 case GL_POLYGON:
587 for (i = 0 ; i < n-1 ; i++) {
588 if (flag[i]) flag[i] = 0x5;
589 }
590 if (flag[i]) flag[i] = 0x6;
591 break;
592 default:
593 break;
594 }
595}
596
597
598
599/* Could eventually generalize to handle changes of rasterization
600 * state other than change-of-primitive. An example might be
601 * some bind-texture calls.
602 */
603void gl_render_vb( struct vertex_buffer *VB )
604{
605 GLcontext *ctx = VB->ctx;
606 GLuint i, next, prim;
607 GLuint parity = VB->Parity;
608 render_func *tab;
609 GLuint count = VB->Count;
610 GLint p = 0;
611
612 if (VB->Indirect) {
613/* gl_render_vb_indirect( VB, VB ); */
614 return;
615 } else if (VB->CullMode & CULL_MASK_ACTIVE) {
616 tab = ctx->Driver.RenderVBCulledTab;
617 } else if (VB->CullMode & CLIP_MASK_ACTIVE) {
618 tab = ctx->Driver.RenderVBClippedTab;
619 } else {
620 tab = ctx->Driver.RenderVBRawTab;
621 }
622
623 if (!VB->CullDone)
624 gl_fast_copy_vb( VB );
625
626 if (ctx->TriangleCaps & DD_TRI_UNFILLED)
627 gl_import_client_data( VB, VERT_EDGE, VEC_WRITABLE|VEC_GOOD_STRIDE );
628
629 gl_import_client_data( VB, ctx->RenderFlags,
630 (VB->ClipOrMask
631 ? VEC_WRITABLE|VEC_GOOD_STRIDE
632 : VEC_GOOD_STRIDE));
633
634 if (/* ctx->Current.Primitive == GL_POLYGON+1 && */
635 ctx->Driver.RenderStart)
636 ctx->Driver.RenderStart( ctx );
637
638 do
639 {
640 for ( i= VB->CopyStart ; i < count ; parity = 0, i = next )
641 {
642 prim = VB->Primitive[i];
643 next = VB->NextPrimitive[i];
644
645 if (ctx->TriangleCaps & DD_TRI_UNFILLED)
646 gl_setup_edgeflag(VB, (GLenum)prim, i, next, parity);
647
648 tab[prim]( VB, i, next, parity );
649
650 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
651 VB->Specular = VB->Spec[0];
652 VB->ColorPtr = VB->Color[0];
653 VB->IndexPtr = VB->Index[0];
654 }
655 }
656
657 } while (ctx->Driver.MultipassFunc &&
658 ctx->Driver.MultipassFunc( VB, ++p ));
659
660 if (ctx->PB->count > 0)
661 gl_flush_pb(ctx);
662
663 if (/* ctx->Current.Primitive == GL_POLYGON+1 && */
664 ctx->Driver.RenderFinish)
665 ctx->Driver.RenderFinish( ctx );
666}
667
668
669void gl_reduced_prim_change( GLcontext *ctx, GLenum prim )
670{
671 if (ctx->PB->count > 0)
672 gl_flush_pb(ctx);
673
674 ctx->PB->count = 0;
675 ctx->PB->mono = GL_FALSE;
676
677 if (ctx->PB->primitive != prim) {
678 ctx->PB->primitive = prim;
679
680 if (ctx->Driver.ReducedPrimitiveChange)
681 ctx->Driver.ReducedPrimitiveChange( ctx, prim );
682 }
683}
684
685
686void gl_set_render_vb_function( GLcontext *ctx )
687{
688 if (ctx->Driver.RenderVBCulledTab == 0)
689 ctx->Driver.RenderVBCulledTab = render_tab_cull;
690
691 if (ctx->Driver.RenderVBClippedTab == 0)
692 ctx->Driver.RenderVBClippedTab = render_tab_clipped;
693
694 if (ctx->Driver.RenderVBRawTab == 0)
695 ctx->Driver.RenderVBRawTab = render_tab_raw;
696
697 /* Culling will be done earlier by gl_cull_vb().
698 */
699 if (ctx->IndirectTriangles & (DD_SW_SETUP & ~DD_TRI_CULL)) {
700 ctx->TriangleFunc = render_triangle;
701 ctx->QuadFunc = render_quad;
702 } else {
703 ctx->TriangleFunc = ctx->Driver.TriangleFunc;
704 ctx->QuadFunc = ctx->Driver.QuadFunc;
705 }
706
707 if (ctx->IndirectTriangles & (DD_SW_SETUP)) {
708 ctx->ClippedTriangleFunc = render_triangle;
709 } else {
710 ctx->ClippedTriangleFunc = ctx->TriangleFunc;
711 }
712
713}
714
715void gl_init_vbrender( void )
716{
717 render_init_raw();
718 render_init_cull();
719 render_init_clipped();
720}
721
722
723
724
Note: See TracBrowser for help on using the repository browser.