varray.c revision d17485fef9b084a6812c626d9734816429f29199
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 466#if FEATURE_NV_vertex_program 467void GLAPIENTRY 468_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, 469 GLsizei stride, const GLvoid *ptr) 470{ 471 GLboolean normalized = GL_FALSE; 472 GLsizei elementSize; 473 GET_CURRENT_CONTEXT(ctx); 474 ASSERT_OUTSIDE_BEGIN_END(ctx); 475 476 if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { 477 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); 478 return; 479 } 480 481 if (size < 1 || size > 4) { 482 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)"); 483 return; 484 } 485 486 if (stride < 0) { 487 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)"); 488 return; 489 } 490 491 if (type == GL_UNSIGNED_BYTE && size != 4) { 492 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); 493 return; 494 } 495 496 /* check for valid 'type' and compute StrideB right away */ 497 switch (type) { 498 case GL_UNSIGNED_BYTE: 499 normalized = GL_TRUE; 500 elementSize = size * sizeof(GLubyte); 501 break; 502 case GL_SHORT: 503 elementSize = size * sizeof(GLshort); 504 break; 505 case GL_FLOAT: 506 elementSize = size * sizeof(GLfloat); 507 break; 508 case GL_DOUBLE: 509 elementSize = size * sizeof(GLdouble); 510 break; 511 default: 512 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" ); 513 return; 514 } 515 516 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 517 _NEW_ARRAY_ATTRIB(index), 518 elementSize, size, type, stride, normalized, ptr); 519 520 if (ctx->Driver.VertexAttribPointer) 521 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr ); 522} 523#endif 524 525 526#if FEATURE_ARB_vertex_program 527void GLAPIENTRY 528_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, 529 GLboolean normalized, 530 GLsizei stride, const GLvoid *ptr) 531{ 532 GLsizei elementSize; 533 GET_CURRENT_CONTEXT(ctx); 534 ASSERT_OUTSIDE_BEGIN_END(ctx); 535 536 if (index >= ctx->Const.VertexProgram.MaxAttribs) { 537 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); 538 return; 539 } 540 541 if (size < 1 || size > 4) { 542 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)"); 543 return; 544 } 545 546 if (stride < 0) { 547 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)"); 548 return; 549 } 550 551 /* check for valid 'type' and compute StrideB right away */ 552 /* NOTE: more types are supported here than in the NV extension */ 553 switch (type) { 554 case GL_BYTE: 555 elementSize = size * sizeof(GLbyte); 556 break; 557 case GL_UNSIGNED_BYTE: 558 elementSize = size * sizeof(GLubyte); 559 break; 560 case GL_SHORT: 561 elementSize = size * sizeof(GLshort); 562 break; 563 case GL_UNSIGNED_SHORT: 564 elementSize = size * sizeof(GLushort); 565 break; 566 case GL_INT: 567 elementSize = size * sizeof(GLint); 568 break; 569 case GL_UNSIGNED_INT: 570 elementSize = size * sizeof(GLuint); 571 break; 572 case GL_FLOAT: 573 elementSize = size * sizeof(GLfloat); 574 break; 575 case GL_DOUBLE: 576 elementSize = size * sizeof(GLdouble); 577 break; 578 default: 579 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" ); 580 return; 581 } 582 583 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index], 584 _NEW_ARRAY_ATTRIB(index), 585 elementSize, size, type, stride, normalized, ptr); 586 587 if (ctx->Driver.VertexAttribPointer) 588 ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr); 589} 590#endif 591 592 593void GLAPIENTRY 594_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, 595 GLsizei count, const GLvoid *ptr) 596{ 597 (void) count; 598 _mesa_VertexPointer(size, type, stride, ptr); 599} 600 601 602void GLAPIENTRY 603_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, 604 const GLvoid *ptr) 605{ 606 (void) count; 607 _mesa_NormalPointer(type, stride, ptr); 608} 609 610 611void GLAPIENTRY 612_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, 613 const GLvoid *ptr) 614{ 615 (void) count; 616 _mesa_ColorPointer(size, type, stride, ptr); 617} 618 619 620void GLAPIENTRY 621_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, 622 const GLvoid *ptr) 623{ 624 (void) count; 625 _mesa_IndexPointer(type, stride, ptr); 626} 627 628 629void GLAPIENTRY 630_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, 631 GLsizei count, const GLvoid *ptr) 632{ 633 (void) count; 634 _mesa_TexCoordPointer(size, type, stride, ptr); 635} 636 637 638void GLAPIENTRY 639_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) 640{ 641 (void) count; 642 _mesa_EdgeFlagPointer(stride, ptr); 643} 644 645 646void GLAPIENTRY 647_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) 648{ 649 GET_CURRENT_CONTEXT(ctx); 650 GLboolean tflag, cflag, nflag; /* enable/disable flags */ 651 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ 652 GLenum ctype = 0; /* color type */ 653 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ 654 const GLint toffset = 0; /* always zero */ 655 GLint defstride; /* default stride */ 656 GLint c, f; 657 658 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 659 660 f = sizeof(GLfloat); 661 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); 662 663 if (stride < 0) { 664 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); 665 return; 666 } 667 668 switch (format) { 669 case GL_V2F: 670 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 671 tcomps = 0; ccomps = 0; vcomps = 2; 672 voffset = 0; 673 defstride = 2*f; 674 break; 675 case GL_V3F: 676 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; 677 tcomps = 0; ccomps = 0; vcomps = 3; 678 voffset = 0; 679 defstride = 3*f; 680 break; 681 case GL_C4UB_V2F: 682 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 683 tcomps = 0; ccomps = 4; vcomps = 2; 684 ctype = GL_UNSIGNED_BYTE; 685 coffset = 0; 686 voffset = c; 687 defstride = c + 2*f; 688 break; 689 case GL_C4UB_V3F: 690 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 691 tcomps = 0; ccomps = 4; vcomps = 3; 692 ctype = GL_UNSIGNED_BYTE; 693 coffset = 0; 694 voffset = c; 695 defstride = c + 3*f; 696 break; 697 case GL_C3F_V3F: 698 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; 699 tcomps = 0; ccomps = 3; vcomps = 3; 700 ctype = GL_FLOAT; 701 coffset = 0; 702 voffset = 3*f; 703 defstride = 6*f; 704 break; 705 case GL_N3F_V3F: 706 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; 707 tcomps = 0; ccomps = 0; vcomps = 3; 708 noffset = 0; 709 voffset = 3*f; 710 defstride = 6*f; 711 break; 712 case GL_C4F_N3F_V3F: 713 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; 714 tcomps = 0; ccomps = 4; vcomps = 3; 715 ctype = GL_FLOAT; 716 coffset = 0; 717 noffset = 4*f; 718 voffset = 7*f; 719 defstride = 10*f; 720 break; 721 case GL_T2F_V3F: 722 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 723 tcomps = 2; ccomps = 0; vcomps = 3; 724 voffset = 2*f; 725 defstride = 5*f; 726 break; 727 case GL_T4F_V4F: 728 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; 729 tcomps = 4; ccomps = 0; vcomps = 4; 730 voffset = 4*f; 731 defstride = 8*f; 732 break; 733 case GL_T2F_C4UB_V3F: 734 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 735 tcomps = 2; ccomps = 4; vcomps = 3; 736 ctype = GL_UNSIGNED_BYTE; 737 coffset = 2*f; 738 voffset = c+2*f; 739 defstride = c+5*f; 740 break; 741 case GL_T2F_C3F_V3F: 742 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; 743 tcomps = 2; ccomps = 3; vcomps = 3; 744 ctype = GL_FLOAT; 745 coffset = 2*f; 746 voffset = 5*f; 747 defstride = 8*f; 748 break; 749 case GL_T2F_N3F_V3F: 750 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; 751 tcomps = 2; ccomps = 0; vcomps = 3; 752 noffset = 2*f; 753 voffset = 5*f; 754 defstride = 8*f; 755 break; 756 case GL_T2F_C4F_N3F_V3F: 757 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 758 tcomps = 2; ccomps = 4; vcomps = 3; 759 ctype = GL_FLOAT; 760 coffset = 2*f; 761 noffset = 6*f; 762 voffset = 9*f; 763 defstride = 12*f; 764 break; 765 case GL_T4F_C4F_N3F_V4F: 766 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; 767 tcomps = 4; ccomps = 4; vcomps = 4; 768 ctype = GL_FLOAT; 769 coffset = 4*f; 770 noffset = 8*f; 771 voffset = 11*f; 772 defstride = 15*f; 773 break; 774 default: 775 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); 776 return; 777 } 778 779 if (stride==0) { 780 stride = defstride; 781 } 782 783 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); 784 _mesa_DisableClientState( GL_INDEX_ARRAY ); 785 /* XXX also disable secondary color and generic arrays? */ 786 787 /* Texcoords */ 788 if (tflag) { 789 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); 790 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, 791 (GLubyte *) pointer + toffset ); 792 } 793 else { 794 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); 795 } 796 797 /* Color */ 798 if (cflag) { 799 _mesa_EnableClientState( GL_COLOR_ARRAY ); 800 _mesa_ColorPointer( ccomps, ctype, stride, 801 (GLubyte *) pointer + coffset ); 802 } 803 else { 804 _mesa_DisableClientState( GL_COLOR_ARRAY ); 805 } 806 807 808 /* Normals */ 809 if (nflag) { 810 _mesa_EnableClientState( GL_NORMAL_ARRAY ); 811 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); 812 } 813 else { 814 _mesa_DisableClientState( GL_NORMAL_ARRAY ); 815 } 816 817 /* Vertices */ 818 _mesa_EnableClientState( GL_VERTEX_ARRAY ); 819 _mesa_VertexPointer( vcomps, GL_FLOAT, stride, 820 (GLubyte *) pointer + voffset ); 821} 822 823 824void GLAPIENTRY 825_mesa_LockArraysEXT(GLint first, GLsizei count) 826{ 827 GET_CURRENT_CONTEXT(ctx); 828 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 829 830 if (MESA_VERBOSE & VERBOSE_API) 831 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); 832 833 if (first < 0) { 834 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); 835 return; 836 } 837 if (count <= 0) { 838 _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); 839 return; 840 } 841 if (ctx->Array.LockCount != 0) { 842 _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); 843 return; 844 } 845 846 ctx->Array.LockFirst = first; 847 ctx->Array.LockCount = count; 848 849 ctx->NewState |= _NEW_ARRAY; 850 ctx->Array.NewState |= _NEW_ARRAY_ALL; 851 852 if (ctx->Driver.LockArraysEXT) 853 ctx->Driver.LockArraysEXT( ctx, first, count ); 854} 855 856 857void GLAPIENTRY 858_mesa_UnlockArraysEXT( void ) 859{ 860 GET_CURRENT_CONTEXT(ctx); 861 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 862 863 if (MESA_VERBOSE & VERBOSE_API) 864 _mesa_debug(ctx, "glUnlockArrays\n"); 865 866 if (ctx->Array.LockCount == 0) { 867 _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); 868 return; 869 } 870 871 ctx->Array.LockFirst = 0; 872 ctx->Array.LockCount = 0; 873 ctx->NewState |= _NEW_ARRAY; 874 ctx->Array.NewState |= _NEW_ARRAY_ALL; 875 876 if (ctx->Driver.UnlockArraysEXT) 877 ctx->Driver.UnlockArraysEXT( ctx ); 878} 879 880 881/* GL_EXT_multi_draw_arrays */ 882/* Somebody forgot to spec the first and count parameters as const! <sigh> */ 883void GLAPIENTRY 884_mesa_MultiDrawArraysEXT( GLenum mode, GLint *first, 885 GLsizei *count, GLsizei primcount ) 886{ 887 GET_CURRENT_CONTEXT(ctx); 888 GLint i; 889 890 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 891 892 for (i = 0; i < primcount; i++) { 893 if (count[i] > 0) { 894 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i])); 895 } 896 } 897} 898 899 900/* GL_EXT_multi_draw_arrays */ 901void GLAPIENTRY 902_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, 903 const GLvoid **indices, GLsizei primcount ) 904{ 905 GET_CURRENT_CONTEXT(ctx); 906 GLint i; 907 908 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 909 910 for (i = 0; i < primcount; i++) { 911 if (count[i] > 0) { 912 CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i])); 913 } 914 } 915} 916 917 918/* GL_IBM_multimode_draw_arrays */ 919void GLAPIENTRY 920_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, 921 const GLsizei * count, 922 GLsizei primcount, GLint modestride ) 923{ 924 GET_CURRENT_CONTEXT(ctx); 925 GLint i; 926 927 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 928 929 for ( i = 0 ; i < primcount ; i++ ) { 930 if ( count[i] > 0 ) { 931 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 932 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] )); 933 } 934 } 935} 936 937 938/* GL_IBM_multimode_draw_arrays */ 939void GLAPIENTRY 940_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, 941 GLenum type, const GLvoid * const * indices, 942 GLsizei primcount, GLint modestride ) 943{ 944 GET_CURRENT_CONTEXT(ctx); 945 GLint i; 946 947 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 948 949 /* XXX not sure about ARB_vertex_buffer_object handling here */ 950 951 for ( i = 0 ; i < primcount ; i++ ) { 952 if ( count[i] > 0 ) { 953 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); 954 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] )); 955 } 956 } 957} 958 959 960/** 961 * Initialize vertex array state for given context. 962 */ 963void 964_mesa_init_varray(GLcontext *ctx) 965{ 966 ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); 967 ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj; 968 969 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ 970} 971