Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
55 pj 1
/* $Id: varray.c,v 1.1 2003-02-28 11:42:06 pj 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
}