remove TexCoordInterleaveFactor. Clean up _mesa_InterleavedArrays()
[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 const GLint toffset = 0; /* always zero */
622 GLint defstride; /* default stride */
623 GLint c, f;
624 GLint coordUnitSave;
625
626 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
627
628 f = sizeof(GLfloat);
629 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
630
631 if (stride < 0) {
632 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
633 return;
634 }
635
636 switch (format) {
637 case GL_V2F:
638 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
639 tcomps = 0; ccomps = 0; vcomps = 2;
640 voffset = 0;
641 defstride = 2*f;
642 break;
643 case GL_V3F:
644 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
645 tcomps = 0; ccomps = 0; vcomps = 3;
646 voffset = 0;
647 defstride = 3*f;
648 break;
649 case GL_C4UB_V2F:
650 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
651 tcomps = 0; ccomps = 4; vcomps = 2;
652 ctype = GL_UNSIGNED_BYTE;
653 coffset = 0;
654 voffset = c;
655 defstride = c + 2*f;
656 break;
657 case GL_C4UB_V3F:
658 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
659 tcomps = 0; ccomps = 4; vcomps = 3;
660 ctype = GL_UNSIGNED_BYTE;
661 coffset = 0;
662 voffset = c;
663 defstride = c + 3*f;
664 break;
665 case GL_C3F_V3F:
666 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
667 tcomps = 0; ccomps = 3; vcomps = 3;
668 ctype = GL_FLOAT;
669 coffset = 0;
670 voffset = 3*f;
671 defstride = 6*f;
672 break;
673 case GL_N3F_V3F:
674 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
675 tcomps = 0; ccomps = 0; vcomps = 3;
676 noffset = 0;
677 voffset = 3*f;
678 defstride = 6*f;
679 break;
680 case GL_C4F_N3F_V3F:
681 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
682 tcomps = 0; ccomps = 4; vcomps = 3;
683 ctype = GL_FLOAT;
684 coffset = 0;
685 noffset = 4*f;
686 voffset = 7*f;
687 defstride = 10*f;
688 break;
689 case GL_T2F_V3F:
690 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
691 tcomps = 2; ccomps = 0; vcomps = 3;
692 voffset = 2*f;
693 defstride = 5*f;
694 break;
695 case GL_T4F_V4F:
696 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
697 tcomps = 4; ccomps = 0; vcomps = 4;
698 voffset = 4*f;
699 defstride = 8*f;
700 break;
701 case GL_T2F_C4UB_V3F:
702 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
703 tcomps = 2; ccomps = 4; vcomps = 3;
704 ctype = GL_UNSIGNED_BYTE;
705 coffset = 2*f;
706 voffset = c+2*f;
707 defstride = c+5*f;
708 break;
709 case GL_T2F_C3F_V3F:
710 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
711 tcomps = 2; ccomps = 3; vcomps = 3;
712 ctype = GL_FLOAT;
713 coffset = 2*f;
714 voffset = 5*f;
715 defstride = 8*f;
716 break;
717 case GL_T2F_N3F_V3F:
718 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
719 tcomps = 2; ccomps = 0; vcomps = 3;
720 noffset = 2*f;
721 voffset = 5*f;
722 defstride = 8*f;
723 break;
724 case GL_T2F_C4F_N3F_V3F:
725 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
726 tcomps = 2; ccomps = 4; vcomps = 3;
727 ctype = GL_FLOAT;
728 coffset = 2*f;
729 noffset = 6*f;
730 voffset = 9*f;
731 defstride = 12*f;
732 break;
733 case GL_T4F_C4F_N3F_V4F:
734 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
735 tcomps = 4; ccomps = 4; vcomps = 4;
736 ctype = GL_FLOAT;
737 coffset = 4*f;
738 noffset = 8*f;
739 voffset = 11*f;
740 defstride = 15*f;
741 break;
742 default:
743 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
744 return;
745 }
746
747 if (stride==0) {
748 stride = defstride;
749 }
750
751 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
752 _mesa_DisableClientState( GL_INDEX_ARRAY );
753
754 /* Texcoords */
755 coordUnitSave = ctx->Array.ActiveTexture;
756 if (tflag) {
757 GLuint i;
758 /* enable unit 0 texcoord array */
759 _mesa_ClientActiveTextureARB( GL_TEXTURE0_ARB );
760 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
761 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
762 (GLubyte *) pointer + i * toffset );
763 /* disable all other texcoord arrays */
764 for (i = 1; i < ctx->Const.MaxTextureCoordUnits; i++) {
765 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
766 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
767 }
768 }
769 else {
770 /* disable all texcoord arrays */
771 GLuint i;
772 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
773 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
774 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
775 }
776 }
777 /* Restore texture coordinate unit index */
778 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
779
780
781 /* Color */
782 if (cflag) {
783 _mesa_EnableClientState( GL_COLOR_ARRAY );
784 _mesa_ColorPointer( ccomps, ctype, stride,
785 (GLubyte *) pointer + coffset );
786 }
787 else {
788 _mesa_DisableClientState( GL_COLOR_ARRAY );
789 }
790
791
792 /* Normals */
793 if (nflag) {
794 _mesa_EnableClientState( GL_NORMAL_ARRAY );
795 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
796 }
797 else {
798 _mesa_DisableClientState( GL_NORMAL_ARRAY );
799 }
800
801 /* Vertices */
802 _mesa_EnableClientState( GL_VERTEX_ARRAY );
803 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
804 (GLubyte *) pointer + voffset );
805 }
806
807
808 void GLAPIENTRY
809 _mesa_LockArraysEXT(GLint first, GLsizei count)
810 {
811 GET_CURRENT_CONTEXT(ctx);
812 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
813
814 if (MESA_VERBOSE & VERBOSE_API)
815 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
816
817 if (first == 0 && count > 0 &&
818 count <= (GLint) ctx->Const.MaxArrayLockSize) {
819 ctx->Array.LockFirst = first;
820 ctx->Array.LockCount = count;
821 }
822 else {
823 ctx->Array.LockFirst = 0;
824 ctx->Array.LockCount = 0;
825 }
826
827 ctx->NewState |= _NEW_ARRAY;
828 ctx->Array.NewState |= _NEW_ARRAY_ALL;
829
830 if (ctx->Driver.LockArraysEXT)
831 ctx->Driver.LockArraysEXT( ctx, first, count );
832 }
833
834
835 void GLAPIENTRY
836 _mesa_UnlockArraysEXT( void )
837 {
838 GET_CURRENT_CONTEXT(ctx);
839 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
840
841 if (MESA_VERBOSE & VERBOSE_API)
842 _mesa_debug(ctx, "glUnlockArrays\n");
843
844 ctx->Array.LockFirst = 0;
845 ctx->Array.LockCount = 0;
846 ctx->NewState |= _NEW_ARRAY;
847 ctx->Array.NewState |= _NEW_ARRAY_ALL;
848
849 if (ctx->Driver.UnlockArraysEXT)
850 ctx->Driver.UnlockArraysEXT( ctx );
851 }
852
853
854 /* GL_EXT_multi_draw_arrays */
855 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
856 void GLAPIENTRY
857 _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
858 GLsizei *count, GLsizei primcount )
859 {
860 GET_CURRENT_CONTEXT(ctx);
861 GLint i;
862
863 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
864
865 for (i = 0; i < primcount; i++) {
866 if (count[i] > 0) {
867 (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
868 }
869 }
870 }
871
872
873 /* GL_EXT_multi_draw_arrays */
874 void GLAPIENTRY
875 _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
876 const GLvoid **indices, GLsizei primcount )
877 {
878 GET_CURRENT_CONTEXT(ctx);
879 GLint i;
880
881 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
882
883 for (i = 0; i < primcount; i++) {
884 if (count[i] > 0) {
885 (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
886 }
887 }
888 }
889
890
891 /* GL_IBM_multimode_draw_arrays */
892 void GLAPIENTRY
893 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
894 const GLsizei * count,
895 GLsizei primcount, GLint modestride )
896 {
897 GET_CURRENT_CONTEXT(ctx);
898 GLint i;
899
900 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
901
902 for ( i = 0 ; i < primcount ; i++ ) {
903 if ( count[i] > 0 ) {
904 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
905 (ctx->Exec->DrawArrays)( m, first[i], count[i] );
906 }
907 }
908 }
909
910
911 /* GL_IBM_multimode_draw_arrays */
912 void GLAPIENTRY
913 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
914 GLenum type, const GLvoid * const * indices,
915 GLsizei primcount, GLint modestride )
916 {
917 GET_CURRENT_CONTEXT(ctx);
918 GLint i;
919
920 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
921
922 /* XXX not sure about ARB_vertex_buffer_object handling here */
923
924 for ( i = 0 ; i < primcount ; i++ ) {
925 if ( count[i] > 0 ) {
926 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
927 (ctx->Exec->DrawElements)( m, count[i], type, indices[i] );
928 }
929 }
930 }
931
932
933 /**********************************************************************/
934 /***** Initialization *****/
935 /**********************************************************************/
936
937 void
938 _mesa_init_varray( GLcontext * ctx )
939 {
940 GLuint i;
941
942 /* Vertex arrays */
943 ctx->Array.Vertex.Size = 4;
944 ctx->Array.Vertex.Type = GL_FLOAT;
945 ctx->Array.Vertex.Stride = 0;
946 ctx->Array.Vertex.StrideB = 0;
947 ctx->Array.Vertex.Ptr = NULL;
948 ctx->Array.Vertex.Enabled = GL_FALSE;
949 ctx->Array.Vertex.Flags = CA_CLIENT_DATA;
950 ctx->Array.Normal.Type = GL_FLOAT;
951 ctx->Array.Normal.Stride = 0;
952 ctx->Array.Normal.StrideB = 0;
953 ctx->Array.Normal.Ptr = NULL;
954 ctx->Array.Normal.Enabled = GL_FALSE;
955 ctx->Array.Normal.Flags = CA_CLIENT_DATA;
956 ctx->Array.Color.Size = 4;
957 ctx->Array.Color.Type = GL_FLOAT;
958 ctx->Array.Color.Stride = 0;
959 ctx->Array.Color.StrideB = 0;
960 ctx->Array.Color.Ptr = NULL;
961 ctx->Array.Color.Enabled = GL_FALSE;
962 ctx->Array.Color.Flags = CA_CLIENT_DATA;
963 ctx->Array.SecondaryColor.Size = 4;
964 ctx->Array.SecondaryColor.Type = GL_FLOAT;
965 ctx->Array.SecondaryColor.Stride = 0;
966 ctx->Array.SecondaryColor.StrideB = 0;
967 ctx->Array.SecondaryColor.Ptr = NULL;
968 ctx->Array.SecondaryColor.Enabled = GL_FALSE;
969 ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA;
970 ctx->Array.FogCoord.Size = 1;
971 ctx->Array.FogCoord.Type = GL_FLOAT;
972 ctx->Array.FogCoord.Stride = 0;
973 ctx->Array.FogCoord.StrideB = 0;
974 ctx->Array.FogCoord.Ptr = NULL;
975 ctx->Array.FogCoord.Enabled = GL_FALSE;
976 ctx->Array.FogCoord.Flags = CA_CLIENT_DATA;
977 ctx->Array.Index.Type = GL_FLOAT;
978 ctx->Array.Index.Stride = 0;
979 ctx->Array.Index.StrideB = 0;
980 ctx->Array.Index.Ptr = NULL;
981 ctx->Array.Index.Enabled = GL_FALSE;
982 ctx->Array.Index.Flags = CA_CLIENT_DATA;
983 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
984 ctx->Array.TexCoord[i].Size = 4;
985 ctx->Array.TexCoord[i].Type = GL_FLOAT;
986 ctx->Array.TexCoord[i].Stride = 0;
987 ctx->Array.TexCoord[i].StrideB = 0;
988 ctx->Array.TexCoord[i].Ptr = NULL;
989 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
990 ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
991 }
992 ctx->Array.EdgeFlag.Stride = 0;
993 ctx->Array.EdgeFlag.StrideB = 0;
994 ctx->Array.EdgeFlag.Ptr = NULL;
995 ctx->Array.EdgeFlag.Enabled = GL_FALSE;
996 ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA;
997 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
998 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
999 ctx->Array.VertexAttrib[i].Size = 4;
1000 ctx->Array.VertexAttrib[i].Type = GL_FLOAT;
1001 ctx->Array.VertexAttrib[i].Stride = 0;
1002 ctx->Array.VertexAttrib[i].StrideB = 0;
1003 ctx->Array.VertexAttrib[i].Ptr = NULL;
1004 ctx->Array.VertexAttrib[i].Enabled = GL_FALSE;
1005 ctx->Array.VertexAttrib[i].Flags = CA_CLIENT_DATA;
1006 }
1007 }