• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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