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