varray.c revision cdc920a0
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.6 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27#include "glheader.h" 28#include "imports.h" 29#include "bufferobj.h" 30#include "context.h" 31#include "enable.h" 32#include "enums.h" 33#include "hash.h" 34#include "mtypes.h" 35#include "varray.h" 36#include "arrayobj.h" 37#include "main/dispatch.h" 38 39 40/** 41 * Set the fields of a vertex array. 42 * Also do an error check for GL_ARB_vertex_array_object: check that 43 * all arrays reside in VBOs when using a vertex array object. 44 * 45 * \param array the array to update 46 * \param dirtyBit which bit to set in ctx->Array.NewState for this array 47 * \param elementSize size of each array element, in bytes 48 * \param size components per element (1, 2, 3 or 4) 49 * \param type datatype of each component (GL_FLOAT, GL_INT, etc) 50 * \param format either GL_RGBA or GL_BGRA 51 * \param stride stride between elements, in elements 52 * \param normalized are integer types converted to floats in [-1, 1]? 53 * \param ptr the address (or offset inside VBO) of the array data 54 */ 55static void 56update_array(GLcontext *ctx, struct gl_client_array *array, 57 GLbitfield dirtyBit, GLsizei elementSize, 58 GLint size, GLenum type, GLenum format, 59 GLsizei stride, GLboolean normalized, const GLvoid *ptr) 60{ 61 ASSERT(format == GL_RGBA || format == GL_BGRA); 62 63 if (ctx->Array.ArrayObj->VBOonly && 64 ctx->Array.ArrayBufferObj->Name == 0) { 65 /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. 66 * Generate GL_INVALID_OPERATION if that's not true. 67 */ 68 _mesa_error(ctx, GL_INVALID_OPERATION, 69 "glVertex/Normal/EtcPointer(non-VBO array)"); 70 return; 71 } 72 73 array->Size = size; 74 array->Type = type; 75 array->Format = format; 76 array->Stride = stride; 77 array->StrideB = stride ? stride : elementSize; 78 array->Normalized = normalized; 79 array->Ptr = (const GLubyte *) ptr; 80 array->_ElementSize = elementSize; 81 82 _mesa_reference_buffer_object(ctx, &array->BufferObj, 83 ctx->Array.ArrayBufferObj); 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 case GL_HALF_FLOAT: 125 elementSize = size * sizeof(GLhalfARB); 126 break; 127#if FEATURE_fixedpt 128 case GL_FIXED: 129 elementSize = size * sizeof(GLfixed); 130 break; 131#endif 132#if FEATURE_vertex_array_byte 133 case GL_BYTE: 134 elementSize = size * sizeof(GLbyte); 135 break; 136#endif 137 default: 138 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)", 139 _mesa_lookup_enum_by_nr(type)); 140 return; 141 } 142 143 update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, 144 elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr); 145} 146 147 148void GLAPIENTRY 149_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) 150{ 151 GLsizei elementSize; 152 GET_CURRENT_CONTEXT(ctx); 153 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 154 155 if (stride < 0) { 156 _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); 157 return; 158 } 159 160 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 161 _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n", 162 _mesa_lookup_enum_by_nr( type ), stride); 163 164 switch (type) { 165 case GL_BYTE: 166 elementSize = 3 * sizeof(GLbyte); 167 break; 168 case GL_SHORT: 169 elementSize = 3 * sizeof(GLshort); 170 break; 171 case GL_INT: 172 elementSize = 3 * sizeof(GLint); 173 break; 174 case GL_FLOAT: 175 elementSize = 3 * sizeof(GLfloat); 176 break; 177 case GL_DOUBLE: 178 elementSize = 3 * sizeof(GLdouble); 179 break; 180 case GL_HALF_FLOAT: 181 elementSize = 3 * sizeof(GLhalfARB); 182 break; 183#if FEATURE_fixedpt 184 case GL_FIXED: 185 elementSize = 3 * sizeof(GLfixed); 186 break; 187#endif 188 default: 189 _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)", 190 _mesa_lookup_enum_by_nr(type)); 191 return; 192 } 193 194 update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, 195 elementSize, 3, type, GL_RGBA, stride, GL_TRUE, ptr); 196} 197 198 199void GLAPIENTRY 200_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) 201{ 202 GLsizei elementSize; 203 GLenum format; 204 GET_CURRENT_CONTEXT(ctx); 205 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 206 207 if (size < 3 || size > 4) { 208 if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) { 209 _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(size)"); 210 return; 211 } 212 } 213 if (stride < 0) { 214 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); 215 return; 216 } 217 218 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 219 _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size, 220 _mesa_lookup_enum_by_nr( type ), stride); 221 222 if (size == GL_BGRA) { 223 if (type != GL_UNSIGNED_BYTE) { 224 _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(GL_BGRA/GLubyte)"); 225 return; 226 } 227 format = GL_BGRA; 228 size = 4; 229 } 230 else { 231 format = GL_RGBA; 232 } 233 234 switch (type) { 235 case GL_BYTE: 236 elementSize = size * sizeof(GLbyte); 237 break; 238 case GL_UNSIGNED_BYTE: 239 elementSize = size * sizeof(GLubyte); 240 break; 241 case GL_SHORT: 242 elementSize = size * sizeof(GLshort); 243 break; 244 case GL_UNSIGNED_SHORT: 245 elementSize = size * sizeof(GLushort); 246 break; 247 case GL_INT: 248 elementSize = size * sizeof(GLint); 249 break; 250 case GL_UNSIGNED_INT: 251 elementSize = size * sizeof(GLuint); 252 break; 253 case GL_FLOAT: 254 elementSize = size * sizeof(GLfloat); 255 break; 256 case GL_DOUBLE: 257 elementSize = size * sizeof(GLdouble); 258 break; 259 case GL_HALF_FLOAT: 260 elementSize = size * sizeof(GLhalfARB); 261 break; 262#if FEATURE_fixedpt 263 case GL_FIXED: 264 elementSize = size * sizeof(GLfixed); 265 break; 266#endif 267 default: 268 _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)", 269 _mesa_lookup_enum_by_nr(type)); 270 return; 271 } 272 273 update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, 274 elementSize, size, type, format, stride, GL_TRUE, ptr); 275} 276 277 278void GLAPIENTRY 279_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) 280{ 281 GLint elementSize; 282 GET_CURRENT_CONTEXT(ctx); 283 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 284 285 if (stride < 0) { 286 _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" ); 287 return; 288 } 289 290 switch (type) { 291 case GL_FLOAT: 292 elementSize = sizeof(GLfloat); 293 break; 294 case GL_DOUBLE: 295 elementSize = sizeof(GLdouble); 296 break; 297 case GL_HALF_FLOAT: 298 elementSize = sizeof(GLhalfARB); 299 break; 300 default: 301 _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" ); 302 return; 303 } 304 305 update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, 306 elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr); 307} 308 309 310void GLAPIENTRY 311_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) 312{ 313 GLsizei elementSize; 314 GET_CURRENT_CONTEXT(ctx); 315 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 316 317 if (stride < 0) { 318 _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" ); 319 return; 320 } 321 322 switch (type) { 323 case GL_UNSIGNED_BYTE: 324 elementSize = sizeof(GLubyte); 325 break; 326 case GL_SHORT: 327 elementSize = sizeof(GLshort); 328 break; 329 case GL_INT: 330 elementSize = sizeof(GLint); 331 break; 332 case GL_FLOAT: 333 elementSize = sizeof(GLfloat); 334 break; 335 case GL_DOUBLE: 336 elementSize = sizeof(GLdouble); 337 break; 338 default: 339 _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" ); 340 return; 341 } 342 343 update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, 344 elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr); 345} 346 347 348void GLAPIENTRY 349_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, 350 GLsizei stride, const GLvoid *ptr) 351{ 352 GLsizei elementSize; 353 GLenum format; 354 GET_CURRENT_CONTEXT(ctx); 355 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 356 357 if (size != 3 && size != 4) { 358 if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) { 359 _mesa_error(ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)"); 360 return; 361 } 362 } 363 if (stride < 0) { 364 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" ); 365 return; 366 } 367 368 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 369 _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n", 370 size, _mesa_lookup_enum_by_nr( type ), stride); 371 372 if (size == GL_BGRA) { 373 if (type != GL_UNSIGNED_BYTE) { 374 _mesa_error(ctx, GL_INVALID_VALUE, "glColorPointer(GL_BGRA/GLubyte)"); 375 return; 376 } 377 format = GL_BGRA; 378 size = 4; 379 } 380 else { 381 format = GL_RGBA; 382 } 383 384 switch (type) { 385 case GL_BYTE: 386 elementSize = size * sizeof(GLbyte); 387 break; 388 case GL_UNSIGNED_BYTE: 389 elementSize = size * sizeof(GLubyte); 390 break; 391 case GL_SHORT: 392 elementSize = size * sizeof(GLshort); 393 break; 394 case GL_UNSIGNED_SHORT: 395 elementSize = size * sizeof(GLushort); 396 break; 397 case GL_INT: 398 elementSize = size * sizeof(GLint); 399 break; 400 case GL_UNSIGNED_INT: 401 elementSize = size * sizeof(GLuint); 402 break; 403 case GL_FLOAT: 404 elementSize = size * sizeof(GLfloat); 405 break; 406 case GL_DOUBLE: 407 elementSize = size * sizeof(GLdouble); 408 break; 409 case GL_HALF_FLOAT: 410 elementSize = size * sizeof(GLhalfARB); 411 break; 412 default: 413 _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)", 414 _mesa_lookup_enum_by_nr(type)); 415 return; 416 } 417 418 update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1, 419 elementSize, size, type, format, stride, GL_TRUE, ptr); 420} 421 422 423void GLAPIENTRY 424_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, 425 const GLvoid *ptr) 426{ 427 GLint elementSize; 428 GET_CURRENT_CONTEXT(ctx); 429 const GLuint unit = ctx->Array.ActiveTexture; 430 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 431 432 if (size < 1 || size > 4) { 433 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); 434 return; 435 } 436 if (stride < 0) { 437 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); 438 return; 439 } 440 441 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) 442 _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n", 443 unit, size, _mesa_lookup_enum_by_nr( type ), stride); 444 445 /* always need to check that <type> is legal */ 446 switch (type) { 447 case GL_SHORT: 448 elementSize = size * sizeof(GLshort); 449 break; 450 case GL_INT: 451 elementSize = size * sizeof(GLint); 452 break; 453 case GL_FLOAT: 454 elementSize = size * sizeof(GLfloat); 455 break; 456 case GL_DOUBLE: 457 elementSize = size * sizeof(GLdouble); 458 break; 459 case GL_HALF_FLOAT: 460 elementSize = size * sizeof(GLhalfARB); 461 break; 462#if FEATURE_fixedpt 463 case GL_FIXED: 464 elementSize = size * sizeof(GLfixed); 465 break; 466#endif 467#if FEATURE_vertex_array_byte 468 case GL_BYTE: 469 elementSize = size * sizeof(GLbyte); 470 break; 471#endif 472 default: 473 _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)", 474 _mesa_lookup_enum_by_nr(type)); 475 return; 476 } 477 478 ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord)); 479 480 update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit], 481 _NEW_ARRAY_TEXCOORD(unit), 482 elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr); 483} 484 485 486void GLAPIENTRY 487_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) 488{ 489 GET_CURRENT_CONTEXT(ctx); 490 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 491 492 if (stride < 0) { 493 _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" ); 494 return; 495 } 496 497 update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, 498 sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, GL_RGBA, 499 stride, GL_FALSE, ptr); 500} 501 502 503void GLAPIENTRY 504_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) 505{ 506 GLsizei elementSize; 507 GET_CURRENT_CONTEXT(ctx); 508 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 509 510 if (stride < 0) { 511 _mesa_error( ctx, GL_INVALID_VALUE, "glPointSizePointer(stride)" ); 512 return; 513 } 514 515 switch (type) { 516 case GL_FLOAT: 517 elementSize = sizeof(GLfloat); 518 break; 519#if FEATURE_fixedpt 520 case GL_FIXED: 521 elementSize = sizeof(GLfixed); 522 break; 523#endif 524 default: 525 _mesa_error( ctx, GL_INVALID_ENUM, "glPointSizePointer(type)" ); 526 return; 527 } 528 529 update_array(ctx, &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE, 530 elementSize, 1, type, GL_RGBA, stride, GL_FALSE, ptr); 531} 532 533 534#if FEATURE_NV_vertex_program 535/** 536 * Set a vertex attribute array. 537 * Note that these arrays DO alias the conventional GL vertex arrays 538 * (position, normal, color, fog, texcoord, etc). 539 * The generic attribute slots at #16 and above are not touched. 540 */ 541void GLAPIENTRY 542_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, 543 GLsizei stride, const GLvoid *ptr) 544{ 545 GLboolean normalized = GL_FALSE; 546 GLsizei elementSize; 547 GLenum format; 548 GET_CURRENT_CONTEXT(ctx); 549 ASSERT_OUTSIDE_BEGIN_END(ctx); 550 551 if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { 552 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); 553 return; 554 } 555 556 if (size < 1 || size > 4) { 557 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)"); 558 return; 559 } 560 561 if (stride < 0) { 562 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)"); 563 return; 564 } 565 566 if (type == GL_UNSIGNED_BYTE && size != 4) { 567 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); 568 return; 569 } 570 571 if (size == GL_BGRA) { 572 if (type != GL_UNSIGNED_BYTE) { 573 _mesa_error(ctx, GL_INVALID_VALUE, 574 "glVertexAttribPointerNV(GL_BGRA/type)"); 575 return; 576 } 577 578 format = GL_BGRA; 579 size = 4; 580 normalized = GL_TRUE; 581 } 582 else { 583 format = GL_RGBA; 584 } 585 586 /* check for valid 'type' and compute StrideB right away */ 587 switch (type) { 588 case GL_UNSIGNED_BYTE: 589 normalized = GL_TRUE; 590 elementSize = size * sizeof(GLubyte); 591 break; 592 case GL_SHORT: 593 elementSize = size * sizeof(GLshort); 594 break; 595 case GL_FLOAT: 596 elementSize = size * sizeof(GLfloat); 597 break; 598 case GL_DOUBLE: 599 elementSize = size * sizeof(GLdouble); 600 break; 601 default: 602 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)", 603 _mesa_lookup_enum_by_nr(type)); 604 return; 605 } 606 607 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 608 _NEW_ARRAY_ATTRIB(index), 609 elementSize, size, type, format, stride, normalized, ptr); 610} 611#endif 612 613 614#if FEATURE_ARB_vertex_program 615/** 616 * Set a generic vertex attribute array. 617 * Note that these arrays DO NOT alias the conventional GL vertex arrays 618 * (position, normal, color, fog, texcoord, etc). 619 */ 620void GLAPIENTRY 621_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, 622 GLboolean normalized, 623 GLsizei stride, const GLvoid *ptr) 624{ 625 GLsizei elementSize; 626 GLenum format; 627 GET_CURRENT_CONTEXT(ctx); 628 ASSERT_OUTSIDE_BEGIN_END(ctx); 629 630 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 631 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); 632 return; 633 } 634 635 if (size < 1 || size > 4) { 636 if (!ctx->Extensions.EXT_vertex_array_bgra || size != GL_BGRA) { 637 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)"); 638 return; 639 } 640 } 641 642 if (stride < 0) { 643 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)"); 644 return; 645 } 646 647 if (size == GL_BGRA) { 648 if (type != GL_UNSIGNED_BYTE) { 649 _mesa_error(ctx, GL_INVALID_VALUE, 650 "glVertexAttribPointerARB(GL_BGRA/type)"); 651 return; 652 } 653 if (normalized != GL_TRUE) { 654 _mesa_error(ctx, GL_INVALID_VALUE, 655 "glVertexAttribPointerARB(GL_BGRA/normalized)"); 656 return; 657 } 658 659 format = GL_BGRA; 660 size = 4; 661 } 662 else { 663 format = GL_RGBA; 664 } 665 666 /* check for valid 'type' and compute StrideB right away */ 667 /* NOTE: more types are supported here than in the NV extension */ 668 switch (type) { 669 case GL_BYTE: 670 elementSize = size * sizeof(GLbyte); 671 break; 672 case GL_UNSIGNED_BYTE: 673 elementSize = size * sizeof(GLubyte); 674 break; 675 case GL_SHORT: 676 elementSize = size * sizeof(GLshort); 677 break; 678 case GL_UNSIGNED_SHORT: 679 elementSize = size * sizeof(GLushort); 680 break; 681 case GL_INT: 682 elementSize = size * sizeof(GLint); 683 break; 684 case GL_UNSIGNED_INT: 685 elementSize = size * sizeof(GLuint); 686 break; 687 case GL_FLOAT: 688 elementSize = size * sizeof(GLfloat); 689 break; 690 case GL_DOUBLE: 691 elementSize = size * sizeof(GLdouble); 692 break; 693 case GL_HALF_FLOAT: 694 elementSize = size * sizeof(GLhalfARB); 695 break; 696#if FEATURE_fixedpt 697 case GL_FIXED: 698 elementSize = size * sizeof(GLfixed); 699 break; 700#endif 701 default: 702 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" ); 703 return; 704 } 705 706 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 707 _NEW_ARRAY_ATTRIB(index), 708 elementSize, size, type, format, stride, normalized, ptr); 709} 710#endif 711 712 713void GLAPIENTRY 714_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 715 GLsizei count, const GLvoid *ptr) 716{ 717 (void) count; 718 _mesa_VertexPointer(size, type, stride, ptr); 719} 720 721 722void GLAPIENTRY 723_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 724 const GLvoid *ptr) 725{ 726 (void) count; 727 _mesa_NormalPointer(type, stride, ptr); 728} 729 730 731void GLAPIENTRY 732_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 733 const GLvoid *ptr) 734{ 735 (void) count; 736 _mesa_ColorPointer(size, type, stride, ptr); 737} 738 739 740void GLAPIENTRY 741_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 742 const GLvoid *ptr) 743{ 744 (void) count; 745 _mesa_IndexPointer(type, stride, ptr); 746} 747 748 749void GLAPIENTRY 750_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 751 GLsizei count, const GLvoid *ptr) 752{ 753 (void) count; 754 _mesa_TexCoordPointer(size, type, stride, ptr); 755} 756 757 758void GLAPIENTRY 759_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 760{ 761 (void) count; 762 _mesa_EdgeFlagPointer(stride, ptr); 763} 764 765 766void GLAPIENTRY 767_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 768{ 769 GET_CURRENT_CONTEXT(ctx); 770 GLboolean tflag, cflag, nflag; /* enable/disable flags */ 771 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ 772 GLenum ctype = 0; /* color type */ 773 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ 774 const GLint toffset = 0; /* always zero */ 775 GLint defstride; /* default stride */ 776 GLint c, f; 777 778 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 779 780 f = sizeof(GLfloat); 781 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 782 783 if (stride < 0) { 784 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 785 return; 786 } 787 788 switch (format) { 789 case GL_V2F: 790 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 791 tcomps = 0; ccomps = 0; vcomps = 2; 792 voffset = 0; 793 defstride = 2*f; 794 break; 795 case GL_V3F: 796 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 797 tcomps = 0; ccomps = 0; vcomps = 3; 798 voffset = 0; 799 defstride = 3*f; 800 break; 801 case GL_C4UB_V2F: 802 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 803 tcomps = 0; ccomps = 4; vcomps = 2; 804 ctype = GL_UNSIGNED_BYTE; 805 coffset = 0; 806 voffset = c; 807 defstride = c + 2*f; 808 break; 809 case GL_C4UB_V3F: 810 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 811 tcomps = 0; ccomps = 4; vcomps = 3; 812 ctype = GL_UNSIGNED_BYTE; 813 coffset = 0; 814 voffset = c; 815 defstride = c + 3*f; 816 break; 817 case GL_C3F_V3F: 818 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 819 tcomps = 0; ccomps = 3; vcomps = 3; 820 ctype = GL_FLOAT; 821 coffset = 0; 822 voffset = 3*f; 823 defstride = 6*f; 824 break; 825 case GL_N3F_V3F: 826 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; 827 tcomps = 0; ccomps = 0; vcomps = 3; 828 noffset = 0; 829 voffset = 3*f; 830 defstride = 6*f; 831 break; 832 case GL_C4F_N3F_V3F: 833 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; 834 tcomps = 0; ccomps = 4; vcomps = 3; 835 ctype = GL_FLOAT; 836 coffset = 0; 837 noffset = 4*f; 838 voffset = 7*f; 839 defstride = 10*f; 840 break; 841 case GL_T2F_V3F: 842 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 843 tcomps = 2; ccomps = 0; vcomps = 3; 844 voffset = 2*f; 845 defstride = 5*f; 846 break; 847 case GL_T4F_V4F: 848 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 849 tcomps = 4; ccomps = 0; vcomps = 4; 850 voffset = 4*f; 851 defstride = 8*f; 852 break; 853 case GL_T2F_C4UB_V3F: 854 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 855 tcomps = 2; ccomps = 4; vcomps = 3; 856 ctype = GL_UNSIGNED_BYTE; 857 coffset = 2*f; 858 voffset = c+2*f; 859 defstride = c+5*f; 860 break; 861 case GL_T2F_C3F_V3F: 862 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 863 tcomps = 2; ccomps = 3; vcomps = 3; 864 ctype = GL_FLOAT; 865 coffset = 2*f; 866 voffset = 5*f; 867 defstride = 8*f; 868 break; 869 case GL_T2F_N3F_V3F: 870 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; 871 tcomps = 2; ccomps = 0; vcomps = 3; 872 noffset = 2*f; 873 voffset = 5*f; 874 defstride = 8*f; 875 break; 876 case GL_T2F_C4F_N3F_V3F: 877 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 878 tcomps = 2; ccomps = 4; vcomps = 3; 879 ctype = GL_FLOAT; 880 coffset = 2*f; 881 noffset = 6*f; 882 voffset = 9*f; 883 defstride = 12*f; 884 break; 885 case GL_T4F_C4F_N3F_V4F: 886 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 887 tcomps = 4; ccomps = 4; vcomps = 4; 888 ctype = GL_FLOAT; 889 coffset = 4*f; 890 noffset = 8*f; 891 voffset = 11*f; 892 defstride = 15*f; 893 break; 894 default: 895 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 896 return; 897 } 898 899 if (stride==0) { 900 stride = defstride; 901 } 902 903 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 904 _mesa_DisableClientState( GL_INDEX_ARRAY ); 905 /* XXX also disable secondary color and generic arrays? */ 906 907 /* Texcoords */ 908 if (tflag) { 909 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 910 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, 911 (GLubyte *) pointer + toffset ); 912 } 913 else { 914 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 915 } 916 917 /* Color */ 918 if (cflag) { 919 _mesa_EnableClientState( GL_COLOR_ARRAY ); 920 _mesa_ColorPointer( ccomps, ctype, stride, 921 (GLubyte *) pointer + coffset ); 922 } 923 else { 924 _mesa_DisableClientState( GL_COLOR_ARRAY ); 925 } 926 927 928 /* Normals */ 929 if (nflag) { 930 _mesa_EnableClientState( GL_NORMAL_ARRAY ); 931 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); 932 } 933 else { 934 _mesa_DisableClientState( GL_NORMAL_ARRAY ); 935 } 936 937 /* Vertices */ 938 _mesa_EnableClientState( GL_VERTEX_ARRAY ); 939 _mesa_VertexPointer( vcomps, GL_FLOAT, stride, 940 (GLubyte *) pointer + voffset ); 941} 942 943 944void GLAPIENTRY 945_mesa_LockArraysEXT(GLint first, GLsizei count) 946{ 947 GET_CURRENT_CONTEXT(ctx); 948 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 949 950 if (MESA_VERBOSE & VERBOSE_API) 951 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 952 953 if (first < 0) { 954 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 955 return; 956 } 957 if (count <= 0) { 958 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 959 return; 960 } 961 if (ctx->Array.LockCount != 0) { 962 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 963 return; 964 } 965 966 ctx->Array.LockFirst = first; 967 ctx->Array.LockCount = count; 968 969 ctx->NewState |= _NEW_ARRAY; 970 ctx->Array.NewState |= _NEW_ARRAY_ALL; 971} 972 973 974void GLAPIENTRY 975_mesa_UnlockArraysEXT( void ) 976{ 977 GET_CURRENT_CONTEXT(ctx); 978 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 979 980 if (MESA_VERBOSE & VERBOSE_API) 981 _mesa_debug(ctx, "glUnlockArrays\n"); 982 983 if (ctx->Array.LockCount == 0) { 984 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 985 return; 986 } 987 988 ctx->Array.LockFirst = 0; 989 ctx->Array.LockCount = 0; 990 ctx->NewState |= _NEW_ARRAY; 991 ctx->Array.NewState |= _NEW_ARRAY_ALL; 992} 993 994 995/* GL_EXT_multi_draw_arrays */ 996/* Somebody forgot to spec the first and count parameters as const! <sigh> */ 997void GLAPIENTRY 998_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first, 999 GLsizei *count, GLsizei primcount ) 1000{ 1001 GET_CURRENT_CONTEXT(ctx); 1002 GLint i; 1003 1004 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1005 1006 for (i = 0; i < primcount; i++) { 1007 if (count[i] > 0) { 1008 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i])); 1009 } 1010 } 1011} 1012 1013 1014/* GL_IBM_multimode_draw_arrays */ 1015void GLAPIENTRY 1016_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 1017 const GLsizei * count, 1018 GLsizei primcount, GLint modestride ) 1019{ 1020 GET_CURRENT_CONTEXT(ctx); 1021 GLint i; 1022 1023 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1024 1025 for ( i = 0 ; i < primcount ; i++ ) { 1026 if ( count[i] > 0 ) { 1027 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 1028 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] )); 1029 } 1030 } 1031} 1032 1033 1034/* GL_IBM_multimode_draw_arrays */ 1035void GLAPIENTRY 1036_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 1037 GLenum type, const GLvoid * const * indices, 1038 GLsizei primcount, GLint modestride ) 1039{ 1040 GET_CURRENT_CONTEXT(ctx); 1041 GLint i; 1042 1043 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1044 1045 /* XXX not sure about ARB_vertex_buffer_object handling here */ 1046 1047 for ( i = 0 ; i < primcount ; i++ ) { 1048 if ( count[i] > 0 ) { 1049 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 1050 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] )); 1051 } 1052 } 1053} 1054 1055 1056/** 1057 * Copy one client vertex array to another. 1058 */ 1059void 1060_mesa_copy_client_array(GLcontext *ctx, 1061 struct gl_client_array *dst, 1062 struct gl_client_array *src) 1063{ 1064 dst->Size = src->Size; 1065 dst->Type = src->Type; 1066 dst->Format = src->Format; 1067 dst->Stride = src->Stride; 1068 dst->StrideB = src->StrideB; 1069 dst->Ptr = src->Ptr; 1070 dst->Enabled = src->Enabled; 1071 dst->Normalized = src->Normalized; 1072 dst->_ElementSize = src->_ElementSize; 1073 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1074 dst->_MaxElement = src->_MaxElement; 1075} 1076 1077 1078 1079/** 1080 * Print vertex array's fields. 1081 */ 1082static void 1083print_array(const char *name, GLint index, const struct gl_client_array *array) 1084{ 1085 if (index >= 0) 1086 printf(" %s[%d]: ", name, index); 1087 else 1088 printf(" %s: ", name); 1089 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %u), MaxElem=%u\n", 1090 array->Ptr, array->Type, array->Size, 1091 array->_ElementSize, array->StrideB, 1092 array->BufferObj->Name, array->BufferObj->Size, 1093 array->_MaxElement); 1094} 1095 1096 1097/** 1098 * Print current vertex object/array info. For debug. 1099 */ 1100void 1101_mesa_print_arrays(GLcontext *ctx) 1102{ 1103 struct gl_array_object *arrayObj = ctx->Array.ArrayObj; 1104 GLuint i; 1105 1106 _mesa_update_array_object_max_element(ctx, arrayObj); 1107 1108 printf("Array Object %u\n", arrayObj->Name); 1109 if (arrayObj->Vertex.Enabled) 1110 print_array("Vertex", -1, &arrayObj->Vertex); 1111 if (arrayObj->Normal.Enabled) 1112 print_array("Normal", -1, &arrayObj->Normal); 1113 if (arrayObj->Color.Enabled) 1114 print_array("Color", -1, &arrayObj->Color); 1115 for (i = 0; i < Elements(arrayObj->TexCoord); i++) 1116 if (arrayObj->TexCoord[i].Enabled) 1117 print_array("TexCoord", i, &arrayObj->TexCoord[i]); 1118 for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) 1119 if (arrayObj->VertexAttrib[i].Enabled) 1120 print_array("Attrib", i, &arrayObj->VertexAttrib[i]); 1121 printf(" _MaxElement = %u\n", arrayObj->_MaxElement); 1122} 1123 1124 1125/** 1126 * Initialize vertex array state for given context. 1127 */ 1128void 1129_mesa_init_varray(GLcontext *ctx) 1130{ 1131 ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); 1132 _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, 1133 ctx->Array.DefaultArrayObj); 1134 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 1135 1136 ctx->Array.Objects = _mesa_NewHashTable(); 1137} 1138 1139 1140/** 1141 * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). 1142 */ 1143static void 1144delete_arrayobj_cb(GLuint id, void *data, void *userData) 1145{ 1146 struct gl_array_object *arrayObj = (struct gl_array_object *) data; 1147 GLcontext *ctx = (GLcontext *) userData; 1148 _mesa_delete_array_object(ctx, arrayObj); 1149} 1150 1151 1152/** 1153 * Free vertex array state for given context. 1154 */ 1155void 1156_mesa_free_varray_data(GLcontext *ctx) 1157{ 1158 _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); 1159 _mesa_DeleteHashTable(ctx->Array.Objects); 1160} 1161