1 /* $Id: varray.c,v 1.17 1998/02/03 01:40:45 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 2.4
6 * Copyright (C) 1995-1997 Brian Paul
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24 /*
25 * $Log: varray.c,v $
26 * Revision 1.17 1998/02/03 01:40:45 brianp
27 * fixed a few expressions for Amiga compilation (Sam Jordan)
28 *
29 * Revision 1.16 1997/08/14 01:15:47 brianp
30 * gl_ArrayElement()'s assignment of current normal was wrong
31 *
32 * Revision 1.15 1997/07/24 01:25:54 brianp
33 * changed precompiled header symbol from PCH to PC_HEADER
34 *
35 * Revision 1.14 1997/06/20 02:50:19 brianp
36 * replaced Current.IntColor with Current.ByteColor
37 *
38 * Revision 1.13 1997/05/28 03:26:49 brianp
39 * added precompiled header (PCH) support
40 *
41 * Revision 1.12 1997/05/24 12:07:43 brianp
42 * colors weren't being used in gl_ArrayElement()
43 *
44 * Revision 1.11 1997/04/20 20:29:11 brianp
45 * replaced abort() with gl_problem()
46 *
47 * Revision 1.10 1997/04/02 03:12:31 brianp
48 * misc changes for new vertex buffer organization
49 *
50 * Revision 1.9 1997/01/30 21:05:03 brianp
51 * moved gl_GetPointerv() to get.c
52 *
53 * Revision 1.8 1996/12/18 20:00:57 brianp
54 * gl_set_material() now takes a bitmask instead of face and pname
55 *
56 * Revision 1.7 1996/12/07 10:21:28 brianp
57 * call gl_set_material() instead of gl_Materialfv()
58 *
59 * Revision 1.6 1996/11/09 03:12:34 brianp
60 * now call gl_render_vb() after gl_transform_vb_part2() call
61 *
62 * Revision 1.5 1996/10/08 00:05:06 brianp
63 * added some missing stuff to gl_ArrayElement()
64 *
65 * Revision 1.4 1996/10/04 02:37:06 brianp
66 * gl_ArrayElement() wasn't always initializing vertex Z and W values
67 *
68 * Revision 1.3 1996/10/03 00:47:56 brianp
69 * added #include <stdlib.h> for abort()
70 *
71 * Revision 1.2 1996/09/27 01:33:07 brianp
72 * added missing default cases to switches
73 *
74 * Revision 1.1 1996/09/13 01:38:16 brianp
75 * Initial revision
76 *
77 */
78
79
80
81 /*
82 * NOTE: At this time, only three vertex array configurations are optimized:
83 * 1. glVertex3fv(), zero stride
84 * 2. glNormal3fv() with glVertex3fv(), zero stride
85 * 3. glNormal3fv() with glVertex4fv(), zero stride
86 *
87 * More optimized array configurations can be added.
88 */
89
90
91 #ifdef PC_HEADER
92 #include "all.h"
93 #else
94 #include <stdlib.h>
95 #include <string.h>
96 #include "context.h"
97 #include "enable.h"
98 #include "dlist.h"
99 #include "light.h"
100 #include "macros.h"
101 #include "types.h"
102 #include "varray.h"
103 #include "vb.h"
104 #include "vbfill.h"
105 #include "vbrender.h"
106 #include "vbxform.h"
107 #include "xform.h"
108 #endif
109
110
gl_VertexPointer(GLcontext * ctx,GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)111 void gl_VertexPointer( GLcontext *ctx,
112 GLint size, GLenum type, GLsizei stride,
113 const GLvoid *ptr )
114 {
115 if (size<2 || size>4) {
116 gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
117 return;
118 }
119 if (stride<0) {
120 gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
121 return;
122 }
123 switch (type) {
124 case GL_SHORT:
125 ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLshort);
126 break;
127 case GL_INT:
128 ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLint);
129 break;
130 case GL_FLOAT:
131 ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLfloat);
132 break;
133 case GL_DOUBLE:
134 ctx->Array.VertexStrideB = stride ? stride : size*sizeof(GLdouble);
135 break;
136 default:
137 gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
138 return;
139 }
140 ctx->Array.VertexSize = size;
141 ctx->Array.VertexType = type;
142 ctx->Array.VertexStride = stride;
143 ctx->Array.VertexPtr = (void *) ptr;
144 }
145
146
147
148
gl_NormalPointer(GLcontext * ctx,GLenum type,GLsizei stride,const GLvoid * ptr)149 void gl_NormalPointer( GLcontext *ctx,
150 GLenum type, GLsizei stride, const GLvoid *ptr )
151 {
152 if (stride<0) {
153 gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
154 return;
155 }
156 switch (type) {
157 case GL_BYTE:
158 ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLbyte);
159 break;
160 case GL_SHORT:
161 ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLshort);
162 break;
163 case GL_INT:
164 ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLint);
165 break;
166 case GL_FLOAT:
167 ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLfloat);
168 break;
169 case GL_DOUBLE:
170 ctx->Array.NormalStrideB = stride ? stride : 3*sizeof(GLdouble);
171 break;
172 default:
173 gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
174 return;
175 }
176 ctx->Array.NormalType = type;
177 ctx->Array.NormalStride = stride;
178 ctx->Array.NormalPtr = (void *) ptr;
179 }
180
181
182
gl_ColorPointer(GLcontext * ctx,GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)183 void gl_ColorPointer( GLcontext *ctx,
184 GLint size, GLenum type, GLsizei stride,
185 const GLvoid *ptr )
186 {
187 if (size<3 || size>4) {
188 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
189 return;
190 }
191 if (stride<0) {
192 gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
193 return;
194 }
195 switch (type) {
196 case GL_BYTE:
197 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLbyte);
198 break;
199 case GL_UNSIGNED_BYTE:
200 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLubyte);
201 break;
202 case GL_SHORT:
203 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLshort);
204 break;
205 case GL_UNSIGNED_SHORT:
206 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLushort);
207 break;
208 case GL_INT:
209 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLint);
210 break;
211 case GL_UNSIGNED_INT:
212 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLuint);
213 break;
214 case GL_FLOAT:
215 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLfloat);
216 break;
217 case GL_DOUBLE:
218 ctx->Array.ColorStrideB = stride ? stride : size*sizeof(GLdouble);
219 break;
220 default:
221 gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
222 return;
223 }
224 ctx->Array.ColorSize = size;
225 ctx->Array.ColorType = type;
226 ctx->Array.ColorStride = stride;
227 ctx->Array.ColorPtr = (void *) ptr;
228 }
229
230
231
gl_IndexPointer(GLcontext * ctx,GLenum type,GLsizei stride,const GLvoid * ptr)232 void gl_IndexPointer( GLcontext *ctx,
233 GLenum type, GLsizei stride, const GLvoid *ptr )
234 {
235 if (stride<0) {
236 gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
237 return;
238 }
239 switch (type) {
240 case GL_SHORT:
241 ctx->Array.IndexStrideB = stride ? stride : sizeof(GLbyte);
242 break;
243 case GL_INT:
244 ctx->Array.IndexStrideB = stride ? stride : sizeof(GLint);
245 break;
246 case GL_FLOAT:
247 ctx->Array.IndexStrideB = stride ? stride : sizeof(GLfloat);
248 break;
249 case GL_DOUBLE:
250 ctx->Array.IndexStrideB = stride ? stride : sizeof(GLdouble);
251 break;
252 default:
253 gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
254 return;
255 }
256 ctx->Array.IndexType = type;
257 ctx->Array.IndexStride = stride;
258 ctx->Array.IndexPtr = (void *) ptr;
259 }
260
261
262
gl_TexCoordPointer(GLcontext * ctx,GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)263 void gl_TexCoordPointer( GLcontext *ctx,
264 GLint size, GLenum type, GLsizei stride,
265 const GLvoid *ptr )
266 {
267 if (size<1 || size>4) {
268 gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
269 return;
270 }
271 switch (type) {
272 case GL_SHORT:
273 ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLshort);
274 break;
275 case GL_INT:
276 ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLint);
277 break;
278 case GL_FLOAT:
279 ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLfloat);
280 break;
281 case GL_DOUBLE:
282 ctx->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLdouble);
283 break;
284 default:
285 gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
286 return;
287 }
288 if (stride<0) {
289 gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
290 return;
291 }
292 ctx->Array.TexCoordSize = size;
293 ctx->Array.TexCoordType = type;
294 ctx->Array.TexCoordStride = stride;
295 ctx->Array.TexCoordPtr = (void *) ptr;
296 }
297
298
299
gl_EdgeFlagPointer(GLcontext * ctx,GLsizei stride,const GLboolean * ptr)300 void gl_EdgeFlagPointer( GLcontext *ctx,
301 GLsizei stride, const GLboolean *ptr )
302 {
303 if (stride<0) {
304 gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
305 return;
306 }
307 ctx->Array.EdgeFlagStride = stride;
308 ctx->Array.EdgeFlagStrideB = stride ? stride : sizeof(GLboolean);
309 ctx->Array.EdgeFlagPtr = (GLboolean *) ptr;
310 }
311
312
313
314 /*
315 * Execute
316 */
gl_ArrayElement(GLcontext * ctx,GLint i)317 void gl_ArrayElement( GLcontext *ctx, GLint i )
318 {
319 struct vertex_buffer *VB = ctx->VB;
320 GLint count = VB->Count;
321
322 /* copy vertex data into the Vertex Buffer */
323
324 if (ctx->Array.NormalEnabled) {
325 GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
326 + i * ctx->Array.NormalStrideB;
327 switch (ctx->Array.NormalType) {
328 case GL_BYTE:
329 VB->Normal[count][0] = BYTE_TO_FLOAT( p[0] );
330 VB->Normal[count][1] = BYTE_TO_FLOAT( p[1] );
331 VB->Normal[count][2] = BYTE_TO_FLOAT( p[2] );
332 break;
333 case GL_SHORT:
334 VB->Normal[count][0] = SHORT_TO_FLOAT( ((GLshort*)p)[0] );
335 VB->Normal[count][1] = SHORT_TO_FLOAT( ((GLshort*)p)[1] );
336 VB->Normal[count][2] = SHORT_TO_FLOAT( ((GLshort*)p)[2] );
337 break;
338 case GL_INT:
339 VB->Normal[count][0] = INT_TO_FLOAT( ((GLint*)p)[0] );
340 VB->Normal[count][1] = INT_TO_FLOAT( ((GLint*)p)[1] );
341 VB->Normal[count][2] = INT_TO_FLOAT( ((GLint*)p)[2] );
342 break;
343 case GL_FLOAT:
344 VB->Normal[count][0] = ((GLfloat*)p)[0];
345 VB->Normal[count][1] = ((GLfloat*)p)[1];
346 VB->Normal[count][2] = ((GLfloat*)p)[2];
347 break;
348 case GL_DOUBLE:
349 VB->Normal[count][0] = ((GLdouble*)p)[0];
350 VB->Normal[count][1] = ((GLdouble*)p)[1];
351 VB->Normal[count][2] = ((GLdouble*)p)[2];
352 break;
353 default:
354 gl_problem(ctx, "Bad normal type in gl_ArrayElement");
355 return;
356 }
357 VB->MonoNormal = GL_FALSE;
358 }
359 else {
360 VB->Normal[count][0] = ctx->Current.Normal[0];
361 VB->Normal[count][1] = ctx->Current.Normal[1];
362 VB->Normal[count][2] = ctx->Current.Normal[2];
363 }
364
365 /* TODO: directly set VB->Fcolor instead of calling a glColor command */
366 if (ctx->Array.ColorEnabled) {
367 GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
368 switch (ctx->Array.ColorType) {
369 case GL_BYTE:
370 switch (ctx->Array.ColorSize) {
371 case 4: glColor4bv( (GLbyte*) p ); break;
372 case 3: glColor3bv( (GLbyte*) p ); break;
373 }
374 break;
375 case GL_UNSIGNED_BYTE:
376 switch (ctx->Array.ColorSize) {
377 case 3: glColor3ubv( (GLubyte*) p ); break;
378 case 4: glColor4ubv( (GLubyte*) p ); break;
379 }
380 break;
381 case GL_SHORT:
382 switch (ctx->Array.ColorSize) {
383 case 3: glColor3sv( (GLshort*) p ); break;
384 case 4: glColor4sv( (GLshort*) p ); break;
385 }
386 break;
387 case GL_UNSIGNED_SHORT:
388 switch (ctx->Array.ColorSize) {
389 case 3: glColor3usv( (GLushort*) p ); break;
390 case 4: glColor4usv( (GLushort*) p ); break;
391 }
392 break;
393 case GL_INT:
394 switch (ctx->Array.ColorSize) {
395 case 3: glColor3iv( (GLint*) p ); break;
396 case 4: glColor4iv( (GLint*) p ); break;
397 }
398 break;
399 case GL_UNSIGNED_INT:
400 switch (ctx->Array.ColorSize) {
401 case 3: glColor3uiv( (GLuint*) p ); break;
402 case 4: glColor4uiv( (GLuint*) p ); break;
403 }
404 break;
405 case GL_FLOAT:
406 switch (ctx->Array.ColorSize) {
407 case 3: glColor3fv( (GLfloat*) p ); break;
408 case 4: glColor4fv( (GLfloat*) p ); break;
409 }
410 break;
411 case GL_DOUBLE:
412 switch (ctx->Array.ColorSize) {
413 case 3: glColor3dv( (GLdouble*) p ); break;
414 case 4: glColor4dv( (GLdouble*) p ); break;
415 }
416 break;
417 default:
418 gl_problem(ctx, "Bad color type in gl_ArrayElement");
419 return;
420 }
421 ctx->VB->MonoColor = GL_FALSE;
422 }
423
424 /* current color has been updated. store in vertex buffer now */
425 {
426 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor );
427 if (ctx->Light.ColorMaterialEnabled) {
428 GLfloat color[4];
429 color[0] = ctx->Current.ByteColor[0] * ctx->Visual->InvRedScale;
430 color[1] = ctx->Current.ByteColor[1] * ctx->Visual->InvGreenScale;
431 color[2] = ctx->Current.ByteColor[2] * ctx->Visual->InvBlueScale;
432 color[3] = ctx->Current.ByteColor[3] * ctx->Visual->InvAlphaScale;
433 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color );
434 }
435 }
436
437 if (ctx->Array.IndexEnabled) {
438 GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
439 switch (ctx->Array.IndexType) {
440 case GL_SHORT:
441 VB->Findex[count] = (GLuint) (*((GLshort*) p));
442 break;
443 case GL_INT:
444 VB->Findex[count] = (GLuint) (*((GLint*) p));
445 break;
446 case GL_FLOAT:
447 VB->Findex[count] = (GLuint) (*((GLfloat*) p));
448 break;
449 case GL_DOUBLE:
450 VB->Findex[count] = (GLuint) (*((GLdouble*) p));
451 break;
452 default:
453 gl_problem(ctx, "Bad index type in gl_ArrayElement");
454 return;
455 }
456 ctx->VB->MonoColor = GL_FALSE;
457 }
458 else {
459 VB->Findex[count] = ctx->Current.Index;
460 }
461
462 if (ctx->Array.TexCoordEnabled) {
463 GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
464 + i * ctx->Array.TexCoordStrideB;
465 VB->TexCoord[count][1] = 0.0F;
466 VB->TexCoord[count][2] = 0.0F;
467 VB->TexCoord[count][3] = 1.0F;
468 switch (ctx->Array.TexCoordType) {
469 case GL_SHORT:
470 switch (ctx->Array.TexCoordSize) {
471 /* FALL THROUGH! */
472 case 4: VB->TexCoord[count][3] = ((GLshort*) p)[3];
473 case 3: VB->TexCoord[count][2] = ((GLshort*) p)[2];
474 case 2: VB->TexCoord[count][1] = ((GLshort*) p)[1];
475 case 1: VB->TexCoord[count][0] = ((GLshort*) p)[0];
476 }
477 break;
478 case GL_INT:
479 switch (ctx->Array.TexCoordSize) {
480 /* FALL THROUGH! */
481 case 4: VB->TexCoord[count][3] = ((GLint*) p)[3];
482 case 3: VB->TexCoord[count][2] = ((GLint*) p)[2];
483 case 2: VB->TexCoord[count][1] = ((GLint*) p)[1];
484 case 1: VB->TexCoord[count][0] = ((GLint*) p)[0];
485 }
486 break;
487 case GL_FLOAT:
488 switch (ctx->Array.TexCoordSize) {
489 /* FALL THROUGH! */
490 case 4: VB->TexCoord[count][3] = ((GLfloat*) p)[3];
491 case 3: VB->TexCoord[count][2] = ((GLfloat*) p)[2];
492 case 2: VB->TexCoord[count][1] = ((GLfloat*) p)[1];
493 case 1: VB->TexCoord[count][0] = ((GLfloat*) p)[0];
494 }
495 break;
496 case GL_DOUBLE:
497 switch (ctx->Array.TexCoordSize) {
498 /* FALL THROUGH! */
499 case 4: VB->TexCoord[count][3] = ((GLdouble*) p)[3];
500 case 3: VB->TexCoord[count][2] = ((GLdouble*) p)[2];
501 case 2: VB->TexCoord[count][1] = ((GLdouble*) p)[1];
502 case 1: VB->TexCoord[count][0] = ((GLdouble*) p)[0];
503 }
504 break;
505 default:
506 gl_problem(ctx, "Bad texcoord type in gl_ArrayElement");
507 return;
508 }
509 }
510 else {
511 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord );
512 }
513
514 if (ctx->Array.EdgeFlagEnabled) {
515 GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr
516 + i * ctx->Array.EdgeFlagStrideB;
517 VB->Edgeflag[count] = *((GLboolean*) b);
518 }
519 else {
520 VB->Edgeflag[count] = ctx->Current.EdgeFlag;
521 }
522
523 if (ctx->Array.VertexEnabled) {
524 GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
525 + i * ctx->Array.VertexStrideB;
526 VB->Obj[count][2] = 0.0F;
527 VB->Obj[count][3] = 1.0F;
528 switch (ctx->Array.VertexType) {
529 case GL_SHORT:
530 switch (ctx->Array.VertexSize) {
531 /* FALL THROUGH */
532 case 4: VB->Obj[count][3] = ((GLshort*) b)[3];
533 case 3: VB->Obj[count][2] = ((GLshort*) b)[2];
534 case 2: VB->Obj[count][1] = ((GLshort*) b)[1];
535 VB->Obj[count][0] = ((GLshort*) b)[0];
536 }
537 break;
538 case GL_INT:
539 switch (ctx->Array.VertexSize) {
540 /* FALL THROUGH */
541 case 4: VB->Obj[count][3] = ((GLint*) b)[3];
542 case 3: VB->Obj[count][2] = ((GLint*) b)[2];
543 case 2: VB->Obj[count][1] = ((GLint*) b)[1];
544 VB->Obj[count][0] = ((GLint*) b)[0];
545 }
546 break;
547 case GL_FLOAT:
548 switch (ctx->Array.VertexSize) {
549 /* FALL THROUGH */
550 case 4: VB->Obj[count][3] = ((GLfloat*) b)[3];
551 case 3: VB->Obj[count][2] = ((GLfloat*) b)[2];
552 case 2: VB->Obj[count][1] = ((GLfloat*) b)[1];
553 VB->Obj[count][0] = ((GLfloat*) b)[0];
554 }
555 break;
556 case GL_DOUBLE:
557 switch (ctx->Array.VertexSize) {
558 /* FALL THROUGH */
559 case 4: VB->Obj[count][3] = ((GLdouble*) b)[3];
560 case 3: VB->Obj[count][2] = ((GLdouble*) b)[2];
561 case 2: VB->Obj[count][1] = ((GLdouble*) b)[1];
562 VB->Obj[count][0] = ((GLdouble*) b)[0];
563 }
564 break;
565 default:
566 gl_problem(ctx, "Bad vertex type in gl_ArrayElement");
567 return;
568 }
569
570 /* Only store vertex if Vertex array pointer is enabled */
571 count++;
572 VB->Count = count;
573 if (count==VB_MAX) {
574 gl_transform_vb_part1( ctx, GL_FALSE );
575 }
576
577 }
578 else {
579 /* vertex array pointer not enabled: no vertex to process */
580 }
581 }
582
583
584
585
586 /*
587 * Save into display list
588 * Use external API entry points since speed isn't too important here
589 * and makes the code simpler. Also, if GL_COMPILE_AND_EXECUTE then
590 * execute will happen too.
591 */
gl_save_ArrayElement(GLcontext * ctx,GLint i)592 void gl_save_ArrayElement( GLcontext *ctx, GLint i )
593 {
594 if (ctx->Array.NormalEnabled) {
595 GLbyte *p = (GLbyte*) ctx->Array.NormalPtr
596 + i * ctx->Array.NormalStrideB;
597 switch (ctx->Array.NormalType) {
598 case GL_BYTE:
599 glNormal3bv( (GLbyte*) p );
600 break;
601 case GL_SHORT:
602 glNormal3sv( (GLshort*) p );
603 break;
604 case GL_INT:
605 glNormal3iv( (GLint*) p );
606 break;
607 case GL_FLOAT:
608 glNormal3fv( (GLfloat*) p );
609 break;
610 case GL_DOUBLE:
611 glNormal3dv( (GLdouble*) p );
612 break;
613 default:
614 gl_problem(ctx, "Bad normal type in gl_save_ArrayElement");
615 return;
616 }
617 }
618
619 if (ctx->Array.ColorEnabled) {
620 GLbyte *p = (GLbyte*) ctx->Array.ColorPtr + i * ctx->Array.ColorStrideB;
621 switch (ctx->Array.ColorType) {
622 case GL_BYTE:
623 switch (ctx->Array.ColorSize) {
624 case 3: glColor3bv( (GLbyte*) p ); break;
625 case 4: glColor4bv( (GLbyte*) p ); break;
626 }
627 break;
628 case GL_UNSIGNED_BYTE:
629 switch (ctx->Array.ColorSize) {
630 case 3: glColor3ubv( (GLubyte*) p ); break;
631 case 4: glColor4ubv( (GLubyte*) p ); break;
632 }
633 break;
634 case GL_SHORT:
635 switch (ctx->Array.ColorSize) {
636 case 3: glColor3sv( (GLshort*) p ); break;
637 case 4: glColor4sv( (GLshort*) p ); break;
638 }
639 break;
640 case GL_UNSIGNED_SHORT:
641 switch (ctx->Array.ColorSize) {
642 case 3: glColor3usv( (GLushort*) p ); break;
643 case 4: glColor4usv( (GLushort*) p ); break;
644 }
645 break;
646 case GL_INT:
647 switch (ctx->Array.ColorSize) {
648 case 3: glColor3iv( (GLint*) p ); break;
649 case 4: glColor4iv( (GLint*) p ); break;
650 }
651 break;
652 case GL_UNSIGNED_INT:
653 switch (ctx->Array.ColorSize) {
654 case 3: glColor3uiv( (GLuint*) p ); break;
655 case 4: glColor4uiv( (GLuint*) p ); break;
656 }
657 break;
658 case GL_FLOAT:
659 switch (ctx->Array.ColorSize) {
660 case 3: glColor3fv( (GLfloat*) p ); break;
661 case 4: glColor4fv( (GLfloat*) p ); break;
662 }
663 break;
664 case GL_DOUBLE:
665 switch (ctx->Array.ColorSize) {
666 case 3: glColor3dv( (GLdouble*) p ); break;
667 case 4: glColor4dv( (GLdouble*) p ); break;
668 }
669 break;
670 default:
671 gl_problem(ctx, "Bad color type in gl_save_ArrayElement");
672 return;
673 }
674 }
675
676 if (ctx->Array.IndexEnabled) {
677 GLbyte *p = (GLbyte*) ctx->Array.IndexPtr + i * ctx->Array.IndexStrideB;
678 switch (ctx->Array.IndexType) {
679 case GL_SHORT:
680 glIndexsv( (GLshort*) p );
681 break;
682 case GL_INT:
683 glIndexiv( (GLint*) p );
684 break;
685 case GL_FLOAT:
686 glIndexfv( (GLfloat*) p );
687 break;
688 case GL_DOUBLE:
689 glIndexdv( (GLdouble*) p );
690 break;
691 default:
692 gl_problem(ctx, "Bad index type in gl_save_ArrayElement");
693 return;
694 }
695 }
696
697 if (ctx->Array.TexCoordEnabled) {
698 GLbyte *p = (GLbyte*) ctx->Array.TexCoordPtr
699 + i * ctx->Array.TexCoordStrideB;
700 switch (ctx->Array.TexCoordType) {
701 case GL_SHORT:
702 switch (ctx->Array.TexCoordSize) {
703 case 1: glTexCoord1sv( (GLshort*) p ); break;
704 case 2: glTexCoord2sv( (GLshort*) p ); break;
705 case 3: glTexCoord3sv( (GLshort*) p ); break;
706 case 4: glTexCoord4sv( (GLshort*) p ); break;
707 }
708 break;
709 case GL_INT:
710 switch (ctx->Array.TexCoordSize) {
711 case 1: glTexCoord1iv( (GLint*) p ); break;
712 case 2: glTexCoord2iv( (GLint*) p ); break;
713 case 3: glTexCoord3iv( (GLint*) p ); break;
714 case 4: glTexCoord4iv( (GLint*) p ); break;
715 }
716 break;
717 case GL_FLOAT:
718 switch (ctx->Array.TexCoordSize) {
719 case 1: glTexCoord1fv( (GLfloat*) p ); break;
720 case 2: glTexCoord2fv( (GLfloat*) p ); break;
721 case 3: glTexCoord3fv( (GLfloat*) p ); break;
722 case 4: glTexCoord4fv( (GLfloat*) p ); break;
723 }
724 break;
725 case GL_DOUBLE:
726 switch (ctx->Array.TexCoordSize) {
727 case 1: glTexCoord1dv( (GLdouble*) p ); break;
728 case 2: glTexCoord2dv( (GLdouble*) p ); break;
729 case 3: glTexCoord3dv( (GLdouble*) p ); break;
730 case 4: glTexCoord4dv( (GLdouble*) p ); break;
731 }
732 break;
733 default:
734 gl_problem(ctx, "Bad texcoord type in gl_save_ArrayElement");
735 return;
736 }
737 }
738
739 if (ctx->Array.EdgeFlagEnabled) {
740 GLbyte *b = (GLbyte*) ctx->Array.EdgeFlagPtr + i * ctx->Array.EdgeFlagStrideB;
741 glEdgeFlagv( (GLboolean*) b );
742 }
743
744 if (ctx->Array.VertexEnabled) {
745 GLbyte *b = (GLbyte*) ctx->Array.VertexPtr
746 + i * ctx->Array.VertexStrideB;
747 switch (ctx->Array.VertexType) {
748 case GL_SHORT:
749 switch (ctx->Array.VertexSize) {
750 case 2: glVertex2sv( (GLshort*) b ); break;
751 case 3: glVertex3sv( (GLshort*) b ); break;
752 case 4: glVertex4sv( (GLshort*) b ); break;
753 }
754 break;
755 case GL_INT:
756 switch (ctx->Array.VertexSize) {
757 case 2: glVertex2iv( (GLint*) b ); break;
758 case 3: glVertex3iv( (GLint*) b ); break;
759 case 4: glVertex4iv( (GLint*) b ); break;
760 }
761 break;
762 case GL_FLOAT:
763 switch (ctx->Array.VertexSize) {
764 case 2: glVertex2fv( (GLfloat*) b ); break;
765 case 3: glVertex3fv( (GLfloat*) b ); break;
766 case 4: glVertex4fv( (GLfloat*) b ); break;
767 }
768 break;
769 case GL_DOUBLE:
770 switch (ctx->Array.VertexSize) {
771 case 2: glVertex2dv( (GLdouble*) b ); break;
772 case 3: glVertex3dv( (GLdouble*) b ); break;
773 case 4: glVertex4dv( (GLdouble*) b ); break;
774 }
775 break;
776 default:
777 gl_problem(ctx, "Bad vertex type in gl_save_ArrayElement");
778 return;
779 }
780 }
781 }
782
783
784
785 /*
786 * Execute
787 */
gl_DrawArrays(GLcontext * ctx,GLenum mode,GLint first,GLsizei count)788 void gl_DrawArrays( GLcontext *ctx,
789 GLenum mode, GLint first, GLsizei count )
790 {
791 struct vertex_buffer* VB = ctx->VB;
792
793 GLint i;
794 GLboolean need_edges;
795
796 if (INSIDE_BEGIN_END(ctx)) {
797 gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
798 return;
799 }
800 if (count<0) {
801 gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
802 return;
803 }
804
805 if (ctx->Primitive==GL_TRIANGLES || ctx->Primitive==GL_QUADS
806 || ctx->Primitive==GL_POLYGON) {
807 need_edges = GL_TRUE;
808 }
809 else {
810 need_edges = GL_FALSE;
811 }
812
813 if (!ctx->Light.Enabled
814 && !ctx->Texture.Enabled
815 && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
816 && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
817 && !ctx->Array.NormalEnabled
818 && !ctx->Array.ColorEnabled
819 && !ctx->Array.IndexEnabled
820 && !ctx->Array.TexCoordEnabled
821 && !ctx->Array.EdgeFlagEnabled) {
822 /*
823 * SPECIAL CASE: glVertex3fv() with no lighting
824 */
825 GLfloat (*vptr)[3];
826 GLint remaining;
827
828 gl_Begin( ctx, mode );
829
830 remaining = count;
831 vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr;
832 vptr += 3 * first;
833 while (remaining>0) {
834 GLint vbspace, n;
835
836 vbspace = VB_MAX - VB->Start;
837 n = MIN2( vbspace, remaining );
838
839 gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
840
841 /* assign vertex colors */
842 {
843 GLint i, start = VB->Start;
844 for (i=0;i<n;i++) {
845 COPY_4UBV( VB->Fcolor[start+i], ctx->Current.ByteColor );
846 }
847 }
848
849 /* assign polygon edgeflags */
850 if (need_edges) {
851 GLint i;
852 for (i=0;i<n;i++) {
853 VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
854 }
855 }
856
857 remaining -= n;
858
859 VB->MonoNormal = GL_FALSE;
860 VB->Count = VB->Start + n;
861 gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
862
863 vptr += n;
864 }
865
866 gl_End( ctx );
867 }
868 else if (!ctx->CompileFlag
869 && ctx->Light.Enabled
870 && !ctx->Texture.Enabled
871 && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
872 && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==4
873 && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
874 && ctx->Array.NormalStride==0
875 && !ctx->Array.ColorEnabled
876 && !ctx->Array.IndexEnabled
877 && !ctx->Array.TexCoordEnabled
878 && !ctx->Array.EdgeFlagEnabled) {
879 /*
880 * SPECIAL CASE: glNormal3fv(); glVertex4fv(); with lighting
881 */
882 GLfloat (*vptr)[4], (*nptr)[3];
883 GLint remaining;
884
885 gl_Begin( ctx, mode );
886
887 remaining = count;
888 vptr = (GLfloat (*)[4]) ctx->Array.VertexPtr;
889 vptr += 4 * first;
890 nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr;
891 nptr += 3 * first;
892 while (remaining>0) {
893 GLint vbspace, n;
894
895 vbspace = VB_MAX - VB->Start;
896 n = MIN2( vbspace, remaining );
897
898 gl_xform_points_4fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
899 gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
900 ctx->Transform.Normalize );
901
902 /* assign polygon edgeflags */
903 if (need_edges) {
904 GLint i;
905 for (i=0;i<n;i++) {
906 VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
907 }
908 }
909
910 remaining -= n;
911
912 VB->MonoNormal = GL_FALSE;
913 VB->Count = VB->Start + n;
914 gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
915
916 vptr += n;
917 nptr += n;
918 }
919
920 gl_End( ctx );
921 }
922 else if (!ctx->CompileFlag
923 && ctx->Light.Enabled
924 && !ctx->Texture.Enabled
925 && ctx->Array.VertexEnabled && ctx->Array.VertexType==GL_FLOAT
926 && ctx->Array.VertexStride==0 && ctx->Array.VertexSize==3
927 && ctx->Array.NormalEnabled && ctx->Array.NormalType==GL_FLOAT
928 && ctx->Array.NormalStride==0
929 && !ctx->Array.ColorEnabled
930 && !ctx->Array.IndexEnabled
931 && !ctx->Array.TexCoordEnabled
932 && !ctx->Array.EdgeFlagEnabled) {
933 /*
934 * SPECIAL CASE: glNormal3fv(); glVertex3fv(); with lighting
935 */
936 GLfloat (*vptr)[3], (*nptr)[3];
937 GLint remaining;
938
939 gl_Begin( ctx, mode );
940
941 remaining = count;
942 vptr = (GLfloat (*)[3]) ctx->Array.VertexPtr;
943 vptr += 3 * first;
944 nptr = (GLfloat (*)[3]) ctx->Array.NormalPtr;
945 nptr += 3 * first;
946 while (remaining>0) {
947 GLint vbspace, n;
948
949 vbspace = VB_MAX - VB->Start;
950 n = MIN2( vbspace, remaining );
951
952 gl_xform_points_3fv( n, VB->Eye+VB->Start, ctx->ModelViewMatrix, vptr );
953 gl_xform_normals_3fv( n, VB->Normal+VB->Start, ctx->ModelViewInv, nptr,
954 ctx->Transform.Normalize );
955
956 /* assign polygon edgeflags */
957 if (need_edges) {
958 GLint i;
959 for (i=0;i<n;i++) {
960 VB->Edgeflag[VB->Start+i] = ctx->Current.EdgeFlag;
961 }
962 }
963
964 remaining -= n;
965
966 VB->MonoNormal = GL_FALSE;
967 VB->Count = VB->Start + n;
968 gl_transform_vb_part2( ctx, remaining==0 ? GL_TRUE : GL_FALSE );
969
970 vptr += n;
971 nptr += n;
972 }
973
974 gl_End( ctx );
975 }
976 else {
977 /*
978 * GENERAL CASE:
979 */
980 gl_Begin( ctx, mode );
981 for (i=0;i<count;i++) {
982 gl_ArrayElement( ctx, first+i );
983 }
984 gl_End( ctx );
985 }
986 }
987
988
989
990 /*
991 * Save into a display list
992 */
gl_save_DrawArrays(GLcontext * ctx,GLenum mode,GLint first,GLsizei count)993 void gl_save_DrawArrays( GLcontext *ctx,
994 GLenum mode, GLint first, GLsizei count )
995 {
996 GLint i;
997
998 if (INSIDE_BEGIN_END(ctx)) {
999 gl_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
1000 return;
1001 }
1002 if (count<0) {
1003 gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
1004 return;
1005 }
1006 switch (mode) {
1007 case GL_POINTS:
1008 case GL_LINES:
1009 case GL_LINE_STRIP:
1010 case GL_LINE_LOOP:
1011 case GL_TRIANGLES:
1012 case GL_TRIANGLE_STRIP:
1013 case GL_TRIANGLE_FAN:
1014 case GL_QUADS:
1015 case GL_QUAD_STRIP:
1016 case GL_POLYGON:
1017 /* OK */
1018 break;
1019 default:
1020 gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
1021 return;
1022 }
1023
1024
1025 /* Note: this will do compile AND execute if needed */
1026 gl_save_Begin( ctx, mode );
1027 for (i=0;i<count;i++) {
1028 gl_save_ArrayElement( ctx, first+i );
1029 }
1030 gl_save_End( ctx );
1031 }
1032
1033
1034
1035
1036 /*
1037 * Execute only
1038 */
gl_DrawElements(GLcontext * ctx,GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1039 void gl_DrawElements( GLcontext *ctx,
1040 GLenum mode, GLsizei count,
1041 GLenum type, const GLvoid *indices )
1042 {
1043
1044 if (INSIDE_BEGIN_END(ctx)) {
1045 gl_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
1046 return;
1047 }
1048 if (count<0) {
1049 gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
1050 return;
1051 }
1052 switch (mode) {
1053 case GL_POINTS:
1054 case GL_LINES:
1055 case GL_LINE_STRIP:
1056 case GL_LINE_LOOP:
1057 case GL_TRIANGLES:
1058 case GL_TRIANGLE_STRIP:
1059 case GL_TRIANGLE_FAN:
1060 case GL_QUADS:
1061 case GL_QUAD_STRIP:
1062 case GL_POLYGON:
1063 /* OK */
1064 break;
1065 default:
1066 gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
1067 return;
1068 }
1069 switch (type) {
1070 case GL_UNSIGNED_BYTE:
1071 {
1072 GLubyte *ub_indices = (GLubyte *) indices;
1073 GLint i;
1074 gl_Begin( ctx, mode );
1075 for (i=0;i<count;i++) {
1076 gl_ArrayElement( ctx, (GLint) ub_indices[i] );
1077 }
1078 gl_End( ctx );
1079 }
1080 break;
1081 case GL_UNSIGNED_SHORT:
1082 {
1083 GLushort *us_indices = (GLushort *) indices;
1084 GLint i;
1085 gl_Begin( ctx, mode );
1086 for (i=0;i<count;i++) {
1087 gl_ArrayElement( ctx, (GLint) us_indices[i] );
1088 }
1089 gl_End( ctx );
1090 }
1091 break;
1092 case GL_UNSIGNED_INT:
1093 {
1094 GLuint *ui_indices = (GLuint *) indices;
1095 GLint i;
1096 gl_Begin( ctx, mode );
1097 for (i=0;i<count;i++) {
1098 gl_ArrayElement( ctx, (GLint) ui_indices[i] );
1099 }
1100 gl_End( ctx );
1101 }
1102 break;
1103 default:
1104 gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
1105 return;
1106 }
1107 }
1108
1109
1110
1111
1112 /*
1113 * Save (and perhaps execute)
1114 */
gl_save_DrawElements(GLcontext * ctx,GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1115 void gl_save_DrawElements( GLcontext *ctx,
1116 GLenum mode, GLsizei count,
1117 GLenum type, const GLvoid *indices )
1118 {
1119 switch (type) {
1120 case GL_UNSIGNED_BYTE:
1121 {
1122 GLubyte *ub_indices = (GLubyte *) indices;
1123 GLint i;
1124 gl_save_Begin( ctx, mode );
1125 for (i=0;i<count;i++) {
1126 gl_save_ArrayElement( ctx, (GLint) ub_indices[i] );
1127 }
1128 gl_save_End( ctx );
1129 }
1130 break;
1131 case GL_UNSIGNED_SHORT:
1132 {
1133 GLushort *us_indices = (GLushort *) indices;
1134 GLint i;
1135 gl_save_Begin( ctx, mode );
1136 for (i=0;i<count;i++) {
1137 gl_save_ArrayElement( ctx, (GLint) us_indices[i] );
1138 }
1139 gl_save_End( ctx );
1140 }
1141 break;
1142 case GL_UNSIGNED_INT:
1143 {
1144 GLuint *ui_indices = (GLuint *) indices;
1145 GLint i;
1146 gl_save_Begin( ctx, mode );
1147 for (i=0;i<count;i++) {
1148 gl_save_ArrayElement( ctx, (GLint) ui_indices[i] );
1149 }
1150 gl_save_End( ctx );
1151 }
1152 break;
1153 default:
1154 gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
1155 return;
1156 }
1157 }
1158
1159
1160
1161
gl_InterleavedArrays(GLcontext * ctx,GLenum format,GLsizei stride,const GLvoid * pointer)1162 void gl_InterleavedArrays( GLcontext *ctx,
1163 GLenum format, GLsizei stride,
1164 const GLvoid *pointer )
1165 {
1166 GLboolean tflag, cflag, nflag; /* enable/disable flags */
1167 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
1168 GLenum ctype; /* color type */
1169 GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
1170 GLint defstride; /* default stride */
1171 GLint c, f;
1172
1173 f = sizeof(GLfloat);
1174 c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
1175
1176 if (stride<0) {
1177 gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
1178 return;
1179 }
1180
1181 switch (format) {
1182 case GL_V2F:
1183 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1184 tcomps = 0; ccomps = 0; vcomps = 2;
1185 voffset = 0;
1186 defstride = 2*f;
1187 break;
1188 case GL_V3F:
1189 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
1190 tcomps = 0; ccomps = 0; vcomps = 3;
1191 voffset = 0;
1192 defstride = 3*f;
1193 break;
1194 case GL_C4UB_V2F:
1195 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1196 tcomps = 0; ccomps = 4; vcomps = 2;
1197 ctype = GL_UNSIGNED_BYTE;
1198 coffset = 0;
1199 voffset = c;
1200 defstride = c + 2*f;
1201 break;
1202 case GL_C4UB_V3F:
1203 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1204 tcomps = 0; ccomps = 4; vcomps = 3;
1205 ctype = GL_UNSIGNED_BYTE;
1206 coffset = 0;
1207 voffset = c;
1208 defstride = c + 3*f;
1209 break;
1210 case GL_C3F_V3F:
1211 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
1212 tcomps = 0; ccomps = 3; vcomps = 3;
1213 ctype = GL_FLOAT;
1214 coffset = 0;
1215 voffset = 3*f;
1216 defstride = 6*f;
1217 break;
1218 case GL_N3F_V3F:
1219 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
1220 tcomps = 0; ccomps = 0; vcomps = 3;
1221 noffset = 0;
1222 voffset = 3*f;
1223 defstride = 6*f;
1224 break;
1225 case GL_C4F_N3F_V3F:
1226 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
1227 tcomps = 0; ccomps = 4; vcomps = 3;
1228 ctype = GL_FLOAT;
1229 coffset = 0;
1230 noffset = 4*f;
1231 voffset = 7*f;
1232 defstride = 10*f;
1233 break;
1234 case GL_T2F_V3F:
1235 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1236 tcomps = 2; ccomps = 0; vcomps = 3;
1237 voffset = 2*f;
1238 defstride = 5*f;
1239 break;
1240 case GL_T4F_V4F:
1241 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
1242 tcomps = 4; ccomps = 0; vcomps = 4;
1243 voffset = 4*f;
1244 defstride = 8*f;
1245 break;
1246 case GL_T2F_C4UB_V3F:
1247 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1248 tcomps = 2; ccomps = 4; vcomps = 3;
1249 ctype = GL_UNSIGNED_BYTE;
1250 coffset = 2*f;
1251 voffset = c+2*f;
1252 defstride = c+5*f;
1253 break;
1254 case GL_T2F_C3F_V3F:
1255 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
1256 tcomps = 2; ccomps = 3; vcomps = 3;
1257 ctype = GL_FLOAT;
1258 coffset = 2*f;
1259 voffset = 5*f;
1260 defstride = 8*f;
1261 break;
1262 case GL_T2F_N3F_V3F:
1263 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
1264 tcomps = 2; ccomps = 0; vcomps = 3;
1265 noffset = 2*f;
1266 voffset = 5*f;
1267 defstride = 8*f;
1268 break;
1269 case GL_T2F_C4F_N3F_V3F:
1270 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1271 tcomps = 2; ccomps = 4; vcomps = 3;
1272 ctype = GL_FLOAT;
1273 coffset = 2*f;
1274 noffset = 6*f;
1275 voffset = 9*f;
1276 defstride = 12*f;
1277 break;
1278 case GL_T4F_C4F_N3F_V4F:
1279 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
1280 tcomps = 4; ccomps = 4; vcomps = 4;
1281 ctype = GL_FLOAT;
1282 coffset = 4*f;
1283 noffset = 8*f;
1284 voffset = 11*f;
1285 defstride = 15*f;
1286 break;
1287 default:
1288 gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
1289 return;
1290 }
1291
1292 if (stride==0) {
1293 stride = defstride;
1294 }
1295
1296 gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY );
1297 gl_DisableClientState( ctx, GL_INDEX_ARRAY );
1298
1299 if (tflag) {
1300 gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
1301 gl_TexCoordPointer( ctx, tcomps, GL_FLOAT, stride, pointer );
1302 }
1303 else {
1304 gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
1305 }
1306
1307 if (cflag) {
1308 gl_EnableClientState( ctx, GL_COLOR_ARRAY );
1309 gl_ColorPointer( ctx, ccomps, ctype, stride,
1310 (GLubyte*) pointer + coffset );
1311 }
1312 else {
1313 gl_DisableClientState( ctx, GL_COLOR_ARRAY );
1314 }
1315
1316 if (nflag) {
1317 gl_EnableClientState( ctx, GL_NORMAL_ARRAY );
1318 gl_NormalPointer( ctx, GL_FLOAT, stride,
1319 (GLubyte*) pointer + noffset );
1320 }
1321 else {
1322 gl_DisableClientState( ctx, GL_NORMAL_ARRAY );
1323 }
1324
1325 gl_EnableClientState( ctx, GL_VERTEX_ARRAY );
1326 gl_VertexPointer( ctx, vcomps, GL_FLOAT, stride,
1327 (GLubyte *) pointer + voffset );
1328 }
1329
1330
1331
gl_save_InterleavedArrays(GLcontext * ctx,GLenum format,GLsizei stride,const GLvoid * pointer)1332 void gl_save_InterleavedArrays( GLcontext *ctx,
1333 GLenum format, GLsizei stride,
1334 const GLvoid *pointer )
1335 {
1336 /* Just execute since client-side state changes aren't put in
1337 * display lists.
1338 */
1339 gl_InterleavedArrays( ctx, format, stride, pointer );
1340 }
1341
1342