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>
40 #include "glut_wrap.h"
42 static int Width
= 400;
43 static int Height
= 300;
44 static const GLfloat Near
= 5.0, Far
= 25.0;
46 static const GLfloat t
[][4] = {
47 { 0.5, 0.0, 0.0, 1.0 },
49 { 0.25, 0.5, 0.0, 1.0 },
50 { 0.75, 0.5, 0.0, 1.0 },
52 { 0.0, 1.0, 0.0, 1.0 },
53 { 0.5, 1.0, 0.0, 1.0 },
54 { 1.0, 1.0, 0.0, 1.0 },
57 static const GLfloat c_f
[][4] = {
58 { 1.0, 0.0, 0.0, 1.0 },
60 { 0.0, 1.0, 0.0, 1.0 },
61 { 0.0, 1.0, 0.0, 1.0 },
63 { 0.0, 0.0, 1.0, 1.0 },
64 { 1.0, 0.0, 1.0, 1.0 },
65 { 0.0, 0.0, 1.0, 1.0 },
68 static const GLubyte c_ub
[][4] = {
69 { 0xff, 0x00, 0x00, 0xff },
71 { 0x00, 0xff, 0x00, 0xff },
72 { 0x00, 0xff, 0x00, 0xff },
74 { 0x00, 0x00, 0xff, 0xff },
75 { 0xff, 0x00, 0xff, 0xff },
76 { 0x00, 0x00, 0xff, 0xff },
79 static const GLfloat n
[][3] = {
90 static const GLfloat v
[][4] = {
91 { 0.0, 1.0, 0.0, 1.0, },
93 { -0.5, 0.0, 0.0, 1.0, },
94 { 0.5, 0.0, 0.0, 1.0, },
96 { -1.0, -1.0, 0.0, 1.0, },
97 { 0.0, -1.0, 0.0, 1.0, },
98 { 1.0, -1.0, 0.0, 1.0, },
101 static const unsigned indicies
[12] = {
108 #define NONE { NULL, 0, 0, 0, sizeof( NULL ) }
109 #define V2F { v, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
110 #define V3F { v, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
111 #define V4F { v, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
113 #define C4UB { c_ub, 4, 4 * sizeof( GLubyte ), GL_UNSIGNED_BYTE, sizeof( c_ub[0] ) }
114 #define C3F { c_f, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
115 #define C4F { c_f, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
117 #define T2F { t, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
118 #define T4F { t, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
120 #define N3F { n, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( n[0] ) }
122 struct interleave_info
{
131 #define INVALID_MODE 14
132 #define INVALID_STRIDE 15
134 struct interleave_info info
[ NUM_MODES
][4] = {
135 { NONE
, NONE
, NONE
, V2F
},
136 { NONE
, NONE
, NONE
, V3F
},
137 { NONE
, C4UB
, NONE
, V2F
},
138 { NONE
, C4UB
, NONE
, V3F
},
139 { NONE
, C3F
, NONE
, V3F
},
141 { NONE
, NONE
, N3F
, V3F
},
142 { NONE
, C4F
, N3F
, V3F
},
144 { T2F
, NONE
, NONE
, V3F
},
145 { T4F
, NONE
, NONE
, V4F
},
147 { T2F
, C4UB
, NONE
, V3F
},
148 { T2F
, C3F
, NONE
, V3F
},
149 { T2F
, NONE
, N3F
, V3F
},
150 { T2F
, C4F
, N3F
, V3F
},
151 { T4F
, C4F
, N3F
, V4F
},
154 const char * const mode_names
[ NUM_MODES
] = {
167 "GL_T2F_C4F_N3F_V3F",
168 "GL_T4F_C4F_N3F_V4F",
171 static unsigned interleave_mode
= 0;
172 static GLboolean use_invalid_mode
= GL_FALSE
;
173 static GLboolean use_invalid_stride
= GL_FALSE
;
175 #define DEREF(item,idx) (void *) & ((char *)curr_info[item].data)[idx * curr_info[item].stride]
177 static void Display( void )
179 const struct interleave_info
* const curr_info
= info
[ interleave_mode
];
181 /* 4 floats for 12 verticies for 4 data elements.
183 char data
[ (sizeof( GLfloat
) * 4) * 12 * 4 ];
192 glClearColor(0.2, 0.2, 0.8, 0);
193 glClear( GL_COLOR_BUFFER_BIT
);
197 glTranslatef(-1.5, 0, 0);
199 glColor3fv( c_f
[0] );
201 if ( curr_info
[0].data
!= NULL
) {
202 glEnable( GL_TEXTURE_2D
);
205 glDisable( GL_TEXTURE_2D
);
210 glBegin(GL_TRIANGLES
);
211 for ( i
= 0 ; i
< 12 ; i
++ ) {
212 const unsigned index
= indicies
[i
];
215 /* Handle the vertex texture coordinate.
217 if ( curr_info
[0].data
!= NULL
) {
218 if ( curr_info
[0].count
== 2 ) {
219 glTexCoord2fv( DEREF(0, index
) );
222 glTexCoord4fv( DEREF(0, index
) );
225 (void) memcpy( & data
[ offset
], DEREF(0, index
),
227 offset
+= curr_info
[0].size
;
231 /* Handle the vertex color.
233 if ( curr_info
[1].data
!= NULL
) {
234 if ( curr_info
[1].type
== GL_FLOAT
) {
235 if ( curr_info
[1].count
== 3 ) {
236 glColor3fv( DEREF(1, index
) );
239 glColor4fv( DEREF(1, index
) );
243 glColor4ubv( DEREF(1, index
) );
246 (void) memcpy( & data
[ offset
], DEREF(1, index
),
248 offset
+= curr_info
[1].size
;
252 /* Handle the vertex normal.
254 if ( curr_info
[2].data
!= NULL
) {
255 glNormal3fv( DEREF(2, index
) );
257 (void) memcpy( & data
[ offset
], DEREF(2, index
),
259 offset
+= curr_info
[2].size
;
263 switch( curr_info
[3].count
) {
265 glVertex2fv( DEREF(3, index
) );
268 glVertex3fv( DEREF(3, index
) );
271 glVertex4fv( DEREF(3, index
) );
275 (void) memcpy( & data
[ offset
], DEREF(3, index
),
277 offset
+= curr_info
[3].size
;
282 glTranslatef(3.0, 0, 0);
284 /* The masking with ~0x2A00 is a bit of a hack to make sure that format
285 * ends up with an invalid value no matter what rand() returns.
287 format
= (use_invalid_mode
)
288 ? (rand() & ~0x2A00) : GL_V2F
+ interleave_mode
;
289 stride
= (use_invalid_stride
) ? -abs(rand()) : 0;
292 glInterleavedArrays( format
, stride
, data
);
295 printf("glInterleavedArrays(0x%04x, %d, %p) generated the error 0x%04x\n",
296 format
, stride
, data
, err
);
299 glDrawArrays( GL_TRIANGLES
, 0, 12 );
308 static void Reshape( int width
, int height
)
310 GLfloat ar
= (float) width
/ (float) height
;
313 glViewport( 0, 0, width
, height
);
314 glMatrixMode( GL_PROJECTION
);
316 glFrustum( -ar
, ar
, -1.0, 1.0, Near
, Far
);
317 glMatrixMode( GL_MODELVIEW
);
319 glTranslatef( 0.0, 0.0, -15.0 );
323 static void Key( unsigned char key
, int x
, int y
)
336 static void ModeMenu( int entry
)
338 if ( entry
== INVALID_MODE
) {
339 use_invalid_mode
= GL_TRUE
;
340 use_invalid_stride
= GL_FALSE
;
342 else if ( entry
== INVALID_STRIDE
) {
343 use_invalid_mode
= GL_FALSE
;
344 use_invalid_stride
= GL_TRUE
;
347 use_invalid_mode
= GL_FALSE
;
348 use_invalid_stride
= GL_FALSE
;
349 interleave_mode
= entry
;
353 static void Init( void )
355 const char * const ver_string
= (const char *)
356 glGetString( GL_VERSION
);
357 const GLubyte tex
[16] = {
358 0xff, 0x00, 0xff, 0x00,
359 0x00, 0xff, 0x00, 0xff,
360 0xff, 0x00, 0xff, 0x00,
361 0x00, 0xff, 0x00, 0xff,
364 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
365 printf("GL_VERSION = %s\n", ver_string
);
367 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
368 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
369 glTexEnvi( GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
370 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, 4, 4, 0,
371 GL_LUMINANCE
, GL_UNSIGNED_BYTE
, tex
);
373 printf("Use the context menu (right click) to select the interleaved array mode.\n");
374 printf("Press ESCAPE to exit.\n\n");
375 printf("NOTE: This is *NOT* a very good test of the modes that use normals.\n");
379 int main( int argc
, char *argv
[] )
383 srand( time( NULL
) );
385 glutInit( &argc
, argv
);
386 glutInitWindowPosition( 0, 0 );
387 glutInitWindowSize( Width
, Height
);
388 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
389 glutCreateWindow( "glInterleavedArrays test" );
391 glutReshapeFunc( Reshape
);
392 glutKeyboardFunc( Key
);
393 glutDisplayFunc( Display
);
395 glutCreateMenu( ModeMenu
);
396 for ( i
= 0 ; i
< NUM_MODES
; i
++ ) {
397 glutAddMenuEntry( mode_names
[i
], i
);
400 glutAddMenuEntry( "Random invalid mode", INVALID_MODE
);
401 glutAddMenuEntry( "Random invalid stride", INVALID_STRIDE
);
403 glutAttachMenu(GLUT_RIGHT_BUTTON
);