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