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