1Name 2 3 ARB_matrix_palette 4 5Name Strings 6 7 GL_ARB_matrix_palette 8 9Contact 10 11 Jon Paul Schelter (jschelte 'at' matrox.com) 12 13Notice 14 15 Copyright (c) 2000-2013 The Khronos Group Inc. Copyright terms at 16 http://www.khronos.org/registry/speccopyright.html 17 18Specification Update Policy 19 20 Khronos-approved extension specifications are updated in response to 21 issues and bugs prioritized by the Khronos OpenGL Working Group. For 22 extensions which have been promoted to a core Specification, fixes will 23 first appear in the latest version of that core Specification, and will 24 eventually be backported to the extension document. This policy is 25 described in more detail at 26 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 27 28Status 29 30 Complete. Approved by ARB on December 5, 2000. 31 32Version 33 34 Date: 2004/04/02 35 Revision: 0.7 36 37Number 38 39 ARB Extension #16 40 41Dependencies 42 43 ARB_vertex_blend and OpenGL 1.0 are required. 44 This extension is written against the ARB_vertex_blend extended 45 OpenGL 1.2.1 Specification. 46 47Overview 48 49 This extension extends the abilities of ARB_vertex_blend to include 50 a palette of modelview matrices. The n vertex units use a palette 51 of m modelview matrices. (Where n and m are constrained to 52 implementation defined maxima.) Each vertex has a set of n 53 indices into the palette, and a corresponding set of n weights. 54 Matrix indices can be changed for each vertex (between Begin and 55 End). 56 57 When this extension is utilized, the enabled units transform each 58 vertex by the modelview matrices specified by the vertices' 59 respective indices. These results are subsequently scaled by the 60 weights of the respective units and then summed to create the 61 eyespace vertex. 62 63 A similar procedure is followed for normals. Normals, however, 64 are transformed by the inverse transpose of the modelview matrix. 65 66IP Status 67 68 Unknown, but believed to be none. 69 70Issues 71 72 73 Should the matrix palette be loaded by adding MODELVIEWm tokens 74 for MatrixMode? 75 76 No, this method is too difficult to extend to an arbitrary 77 (implementation defined) size palette, 78 and would imply having a 32 entry (minimum) stack per 79 matrix. 80 81 82 Should the Matrix palette be loaded with a new LoadMatrixPalette 83 command? 84 85 No, although this provides an easy way to support arbitrary 86 palette sizes, the method loses the current (MultMatrix, 87 Rotate, Translate, Scale..) matrix functionality. 88 89 Matrices will be Loaded into the palette with current 90 functions when MATRIX_MODE is MATRIX_PALETTE_ARB. The current 91 palette index is set by an explicit command: 92 CurrentPaletteMatrixARB(). 93 94 95 Should the Matrix Palette have a stack? 96 97 Not required, this wastes a lot of space. Define the min 98 stack depth for the MATRIX_PALETTE_ARB MatrixMode to be 1. 99 This alows some implementations to add a stack if desired. 100 101 The stacks established in ARB_vertex_blend for 102 MODELVIEW_MATRIXn are still present. 103 104 105 Should the matrix palette be gettable? 106 107 Yes, CurrentPaletteMatrixARB() and 108 GetIntegerv(CURRENT_PALETTE_MATRIX_ARB, *data) define which 109 matrix in the palette is returned by 110 GetFloatv(MATRIX_PALETTE_ARB, *data). 111 112 113 Should MatrixIndexARB be changed to imply LoadMatrix calls to the 114 applicable MODELVIEW_MATRIXn stacks? 115 116 No, the MODELVIEW_MATRIXn matrices are unused when 117 MATRIX_PALETTE is enabled. 118 119 120 Should there be a way to specify that the modelview matrices 121 for two different vertex units are identical? 122 123 Not explicitely, but indexing the matrix palette provides this 124 functionality. (Both units will have the same matrix index.) 125 126 Currently, the MATRIX_PALETTE_ARB enum is used to enable the 127 extension, to set the Matrix Mode, and to get the current matrix. 128 Is this confusing? Should more enums be added? 129 130 No. 131 132New Procedures and Functions 133 134 void CurrentPaletteMatrixARB(int index) 135 136 void MatrixIndex{ubusui}vARB(int size, T *indices) 137 138 void MatrixIndexPointerARB(int size, enum type, sizei stride, 139 void *pointer) 140 141 142New Tokens 143 144 Accepted by the <pname> parameters of GetFloatv, GetDoublev, 145 and IsEnabled, by the <mode> parameter of MatrixMode, and by the 146 <cap> parameters of Enable and Disable: 147 148 MATRIX_PALETTE_ARB: 0x8840 149 150 Accepted by the <pname> parameters of GetIntegerv, GetFloatv, and 151 GetDoublev: 152 153 MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 154 MAX_PALETTE_MATRICES_ARB 0x8842 155 CURRENT_PALETTE_MATRIX_ARB 0x8843 156 157 Accepted by the <cap> parameters of EnableClientState and 158 DisableClientState and by the <pname> parameter of IsEnabled: 159 160 MATRIX_INDEX_ARRAY_ARB: 0x8844 161 162 Accepted by the <pname> parameter of GetFloatv: 163 164 CURRENT_MATRIX_INDEX_ARB 0x8845 165 166 Accepted by the <pname> parameter of GetIntegerv: 167 MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 168 MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 169 MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 170 171 Accepted by the <pname> parameter of GetPointerv: 172 MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 173 174Additions to Chapter 2 of the OpenGL 1.2.1 Specification (Operation) 175 176 - (2.6, p. 12) Second paragraph changed to: 177 178 "Each vertex is specified with two, three, or four 179 coordinates. In addition, a current normal, current texture 180 coordinates, current color, current matrix indices, and 181 current weights may be used in processing each vertex. Normals 182 are used by the GL in lighting calculations; the current 183 normal is a three- dimensional vector that may be set by 184 sending three coordinates that specify it. Texture coordinates 185 determine how a texture image is mapped onto a 186 primitive. Indices are used to select modelview matrices 187 from the palette when blending is enabled. Weights are used 188 as blending factors when vertex blending is enabled. One 189 weight and one index exists for each enabled vertex blend 190 unit. Vertex units are enabled with Enable, and disabled 191 with Disable. Enabling or Disabling a vertex unit not 192 supported in the implementation results in the error 193 INVALID_OPERATION." 194 195 - (2.6.3, p. 19) First paragraph changed to: 196 197 "The only GL commands that are allowed within Begin/End 198 pairs are the commands for specifying vertex coordinates, 199 vertex color, normal coordinates, texture coordinates, matrix 200 indices, and weights (Vertex, Color, Index, Normal, TexCoord, 201 MatrixIndexARB, WeightARB), the ArrayElement command (see 202 section 2.8), the EvalCoord and EvalPoint commands (see 203 section 5.1), commands for specifying lighting material 204 parameters (Material commands; see section 2.13.2), display 205 list invocation commands (CallList and CallLists; see section 206 5.4), and the EdgeFlag command. Executing any other GL command 207 between the execution of Begin and the corresponding execution 208 of End results in the error INVALID_OPERATION. Executing Begin 209 after Begin has already been executed but before an End is 210 executed generates the INVALID_OPERATION error, as does 211 executing End without a previous corresponding Begin." 212 213 - (2.7, p. 20) Added after the third paragraph: 214 215 "The current weights are set using 216 217 void Weight{bsifd ubusui}vARB(int size, T *weights); 218 219 the floating point values are assigned to the current 220 weight vector. The first <size> current weights are 221 replaced with <weights> such that: 222 223 CURRENT_WEIGHT_ARB[i] = <weights>[i] 224 225 When WEIGHT_SUM_UNITY_ARB is enabled, 226 227 <size>-1 228 CURRENT_WEIGHT_ARB[<size>] = 1 - SUM <weights>[i] 229 i=0 230 231 otherwise the rest of the current weights are set to 0. If 232 <size> is greater than MAX_VERTEX_UNITS_ARB or if 233 WEIGHTS_SUM_UNITY_ARB is enabled and <size> equals 234 MAX_VERTEX_UNITS_ARB, then the error INVALID_VALUE is 235 generated. When the values are supplied as byte, short, or 236 int, they are converted to floating-point values as 237 indicated for the corresponting type in Table 2.6. 238 239 The current matrix indices are set using 240 241 void MatrixIndex{ubusui}vARB(int size, T *indices); 242 243 The specified indices are set to the first <size> Vertex 244 Unit index values. <size> indicates the count of matrix 245 indices in the <indices> array. 246 247 Note that vertex units which are disabled can still receive 248 weights and indices." 249 250 251 - (2.8, p. 21) First paragraph changed to read: 252 253 "The vertex specification commands described in section 2.7 254 accept data in almost any format, but their use requires 255 many command executions to specify even simple geometry. 256 Vertex data may also be placed into arrays that are stored 257 in the client's address space. Blocks of data in these 258 arrays may then be used to specify multiple geometric 259 primitives through the execution of a single GL command. 260 The client may specify an implementation dependent set of 261 arrays: one each to store edge flags, texture coordinates, 262 colors, color indices, normals, and vertices, weights, and 263 matrix indices. The commands 264 265 void EdgeFlagPointer( sizei stride, void *pointer); 266 267 void TexCoordPointer( int size, enum type, sizei stride, 268 void *pointer ); 269 270 void ColorPointer( int size, enum type, sizei stride, 271 void *pointer ); 272 273 void IndexPointer( enum type, sizei stride, void 274 *pointer ); 275 276 void NormalPointer( enum type, sizei stride, void 277 *pointer ); 278 279 void VertexPointer( int size, enum type, sizei stride, 280 void *pointer ); 281 282 void WeightPointerARB(int size, enum type, 283 sizei stride, void *pointer) 284 285 void MatrixIndexPointerARB(int size, enum type, 286 sizei stride, void *pointer) 287 288 describe the locations and organizations of these arrays. 289 For each command, type specifies the data type of the 290 values stored in the array. Because edge flags are always 291 type boolean, EdgeFlagPointer has no type argument. Size, 292 when present, indicates the number of values per vertex 293 that are stored in the array. Because normals are always 294 specified with three values, NormalPointer has no size 295 argument. Likewise, because color indices, and edge flags 296 are always specified with a single value, IndexPointer, and 297 EdgeFlagPointer also have no size argument. Table 2.4 298 indicates the allowable values for size and type (when 299 present). For type the values BYTE, SHORT, INT, FLOAT, and 300 DOUBLE indicates types byte, short, int, float, and double, 301 respectively; and the values UNSIGNED_BYTE, UNSIGNED_SHORT, 302 and UNSIGNED_INT indicate types ubyte, ushort, and uint, 303 respectively. The error INVALID_VALUE is generated if size 304 is specified with a value other than that indicated in the 305 table. For implementations supporting vertex blending, note 306 that <size> values for WeightPointerARB and 307 MatrixIndexPointerARB must be less than the implementation 308 defined value MAX_VERTEX_UNITS_ARB." 309 310 - (2.8, p. 22) Change table 2.4 to read: 311 312 Command Sizes Types 313 ------- ----- ----- 314 VertexPointer 2,3,4 short, int, float, 315 double 316 NormalPointer 3 byte, short, int, float, 317 double 318 ColorPointer 3,4 byte, ubyte, short, 319 ushort, int, uint, 320 float, double 321 IndexPointer 1 ubyte, short, int, 322 float, double 323 TexCoordPointer 1,2,3,4 short, int, float, 324 double 325 EdgeFlagPointer 1 boolean 326 WeightPointerARB 1..MAX_VERTEX byte, ubyte, short, 327 _UNITS_ARB ushort, int, uint, 328 float, double 329 330 MatrixIndexPointerARB 1..MAX_VERTEX unsigned byte, unsigned 331 _UNITS_ARB short, unsigned int 332 333 334 - (2.8 p. 23) Change paragraph two to: 335 336 "An individual array is enabled or disabled by calling one 337 of 338 339 void EnableClientState( enum array ); 340 void DisableClientState( enum array ); 341 342 with array set to EDGE_FLAG_ARRAY, TEXTURE_COORD_ARRAY, 343 COLOR_ARRAY, INDEX_ARRAY, NORMAL_ARRAY, VERTEX_ARRAY, 344 MATRIX_INDEX_ARRAY_ARB, or WEIGHT_ARRAY_ARB, for the edge 345 flag, texture coordinate, color, color index, normal, vertex, 346 matrix index, or weight array, respectively. " 347 348 - (2.8 p. 23) Change paragraph three to: 349 350 "The ith element of every enabled array is transferred to 351 the GL by calling 352 353 void ArrayElement( int i ); 354 355 For each enabled array, it is as though the corresponding 356 command from section 2.7 or 2.6.2 were called with a 357 pointer to element i. For the vertex array, the 358 corresponding command is Vertex[size][type]v, where size is 359 one of [2,3,4], and type is one of [s,i,f,d], corresponding 360 to array types short, int, float, and double respectively. 361 The corresponding commands for the edge flag, texture 362 coordinate, color, color index, normal, and weight arrays 363 are EdgeFlagv, TexCoord[size][type]v, Color[size][type]v, 364 Index[type]v, Normal[type]v, MatrixIndex[type]vARB, and 365 Weight[type]vARB, respectively. If the vertex array is 366 enabled, it is as though Vertex[size][type]v is executed last, 367 after the executions of the other corresponding commands." 368 369 - (2.10 p. 28) Edit to the last paragraph: 370 371 "Figure 2.6 diagrams the sequence of transformations that are 372 applied to vertices. The vertex coordinates that are 373 presented to the GL are termed object coordinates. The 374 model-view matrix is applied to these coordinates to yield eye 375 coordinates. In implementations with vertex blending, all 376 enabled modelview matrices are applied to these coordinates, 377 and the weighted sum of the results are the eye coordinates. 378 Then another matrix, called the projection matrix, is applied 379 to eye coordinates to yield clip coordinates. A perspective 380 division is carried out on clip coordinates to yield 381 normalized device coordinates. A final viewport 382 transformation is applied to convert these coordinates into 383 window coordinates." 384 385 - (2.10 p. 29) Edit to the second paragraph: 386 387 "... the vertex's eye coordinates are found as: 388 389 (xe) n-1 (xo) 390 (ye) = SUM w_i * M_i * (yo) 391 (ze) i=0 (zo) 392 (we) (wo) 393 394 where M_i is the palette matrix associated with the i'th 395 Vertex unit: 396 397 M_i = MatrixPalette[MatrixIndex[i]], if VERTEX_BLEND_ARB, 398 MATRIX_PALETTE_ARB and VERTEX_UNIT_ARB<i> are enabled, and 399 M_i = MODELVIEW_MATRIX, otherwise. 400 401 w_i is the Vertex's associated weight for vertex unit i: 402 403 w_i = weight_i, if VERTEX_BLEND_ARB, MATRIX_PALETTE_ARB 404 and VERTEX_UNIT_ARB<i> are enabled, 405 1, if MATRIX_PALETTE_ARB is disabled, 406 407 and, 408 409 n = ACTIVE_VERTEX_UNITS_ARB." 410 411 - (2.10.2 p. 31) Change the first paragraph to: 412 413 "The projection matrix and model-view matrices are set 414 with a variety of commands. The affected matrix is 415 determined by the current matrix mode. The current 416 matrix mode is set with 417 418 void MatrixMode( enum mode ); 419 420 which takes one of the pre-defined constants TEXTURE, 421 MODELVIEW, COLOR, PROJECTION, MODELVIEWn_ARB, 422 MATRIX_PALETTE_ARB. TEXTURE is described later in section 423 2.10.2, and COLOR is described in section 3.6.3. If the 424 current matrix mode is MODELVIEW, the matrix operations 425 apply to the model-view matrix; if PROJECTION, then they 426 apply to the projection matrix. 427 428 429 In implementations supporting ARB_matrix_palette, 430 431 void CurrentPaletteMatrixARB(int index); 432 433 defines which of the palette's matrices is affected by 434 subsequent matrix operations when the current matrix mode is 435 MATRIX_PALETTE_ARB. CurrentBlendMatrixARB generates the 436 error INVALID_VALUE if the <index> parameter is not between 437 0 and MAX_PALETTE_MATRICES_ARB. 438 The CURRENT_PALETTE_MATRIX_ARB enum can be used to query the 439 last value set by CurrentPaletteMatrixARB." 440 441 - (2.10.2 p. 34) Change to the fourth paragraph: 442 443 "The state required to implement transformations consists of a 444 four-valued integer indicating the current matrix mode, a 445 stack of at least two 4 x 4 matrices for each of COLOR, 446 PROJECTION, and TEXTURE with associated stack pointers, a 447 stack of at least 32 4 x 4 matrices with an associated stack 448 pointer for MODELVIEW, and a set of MAX_PALETTE_MATRICES_ARB 449 stacks of at least 1 4 x 4 matrices each for the matrix palette. 450 Initially, there is only one matrix on each stack, and all 451 matrices are set to the identity. The initial matrix mode 452 is MODELVIEW. 453 454 - (2.10.3 p. 35) Added after the second paragraph: 455 456 "When vertex blending is enabled, the normal is transformed 457 to eye space by: 458 459 n-1 460 (nx' ny' nz') = (nx ny nz) Inv ( SUM w_i * Mu_i) 461 i=0 462 463 Alternatively implementations may choose to transform the 464 normal to eye-space by: 465 466 n-1 467 (nx' ny' nz') = SUM w_i * (nx ny nz) Inv(Mu_i) 468 i=0 469 470 where Mu_i is the upper leftmost 3x3 matrix taken from the 471 modelview for vertex unit i (M_i), 472 473 M_i = MatrixPalette[MatrixIndex[i]] 474 475 if VERTEX_BLEND_ARB, MATRIX_PALETTE_ARB and VERTEX_UNIT_ARB<i> 476 are enabled, and 477 478 M_i = MODELVIEW_MATRIX 479 480 otherwise. 481 482 weight_i is the vertex's associated weight for vertex unit i, 483 484 w_i = weight_i 485 486 and 487 488 n = ACTIVE_VERTEX_UNITS_ARB" 489 490 491Additions to Chapter 3: 492 493 None 494 495Additions to Chapter 4: 496 497 None 498 499Additions to Chapter 5: 500 501 None 502 503Additions to Chapter 6: 504 505 None 506 507Additions to the GLX Specification 508 509 In progress. 510 511Additions to the GLX Stream Protocol: 512 513 514 Four new GL rendering commandsl are added. The following commands 515 are sent to the server as part of a glXRender request: 516 517 MatrixIndexubvARB 518 2 8+n+p rendering command length 519 2 4326 rendering command opcode 520 4 INT32 size 521 1*n CARD8 weights 522 p pad(n) 523 524 MatrixIndexusvARB 525 2 8+2*n rendering command length 526 2 4327 rendering command opcode 527 4 INT32 size 528 2*n CARD16 weights 529 p pad(2*n) 530 531 MatrixIndexuivARB 532 2 8+4*n rendering command length 533 2 4328 rendering command opcode 534 4 INT32 size 535 4*n CARD32 weights 536 537 CurrentPaletteMatrixARB 538 2 8 rendering command length 539 2 4329 rendering command opcode 540 4 INT32 count 541 542Errors 543 544 INVALID_VALUE is generated if the <size> parameter for 545 MatrixIndexARB or MatrixIndexPointerARB is greater than 546 MAX_VERTEX_UNITS_ARB, or if WEIGHT_SUM_UNITY_ARB is enabled 547 and <size> is equal to MAX_VERTEX_UNITS_ARB. 548 549 INVALID_VALUE is generated if the <count> parameter to 550 CurrentPaletteMatrixARB is greater than MAX_PALETTE_MATRICES_ARB 551 or if <count> is equal to zero. 552 553New State 554 555 Modified State in Table 6.5 (p. 195): 556 Initial 557Get Value Get Command Type Value Attribute Description 558--------- ----------- ---- ------- --------- ----------- 559CURRENT_MATRIX_INDEX_ARB GetIntegerv n*Z+ 0 current array of current matrix indices 560 561 562 Modified State in Table 6.6 (p. 196): 563 Initial 564Get Value Type Get Command Value Description Sec. Attribute 565--------- ---- ----------- ------- ----------- ---- --------- 566MATRIX_INDEX_ARRAY_ARB B IsEnabled False Matrix indices enable 2.8 vertex-array 567MATRIX_INDEX_ARRAY_SIZE_ARB Z+ GetIntegerv 0 Indices per element 2.8 vertex-array 568MATRIX_INDEX_ARRAY_TYPE_ARB Z_3 GetIntegerv UBYTE Type of indices 2.8 vertex-array 569MATRIX_INDEX_ARRAY_POINTER_ARB Y GetPointerv False Pointer to the Matrix 2.8 vertex-array 570 indices array 571 572 Modified state in Table 6.7 (p. 197) Transformation State: 573 Initial 574Get Value Get Command Type Value Attribute Description 575--------- ----------- ---- --------- --------- ----------- 576MATRIX_PALETTE_ARB GetFloatv 2*x1*xM4 Identity - stack of current modelview matrix in the palette 577MATRIX_PALETTE_ARB IsEnabled B FALSE transform Enable for ARB_matrix_palette 578CURRENT_PALETTE_ GetIntegerv Z+ 0 transform index of current modelview matrix in the 579MATRIX_ARB palette, as set by CurrentPaletteMatrixARB() 580 581 582New Implementation Dependent State 583 584 Modified state in Table 6.24 (p. 214) Implementation Dependant Values: 585 586Get Value Get Command Type Min Value Description 587--------- ----------- ---- --------- ----------- 588MAX_MATRIX_PALETTE_ GetIntegerv Z+ 1 Max matrix palette stack depth 589STACK_DEPTH_ARB 590 591 592 Modified state in Table 6.25 (p. 215): 593 594Get Value Get Command Type Min Value Description 595--------- ----------- ---- --------- ----------- 596MAX_PALETTE_MATRICES_ARB GetIntegerv Z+ MAX_VERTEX_ Max size of the matrix palette 597 UNITS_ARB 598 599Additions to Appendix A: 600 601 None 602 603 604Revision History 605 2000/10/17 v 0.3 jschelte - added Usage example. 606 2000/11/09 v 0.4 jschelte - cleaned up some "issues". 607 2000/11/27 v 0.5 jschelte - closed last issue, fixed typo in Usage 608 2000/11/30 v 0.6 jschelte - replaced "blend matrices" with 609 "palette matrices" 610 - cleared up some confusion in the 611 naming of the enum for the current 612 indices and the current palette 613 matrix for load/get. 614 2004/04/02 v 0.7 Thomas Roell - added GLX protocol 615 616Addendum: Using this extension. 617 618 // Get the implementation's capabilities 619 glGetIntegerv(MAX_VERTEX_UNITS_ARB, *max_blends); 620 glGetIntegerv(MAX_PALETTE_MATRICES_ARB, *max_matrices); 621 622 //validate that max_blends and max_matrices are sufficient here. 623 624 // enable the units 625 glEnable(VERTEX_UNIT_0_ARB); 626 glEnable(VERTEX_UNIT_1_ARB); 627 glEnable(VERTEX_UNIT_2_ARB); 628 glEnable(VERTEX_UNIT_3_ARB); 629 630 // Load the matrix Palette 631 glMatrixMode(MATRIX_PALETTE_ARB); 632 for (i=0; i<palette_size; i++) 633 { 634 glCurrentPaletteMatrix(i); 635 glLoadMatrix(mat[i]); 636 // N.B. 637 // glGetIntegerv(CURRENT_PALETTE_MATRIX_ARB, &index); 638 // .. will return index==i. 639 // glGetFloatv(MATRIX_PALETTE_ARB, &matrix); 640 // .. will return matrix==mat[i]. 641 } 642 643 // Per vertex array 644 // Enable and define the Vertex Arrays: 645 // e.g. V3F C4UB N3F W4F MI4UB T4F 646 glEnableClientState(VERTEX_ARRAY); 647 glEnableClientState(NORMAL_ARRAY); 648 glEnableClientState(COLOR_ARRAY); 649 glEnableClientState(TEXTURE_COORD_ARRAY); 650 glEnableClientState(WEIGHT_ARRAY_ARB); 651 glEnableClientState(MATRIX_INDEX_ARRAY_ARB); 652 653 glVertexPointer(3, FLOAT, 3, vertices); 654 glNormalPointer(FLOAT, 3, normals); 655 glColorPointer(4, UNSIGNED_BYTE, 4, colors); 656 glTexCoordPointer(4, FLOAT, 4, texcoords); 657 glWeightPointerARB(4, FLOAT, 4, weights); 658 glMatrixIndexPointerARB(4, UNSIGNED_BYTE, 4, indices); 659 660 // Draw Primitives from the array 661 glDrawArrays(TRIANGLES, 0, vert_array_size); 662 663 664 // **alternatively** 665 typdef struct st_interleaved_vertex { 666 FLOAT position[4]; 667 FLOAT weights[4]; 668 UNSIGNED_BYTE indices[4]; 669 FLOAT normal[3]; 670 FLOAT color[4]; 671 FLOAT texcoord[4]; 672 } interleaved_vertex; 673 interleaved_vertex vertices[NUM_VERTS]; 674 675 // the rest as above, except the Array Pointer definition: 676 int stride = sizeof(interleaved_vertex); 677 678 glVertexPointer( 3, FLOAT, stride, &(vertices[0].position) ); 679 glNormalPointer( FLOAT, stride, &(vertices[0].normal) ); 680 glColorPointer( 4, UNSIGNED_BYTE, stride, &(vertices[0].color) ); 681 glTexCoordPointer( 4, FLOAT, stride, &(vertices[0].texcoords) ); 682 glWeightPointerARB( 4, FLOAT, stride, &(vertices[0].weights) ); 683 glMatrixIndexPointerARB( 4, UNSIGNED_BYTE, stride, 684 &(vertices[0].indices) ); 685 686