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