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 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 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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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