Replace the flags Mesa was using for ctx->NewState with a new set
[mesa.git] / src / mesa / main / varray.c
1 /* $Id: varray.c,v 1.27 2000/10/30 13:32:02 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 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 #ifdef PC_HEADER
28 #include "all.h"
29 #else
30 #include "glheader.h"
31 #include "context.h"
32 #include "cva.h"
33 #include "enable.h"
34 #include "enums.h"
35 #include "dlist.h"
36 #include "light.h"
37 #include "macros.h"
38 #include "mmath.h"
39 #include "pipeline.h"
40 #include "state.h"
41 #include "texstate.h"
42 #include "translate.h"
43 #include "types.h"
44 #include "varray.h"
45 #include "vb.h"
46 #include "vbfill.h"
47 #include "vbrender.h"
48 #include "vbindirect.h"
49 #include "vbxform.h"
50 #include "xform.h"
51 #endif
52
53
54
55 void
56 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
57 {
58 GET_CURRENT_CONTEXT(ctx);
59
60 if (size<2 || size>4) {
61 gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
62 return;
63 }
64 if (stride<0) {
65 gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
66 return;
67 }
68
69 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
70 fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size,
71 gl_lookup_enum_by_nr( type ),
72 stride);
73
74 ctx->Array.Vertex.StrideB = stride;
75 if (!stride) {
76 switch (type) {
77 case GL_SHORT:
78 ctx->Array.Vertex.StrideB = size*sizeof(GLshort);
79 break;
80 case GL_INT:
81 ctx->Array.Vertex.StrideB = size*sizeof(GLint);
82 break;
83 case GL_FLOAT:
84 ctx->Array.Vertex.StrideB = size*sizeof(GLfloat);
85 break;
86 case GL_DOUBLE:
87 ctx->Array.Vertex.StrideB = size*sizeof(GLdouble);
88 break;
89 default:
90 gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
91 return;
92 }
93 }
94 ctx->Array.Vertex.Size = size;
95 ctx->Array.Vertex.Type = type;
96 ctx->Array.Vertex.Stride = stride;
97 ctx->Array.Vertex.Ptr = (void *) ptr;
98 ctx->Array.VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
99 ctx->Array.VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
100 ctx->Array.NewArrayState |= VERT_OBJ_ANY;
101 ctx->NewState |= _NEW_ARRAY;
102 }
103
104
105
106
107 void
108 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
109 {
110 GET_CURRENT_CONTEXT(ctx);
111
112 if (stride<0) {
113 gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
114 return;
115 }
116
117 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
118 fprintf(stderr, "glNormalPointer( type %s stride %d )\n",
119 gl_lookup_enum_by_nr( type ),
120 stride);
121
122 ctx->Array.Normal.StrideB = stride;
123 if (!stride) {
124 switch (type) {
125 case GL_BYTE:
126 ctx->Array.Normal.StrideB = 3*sizeof(GLbyte);
127 break;
128 case GL_SHORT:
129 ctx->Array.Normal.StrideB = 3*sizeof(GLshort);
130 break;
131 case GL_INT:
132 ctx->Array.Normal.StrideB = 3*sizeof(GLint);
133 break;
134 case GL_FLOAT:
135 ctx->Array.Normal.StrideB = 3*sizeof(GLfloat);
136 break;
137 case GL_DOUBLE:
138 ctx->Array.Normal.StrideB = 3*sizeof(GLdouble);
139 break;
140 default:
141 gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
142 return;
143 }
144 }
145 ctx->Array.Normal.Type = type;
146 ctx->Array.Normal.Stride = stride;
147 ctx->Array.Normal.Ptr = (void *) ptr;
148 ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
149 ctx->Array.NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)];
150 ctx->Array.NewArrayState |= VERT_NORM;
151 ctx->NewState |= _NEW_ARRAY;
152 }
153
154
155
156 void
157 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
158 {
159 GET_CURRENT_CONTEXT(ctx);
160
161 if (size<3 || size>4) {
162 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
163 return;
164 }
165 if (stride<0) {
166 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
167 return;
168 }
169
170 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
171 fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size,
172 gl_lookup_enum_by_nr( type ),
173 stride);
174
175 ctx->Array.Color.StrideB = stride;
176 if (!stride) {
177 switch (type) {
178 case GL_BYTE:
179 ctx->Array.Color.StrideB = size*sizeof(GLbyte);
180 break;
181 case GL_UNSIGNED_BYTE:
182 ctx->Array.Color.StrideB = size*sizeof(GLubyte);
183 break;
184 case GL_SHORT:
185 ctx->Array.Color.StrideB = size*sizeof(GLshort);
186 break;
187 case GL_UNSIGNED_SHORT:
188 ctx->Array.Color.StrideB = size*sizeof(GLushort);
189 break;
190 case GL_INT:
191 ctx->Array.Color.StrideB = size*sizeof(GLint);
192 break;
193 case GL_UNSIGNED_INT:
194 ctx->Array.Color.StrideB = size*sizeof(GLuint);
195 break;
196 case GL_FLOAT:
197 ctx->Array.Color.StrideB = size*sizeof(GLfloat);
198 break;
199 case GL_DOUBLE:
200 ctx->Array.Color.StrideB = size*sizeof(GLdouble);
201 break;
202 default:
203 gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
204 return;
205 }
206 }
207 ctx->Array.Color.Size = size;
208 ctx->Array.Color.Type = type;
209 ctx->Array.Color.Stride = stride;
210 ctx->Array.Color.Ptr = (void *) ptr;
211 ctx->Array.ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
212 ctx->Array.ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
213 ctx->Array.NewArrayState |= VERT_RGBA;
214 ctx->NewState |= _NEW_ARRAY;
215 }
216
217
218
219 void
220 _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
221 {
222 GET_CURRENT_CONTEXT(ctx);
223
224 if (stride<0) {
225 gl_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
226 return;
227 }
228
229 ctx->Array.FogCoord.StrideB = stride;
230 if (!stride) {
231 switch (type) {
232 case GL_FLOAT:
233 ctx->Array.FogCoord.StrideB = sizeof(GLfloat);
234 break;
235 case GL_DOUBLE:
236 ctx->Array.FogCoord.StrideB = sizeof(GLdouble);
237 break;
238 default:
239 gl_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
240 return;
241 }
242 }
243 ctx->Array.FogCoord.Type = type;
244 ctx->Array.FogCoord.Stride = stride;
245 ctx->Array.FogCoord.Ptr = (void *) ptr;
246 ctx->Array.FogCoordFunc = gl_trans_1f_tab[TYPE_IDX(type)];
247 ctx->Array.FogCoordEltFunc = gl_trans_elt_1f_tab[TYPE_IDX(type)];
248 ctx->Array.NewArrayState |= VERT_FOG_COORD;
249 ctx->NewState |= _NEW_ARRAY;
250 }
251
252
253 void
254 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
255 {
256 GET_CURRENT_CONTEXT(ctx);
257
258 if (stride<0) {
259 gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
260 return;
261 }
262
263 ctx->Array.Index.StrideB = stride;
264 if (!stride) {
265 switch (type) {
266 case GL_UNSIGNED_BYTE:
267 ctx->Array.Index.StrideB = sizeof(GLubyte);
268 break;
269 case GL_SHORT:
270 ctx->Array.Index.StrideB = sizeof(GLshort);
271 break;
272 case GL_INT:
273 ctx->Array.Index.StrideB = sizeof(GLint);
274 break;
275 case GL_FLOAT:
276 ctx->Array.Index.StrideB = sizeof(GLfloat);
277 break;
278 case GL_DOUBLE:
279 ctx->Array.Index.StrideB = sizeof(GLdouble);
280 break;
281 default:
282 gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
283 return;
284 }
285 }
286 ctx->Array.Index.Type = type;
287 ctx->Array.Index.Stride = stride;
288 ctx->Array.Index.Ptr = (void *) ptr;
289 ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
290 ctx->Array.IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)];
291 ctx->Array.NewArrayState |= VERT_INDEX;
292 ctx->NewState |= _NEW_ARRAY;
293 }
294
295
296 void
297 _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
298 GLsizei stride, const GLvoid *ptr)
299 {
300 GET_CURRENT_CONTEXT(ctx);
301
302 fprintf(stderr, "%s\n", __FUNCTION__);
303
304 if (size != 3 && size != 4) {
305 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
306 return;
307 }
308 if (stride<0) {
309 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
310 return;
311 }
312
313 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
314 fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size,
315 gl_lookup_enum_by_nr( type ),
316 stride);
317
318 ctx->Array.SecondaryColor.StrideB = stride;
319 if (!stride) {
320 switch (type) {
321 case GL_BYTE:
322 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLbyte);
323 break;
324 case GL_UNSIGNED_BYTE:
325 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLubyte);
326 break;
327 case GL_SHORT:
328 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLshort);
329 break;
330 case GL_UNSIGNED_SHORT:
331 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLushort);
332 break;
333 case GL_INT:
334 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLint);
335 break;
336 case GL_UNSIGNED_INT:
337 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLuint);
338 break;
339 case GL_FLOAT:
340 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLfloat);
341 break;
342 case GL_DOUBLE:
343 ctx->Array.SecondaryColor.StrideB = size*sizeof(GLdouble);
344 break;
345 default:
346 gl_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
347 return;
348 }
349 }
350 ctx->Array.SecondaryColor.Size = 3; /* hardwire */
351 ctx->Array.SecondaryColor.Type = type;
352 ctx->Array.SecondaryColor.Stride = stride;
353 ctx->Array.SecondaryColor.Ptr = (void *) ptr;
354 ctx->Array.SecondaryColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
355 ctx->Array.SecondaryColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
356 ctx->Array.NewArrayState |= VERT_SPEC_RGB;
357 ctx->NewState |= _NEW_ARRAY;
358 }
359
360
361
362 void
363 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
364 {
365 GET_CURRENT_CONTEXT(ctx);
366 GLuint texUnit;
367
368 texUnit = ctx->Array.ActiveTexture;
369
370 if (size<1 || size>4) {
371 gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
372 return;
373 }
374 if (stride<0) {
375 gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
376 return;
377 }
378
379 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
380 fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n",
381 texUnit,
382 size,
383 gl_lookup_enum_by_nr( type ),
384 stride);
385
386 ctx->Array.TexCoord[texUnit].StrideB = stride;
387 if (!stride) {
388 switch (type) {
389 case GL_SHORT:
390 ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLshort);
391 break;
392 case GL_INT:
393 ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLint);
394 break;
395 case GL_FLOAT:
396 ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLfloat);
397 break;
398 case GL_DOUBLE:
399 ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLdouble);
400 break;
401 default:
402 gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
403 return;
404 }
405 }
406 ctx->Array.TexCoord[texUnit].Size = size;
407 ctx->Array.TexCoord[texUnit].Type = type;
408 ctx->Array.TexCoord[texUnit].Stride = stride;
409 ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
410
411 ctx->Array.TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
412 ctx->Array.TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
413 ctx->Array.NewArrayState |= PIPE_TEX(texUnit);
414 ctx->NewState |= _NEW_ARRAY;
415 }
416
417
418
419
420 void
421 _mesa_EdgeFlagPointer(GLsizei stride, const void *vptr)
422 {
423 GET_CURRENT_CONTEXT(ctx);
424 const GLboolean *ptr = (GLboolean *)vptr;
425
426 if (stride<0) {
427 gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
428 return;
429 }
430 ctx->Array.EdgeFlag.Stride = stride;
431 ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
432 ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
433 if (stride != sizeof(GLboolean)) {
434 ctx->Array.EdgeFlagFunc = gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
435 } else {
436 ctx->Array.EdgeFlagFunc = 0;
437 }
438 ctx->Array.EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
439 ctx->Array.NewArrayState |= VERT_EDGE;
440 ctx->NewState |= _NEW_ARRAY;
441 }
442
443
444
445
446
447 void
448 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
449 GLsizei count, const GLvoid *ptr)
450 {
451 (void) count;
452 _mesa_VertexPointer(size, type, stride, ptr);
453 }
454
455
456 void
457 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
458 const GLvoid *ptr)
459 {
460 (void) count;
461 _mesa_NormalPointer(type, stride, ptr);
462 }
463
464
465 void
466 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
467 const GLvoid *ptr)
468 {
469 (void) count;
470 _mesa_ColorPointer(size, type, stride, ptr);
471 }
472
473
474 void
475 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
476 const GLvoid *ptr)
477 {
478 (void) count;
479 _mesa_IndexPointer(type, stride, ptr);
480 }
481
482
483 void
484 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
485 GLsizei count, const GLvoid *ptr)
486 {
487 (void) count;
488 _mesa_TexCoordPointer(size, type, stride, ptr);
489 }
490
491
492 void
493 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
494 {
495 (void) count;
496 _mesa_EdgeFlagPointer(stride, ptr);
497 }
498
499
500
501
502
503 /* KW: Batch function to exec all the array elements in the input
504 * buffer prior to transform. Done only the first time a vertex
505 * buffer is executed or compiled.
506 *
507 * KW: Have to do this after each glEnd if cva isn't active. (also
508 * have to do it after each full buffer)
509 */
510 void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM,
511 GLuint start,
512 GLuint count)
513 {
514 GLuint *flags = IM->Flag;
515 GLuint *elts = IM->Elt;
516 GLuint translate = ctx->Array.Flags;
517 GLuint i;
518
519 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
520 fprintf(stderr, "exec_array_elements %d .. %d\n", start, count);
521
522 if (translate & VERT_OBJ_ANY)
523 (ctx->Array.VertexEltFunc)( IM->Obj,
524 &ctx->Array.Vertex,
525 flags, elts, (VERT_ELT|VERT_OBJ_ANY),
526 start, count);
527
528 if (translate & VERT_NORM)
529 (ctx->Array.NormalEltFunc)( IM->Normal,
530 &ctx->Array.Normal,
531 flags, elts, (VERT_ELT|VERT_NORM),
532 start, count);
533
534 if (translate & VERT_EDGE)
535 (ctx->Array.EdgeFlagEltFunc)( IM->EdgeFlag,
536 &ctx->Array.EdgeFlag,
537 flags, elts, (VERT_ELT|VERT_EDGE),
538 start, count);
539
540 if (translate & VERT_RGBA)
541 (ctx->Array.ColorEltFunc)( IM->Color,
542 &ctx->Array.Color,
543 flags, elts, (VERT_ELT|VERT_RGBA),
544 start, count);
545
546
547 if (translate & VERT_SPEC_RGB)
548 (ctx->Array.SecondaryColorEltFunc)( IM->SecondaryColor,
549 &ctx->Array.SecondaryColor,
550 flags, elts, (VERT_ELT|VERT_SPEC_RGB),
551 start, count);
552
553 if (translate & VERT_FOG_COORD)
554 (ctx->Array.FogCoordEltFunc)( IM->FogCoord,
555 &ctx->Array.FogCoord,
556 flags, elts, (VERT_ELT|VERT_FOG_COORD),
557 start, count);
558
559 if (translate & VERT_INDEX)
560 (ctx->Array.IndexEltFunc)( IM->Index,
561 &ctx->Array.Index,
562 flags, elts, (VERT_ELT|VERT_INDEX),
563 start, count);
564
565 if (translate & VERT_TEX0_ANY)
566 (ctx->Array.TexCoordEltFunc[0])( IM->TexCoord[0],
567 &ctx->Array.TexCoord[0],
568 flags, elts, (VERT_ELT|VERT_TEX0_ANY),
569 start, count);
570
571 if (translate & VERT_TEX1_ANY)
572 (ctx->Array.TexCoordEltFunc[1])( IM->TexCoord[1],
573 &ctx->Array.TexCoord[1],
574 flags, elts, (VERT_ELT|VERT_TEX1_ANY),
575 start, count);
576
577 #if MAX_TEXTURE_UNITS > 2
578 if (translate & VERT_TEX2_ANY)
579 (ctx->Array.TexCoordEltFunc[2])( IM->TexCoord[2],
580 &ctx->Array.TexCoord[2],
581 flags, elts, (VERT_ELT|VERT_TEX2_ANY),
582 start, count);
583 #endif
584 #if MAX_TEXTURE_UNITS > 3
585 if (translate & VERT_TEX3_ANY)
586 (ctx->Array.TexCoordEltFunc[3])( IM->TexCoord[3],
587 &ctx->Array.TexCoord[3],
588 flags, elts, (VERT_ELT|VERT_TEX3_ANY),
589 start, count);
590 #endif
591
592 for (i = start ; i < count ; i++)
593 if (flags[i] & VERT_ELT)
594 flags[i] |= translate;
595
596 }
597
598
599
600 /* Enough funny business going on in here it might be quicker to use a
601 * function pointer.
602 */
603 #define ARRAY_ELT( IM, i ) \
604 { \
605 GLuint count = IM->Count; \
606 IM->Elt[count] = i; \
607 IM->Flag[count] = ((IM->Flag[count] & IM->ArrayAndFlags) | \
608 VERT_ELT); \
609 IM->FlushElt |= IM->ArrayEltFlush; \
610 IM->Count = count += IM->ArrayIncr; \
611 if (count == VB_MAX) \
612 _mesa_maybe_transform_vb( IM ); \
613 }
614
615
616 void
617 _mesa_ArrayElement( GLint i )
618 {
619 GET_IMMEDIATE;
620 ARRAY_ELT( IM, i );
621 }
622
623
624 static void
625 gl_ArrayElement( GLcontext *CC, GLint i )
626 {
627 struct immediate *im = CC->input;
628 ARRAY_ELT( im, i );
629 }
630
631
632
633 void
634 _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count)
635 {
636 GET_CURRENT_CONTEXT(ctx);
637 struct vertex_buffer *VB = ctx->VB;
638 GLint i;
639
640 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays");
641
642 if (count<0) {
643 gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
644 return;
645 }
646
647 if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled) {
648 GLint remaining = count;
649 GLint i;
650 struct gl_client_array *Normal;
651 struct gl_client_array *Color;
652 struct gl_client_array *SecondaryColor;
653 struct gl_client_array *FogCoord;
654 struct gl_client_array *Index;
655 struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS];
656 struct gl_client_array *EdgeFlag;
657 struct immediate *IM = VB->IM;
658 struct gl_pipeline *elt = &ctx->CVA.elt;
659 GLboolean relock;
660 GLuint fallback, required;
661
662 if (ctx->NewState)
663 gl_update_state( ctx );
664
665 /* Just turn off cva on this path. Could be useful for multipass
666 * rendering to keep it turned on.
667 */
668 relock = ctx->CompileCVAFlag;
669
670 if (relock) {
671 ctx->CompileCVAFlag = 0;
672 elt->pipeline_valid = 0;
673 }
674
675 if (!elt->pipeline_valid)
676 gl_build_immediate_pipeline( ctx );
677
678 required = elt->inputs;
679 fallback = (elt->inputs & ~ctx->Array.Summary);
680
681 /* The translate function doesn't do anything about size. It
682 * just ensures that type and stride come out right.
683 */
684 IM->v.Obj.size = ctx->Array.Vertex.Size;
685
686 if (required & VERT_RGBA) {
687 Color = &ctx->Array.Color;
688 if (fallback & VERT_RGBA) {
689 Color = &ctx->Fallback.Color;
690 ctx->Array.ColorFunc =
691 gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
692 }
693 }
694
695 if (required & VERT_SPEC_RGB)
696 {
697 SecondaryColor = &ctx->Array.SecondaryColor;
698 if (fallback & VERT_SPEC_RGB) {
699 SecondaryColor = &ctx->Fallback.SecondaryColor;
700 ctx->Array.SecondaryColorFunc =
701 gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
702 }
703 }
704
705 if (required & VERT_FOG_COORD)
706 {
707 FogCoord = &ctx->Array.FogCoord;
708 if (fallback & VERT_FOG_COORD) {
709 FogCoord = &ctx->Fallback.FogCoord;
710 ctx->Array.FogCoordFunc =
711 gl_trans_1f_tab[TYPE_IDX(GL_FLOAT)];
712 }
713 }
714
715 if (required & VERT_INDEX) {
716 Index = &ctx->Array.Index;
717 if (fallback & VERT_INDEX) {
718 Index = &ctx->Fallback.Index;
719 ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)];
720 }
721 }
722
723 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
724 GLuint flag = VERT_TEX_ANY(i);
725
726 if (required & flag) {
727 TexCoord[i] = &ctx->Array.TexCoord[i];
728
729 if (fallback & flag) {
730 TexCoord[i] = &ctx->Fallback.TexCoord[i];
731 TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i );
732
733 ctx->Array.TexCoordFunc[i] =
734 gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)];
735 }
736 }
737 }
738
739 if (ctx->Array.Flags != ctx->Array.Flag[0]) {
740 for (i = 0 ; i < VB_MAX ; i++)
741 ctx->Array.Flag[i] = ctx->Array.Flags;
742 }
743
744 if (required & VERT_NORM) {
745 Normal = &ctx->Array.Normal;
746 if (fallback & VERT_NORM) {
747 Normal = &ctx->Fallback.Normal;
748 ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)];
749 }
750 }
751
752 if ( required & VERT_EDGE ) {
753 if (mode == GL_TRIANGLES ||
754 mode == GL_QUADS ||
755 mode == GL_POLYGON) {
756 EdgeFlag = &ctx->Array.EdgeFlag;
757 if (fallback & VERT_EDGE) {
758 EdgeFlag = &ctx->Fallback.EdgeFlag;
759 ctx->Array.EdgeFlagFunc =
760 gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
761 }
762 }
763 else
764 required &= ~VERT_EDGE;
765 }
766
767 VB->Primitive = IM->Primitive;
768 VB->NextPrimitive = IM->NextPrimitive;
769 VB->MaterialMask = IM->MaterialMask;
770 VB->Material = IM->Material;
771 VB->BoundsPtr = 0;
772
773 while (remaining > 0) {
774 GLint vbspace = VB_MAX - VB_START;
775 GLuint count, n;
776
777 if (vbspace >= remaining) {
778 n = remaining;
779 VB->LastPrimitive = VB_START + n;
780 }
781 else {
782 n = vbspace;
783 VB->LastPrimitive = VB_START;
784 }
785
786 VB->CullMode = 0;
787
788 ctx->Array.VertexFunc( IM->Obj + VB_START,
789 &ctx->Array.Vertex, start, n );
790
791 if (required & VERT_NORM) {
792 ctx->Array.NormalFunc( IM->Normal + VB_START,
793 Normal, start, n );
794 }
795
796 if (required & VERT_EDGE) {
797 ctx->Array.EdgeFlagFunc( IM->EdgeFlag + VB_START,
798 EdgeFlag, start, n );
799 }
800
801 if (required & VERT_RGBA) {
802 ctx->Array.ColorFunc( IM->Color + VB_START,
803 Color, start, n );
804 }
805
806 if (required & VERT_SPEC_RGB) {
807 ctx->Array.SecondaryColorFunc( IM->SecondaryColor + VB_START,
808 SecondaryColor, start, n );
809 }
810
811 if (required & VERT_FOG_COORD) {
812 ctx->Array.FogCoordFunc( IM->FogCoord + VB_START,
813 FogCoord, start, n );
814 }
815
816 if (required & VERT_INDEX) {
817 ctx->Array.IndexFunc( IM->Index + VB_START,
818 Index, start, n );
819 }
820
821 if (required & VERT_TEX0_ANY) {
822 IM->v.TexCoord[0].size = TexCoord[0]->Size;
823 ctx->Array.TexCoordFunc[0]( IM->TexCoord[0] + VB_START,
824 TexCoord[0], start, n );
825 }
826
827 if (required & VERT_TEX1_ANY) {
828 IM->v.TexCoord[1].size = TexCoord[1]->Size;
829 ctx->Array.TexCoordFunc[1]( IM->TexCoord[1] + VB_START,
830 TexCoord[1], start, n );
831 }
832 #if MAX_TEXTURE_UNITS > 2
833 if (required & VERT_TEX2_ANY) {
834 IM->v.TexCoord[2].size = TexCoord[2]->Size;
835 ctx->Array.TexCoordFunc[2]( IM->TexCoord[2] + VB_START,
836 TexCoord[2], start, n );
837 }
838 #endif
839 #if MAX_TEXTURE_UNITS > 3
840 if (required & VERT_TEX3_ANY) {
841 IM->v.TexCoord[3].size = TexCoord[3]->Size;
842 ctx->Array.TexCoordFunc[3]( IM->TexCoord[3] + VB_START,
843 TexCoord[3], start, n );
844 }
845 #endif
846
847 VB->ObjPtr = &IM->v.Obj;
848 VB->NormalPtr = &IM->v.Normal;
849 VB->ColorPtr = &IM->v.Color;
850 VB->Color[0] = VB->Color[1] = VB->ColorPtr;
851 VB->IndexPtr = &IM->v.Index;
852 VB->EdgeFlagPtr = &IM->v.EdgeFlag;
853 VB->SecondaryColorPtr = &IM->v.SecondaryColor;
854 VB->FogCoordPtr = &IM->v.FogCoord;
855 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
856 VB->TexCoordPtr[i] = &IM->v.TexCoord[i];
857 }
858
859 VB->Flag = ctx->Array.Flag;
860 VB->OrFlag = ctx->Array.Flags;
861
862 VB->Start = IM->Start = VB_START;
863 count = VB->Count = IM->Count = VB_START + n;
864
865 #define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c)
866
867 RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count);
868 RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count);
869 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
870 RESET_VEC(IM->v.TexCoord[i], (GLfloat *), VB_START, count);
871 }
872 RESET_VEC(IM->v.Index, &, VB_START, count);
873 RESET_VEC(IM->v.Elt, &, VB_START, count);
874 RESET_VEC(IM->v.EdgeFlag, &, VB_START, count);
875 RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count);
876 RESET_VEC(VB->Clip, (GLfloat *), VB_START, count);
877 RESET_VEC(VB->Eye, (GLfloat *), VB_START, count);
878 RESET_VEC(VB->Win, (GLfloat *), VB_START, count);
879 RESET_VEC(VB->BColor, (GLubyte *), VB_START, count);
880 RESET_VEC(VB->BIndex, &, VB_START, count);
881
882 VB->NextPrimitive[VB->CopyStart] = VB->Count;
883 VB->Primitive[VB->CopyStart] = mode;
884 ctx->Array.Flag[count] |= VERT_END_VB;
885
886 /* Transform and render.
887 */
888 gl_run_pipeline( VB );
889 gl_reset_vb( VB );
890
891 ctx->Array.Flag[count] = ctx->Array.Flags;
892 ctx->Array.Flag[VB_START] = ctx->Array.Flags;
893
894 start += n;
895 remaining -= n;
896 }
897
898 gl_reset_input( ctx );
899
900 if (relock) {
901 ctx->CompileCVAFlag = relock;
902 elt->pipeline_valid = 0;
903 }
904 }
905 else if (ctx->Array.Vertex.Enabled)
906 {
907 /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases. These
908 * could be handled by the above code, but it gets a little
909 * complex. The generated list is still of good quality
910 * this way.
911 */
912 gl_Begin( ctx, mode );
913 for (i=0;i<count;i++) {
914 gl_ArrayElement( ctx, start+i );
915 }
916 gl_End( ctx );
917 }
918 else
919 {
920 /* The degenerate case where vertices are not enabled - only
921 * need to process the very final array element, as all of the
922 * preceding ones would be overwritten anyway.
923 */
924 gl_Begin( ctx, mode );
925 gl_ArrayElement( ctx, start+count );
926 gl_End( ctx );
927 }
928 }
929
930
931
932 /* KW: Exactly fakes the effects of calling glArrayElement multiple times.
933 */
934 #if 1
935 #define DRAW_ELT(FUNC, TYPE) \
936 static void FUNC( GLcontext *ctx, GLenum mode, \
937 TYPE *indices, GLuint count ) \
938 { \
939 GLuint i,j; \
940 \
941 gl_Begin( ctx, mode ); \
942 \
943 for (j = 0 ; j < count ; ) { \
944 struct immediate *IM = ctx->input; \
945 GLuint start = IM->Start; \
946 GLuint nr = MIN2( VB_MAX, count - j + start ); \
947 GLuint sf = IM->Flag[start]; \
948 IM->FlushElt |= IM->ArrayEltFlush; \
949 \
950 for (i = start ; i < nr ; i++) { \
951 IM->Elt[i] = (GLuint) *indices++; \
952 IM->Flag[i] = VERT_ELT; \
953 } \
954 \
955 if (j == 0) IM->Flag[start] |= sf; \
956 \
957 IM->Count = nr; \
958 j += nr - start; \
959 \
960 if (j == count) \
961 gl_End( ctx ); \
962 _mesa_maybe_transform_vb( IM ); \
963 } \
964 }
965 #else
966 #define DRAW_ELT(FUNC, TYPE) \
967 static void FUNC( GLcontext *ctx, GLenum mode, \
968 TYPE *indices, GLuint count ) \
969 { \
970 int i; \
971 glBegin(mode); \
972 for (i = 0 ; i < count ; i++) \
973 glArrayElement( indices[i] ); \
974 glEnd(); \
975 }
976 #endif
977
978
979 DRAW_ELT( draw_elt_ubyte, GLubyte )
980 DRAW_ELT( draw_elt_ushort, GLushort )
981 DRAW_ELT( draw_elt_uint, GLuint )
982
983
984 static GLuint natural_stride[0x10] =
985 {
986 sizeof(GLbyte), /* 0 */
987 sizeof(GLubyte), /* 1 */
988 sizeof(GLshort), /* 2 */
989 sizeof(GLushort), /* 3 */
990 sizeof(GLint), /* 4 */
991 sizeof(GLuint), /* 5 */
992 sizeof(GLfloat), /* 6 */
993 2 * sizeof(GLbyte), /* 7 */
994 3 * sizeof(GLbyte), /* 8 */
995 4 * sizeof(GLbyte), /* 9 */
996 sizeof(GLdouble), /* a */
997 0, /* b */
998 0, /* c */
999 0, /* d */
1000 0, /* e */
1001 0 /* f */
1002 };
1003
1004
1005 void
1006 _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
1007 {
1008 GET_CURRENT_CONTEXT(ctx);
1009 struct gl_cva *cva;
1010
1011 cva = &ctx->CVA;
1012 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements");
1013
1014 if (count <= 0) {
1015 if (count < 0)
1016 gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
1017 return;
1018 }
1019
1020 if (mode < 0 || mode > GL_POLYGON) {
1021 gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
1022 return;
1023 }
1024
1025 if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT)
1026 {
1027 gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
1028 return;
1029 }
1030
1031 if (ctx->NewState)
1032 gl_update_state(ctx);
1033
1034 if (ctx->CompileCVAFlag)
1035 {
1036 /* Treat VERT_ELT like a special client array.
1037 */
1038 ctx->Array.NewArrayState |= VERT_ELT;
1039 ctx->Array.Summary |= VERT_ELT;
1040 ctx->Array.Flags |= VERT_ELT;
1041
1042 cva->elt_mode = mode;
1043 cva->elt_count = count;
1044 cva->Elt.Type = type;
1045 cva->Elt.Ptr = (void *) indices;
1046 cva->Elt.StrideB = natural_stride[TYPE_IDX(type)];
1047 cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
1048
1049 if (!cva->pre.pipeline_valid)
1050 gl_build_precalc_pipeline( ctx );
1051 else if (MESA_VERBOSE & VERBOSE_PIPELINE)
1052 fprintf(stderr, ": dont rebuild\n");
1053
1054 gl_cva_force_precalc( ctx );
1055
1056 /* Did we 'precalculate' the render op?
1057 */
1058 if (ctx->CVA.pre.ops & PIPE_OP_RENDER) {
1059 ctx->Array.NewArrayState |= VERT_ELT;
1060 ctx->Array.Summary &= ~VERT_ELT;
1061 ctx->Array.Flags &= ~VERT_ELT;
1062 return;
1063 }
1064
1065 if ( (MESA_VERBOSE&VERBOSE_VARRAY) )
1066 printf("using immediate\n");
1067 }
1068
1069
1070 /* Otherwise, have to use the immediate path to render.
1071 */
1072 switch (type) {
1073 case GL_UNSIGNED_BYTE:
1074 {
1075 GLubyte *ub_indices = (GLubyte *) indices;
1076 if (ctx->Array.Summary & VERT_OBJ_ANY) {
1077 draw_elt_ubyte( ctx, mode, ub_indices, count );
1078 } else {
1079 gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] );
1080 }
1081 }
1082 break;
1083 case GL_UNSIGNED_SHORT:
1084 {
1085 GLushort *us_indices = (GLushort *) indices;
1086 if (ctx->Array.Summary & VERT_OBJ_ANY) {
1087 draw_elt_ushort( ctx, mode, us_indices, count );
1088 } else {
1089 gl_ArrayElement( ctx, (GLuint) us_indices[count-1] );
1090 }
1091 }
1092 break;
1093 case GL_UNSIGNED_INT:
1094 {
1095 GLuint *ui_indices = (GLuint *) indices;
1096 if (ctx->Array.Summary & VERT_OBJ_ANY) {
1097 draw_elt_uint( ctx, mode, ui_indices, count );
1098 } else {
1099 gl_ArrayElement( ctx, ui_indices[count-1] );
1100 }
1101 }
1102 break;
1103 default:
1104 gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
1105 break;
1106 }
1107
1108 if (ctx->CompileCVAFlag) {
1109 ctx->Array.NewArrayState |= VERT_ELT;
1110 ctx->Array.Summary &= ~VERT_ELT;
1111 }
1112 }
1113
1114
1115
1116 void
1117 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
1118 {
1119 GET_CURRENT_CONTEXT(ctx);
1120 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1121 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1122
1123 GLenum ctype; /* color type */
1124 GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
1125 GLint defstride; /* default stride */
1126 GLint c, f;
1127 GLint coordUnitSave;
1128
1129 f = sizeof(GLfloat);
1130 c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
1131
1132 if (stride<0) {
1133 gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1134 return;
1135 }
1136
1137 switch (format) {
1138 case GL_V2F:
1139 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1140 tcomps = 0; ccomps = 0; vcomps = 2;
1141 voffset = 0;
1142 defstride = 2*f;
1143 break;
1144 case GL_V3F:
1145 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1146 tcomps = 0; ccomps = 0; vcomps = 3;
1147 voffset = 0;
1148 defstride = 3*f;
1149 break;
1150 case GL_C4UB_V2F:
1151 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1152 tcomps = 0; ccomps = 4; vcomps = 2;
1153 ctype = GL_UNSIGNED_BYTE;
1154 coffset = 0;
1155 voffset = c;
1156 defstride = c + 2*f;
1157 break;
1158 case GL_C4UB_V3F:
1159 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1160 tcomps = 0; ccomps = 4; vcomps = 3;
1161 ctype = GL_UNSIGNED_BYTE;
1162 coffset = 0;
1163 voffset = c;
1164 defstride = c + 3*f;
1165 break;
1166 case GL_C3F_V3F:
1167 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1168 tcomps = 0; ccomps = 3; vcomps = 3;
1169 ctype = GL_FLOAT;
1170 coffset = 0;
1171 voffset = 3*f;
1172 defstride = 6*f;
1173 break;
1174 case GL_N3F_V3F:
1175 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1176 tcomps = 0; ccomps = 0; vcomps = 3;
1177 noffset = 0;
1178 voffset = 3*f;
1179 defstride = 6*f;
1180 break;
1181 case GL_C4F_N3F_V3F:
1182 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1183 tcomps = 0; ccomps = 4; vcomps = 3;
1184 ctype = GL_FLOAT;
1185 coffset = 0;
1186 noffset = 4*f;
1187 voffset = 7*f;
1188 defstride = 10*f;
1189 break;
1190 case GL_T2F_V3F:
1191 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1192 tcomps = 2; ccomps = 0; vcomps = 3;
1193 voffset = 2*f;
1194 defstride = 5*f;
1195 break;
1196 case GL_T4F_V4F:
1197 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1198 tcomps = 4; ccomps = 0; vcomps = 4;
1199 voffset = 4*f;
1200 defstride = 8*f;
1201 break;
1202 case GL_T2F_C4UB_V3F:
1203 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1204 tcomps = 2; ccomps = 4; vcomps = 3;
1205 ctype = GL_UNSIGNED_BYTE;
1206 coffset = 2*f;
1207 voffset = c+2*f;
1208 defstride = c+5*f;
1209 break;
1210 case GL_T2F_C3F_V3F:
1211 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1212 tcomps = 2; ccomps = 3; vcomps = 3;
1213 ctype = GL_FLOAT;
1214 coffset = 2*f;
1215 voffset = 5*f;
1216 defstride = 8*f;
1217 break;
1218 case GL_T2F_N3F_V3F:
1219 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1220 tcomps = 2; ccomps = 0; vcomps = 3;
1221 noffset = 2*f;
1222 voffset = 5*f;
1223 defstride = 8*f;
1224 break;
1225 case GL_T2F_C4F_N3F_V3F:
1226 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1227 tcomps = 2; ccomps = 4; vcomps = 3;
1228 ctype = GL_FLOAT;
1229 coffset = 2*f;
1230 noffset = 6*f;
1231 voffset = 9*f;
1232 defstride = 12*f;
1233 break;
1234 case GL_T4F_C4F_N3F_V4F:
1235 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1236 tcomps = 4; ccomps = 4; vcomps = 4;
1237 ctype = GL_FLOAT;
1238 coffset = 4*f;
1239 noffset = 8*f;
1240 voffset = 11*f;
1241 defstride = 15*f;
1242 break;
1243 default:
1244 gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1245 return;
1246 }
1247
1248 if (stride==0) {
1249 stride = defstride;
1250 }
1251
1252 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
1253 _mesa_DisableClientState( GL_INDEX_ARRAY );
1254
1255 /* Texcoords */
1256 coordUnitSave = ctx->Array.ActiveTexture;
1257 if (tflag) {
1258 GLint i;
1259 GLint factor = ctx->Array.TexCoordInterleaveFactor;
1260 for (i = 0; i < factor; i++) {
1261 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
1262 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
1263 glTexCoordPointer( tcomps, GL_FLOAT, stride,
1264 (GLubyte *) pointer + i * coffset );
1265 }
1266 for (i = factor; i < ctx->Const.MaxTextureUnits; i++) {
1267 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
1268 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1269 }
1270 }
1271 else {
1272 GLint i;
1273 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1274 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
1275 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
1276 }
1277 }
1278 /* Restore texture coordinate unit index */
1279 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
1280
1281
1282 /* Color */
1283 if (cflag) {
1284 _mesa_EnableClientState( GL_COLOR_ARRAY );
1285 glColorPointer( ccomps, ctype, stride,
1286 (GLubyte*) pointer + coffset );
1287 }
1288 else {
1289 _mesa_DisableClientState( GL_COLOR_ARRAY );
1290 }
1291
1292
1293 /* Normals */
1294 if (nflag) {
1295 _mesa_EnableClientState( GL_NORMAL_ARRAY );
1296 glNormalPointer( GL_FLOAT, stride,
1297 (GLubyte*) pointer + noffset );
1298 }
1299 else {
1300 _mesa_DisableClientState( GL_NORMAL_ARRAY );
1301 }
1302
1303 _mesa_EnableClientState( GL_VERTEX_ARRAY );
1304 glVertexPointer( vcomps, GL_FLOAT, stride,
1305 (GLubyte *) pointer + voffset );
1306 }
1307
1308
1309
1310 void
1311 _mesa_DrawRangeElements(GLenum mode, GLuint start,
1312 GLuint end, GLsizei count,
1313 GLenum type, const GLvoid *indices)
1314 {
1315 GET_CURRENT_CONTEXT(ctx);
1316
1317 if (end < start) {
1318 gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )");
1319 return;
1320 }
1321
1322 #if 0
1323 /*
1324 * XXX something in locked arrays is broken! If start = 0,
1325 * end = 1 and count = 2 we'll take the LockArrays path and
1326 * get incorrect results. See Scott McMillan's bug of 3 Jan 2000.
1327 * For now, don't use locked arrays.
1328 */
1329 if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) {
1330 glLockArraysEXT( start, end );
1331 glDrawElements( mode, count, type, indices );
1332 glUnlockArraysEXT();
1333 } else {
1334 glDrawElements( mode, count, type, indices );
1335 }
1336 #else
1337 glDrawElements( mode, count, type, indices );
1338 #endif
1339 }
1340
1341
1342
1343 void gl_update_client_state( GLcontext *ctx )
1344 {
1345 static const GLuint sz_flags[5] = {
1346 0,
1347 0,
1348 VERT_OBJ_2,
1349 VERT_OBJ_23,
1350 VERT_OBJ_234
1351 };
1352 static const GLuint tc_flags[5] = {
1353 0,
1354 VERT_TEX0_1,
1355 VERT_TEX0_12,
1356 VERT_TEX0_123,
1357 VERT_TEX0_1234
1358 };
1359 GLint i;
1360
1361 ctx->Array.Flags = 0;
1362 ctx->Array.Summary = 0;
1363 ctx->input->ArrayIncr = 0;
1364
1365 if (ctx->Array.Normal.Enabled) ctx->Array.Flags |= VERT_NORM;
1366 if (ctx->Array.Color.Enabled) ctx->Array.Flags |= VERT_RGBA;
1367 if (ctx->Array.SecondaryColor.Enabled) ctx->Array.Flags |= VERT_SPEC_RGB;
1368 if (ctx->Array.FogCoord.Enabled) ctx->Array.Flags |= VERT_FOG_COORD;
1369 if (ctx->Array.Index.Enabled) ctx->Array.Flags |= VERT_INDEX;
1370 if (ctx->Array.EdgeFlag.Enabled) ctx->Array.Flags |= VERT_EDGE;
1371 if (ctx->Array.Vertex.Enabled) {
1372 ctx->Array.Flags |= sz_flags[ctx->Array.Vertex.Size];
1373 ctx->input->ArrayIncr = 1;
1374 }
1375 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
1376 if (ctx->Array.TexCoord[i].Enabled) {
1377 ctx->Array.Flags |= (tc_flags[ctx->Array.TexCoord[i].Size] << (i * NR_TEXSIZE_BITS));
1378 }
1379 }
1380
1381 /* Not really important any more:
1382 */
1383 ctx->Array.Summary = ctx->Array.Flags & VERT_DATA;
1384 ctx->input->ArrayAndFlags = ~ctx->Array.Flags;
1385 ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag);
1386 }
1387