2 * (C) Copyright IBM Corporation 2005
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Simple test of glInterleavedArrays functionality. For each mode, two
29 * meshes are drawn. One is drawn using interleaved arrays and the othe is
30 * drawn using immediate mode. Both should look identical.
32 * \author Ian Romanick <idr@us.ibm.com>
41 static int Width
= 400;
42 static int Height
= 300;
43 static const GLfloat Near
= 5.0, Far
= 25.0;
45 static const GLfloat t
[][4] = {
46 { 0.5, 0.0, 0.0, 1.0 },
48 { 0.25, 0.5, 0.0, 1.0 },
49 { 0.75, 0.5, 0.0, 1.0 },
51 { 0.0, 1.0, 0.0, 1.0 },
52 { 0.5, 1.0, 0.0, 1.0 },
53 { 1.0, 1.0, 0.0, 1.0 },
56 static const GLfloat c_f
[][4] = {
57 { 1.0, 0.0, 0.0, 1.0 },
59 { 0.0, 1.0, 0.0, 1.0 },
60 { 0.0, 1.0, 0.0, 1.0 },
62 { 0.0, 0.0, 1.0, 1.0 },
63 { 1.0, 0.0, 1.0, 1.0 },
64 { 0.0, 0.0, 1.0, 1.0 },
67 static const GLubyte c_ub
[][4] = {
68 { 0xff, 0x00, 0x00, 0xff },
70 { 0x00, 0xff, 0x00, 0xff },
71 { 0x00, 0xff, 0x00, 0xff },
73 { 0x00, 0x00, 0xff, 0xff },
74 { 0xff, 0x00, 0xff, 0xff },
75 { 0x00, 0x00, 0xff, 0xff },
78 static const GLfloat n
[][3] = {
89 static const GLfloat v
[][4] = {
90 { 0.0, 1.0, 0.0, 1.0, },
92 { -0.5, 0.0, 0.0, 1.0, },
93 { 0.5, 0.0, 0.0, 1.0, },
95 { -1.0, -1.0, 0.0, 1.0, },
96 { 0.0, -1.0, 0.0, 1.0, },
97 { 1.0, -1.0, 0.0, 1.0, },
100 static const unsigned indicies
[12] = {
107 #define NONE { NULL, 0, 0, 0 }
108 #define V2F { v, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
109 #define V3F { v, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
110 #define V4F { v, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
112 #define C4UB { c_ub, 4, 4 * sizeof( GLubyte ), GL_UNSIGNED_BYTE, sizeof( c_ub[0] ) }
113 #define C3F { c_f, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
114 #define C4F { c_f, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
116 #define T2F { t, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
117 #define T4F { t, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
119 #define N3F { n, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( n[0] ) }
121 struct interleave_info
{
130 #define INVALID_MODE 14
131 #define INVALID_STRIDE 15
133 struct interleave_info info
[ NUM_MODES
][4] = {
134 { NONE
, NONE
, NONE
, V2F
},
135 { NONE
, NONE
, NONE
, V3F
},
136 { NONE
, C4UB
, NONE
, V2F
},
137 { NONE
, C4UB
, NONE
, V3F
},
138 { NONE
, C3F
, NONE
, V3F
},
140 { NONE
, NONE
, N3F
, V3F
},
141 { NONE
, C4F
, N3F
, V3F
},
143 { T2F
, NONE
, NONE
, V3F
},
144 { T4F
, NONE
, NONE
, V4F
},
146 { T2F
, C4UB
, NONE
, V3F
},
147 { T2F
, C3F
, NONE
, V3F
},
148 { T2F
, NONE
, N3F
, V3F
},
149 { T2F
, C4F
, N3F
, V3F
},
150 { T4F
, C4F
, N3F
, V4F
},
153 const char * const mode_names
[ NUM_MODES
] = {
166 "GL_T2F_C4F_N3F_V3F",
167 "GL_T4F_C4F_N3F_V4F",
170 static unsigned interleave_mode
= 0;
171 static GLboolean use_invalid_mode
= GL_FALSE
;
172 static GLboolean use_invalid_stride
= GL_FALSE
;
174 #define DEREF(item,idx) (void *) & ((char *)curr_info[item].data)[idx * curr_info[item].stride]
176 static void Display( void )
178 const struct interleave_info
* const curr_info
= info
[ interleave_mode
];
180 /* 4 floats for 12 verticies for 4 data elements.
182 char data
[ (sizeof( GLfloat
) * 4) * 12 * 4 ];
191 glClearColor(0.2, 0.2, 0.8, 0);
192 glClear( GL_COLOR_BUFFER_BIT
);
196 glTranslatef(-1.5, 0, 0);
198 glColor3fv( c_f
[0] );
200 if ( curr_info
[0].data
!= NULL
) {
201 glEnable( GL_TEXTURE_2D
);
204 glDisable( GL_TEXTURE_2D
);
209 glBegin(GL_TRIANGLES
);
210 for ( i
= 0 ; i
< 12 ; i
++ ) {
211 const unsigned index
= indicies
[i
];
214 /* Handle the vertex texture coordinate.
216 if ( curr_info
[0].data
!= NULL
) {
217 if ( curr_info
[0].count
== 2 ) {
218 glTexCoord2fv( DEREF(0, index
) );
221 glTexCoord4fv( DEREF(0, index
) );
224 (void) memcpy( & data
[ offset
], DEREF(0, index
),
226 offset
+= curr_info
[0].size
;
230 /* Handle the vertex color.
232 if ( curr_info
[1].data
!= NULL
) {
233 if ( curr_info
[1].type
== GL_FLOAT
) {
234 if ( curr_info
[1].count
== 3 ) {
235 glColor3fv( DEREF(1, index
) );
238 glColor4fv( DEREF(1, index
) );
242 glColor4ubv( DEREF(1, index
) );
245 (void) memcpy( & data
[ offset
], DEREF(1, index
),
247 offset
+= curr_info
[1].size
;
251 /* Handle the vertex normal.
253 if ( curr_info
[2].data
!= NULL
) {
254 glNormal3fv( DEREF(2, index
) );
256 (void) memcpy( & data
[ offset
], DEREF(2, index
),
258 offset
+= curr_info
[2].size
;
262 switch( curr_info
[3].count
) {
264 glVertex2fv( DEREF(3, index
) );
267 glVertex3fv( DEREF(3, index
) );
270 glVertex4fv( DEREF(3, index
) );
274 (void) memcpy( & data
[ offset
], DEREF(3, index
),
276 offset
+= curr_info
[3].size
;
281 glTranslatef(3.0, 0, 0);
283 /* The masking with ~0x2A00 is a bit of a hack to make sure that format
284 * ends up with an invalid value no matter what rand() returns.
286 format
= (use_invalid_mode
)
287 ? (rand() & ~0x2A00) : GL_V2F
+ interleave_mode
;
288 stride
= (use_invalid_stride
) ? -abs(rand()) : 0;
291 glInterleavedArrays( format
, stride
, data
);
294 printf("glInterleavedArrays(0x%04x, %d, %p) generated the error 0x%04x\n",
295 format
, stride
, data
, err
);
298 glDrawArrays( GL_TRIANGLES
, 0, 12 );
307 static void Reshape( int width
, int height
)
309 GLfloat ar
= (float) width
/ (float) height
;
312 glViewport( 0, 0, width
, height
);
313 glMatrixMode( GL_PROJECTION
);
315 glFrustum( -ar
, ar
, -1.0, 1.0, Near
, Far
);
316 glMatrixMode( GL_MODELVIEW
);
318 glTranslatef( 0.0, 0.0, -15.0 );
322 static void Key( unsigned char key
, int x
, int y
)
335 static void ModeMenu( int entry
)
337 if ( entry
== INVALID_MODE
) {
338 use_invalid_mode
= GL_TRUE
;
339 use_invalid_stride
= GL_FALSE
;
341 else if ( entry
== INVALID_STRIDE
) {
342 use_invalid_mode
= GL_FALSE
;
343 use_invalid_stride
= GL_TRUE
;
346 use_invalid_mode
= GL_FALSE
;
347 use_invalid_stride
= GL_FALSE
;
348 interleave_mode
= entry
;
352 static void Init( void )
354 const char * const ver_string
= (const char * const)
355 glGetString( GL_VERSION
);
356 const GLubyte tex
[16] = {
357 0xff, 0x00, 0xff, 0x00,
358 0x00, 0xff, 0x00, 0xff,
359 0xff, 0x00, 0xff, 0x00,
360 0x00, 0xff, 0x00, 0xff,
363 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
364 printf("GL_VERSION = %s\n", ver_string
);
366 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
367 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
368 glTexEnvi( GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
369 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, 4, 4, 0,
370 GL_LUMINANCE
, GL_UNSIGNED_BYTE
, tex
);
372 printf("Use the context menu (right click) to select the interleaved array mode.\n");
373 printf("Press ESCAPE to exit.\n\n");
374 printf("NOTE: This is *NOT* a very good test of the modes that use normals.\n");
378 int main( int argc
, char *argv
[] )
382 srand( time( NULL
) );
384 glutInit( &argc
, argv
);
385 glutInitWindowPosition( 0, 0 );
386 glutInitWindowSize( Width
, Height
);
387 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
388 glutCreateWindow( "glInterleavedArrays test" );
389 glutReshapeFunc( Reshape
);
390 glutKeyboardFunc( Key
);
391 glutDisplayFunc( Display
);
393 glutCreateMenu( ModeMenu
);
394 for ( i
= 0 ; i
< NUM_MODES
; i
++ ) {
395 glutAddMenuEntry( mode_names
[i
], i
);
398 glutAddMenuEntry( "Random invalid mode", INVALID_MODE
);
399 glutAddMenuEntry( "Random invalid stride", INVALID_STRIDE
);
401 glutAttachMenu(GLUT_RIGHT_BUTTON
);