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