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