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