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