varray.c revision ad2ac216fa0cbebc36530bf9e5256e902710b892
1/* $Id: varray.c,v 1.33 2000/11/24 10:25:06 keithw Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2000  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
47void
48_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
49{
50   GET_CURRENT_CONTEXT(ctx);
51
52   if (size<2 || size>4) {
53      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
54      return;
55   }
56   if (stride<0) {
57      gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
58      return;
59   }
60
61   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
62      fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size,
63	      gl_lookup_enum_by_nr( type ),
64	      stride);
65
66   ctx->Array.Vertex.StrideB = stride;
67   if (!stride) {
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         gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
83         return;
84      }
85   }
86   ctx->Array.Vertex.Size = size;
87   ctx->Array.Vertex.Type = type;
88   ctx->Array.Vertex.Stride = stride;
89   ctx->Array.Vertex.Ptr = (void *) ptr;
90   ctx->Array._VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
91   ctx->NewState |= _NEW_ARRAY;
92
93   if (ctx->Driver.VertexPointer)
94      ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
95}
96
97
98
99
100void
101_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
102{
103   GET_CURRENT_CONTEXT(ctx);
104
105   if (stride<0) {
106      gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
107      return;
108   }
109
110   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
111      fprintf(stderr, "glNormalPointer( type %s stride %d )\n",
112	      gl_lookup_enum_by_nr( type ),
113	      stride);
114
115   ctx->Array.Normal.StrideB = stride;
116   if (!stride) {
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         gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
135         return;
136      }
137   }
138   ctx->Array.Normal.Type = type;
139   ctx->Array.Normal.Stride = stride;
140   ctx->Array.Normal.Ptr = (void *) ptr;
141   ctx->Array._NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
142   ctx->NewState |= _NEW_ARRAY;
143
144   if (ctx->Driver.NormalPointer)
145      ctx->Driver.NormalPointer( ctx, type, stride, ptr );
146}
147
148
149
150void
151_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
152{
153   GET_CURRENT_CONTEXT(ctx);
154
155   if (size<3 || size>4) {
156      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
157      return;
158   }
159   if (stride<0) {
160      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
161      return;
162   }
163
164   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
165      fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size,
166	  gl_lookup_enum_by_nr( type ),
167	  stride);
168
169   ctx->Array.Color.StrideB = stride;
170   if (!stride) {
171      switch (type) {
172      case GL_BYTE:
173         ctx->Array.Color.StrideB =  size*sizeof(GLbyte);
174         break;
175      case GL_UNSIGNED_BYTE:
176         ctx->Array.Color.StrideB =  size*sizeof(GLubyte);
177         break;
178      case GL_SHORT:
179         ctx->Array.Color.StrideB =  size*sizeof(GLshort);
180         break;
181      case GL_UNSIGNED_SHORT:
182         ctx->Array.Color.StrideB =  size*sizeof(GLushort);
183         break;
184      case GL_INT:
185         ctx->Array.Color.StrideB =  size*sizeof(GLint);
186         break;
187      case GL_UNSIGNED_INT:
188         ctx->Array.Color.StrideB =  size*sizeof(GLuint);
189         break;
190      case GL_FLOAT:
191         ctx->Array.Color.StrideB =  size*sizeof(GLfloat);
192         break;
193      case GL_DOUBLE:
194         ctx->Array.Color.StrideB =  size*sizeof(GLdouble);
195         break;
196      default:
197         gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
198         return;
199      }
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->Array._ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
206   ctx->NewState |= _NEW_ARRAY;
207
208   if (ctx->Driver.ColorPointer)
209      ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
210}
211
212
213
214void
215_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
216{
217   GET_CURRENT_CONTEXT(ctx);
218
219   if (stride<0) {
220      gl_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
221      return;
222   }
223
224   ctx->Array.FogCoord.StrideB = stride;
225   if (!stride) {
226      switch (type) {
227      case GL_FLOAT:
228         ctx->Array.FogCoord.StrideB =  sizeof(GLfloat);
229         break;
230      case GL_DOUBLE:
231         ctx->Array.FogCoord.StrideB =  sizeof(GLdouble);
232         break;
233      default:
234         gl_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
235         return;
236      }
237   }
238   ctx->Array.FogCoord.Type = type;
239   ctx->Array.FogCoord.Stride = stride;
240   ctx->Array.FogCoord.Ptr = (void *) ptr;
241   ctx->Array._FogCoordFunc = gl_trans_1f_tab[TYPE_IDX(type)];
242   ctx->NewState |= _NEW_ARRAY;
243
244   if (ctx->Driver.FogCoordPointer)
245      ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
246}
247
248
249void
250_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
251{
252   GET_CURRENT_CONTEXT(ctx);
253
254   if (stride<0) {
255      gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
256      return;
257   }
258
259   ctx->Array.Index.StrideB = stride;
260   if (!stride) {
261      switch (type) {
262      case GL_UNSIGNED_BYTE:
263         ctx->Array.Index.StrideB =  sizeof(GLubyte);
264         break;
265      case GL_SHORT:
266         ctx->Array.Index.StrideB =  sizeof(GLshort);
267         break;
268      case GL_INT:
269         ctx->Array.Index.StrideB =  sizeof(GLint);
270         break;
271      case GL_FLOAT:
272         ctx->Array.Index.StrideB =  sizeof(GLfloat);
273         break;
274      case GL_DOUBLE:
275         ctx->Array.Index.StrideB =  sizeof(GLdouble);
276         break;
277      default:
278         gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
279         return;
280      }
281   }
282   ctx->Array.Index.Type = type;
283   ctx->Array.Index.Stride = stride;
284   ctx->Array.Index.Ptr = (void *) ptr;
285   ctx->Array._IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
286   ctx->NewState |= _NEW_ARRAY;
287
288   if (ctx->Driver.IndexPointer)
289      ctx->Driver.IndexPointer( ctx, type, stride, ptr );
290}
291
292
293void
294_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
295			       GLsizei stride, const GLvoid *ptr)
296{
297   GET_CURRENT_CONTEXT(ctx);
298
299   if (size != 3 && size != 4) {
300      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
301      return;
302   }
303   if (stride<0) {
304      gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
305      return;
306   }
307
308   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
309      fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size,
310	  gl_lookup_enum_by_nr( type ),
311	  stride);
312
313   ctx->Array.SecondaryColor.StrideB = stride;
314   if (!stride) {
315      switch (type) {
316      case GL_BYTE:
317         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLbyte);
318         break;
319      case GL_UNSIGNED_BYTE:
320         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLubyte);
321         break;
322      case GL_SHORT:
323         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLshort);
324         break;
325      case GL_UNSIGNED_SHORT:
326         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLushort);
327         break;
328      case GL_INT:
329         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLint);
330         break;
331      case GL_UNSIGNED_INT:
332         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLuint);
333         break;
334      case GL_FLOAT:
335         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLfloat);
336         break;
337      case GL_DOUBLE:
338         ctx->Array.SecondaryColor.StrideB =  size*sizeof(GLdouble);
339         break;
340      default:
341         gl_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
342         return;
343      }
344   }
345   ctx->Array.SecondaryColor.Size = 3; /* hardwire */
346   ctx->Array.SecondaryColor.Type = type;
347   ctx->Array.SecondaryColor.Stride = stride;
348   ctx->Array.SecondaryColor.Ptr = (void *) ptr;
349   ctx->Array._SecondaryColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
350   ctx->NewState |= _NEW_ARRAY;
351
352   if (ctx->Driver.SecondaryColorPointer)
353      ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
354}
355
356
357
358void
359_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
360{
361   GET_CURRENT_CONTEXT(ctx);
362   GLuint texUnit;
363
364   texUnit = ctx->Array.ActiveTexture;
365
366   if (size<1 || size>4) {
367      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
368      return;
369   }
370   if (stride<0) {
371      gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
372      return;
373   }
374
375   if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
376      fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n",
377	  texUnit,
378	  size,
379	  gl_lookup_enum_by_nr( type ),
380	  stride);
381
382   ctx->Array.TexCoord[texUnit].StrideB = stride;
383   if (!stride) {
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         gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
399         return;
400      }
401   }
402   ctx->Array.TexCoord[texUnit].Size = size;
403   ctx->Array.TexCoord[texUnit].Type = type;
404   ctx->Array.TexCoord[texUnit].Stride = stride;
405   ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
406   ctx->Array._TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
407   ctx->NewState |= _NEW_ARRAY;
408
409   if (ctx->Driver.TexCoordPointer)
410      ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
411}
412
413
414
415
416void
417_mesa_EdgeFlagPointer(GLsizei stride, const void *vptr)
418{
419   GET_CURRENT_CONTEXT(ctx);
420   const GLboolean *ptr = (GLboolean *)vptr;
421
422   if (stride<0) {
423      gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
424      return;
425   }
426   ctx->Array.EdgeFlag.Stride = stride;
427   ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
428   ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
429   if (stride != sizeof(GLboolean)) {
430      ctx->Array._EdgeFlagFunc = gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
431   } else {
432      ctx->Array._EdgeFlagFunc = 0;
433   }
434   ctx->NewState |= _NEW_ARRAY;
435
436   if (ctx->Driver.EdgeFlagPointer)
437      ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
438}
439
440
441
442
443
444void
445_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
446                       GLsizei count, const GLvoid *ptr)
447{
448   (void) count;
449   _mesa_VertexPointer(size, type, stride, ptr);
450}
451
452
453void
454_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
455                       const GLvoid *ptr)
456{
457   (void) count;
458   _mesa_NormalPointer(type, stride, ptr);
459}
460
461
462void
463_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
464                      const GLvoid *ptr)
465{
466   (void) count;
467   _mesa_ColorPointer(size, type, stride, ptr);
468}
469
470
471void
472_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
473                      const GLvoid *ptr)
474{
475   (void) count;
476   _mesa_IndexPointer(type, stride, ptr);
477}
478
479
480void
481_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
482                         GLsizei count, const GLvoid *ptr)
483{
484   (void) count;
485   _mesa_TexCoordPointer(size, type, stride, ptr);
486}
487
488
489void
490_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
491{
492   (void) count;
493   _mesa_EdgeFlagPointer(stride, ptr);
494}
495
496
497
498
499
500
501void
502_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
503{
504   GET_CURRENT_CONTEXT(ctx);
505   GLboolean tflag, cflag, nflag;  /* enable/disable flags */
506   GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
507
508   GLenum ctype;                   /* color type */
509   GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
510   GLint defstride;                /* default stride */
511   GLint c, f;
512   GLint coordUnitSave;
513
514   f = sizeof(GLfloat);
515   c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
516
517   if (stride<0) {
518      gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
519      return;
520   }
521
522   switch (format) {
523      case GL_V2F:
524         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
525         tcomps = 0;  ccomps = 0;  vcomps = 2;
526         voffset = 0;
527         defstride = 2*f;
528         break;
529      case GL_V3F:
530         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
531         tcomps = 0;  ccomps = 0;  vcomps = 3;
532         voffset = 0;
533         defstride = 3*f;
534         break;
535      case GL_C4UB_V2F:
536         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
537         tcomps = 0;  ccomps = 4;  vcomps = 2;
538         ctype = GL_UNSIGNED_BYTE;
539         coffset = 0;
540         voffset = c;
541         defstride = c + 2*f;
542         break;
543      case GL_C4UB_V3F:
544         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
545         tcomps = 0;  ccomps = 4;  vcomps = 3;
546         ctype = GL_UNSIGNED_BYTE;
547         coffset = 0;
548         voffset = c;
549         defstride = c + 3*f;
550         break;
551      case GL_C3F_V3F:
552         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
553         tcomps = 0;  ccomps = 3;  vcomps = 3;
554         ctype = GL_FLOAT;
555         coffset = 0;
556         voffset = 3*f;
557         defstride = 6*f;
558         break;
559      case GL_N3F_V3F:
560         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
561         tcomps = 0;  ccomps = 0;  vcomps = 3;
562         noffset = 0;
563         voffset = 3*f;
564         defstride = 6*f;
565         break;
566      case GL_C4F_N3F_V3F:
567         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
568         tcomps = 0;  ccomps = 4;  vcomps = 3;
569         ctype = GL_FLOAT;
570         coffset = 0;
571         noffset = 4*f;
572         voffset = 7*f;
573         defstride = 10*f;
574         break;
575      case GL_T2F_V3F:
576         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
577         tcomps = 2;  ccomps = 0;  vcomps = 3;
578         voffset = 2*f;
579         defstride = 5*f;
580         break;
581      case GL_T4F_V4F:
582         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
583         tcomps = 4;  ccomps = 0;  vcomps = 4;
584         voffset = 4*f;
585         defstride = 8*f;
586         break;
587      case GL_T2F_C4UB_V3F:
588         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
589         tcomps = 2;  ccomps = 4;  vcomps = 3;
590         ctype = GL_UNSIGNED_BYTE;
591         coffset = 2*f;
592         voffset = c+2*f;
593         defstride = c+5*f;
594         break;
595      case GL_T2F_C3F_V3F:
596         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
597         tcomps = 2;  ccomps = 3;  vcomps = 3;
598         ctype = GL_FLOAT;
599         coffset = 2*f;
600         voffset = 5*f;
601         defstride = 8*f;
602         break;
603      case GL_T2F_N3F_V3F:
604         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
605         tcomps = 2;  ccomps = 0;  vcomps = 3;
606         noffset = 2*f;
607         voffset = 5*f;
608         defstride = 8*f;
609         break;
610      case GL_T2F_C4F_N3F_V3F:
611         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
612         tcomps = 2;  ccomps = 4;  vcomps = 3;
613         ctype = GL_FLOAT;
614         coffset = 2*f;
615         noffset = 6*f;
616         voffset = 9*f;
617         defstride = 12*f;
618         break;
619      case GL_T4F_C4F_N3F_V4F:
620         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
621         tcomps = 4;  ccomps = 4;  vcomps = 4;
622         ctype = GL_FLOAT;
623         coffset = 4*f;
624         noffset = 8*f;
625         voffset = 11*f;
626         defstride = 15*f;
627         break;
628      default:
629         gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
630         return;
631   }
632
633   if (stride==0) {
634      stride = defstride;
635   }
636
637   _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
638   _mesa_DisableClientState( GL_INDEX_ARRAY );
639
640   /* Texcoords */
641   coordUnitSave = ctx->Array.ActiveTexture;
642   if (tflag) {
643      GLint i;
644      GLint factor = ctx->Array.TexCoordInterleaveFactor;
645      for (i = 0; i < factor; i++) {
646         _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
647         _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
648         glTexCoordPointer( tcomps, GL_FLOAT, stride,
649                             (GLubyte *) pointer + i * coffset );
650      }
651      for (i = factor; i < ctx->Const.MaxTextureUnits; i++) {
652         _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
653         _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
654      }
655   }
656   else {
657      GLint i;
658      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
659         _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
660         _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
661      }
662   }
663   /* Restore texture coordinate unit index */
664   _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
665
666
667   /* Color */
668   if (cflag) {
669      _mesa_EnableClientState( GL_COLOR_ARRAY );
670      glColorPointer( ccomps, ctype, stride,
671                       (GLubyte*) pointer + coffset );
672   }
673   else {
674      _mesa_DisableClientState( GL_COLOR_ARRAY );
675   }
676
677
678   /* Normals */
679   if (nflag) {
680      _mesa_EnableClientState( GL_NORMAL_ARRAY );
681      glNormalPointer( GL_FLOAT, stride,
682                        (GLubyte*) pointer + noffset );
683   }
684   else {
685      _mesa_DisableClientState( GL_NORMAL_ARRAY );
686   }
687
688   _mesa_EnableClientState( GL_VERTEX_ARRAY );
689   glVertexPointer( vcomps, GL_FLOAT, stride,
690                     (GLubyte *) pointer + voffset );
691}
692
693
694
695/* Transform the array components now, upto the setup call.  When
696 * actual draw commands arrive, the data will be merged prior to
697 * calling render_vb.
698 */
699void
700_mesa_LockArraysEXT(GLint first, GLsizei count)
701{
702   GET_CURRENT_CONTEXT(ctx);
703   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glLockArraysEXT" );
704
705   if (MESA_VERBOSE & VERBOSE_API)
706      fprintf(stderr, "glLockArrays %d %d\n", first, count);
707
708   if (first == 0 && count > 0 && count <= ctx->Const.MaxArrayLockSize) {
709      ctx->Array.LockFirst = first;
710      ctx->Array.LockCount = count;
711   }
712   else {
713      ctx->Array.LockFirst = 0;
714      ctx->Array.LockCount = 0;
715   }
716
717   ctx->NewState |= _NEW_ARRAY;
718
719   if (ctx->Driver.LockArraysEXT)
720      ctx->Driver.LockArraysEXT( ctx, first, count );
721}
722
723
724void
725_mesa_UnlockArraysEXT( void )
726{
727   GET_CURRENT_CONTEXT(ctx);
728   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glUnlockArraysEXT" );
729
730   if (MESA_VERBOSE & VERBOSE_API)
731      fprintf(stderr, "glUnlockArrays\n");
732
733   ctx->Array.LockFirst = 0;
734   ctx->Array.LockCount = 0;
735   ctx->NewState |= _NEW_ARRAY;
736
737   if (ctx->Driver.UnlockArraysEXT)
738      ctx->Driver.UnlockArraysEXT( ctx );
739}
740