Remove things having to do with ARB_matrix_palette/ARB_vertex_blend
[mesa.git] / src / mesa / main / varray.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include "glheader.h"
27 #include "imports.h"
28 #include "context.h"
29 #include "enable.h"
30 #include "enums.h"
31 #include "dlist.h"
32 #include "texstate.h"
33 #include "mtypes.h"
34 #include "varray.h"
35
36
37 #ifndef GL_BOOLEAN
38 #define GL_BOOLEAN 0x9999
39 #endif
40
41
42 /**
43 * Update the fields of a vertex array structure.
44 * We need to do a few special things for arrays that live in
45 * vertex buffer objects.
46 */
47 static void
48 update_array(GLcontext *ctx, struct gl_client_array *array,
49 GLuint dirtyFlag, GLsizei elementSize,
50 GLint size, GLenum type,
51 GLsizei stride, GLboolean normalized, const GLvoid *ptr)
52 {
53 array->Size = size;
54 array->Type = type;
55 array->Stride = stride;
56 array->StrideB = stride ? stride : elementSize;
57 array->Normalized = normalized;
58 array->Ptr = (const GLubyte *) ptr;
59 #if FEATURE_ARB_vertex_buffer_object
60 array->BufferObj->RefCount--;
61 /* XXX free buffer object if RefCount == 0 ? */
62 array->BufferObj = ctx->Array.ArrayBufferObj;
63 array->BufferObj->RefCount++;
64 /* Compute the index of the last array element that's inside the buffer.
65 * Later in glDrawArrays we'll check if start + count > _MaxElement to
66 * be sure we won't go out of bounds.
67 */
68 if (ctx->Array.ArrayBufferObj->Name)
69 array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size
70 - (GLsizeiptrARB) array->Ptr) / array->StrideB;
71 else
72 #endif
73 array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
74
75 ctx->NewState |= _NEW_ARRAY;
76 ctx->Array.NewState |= dirtyFlag;
77 }
78
79
80 void GLAPIENTRY
81 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
82 {
83 GLsizei elementSize;
84 GET_CURRENT_CONTEXT(ctx);
85 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
86
87 if (size < 2 || size > 4) {
88 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
89 return;
90 }
91 if (stride < 0) {
92 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
93 return;
94 }
95
96 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
97 _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
98 _mesa_lookup_enum_by_nr( type ), stride);
99
100 /* always need to check that <type> is legal */
101 switch (type) {
102 case GL_SHORT:
103 elementSize = size * sizeof(GLshort);
104 break;
105 case GL_INT:
106 elementSize = size * sizeof(GLint);
107 break;
108 case GL_FLOAT:
109 elementSize = size * sizeof(GLfloat);
110 break;
111 case GL_DOUBLE:
112 elementSize = size * sizeof(GLdouble);
113 break;
114 default:
115 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
116 return;
117 }
118
119 update_array(ctx, &ctx->Array.Vertex, _NEW_ARRAY_VERTEX,
120 elementSize, size, type, stride, GL_FALSE, ptr);
121
122 if (ctx->Driver.VertexPointer)
123 ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
124 }
125
126
127 void GLAPIENTRY
128 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
129 {
130 GLsizei elementSize;
131 GET_CURRENT_CONTEXT(ctx);
132 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
133
134 if (stride < 0) {
135 _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
136 return;
137 }
138
139 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
140 _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
141 _mesa_lookup_enum_by_nr( type ), stride);
142
143 switch (type) {
144 case GL_BYTE:
145 elementSize = 3 * sizeof(GLbyte);
146 break;
147 case GL_SHORT:
148 elementSize = 3 * sizeof(GLshort);
149 break;
150 case GL_INT:
151 elementSize = 3 * sizeof(GLint);
152 break;
153 case GL_FLOAT:
154 elementSize = 3 * sizeof(GLfloat);
155 break;
156 case GL_DOUBLE:
157 elementSize = 3 * sizeof(GLdouble);
158 break;
159 default:
160 _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
161 return;
162 }
163
164 update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL,
165 elementSize, 3, type, stride, GL_FALSE, ptr);
166
167 if (ctx->Driver.NormalPointer)
168 ctx->Driver.NormalPointer( ctx, type, stride, ptr );
169 }
170
171
172 void GLAPIENTRY
173 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
174 {
175 GLsizei elementSize;
176 GET_CURRENT_CONTEXT(ctx);
177 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
178
179 if (size < 3 || size > 4) {
180 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
181 return;
182 }
183 if (stride < 0) {
184 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
185 return;
186 }
187
188 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
189 _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
190 _mesa_lookup_enum_by_nr( type ), stride);
191
192 switch (type) {
193 case GL_BYTE:
194 elementSize = size * sizeof(GLbyte);
195 break;
196 case GL_UNSIGNED_BYTE:
197 elementSize = size * sizeof(GLubyte);
198 break;
199 case GL_SHORT:
200 elementSize = size * sizeof(GLshort);
201 break;
202 case GL_UNSIGNED_SHORT:
203 elementSize = size * sizeof(GLushort);
204 break;
205 case GL_INT:
206 elementSize = size * sizeof(GLint);
207 break;
208 case GL_UNSIGNED_INT:
209 elementSize = size * sizeof(GLuint);
210 break;
211 case GL_FLOAT:
212 elementSize = size * sizeof(GLfloat);
213 break;
214 case GL_DOUBLE:
215 elementSize = size * sizeof(GLdouble);
216 break;
217 default:
218 _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
219 return;
220 }
221
222 update_array(ctx, &ctx->Array.Color, _NEW_ARRAY_COLOR0,
223 elementSize, size, type, stride, GL_FALSE, ptr);
224
225 if (ctx->Driver.ColorPointer)
226 ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
227 }
228
229
230 void GLAPIENTRY
231 _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
232 {
233 GLint elementSize;
234 GET_CURRENT_CONTEXT(ctx);
235 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
236
237 if (stride < 0) {
238 _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
239 return;
240 }
241
242 switch (type) {
243 case GL_FLOAT:
244 elementSize = sizeof(GLfloat);
245 break;
246 case GL_DOUBLE:
247 elementSize = sizeof(GLdouble);
248 break;
249 default:
250 _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
251 return;
252 }
253
254 update_array(ctx, &ctx->Array.FogCoord, _NEW_ARRAY_FOGCOORD,
255 elementSize, 1, type, stride, GL_FALSE, ptr);
256
257 if (ctx->Driver.FogCoordPointer)
258 ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
259 }
260
261
262 void GLAPIENTRY
263 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
264 {
265 GLsizei elementSize;
266 GET_CURRENT_CONTEXT(ctx);
267 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
268
269 if (stride < 0) {
270 _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
271 return;
272 }
273
274 switch (type) {
275 case GL_UNSIGNED_BYTE:
276 elementSize = sizeof(GLubyte);
277 break;
278 case GL_SHORT:
279 elementSize = sizeof(GLshort);
280 break;
281 case GL_INT:
282 elementSize = sizeof(GLint);
283 break;
284 case GL_FLOAT:
285 elementSize = sizeof(GLfloat);
286 break;
287 case GL_DOUBLE:
288 elementSize = sizeof(GLdouble);
289 break;
290 default:
291 _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
292 return;
293 }
294
295 update_array(ctx, &ctx->Array.Index, _NEW_ARRAY_INDEX,
296 elementSize, 1, type, stride, GL_FALSE, ptr);
297
298 if (ctx->Driver.IndexPointer)
299 ctx->Driver.IndexPointer( ctx, type, stride, ptr );
300 }
301
302
303 void GLAPIENTRY
304 _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
305 GLsizei stride, const GLvoid *ptr)
306 {
307 GLsizei elementSize;
308 GET_CURRENT_CONTEXT(ctx);
309 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
310
311 if (size != 3 && size != 4) {
312 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
313 return;
314 }
315 if (stride < 0) {
316 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
317 return;
318 }
319
320 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
321 _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
322 size, _mesa_lookup_enum_by_nr( type ), stride);
323
324 switch (type) {
325 case GL_BYTE:
326 elementSize = size * sizeof(GLbyte);
327 break;
328 case GL_UNSIGNED_BYTE:
329 elementSize = size * sizeof(GLubyte);
330 break;
331 case GL_SHORT:
332 elementSize = size * sizeof(GLshort);
333 break;
334 case GL_UNSIGNED_SHORT:
335 elementSize = size * sizeof(GLushort);
336 break;
337 case GL_INT:
338 elementSize = size * sizeof(GLint);
339 break;
340 case GL_UNSIGNED_INT:
341 elementSize = size * sizeof(GLuint);
342 break;
343 case GL_FLOAT:
344 elementSize = size * sizeof(GLfloat);
345 break;
346 case GL_DOUBLE:
347 elementSize = size * sizeof(GLdouble);
348 break;
349 default:
350 _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
351 return;
352 }
353
354 update_array(ctx, &ctx->Array.SecondaryColor, _NEW_ARRAY_COLOR1,
355 elementSize, size, type, stride, GL_FALSE, ptr);
356
357 if (ctx->Driver.SecondaryColorPointer)
358 ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
359 }
360
361
362 void GLAPIENTRY
363 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
364 const GLvoid *ptr)
365 {
366 GLint elementSize;
367 GET_CURRENT_CONTEXT(ctx);
368 const GLuint unit = ctx->Array.ActiveTexture;
369 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
370
371 if (size < 1 || size > 4) {
372 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
373 return;
374 }
375 if (stride < 0) {
376 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
377 return;
378 }
379
380 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
381 _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
382 unit, size, _mesa_lookup_enum_by_nr( type ), stride);
383
384 /* always need to check that <type> is legal */
385 switch (type) {
386 case GL_SHORT:
387 elementSize = size * sizeof(GLshort);
388 break;
389 case GL_INT:
390 elementSize = size * sizeof(GLint);
391 break;
392 case GL_FLOAT:
393 elementSize = size * sizeof(GLfloat);
394 break;
395 case GL_DOUBLE:
396 elementSize = size * sizeof(GLdouble);
397 break;
398 default:
399 _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
400 return;
401 }
402
403 update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit),
404 elementSize, size, type, stride, GL_FALSE, ptr);
405
406 if (ctx->Driver.TexCoordPointer)
407 ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
408 }
409
410
411 void GLAPIENTRY
412 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
413 {
414 GET_CURRENT_CONTEXT(ctx);
415 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
416
417 if (stride < 0) {
418 _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
419 return;
420 }
421
422 update_array(ctx, &ctx->Array.EdgeFlag, _NEW_ARRAY_EDGEFLAG,
423 sizeof(GLboolean), 1, GL_BOOLEAN, stride, GL_FALSE, ptr);
424
425 if (ctx->Driver.EdgeFlagPointer)
426 ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
427 }
428
429
430 #if FEATURE_NV_vertex_program
431 void GLAPIENTRY
432 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
433 GLsizei stride, const GLvoid *ptr)
434 {
435 GLsizei elementSize;
436 GET_CURRENT_CONTEXT(ctx);
437 ASSERT_OUTSIDE_BEGIN_END(ctx);
438
439 if (index >= VERT_ATTRIB_MAX) {
440 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
441 return;
442 }
443
444 if (size < 1 || size > 4) {
445 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
446 return;
447 }
448
449 if (stride < 0) {
450 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
451 return;
452 }
453
454 if (type == GL_UNSIGNED_BYTE && size != 4) {
455 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
456 return;
457 }
458
459 /* check for valid 'type' and compute StrideB right away */
460 switch (type) {
461 case GL_UNSIGNED_BYTE:
462 elementSize = size * sizeof(GLubyte);
463 break;
464 case GL_SHORT:
465 elementSize = size * sizeof(GLshort);
466 break;
467 case GL_FLOAT:
468 elementSize = size * sizeof(GLfloat);
469 break;
470 case GL_DOUBLE:
471 elementSize = size * sizeof(GLdouble);
472 break;
473 default:
474 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
475 return;
476 }
477
478 update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
479 elementSize, size, type, stride, GL_FALSE, ptr);
480
481 if (ctx->Driver.VertexAttribPointer)
482 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
483 }
484 #endif
485
486
487 #if FEATURE_ARB_vertex_program
488 void GLAPIENTRY
489 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
490 GLboolean normalized,
491 GLsizei stride, const GLvoid *ptr)
492 {
493 GLsizei elementSize;
494 GET_CURRENT_CONTEXT(ctx);
495 ASSERT_OUTSIDE_BEGIN_END(ctx);
496
497 if (index >= ctx->Const.MaxVertexProgramAttribs) {
498 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
499 return;
500 }
501
502 if (size < 1 || size > 4) {
503 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
504 return;
505 }
506
507 if (stride < 0) {
508 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)");
509 return;
510 }
511
512 if (type == GL_UNSIGNED_BYTE && size != 4) {
513 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size!=4)");
514 return;
515 }
516
517 /* check for valid 'type' and compute StrideB right away */
518 /* NOTE: more types are supported here than in the NV extension */
519 switch (type) {
520 case GL_BYTE:
521 elementSize = size * sizeof(GLbyte);
522 break;
523 case GL_UNSIGNED_BYTE:
524 elementSize = size * sizeof(GLubyte);
525 break;
526 case GL_SHORT:
527 elementSize = size * sizeof(GLshort);
528 break;
529 case GL_UNSIGNED_SHORT:
530 elementSize = size * sizeof(GLushort);
531 break;
532 case GL_INT:
533 elementSize = size * sizeof(GLint);
534 break;
535 case GL_UNSIGNED_INT:
536 elementSize = size * sizeof(GLuint);
537 break;
538 case GL_FLOAT:
539 elementSize = size * sizeof(GLfloat);
540 break;
541 case GL_DOUBLE:
542 elementSize = size * sizeof(GLdouble);
543 break;
544 default:
545 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" );
546 return;
547 }
548
549 update_array(ctx, &ctx->Array.VertexAttrib[index], _NEW_ARRAY_ATTRIB(index),
550 elementSize, size, type, stride, normalized, ptr);
551
552 /* XXX fix
553 if (ctx->Driver.VertexAttribPointer)
554 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
555 */
556 }
557 #endif
558
559
560 void GLAPIENTRY
561 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
562 GLsizei count, const GLvoid *ptr)
563 {
564 (void) count;
565 _mesa_VertexPointer(size, type, stride, ptr);
566 }
567
568
569 void GLAPIENTRY
570 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
571 const GLvoid *ptr)
572 {
573 (void) count;
574 _mesa_NormalPointer(type, stride, ptr);
575 }
576
577
578 void GLAPIENTRY
579 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
580 const GLvoid *ptr)
581 {
582 (void) count;
583 _mesa_ColorPointer(size, type, stride, ptr);
584 }
585
586
587 void GLAPIENTRY
588 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
589 const GLvoid *ptr)
590 {
591 (void) count;
592 _mesa_IndexPointer(type, stride, ptr);
593 }
594
595
596 void GLAPIENTRY
597 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
598 GLsizei count, const GLvoid *ptr)
599 {
600 (void) count;
601 _mesa_TexCoordPointer(size, type, stride, ptr);
602 }
603
604
605 void GLAPIENTRY
606 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
607 {
608 (void) count;
609 _mesa_EdgeFlagPointer(stride, ptr);
610 }
611
612
613 void GLAPIENTRY
614 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
615 {
616 GET_CURRENT_CONTEXT(ctx);
617 GLboolean tflag, cflag, nflag; /* enable/disable flags */
618 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
619 GLenum ctype = 0; /* color type */
620 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
621 GLint defstride; /* default stride */
622 GLint c, f;
623 GLint coordUnitSave;
624
625 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
626
627 f = sizeof(GLfloat);
628 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
629
630 if (stride < 0) {
631 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
632 return;
633 }
634
635 switch (format) {
636 case GL_V2F:
637 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
638 tcomps = 0; ccomps = 0; vcomps = 2;
639 voffset = 0;
640 defstride = 2*f;
641 break;
642 case GL_V3F:
643 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
644 tcomps = 0; ccomps = 0; vcomps = 3;
645 voffset = 0;
646 defstride = 3*f;
647 break;
648 case GL_C4UB_V2F:
649 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
650 tcomps = 0; ccomps = 4; vcomps = 2;
651 ctype = GL_UNSIGNED_BYTE;
652 coffset = 0;
653 voffset = c;
654 defstride = c + 2*f;
655 break;
656 case GL_C4UB_V3F:
657 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
658 tcomps = 0; ccomps = 4; vcomps = 3;
659 ctype = GL_UNSIGNED_BYTE;
660 coffset = 0;
661 voffset = c;
662 defstride = c + 3*f;
663 break;
664 case GL_C3F_V3F:
665 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
666 tcomps = 0; ccomps = 3; vcomps = 3;
667 ctype = GL_FLOAT;
668 coffset = 0;
669 voffset = 3*f;
670 defstride = 6*f;
671 break;
672 case GL_N3F_V3F:
673 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
674 tcomps = 0; ccomps = 0; vcomps = 3;
675 noffset = 0;
676 voffset = 3*f;
677 defstride = 6*f;
678 break;
679 case GL_C4F_N3F_V3F:
680 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
681 tcomps = 0; ccomps = 4; vcomps = 3;
682 ctype = GL_FLOAT;
683 coffset = 0;
684 noffset = 4*f;
685 voffset = 7*f;
686 defstride = 10*f;
687 break;
688 case GL_T2F_V3F:
689 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
690 tcomps = 2; ccomps = 0; vcomps = 3;
691 voffset = 2*f;
692 defstride = 5*f;
693 break;
694 case GL_T4F_V4F:
695 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
696 tcomps = 4; ccomps = 0; vcomps = 4;
697 voffset = 4*f;
698 defstride = 8*f;
699 break;
700 case GL_T2F_C4UB_V3F:
701 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
702 tcomps = 2; ccomps = 4; vcomps = 3;
703 ctype = GL_UNSIGNED_BYTE;
704 coffset = 2*f;
705 voffset = c+2*f;
706 defstride = c+5*f;
707 break;
708 case GL_T2F_C3F_V3F:
709 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
710 tcomps = 2; ccomps = 3; vcomps = 3;
711 ctype = GL_FLOAT;
712 coffset = 2*f;
713 voffset = 5*f;
714 defstride = 8*f;
715 break;
716 case GL_T2F_N3F_V3F:
717 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
718 tcomps = 2; ccomps = 0; vcomps = 3;
719 noffset = 2*f;
720 voffset = 5*f;
721 defstride = 8*f;
722 break;
723 case GL_T2F_C4F_N3F_V3F:
724 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
725 tcomps = 2; ccomps = 4; vcomps = 3;
726 ctype = GL_FLOAT;
727 coffset = 2*f;
728 noffset = 6*f;
729 voffset = 9*f;
730 defstride = 12*f;
731 break;
732 case GL_T4F_C4F_N3F_V4F:
733 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
734 tcomps = 4; ccomps = 4; vcomps = 4;
735 ctype = GL_FLOAT;
736 coffset = 4*f;
737 noffset = 8*f;
738 voffset = 11*f;
739 defstride = 15*f;
740 break;
741 default:
742 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
743 return;
744 }
745
746 if (stride==0) {
747 stride = defstride;
748 }
749
750 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
751 _mesa_DisableClientState( GL_INDEX_ARRAY );
752
753 /* Texcoords */
754 coordUnitSave = ctx->Array.ActiveTexture;
755 if (tflag) {
756 GLint i;
757 GLint factor = ctx->Array.TexCoordInterleaveFactor;
758 for (i = 0; i < factor; i++) {
759 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
760 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
761 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
762 (GLubyte *) pointer + i * coffset );
763 }
764 for (i = factor; i < (GLint) ctx->Const.MaxTextureCoordUnits; i++) {
765 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
766 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
767 }
768 }
769 else {
770 GLint i;
771 for (i = 0; i < (GLint) ctx->Const.MaxTextureCoordUnits; i++) {
772 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
773 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
774 }
775 }
776 /* Restore texture coordinate unit index */
777 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
778
779
780 /* Color */
781 if (cflag) {
782 _mesa_EnableClientState( GL_COLOR_ARRAY );
783 _mesa_ColorPointer( ccomps, ctype, stride,
784 (GLubyte*) pointer + coffset );
785 }
786 else {
787 _mesa_DisableClientState( GL_COLOR_ARRAY );
788 }
789
790
791 /* Normals */
792 if (nflag) {
793 _mesa_EnableClientState( GL_NORMAL_ARRAY );
794 _mesa_NormalPointer( GL_FLOAT, stride,
795 (GLubyte*) pointer + noffset );
796 }
797 else {
798 _mesa_DisableClientState( GL_NORMAL_ARRAY );
799 }
800
801 _mesa_EnableClientState( GL_VERTEX_ARRAY );
802 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
803 (GLubyte *) pointer + voffset );
804 }
805
806
807 void GLAPIENTRY
808 _mesa_LockArraysEXT(GLint first, GLsizei count)
809 {
810 GET_CURRENT_CONTEXT(ctx);
811 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
812
813 if (MESA_VERBOSE & VERBOSE_API)
814 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
815
816 if (first == 0 && count > 0 &&
817 count <= (GLint) ctx->Const.MaxArrayLockSize) {
818 ctx->Array.LockFirst = first;
819 ctx->Array.LockCount = count;
820 }
821 else {
822 ctx->Array.LockFirst = 0;
823 ctx->Array.LockCount = 0;
824 }
825
826 ctx->NewState |= _NEW_ARRAY;
827 ctx->Array.NewState |= _NEW_ARRAY_ALL;
828
829 if (ctx->Driver.LockArraysEXT)
830 ctx->Driver.LockArraysEXT( ctx, first, count );
831 }
832
833
834 void GLAPIENTRY
835 _mesa_UnlockArraysEXT( void )
836 {
837 GET_CURRENT_CONTEXT(ctx);
838 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
839
840 if (MESA_VERBOSE & VERBOSE_API)
841 _mesa_debug(ctx, "glUnlockArrays\n");
842
843 ctx->Array.LockFirst = 0;
844 ctx->Array.LockCount = 0;
845 ctx->NewState |= _NEW_ARRAY;
846 ctx->Array.NewState |= _NEW_ARRAY_ALL;
847
848 if (ctx->Driver.UnlockArraysEXT)
849 ctx->Driver.UnlockArraysEXT( ctx );
850 }
851
852
853 /* GL_EXT_multi_draw_arrays */
854 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
855 void GLAPIENTRY
856 _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
857 GLsizei *count, GLsizei primcount )
858 {
859 GET_CURRENT_CONTEXT(ctx);
860 GLint i;
861
862 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
863
864 for (i = 0; i < primcount; i++) {
865 if (count[i] > 0) {
866 (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
867 }
868 }
869 }
870
871
872 /* GL_EXT_multi_draw_arrays */
873 void GLAPIENTRY
874 _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
875 const GLvoid **indices, GLsizei primcount )
876 {
877 GET_CURRENT_CONTEXT(ctx);
878 GLint i;
879
880 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
881
882 if (ctx->Array.ElementArrayBufferObj->Name) {
883 /* use indices in the buffer object */
884 ASSERT(ctx->Array.ElementArrayBufferObj->Data);
885 indices = (const GLvoid **) ctx->Array.ElementArrayBufferObj->Data;
886 }
887
888 for (i = 0; i < primcount; i++) {
889 if (count[i] > 0) {
890 (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
891 }
892 }
893 }
894
895
896 /* GL_IBM_multimode_draw_arrays */
897 void GLAPIENTRY
898 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
899 const GLsizei * count,
900 GLsizei primcount, GLint modestride )
901 {
902 GET_CURRENT_CONTEXT(ctx);
903 GLint i;
904
905 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
906
907 for ( i = 0 ; i < primcount ; i++ ) {
908 if ( count[i] > 0 ) {
909 (ctx->Exec->DrawArrays)( *(GLenum *) ((char *) mode + (i * modestride)),
910 first[i], count[i] );
911 }
912 }
913 }
914
915
916 /* GL_IBM_multimode_draw_arrays */
917 void GLAPIENTRY
918 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
919 GLenum type, const GLvoid * const * indices,
920 GLsizei primcount, GLint modestride )
921 {
922 GET_CURRENT_CONTEXT(ctx);
923 GLint i;
924
925 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
926
927 /* XXX not sure about ARB_vertex_buffer_object handling here */
928
929 for ( i = 0 ; i < primcount ; i++ ) {
930 if ( count[i] > 0 ) {
931 (ctx->Exec->DrawElements)( *(GLenum *) ((char *) mode + (i * modestride)),
932 count[i], type, indices[i] );
933 }
934 }
935 }
936
937
938 /**********************************************************************/
939 /***** Initialization *****/
940 /**********************************************************************/
941
942 void
943 _mesa_init_varray( GLcontext * ctx )
944 {
945 GLuint i;
946
947 /* Vertex arrays */
948 ctx->Array.Vertex.Size = 4;
949 ctx->Array.Vertex.Type = GL_FLOAT;
950 ctx->Array.Vertex.Stride = 0;
951 ctx->Array.Vertex.StrideB = 0;
952 ctx->Array.Vertex.Ptr = NULL;
953 ctx->Array.Vertex.Enabled = GL_FALSE;
954 ctx->Array.Vertex.Flags = CA_CLIENT_DATA;
955 ctx->Array.Normal.Type = GL_FLOAT;
956 ctx->Array.Normal.Stride = 0;
957 ctx->Array.Normal.StrideB = 0;
958 ctx->Array.Normal.Ptr = NULL;
959 ctx->Array.Normal.Enabled = GL_FALSE;
960 ctx->Array.Normal.Flags = CA_CLIENT_DATA;
961 ctx->Array.Color.Size = 4;
962 ctx->Array.Color.Type = GL_FLOAT;
963 ctx->Array.Color.Stride = 0;
964 ctx->Array.Color.StrideB = 0;
965 ctx->Array.Color.Ptr = NULL;
966 ctx->Array.Color.Enabled = GL_FALSE;
967 ctx->Array.Color.Flags = CA_CLIENT_DATA;
968 ctx->Array.SecondaryColor.Size = 4;
969 ctx->Array.SecondaryColor.Type = GL_FLOAT;
970 ctx->Array.SecondaryColor.Stride = 0;
971 ctx->Array.SecondaryColor.StrideB = 0;
972 ctx->Array.SecondaryColor.Ptr = NULL;
973 ctx->Array.SecondaryColor.Enabled = GL_FALSE;
974 ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA;
975 ctx->Array.FogCoord.Size = 1;
976 ctx->Array.FogCoord.Type = GL_FLOAT;
977 ctx->Array.FogCoord.Stride = 0;
978 ctx->Array.FogCoord.StrideB = 0;
979 ctx->Array.FogCoord.Ptr = NULL;
980 ctx->Array.FogCoord.Enabled = GL_FALSE;
981 ctx->Array.FogCoord.Flags = CA_CLIENT_DATA;
982 ctx->Array.Index.Type = GL_FLOAT;
983 ctx->Array.Index.Stride = 0;
984 ctx->Array.Index.StrideB = 0;
985 ctx->Array.Index.Ptr = NULL;
986 ctx->Array.Index.Enabled = GL_FALSE;
987 ctx->Array.Index.Flags = CA_CLIENT_DATA;
988 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
989 ctx->Array.TexCoord[i].Size = 4;
990 ctx->Array.TexCoord[i].Type = GL_FLOAT;
991 ctx->Array.TexCoord[i].Stride = 0;
992 ctx->Array.TexCoord[i].StrideB = 0;
993 ctx->Array.TexCoord[i].Ptr = NULL;
994 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
995 ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
996 }
997 ctx->Array.TexCoordInterleaveFactor = 1;
998 ctx->Array.EdgeFlag.Stride = 0;
999 ctx->Array.EdgeFlag.StrideB = 0;
1000 ctx->Array.EdgeFlag.Ptr = NULL;
1001 ctx->Array.EdgeFlag.Enabled = GL_FALSE;
1002 ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA;
1003 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1004 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
1005 ctx->Array.VertexAttrib[i].Size = 4;
1006 ctx->Array.VertexAttrib[i].Type = GL_FLOAT;
1007 ctx->Array.VertexAttrib[i].Stride = 0;
1008 ctx->Array.VertexAttrib[i].StrideB = 0;
1009 ctx->Array.VertexAttrib[i].Ptr = NULL;
1010 ctx->Array.VertexAttrib[i].Enabled = GL_FALSE;
1011 ctx->Array.VertexAttrib[i].Flags = CA_CLIENT_DATA;
1012 }
1013 }