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

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

created

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