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