source: trunk/src/opengl/mesa/vbindirect.c@ 3830

Last change on this file since 3830 was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 10.5 KB
Line 
1/* $Id: vbindirect.c,v 1.2 2000-05-23 20:41:02 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
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 * New (3.1) transformation code written by Keith Whitwell.
29 */
30
31
32#include "glheader.h"
33#include "vb.h"
34#include "vbcull.h"
35#include "vbrender.h"
36#include "pipeline.h"
37#include "pb.h"
38#include "types.h"
39#include "stages.h"
40
41static struct gl_prim_state next_lines[3] = {
42 { 1, 2, 0, 0, &next_lines[1] },
43 { 1, 2, 1, 0, &next_lines[0] }
44};
45
46static struct gl_prim_state next_line_loop[3] = {
47 { 1, 2, 0, 0, &next_line_loop[1] },
48 { 1, 2, 1, 1, &next_line_loop[1] }
49};
50
51static struct gl_prim_state next_line_strip[3] = {
52 { 1, 2, 0, 0, &next_line_strip[1] },
53 { 1, 2, 1, 0, &next_line_strip[1] }
54};
55
56static struct gl_prim_state next_poly[3] = {
57 { 1, 2, 0, 0, &next_poly[1] },
58 { 1, 2, 0, 0, &next_poly[2] },
59 { 0, 2, 1, 0, &next_poly[2] }
60};
61
62static struct gl_prim_state next_tris[3] = {
63 { 1, 2, 0, 0, &next_tris[1] },
64 { 1, 2, 0, 0, &next_tris[2] },
65 { 1, 2, 1, 0, &next_tris[0] }
66};
67
68static struct gl_prim_state next_tri_strip0[4] = {
69 { 2, 1, 0, 0, &next_tri_strip0[1] },
70 { 0, 2, 0, 0, &next_tri_strip0[2] },
71 { 2, 1, 1, 0, &next_tri_strip0[3] },
72 { 0, 2, 1, 0, &next_tri_strip0[2] },
73};
74
75static struct gl_prim_state next_tri_strip1[4] = {
76 { 0, 2, 0, 0, &next_tri_strip1[1] },
77 { 2, 1, 0, 0, &next_tri_strip1[2] },
78 { 0, 2, 1, 0, &next_tri_strip1[3] },
79 { 2, 1, 1, 0, &next_tri_strip1[2] },
80};
81
82static struct gl_prim_state next_quads[4] = {
83 { 1, 2, 0, 0, &next_quads[1] },
84 { 2, 1, 0, 0, &next_quads[2] },
85 { 1, 2, 1, 0, &next_quads[3] },
86 { 1, 2, 1, 0, &next_quads[0] }
87};
88
89static struct gl_prim_state next_quad_strip[4] = {
90 { 2, 1, 0, 0, &next_quad_strip[1] },
91 { 0, 2, 0, 0, &next_quad_strip[2] },
92 { 2, 1, 1, 0, &next_quad_strip[3] },
93 { 0, 2, 1, 0, &next_quad_strip[2] },
94};
95
96
97
98
99
100
101
102#define INIT(ctx, prim) \
103do { \
104 if (ctx->PB->count > 0) gl_flush_pb(ctx); \
105 if (ctx->PB->primitive != prim) { \
106 gl_reduced_prim_change( ctx, (GLenum) prim ); \
107 } \
108} while(0)
109
110
111
112/* Need better driver support for this case.
113 */
114static void
115indexed_render_points( struct vertex_buffer *VB,
116 const struct gl_prim_state *state,
117 const GLuint *elt,
118 GLuint start,
119 GLuint count )
120{
121 GLcontext *ctx = VB->ctx;
122 GLuint i;
123 (void) state;
124 INIT(ctx, GL_POINTS);
125
126 if (VB->ClipOrMask) {
127 const GLubyte *clip = VB->ClipMask;
128 for (i = start ; i < count ; i++)
129 if (!clip[elt[i]])
130 ctx->Driver.PointsFunc( ctx, elt[i], elt[i] );
131 } else {
132 for (i = start ; i < count ; i++)
133 ctx->Driver.PointsFunc( ctx, elt[i], elt[i] );
134 }
135}
136
137static void
138indexed_render_lines( struct vertex_buffer *VB,
139 const struct gl_prim_state *state,
140 const GLuint *elt,
141 GLuint start,
142 GLuint count )
143{
144 GLcontext *ctx = VB->ctx;
145 GLuint i;
146
147 INIT(ctx, GL_LINES);
148
149 if (VB->ClipOrMask) {
150 const GLubyte *clip = VB->ClipMask;
151 GLuint prev = 0;
152
153 for (i = start ; i < count ; i++) {
154 GLuint curr = elt[i];
155 if (state->draw) {
156 if (clip[curr] | clip[prev])
157 gl_render_clipped_line( ctx, prev, curr );
158 else
159 ctx->Driver.LineFunc( ctx, prev, curr, curr );
160 }
161 prev = curr;
162 state = state->next;
163 }
164 if (state->finish_loop) {
165 GLuint curr = elt[start];
166 if (clip[curr] | clip[prev])
167 gl_render_clipped_line( ctx, prev, curr );
168 else
169 ctx->Driver.LineFunc( ctx, prev, curr, curr );
170 }
171 } else {
172 GLuint prev = 0;
173 for (i = start ; i < count ; i++) {
174 GLuint curr = elt[i];
175 if (state->draw) ctx->Driver.LineFunc( ctx, prev, curr, curr );
176 prev = curr;
177 state = state->next;
178 }
179 if (state->finish_loop) {
180 GLuint curr = elt[start];
181 ctx->Driver.LineFunc( ctx, prev, curr, curr );
182 }
183 }
184}
185
186
187
188static void
189indexed_render_tris( struct vertex_buffer *VB,
190 const struct gl_prim_state *state,
191 const GLuint *elt,
192 GLuint start,
193 GLuint count )
194{
195 GLcontext *ctx = VB->ctx;
196 GLuint i;
197
198 INIT(ctx, GL_POLYGON);
199
200 if (VB->ClipOrMask) {
201 GLuint v[3];
202 GLuint vlist[VB_MAX_CLIPPED_VERTS];
203
204 const GLubyte *clip = VB->ClipMask;
205 for (i = start ; i < count ; i++) {
206 v[2] = elt[i];
207 if (state->draw) {
208 if (clip[v[0]] | clip[v[1]] | clip[v[2]]) {
209 if (!(clip[v[0]] & clip[v[1]] & clip[v[2]] & CLIP_ALL_BITS)) {
210 COPY_3V(vlist, v);
211 gl_render_clipped_triangle( ctx, 3, vlist, vlist[2] );
212 }
213 }
214 else
215 ctx->TriangleFunc( ctx, v[0], v[1], v[2], v[2] );
216 }
217 v[0] = v[state->v0];
218 v[1] = v[state->v1];
219 state = state->next;
220 }
221 } else {
222 GLuint v[3];
223 const triangle_func tf = ctx->TriangleFunc;
224
225 for (i = start ; i < count ; i++) {
226 v[2] = elt[i];
227 if (state->draw)
228 tf( ctx, v[0], v[1], v[2], v[2] );
229 v[0] = v[state->v0];
230 v[1] = v[state->v1];
231 state = state->next;
232 }
233 }
234}
235
236
237static void
238indexed_render_noop( struct vertex_buffer *VB,
239 const struct gl_prim_state *state,
240 const GLuint *elt,
241 GLuint start,
242 GLuint count )
243{
244 (void) VB;
245 (void) state;
246 (void) elt;
247 (void) start;
248 (void) count;
249}
250
251
252typedef void (*indexed_render_func)( struct vertex_buffer *VB,
253 const struct gl_prim_state *state,
254 const GLuint *elt,
255 GLuint start,
256 GLuint count );
257
258
259indexed_render_func prim_func[GL_POLYGON+2] = {
260 indexed_render_points,
261 indexed_render_lines,
262 indexed_render_lines,
263 indexed_render_lines,
264 indexed_render_tris,
265 indexed_render_tris,
266 indexed_render_tris,
267 indexed_render_tris,
268 indexed_render_tris,
269 indexed_render_tris,
270 indexed_render_noop
271};
272
273
274CONST struct gl_prim_state *gl_prim_state_machine[GL_POLYGON+2][2] = {
275 { 0, 0 },
276 { next_lines, next_lines },
277 { next_line_loop, next_line_loop },
278 { next_line_strip, next_line_strip },
279 { next_tris, next_tris },
280 { next_tri_strip0, next_tri_strip1 },
281 { next_poly, next_poly },
282 { next_quads, next_quads },
283 { next_quad_strip, next_quad_strip },
284 { next_poly, next_poly },
285};
286
287
288
289
290void gl_render_elts( struct vertex_buffer *VB )
291{
292 GLcontext *ctx = VB->ctx;
293 struct vertex_buffer *saved_vb = ctx->VB;
294 GLenum prim = ctx->CVA.elt_mode;
295 GLuint *elt = VB->EltPtr->start;
296 GLuint nr = VB->EltPtr->count;
297 GLuint p = 0;
298
299 gl_import_client_data( VB, ctx->RenderFlags,
300 (VB->ClipOrMask
301 ? VEC_WRITABLE|VEC_GOOD_STRIDE
302 : VEC_GOOD_STRIDE));
303
304 ctx->VB = VB;
305
306 if (ctx->Driver.RenderStart)
307 ctx->Driver.RenderStart( ctx );
308
309 do {
310 const struct gl_prim_state *state = gl_prim_state_machine[prim][0];
311 indexed_render_func func = prim_func[prim];
312
313 func( VB, state, elt, 0, nr );
314
315 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
316 VB->Specular = VB->Spec[0];
317 VB->ColorPtr = VB->Color[0];
318 VB->IndexPtr = VB->Index[0];
319 }
320
321 } while (ctx->Driver.MultipassFunc &&
322 ctx->Driver.MultipassFunc( VB, ++p ));
323
324
325 if (ctx->PB->count > 0)
326 gl_flush_pb(ctx);
327
328 if (ctx->Driver.RenderFinish)
329 ctx->Driver.RenderFinish( ctx );
330
331 ctx->VB = saved_vb;
332}
333
334
335
336void gl_render_vb_indirect( struct vertex_buffer *VB )
337{
338 GLuint i, next, prim;
339 GLuint parity = VB->Parity;
340 GLuint count = VB->Count;
341 const struct gl_prim_state *state;
342 indexed_render_func func;
343 GLcontext *ctx = VB->ctx;
344 struct vertex_buffer *cvaVB = ctx->CVA.VB;
345 struct vertex_buffer *saved_vb = ctx->VB;
346 GLuint p = 0;
347
348 gl_import_client_data( cvaVB, ctx->RenderFlags,
349 (VB->ClipOrMask
350 ? VEC_WRITABLE|VEC_GOOD_STRIDE
351 : VEC_GOOD_STRIDE));
352
353 ctx->VB = cvaVB;
354
355 if (!VB->CullDone)
356 gl_fast_copy_vb( VB );
357
358 if (/* ctx->Current.Primitive == GL_POLYGON+1 && */ctx->Driver.RenderStart)
359 ctx->Driver.RenderStart( ctx );
360
361 do {
362 for (i = VB->CopyStart ; i < count ; parity = 0, i = next ) {
363 prim = VB->Primitive[i];
364 next = VB->NextPrimitive[i];
365
366 state = gl_prim_state_machine[prim][parity];
367 func = prim_func[prim];
368
369 func( cvaVB, state, VB->EltPtr->data, i, next );
370
371 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
372 cvaVB->Specular = cvaVB->Spec[0];
373 cvaVB->ColorPtr = cvaVB->Color[0];
374 cvaVB->IndexPtr = cvaVB->Index[0];
375 }
376 }
377
378 } while (ctx->Driver.MultipassFunc &&
379 ctx->Driver.MultipassFunc( VB, ++p ));
380
381
382 if (ctx->PB->count > 0)
383 gl_flush_pb(ctx);
384
385 if (/* ctx->Current.Primitive == GL_POLYGON+1 && */ctx->Driver.RenderFinish)
386 ctx->Driver.RenderFinish( ctx );
387
388 ctx->VB = saved_vb;
389}
Note: See TracBrowser for help on using the repository browser.