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