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