varray.c revision 5857e988be9317810cf713478195b4ed849eea4a
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.1 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26#include "glheader.h" 27#include "imports.h" 28#include "bufferobj.h" 29#include "context.h" 30#include "enable.h" 31#include "enums.h" 32#include "mtypes.h" 33#include "varray.h" 34#include "arrayobj.h" 35#include "glapi/dispatch.h" 36 37 38/** 39 * Update the fields of a vertex array object. 40 * We need to do a few special things for arrays that live in 41 * vertex buffer objects. 42 * 43 * \param array the array to update 44 * \param dirtyBit which bit to set in ctx->Array.NewState for this array 45 * \param elementSize size of each array element, in bytes 46 * \param size components per element (1, 2, 3 or 4) 47 * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 48 * \param stride stride between elements, in elements 49 * \param normalized are integer types converted to floats in [-1, 1]? 50 * \param ptr the address (or offset inside VBO) of the array data 51 */ 52static void 53update_array(GLcontext *ctx, struct gl_client_array *array, 54 GLbitfield dirtyBit, GLsizei elementSize, 55 GLint size, GLenum type, 56 GLsizei stride, GLboolean normalized, const GLvoid *ptr) 57{ 58 array->Size = size; 59 array->Type = type; 60 array->Stride = stride; 61 array->StrideB = stride ? stride : elementSize; 62 array->Normalized = normalized; 63 array->Ptr = (const GLubyte *) ptr; 64#if FEATURE_ARB_vertex_buffer_object 65 array->BufferObj->RefCount--; 66 if (array->BufferObj->RefCount <= 0) { 67 ASSERT(array->BufferObj->Name); 68 _mesa_remove_buffer_object( ctx, array->BufferObj ); 69 (*ctx->Driver.DeleteBuffer)( ctx, array->BufferObj ); 70 } 71 array->BufferObj = ctx->Array.ArrayBufferObj; 72 array->BufferObj->RefCount++; 73 /* Compute the index of the last array element that's inside the buffer. 74 * Later in glDrawArrays we'll check if start + count > _MaxElement to 75 * be sure we won't go out of bounds. 76 */ 77 if (ctx->Array.ArrayBufferObj->Name) 78 array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size 79 - (GLsizeiptrARB) array->Ptr + array->StrideB 80 - elementSize) / array->StrideB; 81 else 82#endif 83 array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ 84 85 ctx->NewState |= _NEW_ARRAY; 86 ctx->Array.NewState |= dirtyBit; 87} 88 89 90void GLAPIENTRY 91_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 92{ 93 GLsizei elementSize; 94 GET_CURRENT_CONTEXT(ctx); 95 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 96 97 if (size < 2 || size > 4) { 98 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" ); 99 return; 100 } 101 if (stride < 0) { 102 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" ); 103 return; 104 } 105 106 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 107 _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size, 108 _mesa_lookup_enum_by_nr( type ), stride); 109 110 /* always need to check that <type> is legal */ 111 switch (type) { 112 case GL_SHORT: 113 elementSize = size * sizeof(GLshort); 114 break; 115 case GL_INT: 116 elementSize = size * sizeof(GLint); 117 break; 118 case GL_FLOAT: 119 elementSize = size * sizeof(GLfloat); 120 break; 121 case GL_DOUBLE: 122 elementSize = size * sizeof(GLdouble); 123 break; 124 default: 125 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" ); 126 return; 127 } 128 129 update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, 130 elementSize, size, type, stride, GL_FALSE, ptr); 131 132 if (ctx->Driver.VertexPointer) 133 ctx->Driver.VertexPointer( ctx, size, type, stride, ptr ); 134} 135 136 137void GLAPIENTRY 138_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) 139{ 140 GLsizei elementSize; 141 GET_CURRENT_CONTEXT(ctx); 142 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 143 144 if (stride < 0) { 145 _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); 146 return; 147 } 148 149 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 150 _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n", 151 _mesa_lookup_enum_by_nr( type ), stride); 152 153 switch (type) { 154 case GL_BYTE: 155 elementSize = 3 * sizeof(GLbyte); 156 break; 157 case GL_SHORT: 158 elementSize = 3 * sizeof(GLshort); 159 break; 160 case GL_INT: 161 elementSize = 3 * sizeof(GLint); 162 break; 163 case GL_FLOAT: 164 elementSize = 3 * sizeof(GLfloat); 165 break; 166 case GL_DOUBLE: 167 elementSize = 3 * sizeof(GLdouble); 168 break; 169 default: 170 _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); 171 return; 172 } 173 174 update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, 175 elementSize, 3, type, stride, GL_TRUE, ptr); 176 177 if (ctx->Driver.NormalPointer) 178 ctx->Driver.NormalPointer( ctx, type, stride, ptr ); 179} 180 181 182void GLAPIENTRY 183_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 184{ 185 GLsizei elementSize; 186 GET_CURRENT_CONTEXT(ctx); 187 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 188 189 if (size < 3 || size > 4) { 190 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" ); 191 return; 192 } 193 if (stride < 0) { 194 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); 195 return; 196 } 197 198 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 199 _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size, 200 _mesa_lookup_enum_by_nr( type ), stride); 201 202 switch (type) { 203 case GL_BYTE: 204 elementSize = size * sizeof(GLbyte); 205 break; 206 case GL_UNSIGNED_BYTE: 207 elementSize = size * sizeof(GLubyte); 208 break; 209 case GL_SHORT: 210 elementSize = size * sizeof(GLshort); 211 break; 212 case GL_UNSIGNED_SHORT: 213 elementSize = size * sizeof(GLushort); 214 break; 215 case GL_INT: 216 elementSize = size * sizeof(GLint); 217 break; 218 case GL_UNSIGNED_INT: 219 elementSize = size * sizeof(GLuint); 220 break; 221 case GL_FLOAT: 222 elementSize = size * sizeof(GLfloat); 223 break; 224 case GL_DOUBLE: 225 elementSize = size * sizeof(GLdouble); 226 break; 227 default: 228 _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" ); 229 return; 230 } 231 232 update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, 233 elementSize, size, type, stride, GL_TRUE, ptr); 234 235 if (ctx->Driver.ColorPointer) 236 ctx->Driver.ColorPointer( ctx, size, type, stride, ptr ); 237} 238 239 240void GLAPIENTRY 241_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) 242{ 243 GLint elementSize; 244 GET_CURRENT_CONTEXT(ctx); 245 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 246 247 if (stride < 0) { 248 _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" ); 249 return; 250 } 251 252 switch (type) { 253 case GL_FLOAT: 254 elementSize = sizeof(GLfloat); 255 break; 256 case GL_DOUBLE: 257 elementSize = sizeof(GLdouble); 258 break; 259 default: 260 _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" ); 261 return; 262 } 263 264 update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, 265 elementSize, 1, type, stride, GL_FALSE, ptr); 266 267 if (ctx->Driver.FogCoordPointer) 268 ctx->Driver.FogCoordPointer( ctx, type, stride, ptr ); 269} 270 271 272void GLAPIENTRY 273_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 274{ 275 GLsizei elementSize; 276 GET_CURRENT_CONTEXT(ctx); 277 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 278 279 if (stride < 0) { 280 _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" ); 281 return; 282 } 283 284 switch (type) { 285 case GL_UNSIGNED_BYTE: 286 elementSize = sizeof(GLubyte); 287 break; 288 case GL_SHORT: 289 elementSize = sizeof(GLshort); 290 break; 291 case GL_INT: 292 elementSize = sizeof(GLint); 293 break; 294 case GL_FLOAT: 295 elementSize = sizeof(GLfloat); 296 break; 297 case GL_DOUBLE: 298 elementSize = sizeof(GLdouble); 299 break; 300 default: 301 _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" ); 302 return; 303 } 304 305 update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, 306 elementSize, 1, type, stride, GL_FALSE, ptr); 307 308 if (ctx->Driver.IndexPointer) 309 ctx->Driver.IndexPointer( ctx, type, stride, ptr ); 310} 311 312 313void GLAPIENTRY 314_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, 315 GLsizei stride, const GLvoid *ptr) 316{ 317 GLsizei elementSize; 318 GET_CURRENT_CONTEXT(ctx); 319 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 320 321 if (size != 3 && size != 4) { 322 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" ); 323 return; 324 } 325 if (stride < 0) { 326 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" ); 327 return; 328 } 329 330 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 331 _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n", 332 size, _mesa_lookup_enum_by_nr( type ), stride); 333 334 switch (type) { 335 case GL_BYTE: 336 elementSize = size * sizeof(GLbyte); 337 break; 338 case GL_UNSIGNED_BYTE: 339 elementSize = size * sizeof(GLubyte); 340 break; 341 case GL_SHORT: 342 elementSize = size * sizeof(GLshort); 343 break; 344 case GL_UNSIGNED_SHORT: 345 elementSize = size * sizeof(GLushort); 346 break; 347 case GL_INT: 348 elementSize = size * sizeof(GLint); 349 break; 350 case GL_UNSIGNED_INT: 351 elementSize = size * sizeof(GLuint); 352 break; 353 case GL_FLOAT: 354 elementSize = size * sizeof(GLfloat); 355 break; 356 case GL_DOUBLE: 357 elementSize = size * sizeof(GLdouble); 358 break; 359 default: 360 _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" ); 361 return; 362 } 363 364 update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1, 365 elementSize, size, type, stride, GL_TRUE, ptr); 366 367 if (ctx->Driver.SecondaryColorPointer) 368 ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr ); 369} 370 371 372void GLAPIENTRY 373_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, 374 const GLvoid *ptr) 375{ 376 GLint elementSize; 377 GET_CURRENT_CONTEXT(ctx); 378 const GLuint unit = ctx->Array.ActiveTexture; 379 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 380 381 if (size < 1 || size > 4) { 382 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); 383 return; 384 } 385 if (stride < 0) { 386 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); 387 return; 388 } 389 390 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 391 _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n", 392 unit, size, _mesa_lookup_enum_by_nr( type ), stride); 393 394 /* always need to check that <type> is legal */ 395 switch (type) { 396 case GL_SHORT: 397 elementSize = size * sizeof(GLshort); 398 break; 399 case GL_INT: 400 elementSize = size * sizeof(GLint); 401 break; 402 case GL_FLOAT: 403 elementSize = size * sizeof(GLfloat); 404 break; 405 case GL_DOUBLE: 406 elementSize = size * sizeof(GLdouble); 407 break; 408 default: 409 _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); 410 return; 411 } 412 413 update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit], 414 _NEW_ARRAY_TEXCOORD(unit), 415 elementSize, size, type, stride, GL_FALSE, ptr); 416 417 if (ctx->Driver.TexCoordPointer) 418 ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); 419} 420 421 422void GLAPIENTRY 423_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) 424{ 425 GET_CURRENT_CONTEXT(ctx); 426 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 427 428 if (stride < 0) { 429 _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" ); 430 return; 431 } 432 433 update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, 434 sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, ptr); 435 436 if (ctx->Driver.EdgeFlagPointer) 437 ctx->Driver.EdgeFlagPointer( ctx, stride, ptr ); 438} 439 440 441#if FEATURE_NV_vertex_program 442void GLAPIENTRY 443_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, 444 GLsizei stride, const GLvoid *ptr) 445{ 446 const GLboolean normalized = GL_FALSE; 447 GLsizei elementSize; 448 GET_CURRENT_CONTEXT(ctx); 449 ASSERT_OUTSIDE_BEGIN_END(ctx); 450 451 if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { 452 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); 453 return; 454 } 455 456 if (size < 1 || size > 4) { 457 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)"); 458 return; 459 } 460 461 if (stride < 0) { 462 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)"); 463 return; 464 } 465 466 if (type == GL_UNSIGNED_BYTE && size != 4) { 467 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); 468 return; 469 } 470 471 /* check for valid 'type' and compute StrideB right away */ 472 switch (type) { 473 case GL_UNSIGNED_BYTE: 474 elementSize = size * sizeof(GLubyte); 475 break; 476 case GL_SHORT: 477 elementSize = size * sizeof(GLshort); 478 break; 479 case GL_FLOAT: 480 elementSize = size * sizeof(GLfloat); 481 break; 482 case GL_DOUBLE: 483 elementSize = size * sizeof(GLdouble); 484 break; 485 default: 486 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" ); 487 return; 488 } 489 490 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 491 _NEW_ARRAY_ATTRIB(index), 492 elementSize, size, type, stride, normalized, ptr); 493 494 if (ctx->Driver.VertexAttribPointer) 495 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr ); 496} 497#endif 498 499 500#if FEATURE_ARB_vertex_program 501void GLAPIENTRY 502_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, 503 GLboolean normalized, 504 GLsizei stride, const GLvoid *ptr) 505{ 506 GLsizei elementSize; 507 GET_CURRENT_CONTEXT(ctx); 508 ASSERT_OUTSIDE_BEGIN_END(ctx); 509 510 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 511 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); 512 return; 513 } 514 515 if (size < 1 || size > 4) { 516 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)"); 517 return; 518 } 519 520 if (stride < 0) { 521 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)"); 522 return; 523 } 524 525 if (type == GL_UNSIGNED_BYTE && size != 4) { 526 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size!=4)"); 527 return; 528 } 529 530 /* check for valid 'type' and compute StrideB right away */ 531 /* NOTE: more types are supported here than in the NV extension */ 532 switch (type) { 533 case GL_BYTE: 534 elementSize = size * sizeof(GLbyte); 535 break; 536 case GL_UNSIGNED_BYTE: 537 elementSize = size * sizeof(GLubyte); 538 break; 539 case GL_SHORT: 540 elementSize = size * sizeof(GLshort); 541 break; 542 case GL_UNSIGNED_SHORT: 543 elementSize = size * sizeof(GLushort); 544 break; 545 case GL_INT: 546 elementSize = size * sizeof(GLint); 547 break; 548 case GL_UNSIGNED_INT: 549 elementSize = size * sizeof(GLuint); 550 break; 551 case GL_FLOAT: 552 elementSize = size * sizeof(GLfloat); 553 break; 554 case GL_DOUBLE: 555 elementSize = size * sizeof(GLdouble); 556 break; 557 default: 558 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" ); 559 return; 560 } 561 562 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 563 _NEW_ARRAY_ATTRIB(index), 564 elementSize, size, type, stride, normalized, ptr); 565 566 if (ctx->Driver.VertexAttribPointer) 567 ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr); 568} 569#endif 570 571 572void GLAPIENTRY 573_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 574 GLsizei count, const GLvoid *ptr) 575{ 576 (void) count; 577 _mesa_VertexPointer(size, type, stride, ptr); 578} 579 580 581void GLAPIENTRY 582_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 583 const GLvoid *ptr) 584{ 585 (void) count; 586 _mesa_NormalPointer(type, stride, ptr); 587} 588 589 590void GLAPIENTRY 591_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 592 const GLvoid *ptr) 593{ 594 (void) count; 595 _mesa_ColorPointer(size, type, stride, ptr); 596} 597 598 599void GLAPIENTRY 600_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 601 const GLvoid *ptr) 602{ 603 (void) count; 604 _mesa_IndexPointer(type, stride, ptr); 605} 606 607 608void GLAPIENTRY 609_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 610 GLsizei count, const GLvoid *ptr) 611{ 612 (void) count; 613 _mesa_TexCoordPointer(size, type, stride, ptr); 614} 615 616 617void GLAPIENTRY 618_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 619{ 620 (void) count; 621 _mesa_EdgeFlagPointer(stride, ptr); 622} 623 624 625void GLAPIENTRY 626_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 627{ 628 GET_CURRENT_CONTEXT(ctx); 629 GLboolean tflag, cflag, nflag; /* enable/disable flags */ 630 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ 631 GLenum ctype = 0; /* color type */ 632 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ 633 const GLint toffset = 0; /* always zero */ 634 GLint defstride; /* default stride */ 635 GLint c, f; 636 637 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 638 639 f = sizeof(GLfloat); 640 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 641 642 if (stride < 0) { 643 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 644 return; 645 } 646 647 switch (format) { 648 case GL_V2F: 649 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 650 tcomps = 0; ccomps = 0; vcomps = 2; 651 voffset = 0; 652 defstride = 2*f; 653 break; 654 case GL_V3F: 655 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 656 tcomps = 0; ccomps = 0; vcomps = 3; 657 voffset = 0; 658 defstride = 3*f; 659 break; 660 case GL_C4UB_V2F: 661 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 662 tcomps = 0; ccomps = 4; vcomps = 2; 663 ctype = GL_UNSIGNED_BYTE; 664 coffset = 0; 665 voffset = c; 666 defstride = c + 2*f; 667 break; 668 case GL_C4UB_V3F: 669 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 670 tcomps = 0; ccomps = 4; vcomps = 3; 671 ctype = GL_UNSIGNED_BYTE; 672 coffset = 0; 673 voffset = c; 674 defstride = c + 3*f; 675 break; 676 case GL_C3F_V3F: 677 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 678 tcomps = 0; ccomps = 3; vcomps = 3; 679 ctype = GL_FLOAT; 680 coffset = 0; 681 voffset = 3*f; 682 defstride = 6*f; 683 break; 684 case GL_N3F_V3F: 685 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; 686 tcomps = 0; ccomps = 0; vcomps = 3; 687 noffset = 0; 688 voffset = 3*f; 689 defstride = 6*f; 690 break; 691 case GL_C4F_N3F_V3F: 692 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; 693 tcomps = 0; ccomps = 4; vcomps = 3; 694 ctype = GL_FLOAT; 695 coffset = 0; 696 noffset = 4*f; 697 voffset = 7*f; 698 defstride = 10*f; 699 break; 700 case GL_T2F_V3F: 701 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 702 tcomps = 2; ccomps = 0; vcomps = 3; 703 voffset = 2*f; 704 defstride = 5*f; 705 break; 706 case GL_T4F_V4F: 707 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 708 tcomps = 4; ccomps = 0; vcomps = 4; 709 voffset = 4*f; 710 defstride = 8*f; 711 break; 712 case GL_T2F_C4UB_V3F: 713 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 714 tcomps = 2; ccomps = 4; vcomps = 3; 715 ctype = GL_UNSIGNED_BYTE; 716 coffset = 2*f; 717 voffset = c+2*f; 718 defstride = c+5*f; 719 break; 720 case GL_T2F_C3F_V3F: 721 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 722 tcomps = 2; ccomps = 3; vcomps = 3; 723 ctype = GL_FLOAT; 724 coffset = 2*f; 725 voffset = 5*f; 726 defstride = 8*f; 727 break; 728 case GL_T2F_N3F_V3F: 729 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; 730 tcomps = 2; ccomps = 0; vcomps = 3; 731 noffset = 2*f; 732 voffset = 5*f; 733 defstride = 8*f; 734 break; 735 case GL_T2F_C4F_N3F_V3F: 736 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 737 tcomps = 2; ccomps = 4; vcomps = 3; 738 ctype = GL_FLOAT; 739 coffset = 2*f; 740 noffset = 6*f; 741 voffset = 9*f; 742 defstride = 12*f; 743 break; 744 case GL_T4F_C4F_N3F_V4F: 745 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 746 tcomps = 4; ccomps = 4; vcomps = 4; 747 ctype = GL_FLOAT; 748 coffset = 4*f; 749 noffset = 8*f; 750 voffset = 11*f; 751 defstride = 15*f; 752 break; 753 default: 754 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 755 return; 756 } 757 758 if (stride==0) { 759 stride = defstride; 760 } 761 762 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 763 _mesa_DisableClientState( GL_INDEX_ARRAY ); 764 /* XXX also disable secondary color and generic arrays? */ 765 766 /* Texcoords */ 767 if (tflag) { 768 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 769 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, 770 (GLubyte *) pointer + toffset ); 771 } 772 else { 773 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 774 } 775 776 /* Color */ 777 if (cflag) { 778 _mesa_EnableClientState( GL_COLOR_ARRAY ); 779 _mesa_ColorPointer( ccomps, ctype, stride, 780 (GLubyte *) pointer + coffset ); 781 } 782 else { 783 _mesa_DisableClientState( GL_COLOR_ARRAY ); 784 } 785 786 787 /* Normals */ 788 if (nflag) { 789 _mesa_EnableClientState( GL_NORMAL_ARRAY ); 790 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); 791 } 792 else { 793 _mesa_DisableClientState( GL_NORMAL_ARRAY ); 794 } 795 796 /* Vertices */ 797 _mesa_EnableClientState( GL_VERTEX_ARRAY ); 798 _mesa_VertexPointer( vcomps, GL_FLOAT, stride, 799 (GLubyte *) pointer + voffset ); 800} 801 802 803void GLAPIENTRY 804_mesa_LockArraysEXT(GLint first, GLsizei count) 805{ 806 GET_CURRENT_CONTEXT(ctx); 807 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 808 809 if (MESA_VERBOSE & VERBOSE_API) 810 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 811 812 if (first < 0) { 813 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 814 return; 815 } 816 if (count <= 0) { 817 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 818 return; 819 } 820 if (ctx->Array.LockCount != 0) { 821 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 822 return; 823 } 824 825 ctx->Array.LockFirst = first; 826 ctx->Array.LockCount = count; 827 828 ctx->NewState |= _NEW_ARRAY; 829 ctx->Array.NewState |= _NEW_ARRAY_ALL; 830 831 if (ctx->Driver.LockArraysEXT) 832 ctx->Driver.LockArraysEXT( ctx, first, count ); 833} 834 835 836void GLAPIENTRY 837_mesa_UnlockArraysEXT( void ) 838{ 839 GET_CURRENT_CONTEXT(ctx); 840 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 841 842 if (MESA_VERBOSE & VERBOSE_API) 843 _mesa_debug(ctx, "glUnlockArrays\n"); 844 845 if (ctx->Array.LockCount == 0) { 846 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 847 return; 848 } 849 850 ctx->Array.LockFirst = 0; 851 ctx->Array.LockCount = 0; 852 ctx->NewState |= _NEW_ARRAY; 853 ctx->Array.NewState |= _NEW_ARRAY_ALL; 854 855 if (ctx->Driver.UnlockArraysEXT) 856 ctx->Driver.UnlockArraysEXT( ctx ); 857} 858 859 860/* GL_EXT_multi_draw_arrays */ 861/* Somebody forgot to spec the first and count parameters as const! <sigh> */ 862void GLAPIENTRY 863_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first, 864 GLsizei *count, GLsizei primcount ) 865{ 866 GET_CURRENT_CONTEXT(ctx); 867 GLint i; 868 869 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 870 871 for (i = 0; i < primcount; i++) { 872 if (count[i] > 0) { 873 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i])); 874 } 875 } 876} 877 878 879/* GL_EXT_multi_draw_arrays */ 880void GLAPIENTRY 881_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, 882 const GLvoid **indices, GLsizei primcount ) 883{ 884 GET_CURRENT_CONTEXT(ctx); 885 GLint i; 886 887 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 888 889 for (i = 0; i < primcount; i++) { 890 if (count[i] > 0) { 891 CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i])); 892 } 893 } 894} 895 896 897/* GL_IBM_multimode_draw_arrays */ 898void GLAPIENTRY 899_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 900 const GLsizei * count, 901 GLsizei primcount, GLint modestride ) 902{ 903 GET_CURRENT_CONTEXT(ctx); 904 GLint i; 905 906 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 907 908 for ( i = 0 ; i < primcount ; i++ ) { 909 if ( count[i] > 0 ) { 910 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 911 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] )); 912 } 913 } 914} 915 916 917/* GL_IBM_multimode_draw_arrays */ 918void GLAPIENTRY 919_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 920 GLenum type, const GLvoid * const * indices, 921 GLsizei primcount, GLint modestride ) 922{ 923 GET_CURRENT_CONTEXT(ctx); 924 GLint i; 925 926 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 927 928 /* XXX not sure about ARB_vertex_buffer_object handling here */ 929 930 for ( i = 0 ; i < primcount ; i++ ) { 931 if ( count[i] > 0 ) { 932 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 933 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] )); 934 } 935 } 936} 937 938 939/** 940 * Initialize vertex array state for given context. 941 */ 942void 943_mesa_init_varray(GLcontext *ctx) 944{ 945 ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); 946 ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj; 947 948 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 949} 950