varray.c revision 3c63452e64df7e10aa073c6c3b9492b1d7dabbb8
1/* $Id: varray.c,v 1.47 2002/10/24 23:57:21 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 4.1 6 * 7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27#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 43void 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 98void 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 149void 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 214void 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 252void 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 299void 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 365void 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 420void 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 442void _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 503void 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 512void 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 521void 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 530void 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 539void 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 548void 549_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 550{ 551 (void) count; 552 _mesa_EdgeFlagPointer(stride, ptr); 553} 554 555 556 557 558void 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 754void 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 781void 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> */ 803void 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 */ 821void 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} 836