~ubuntu-branches/ubuntu/oneiric/mesa-demos/oneiric

« back to all changes in this revision

Viewing changes to src/tests/interleave.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2010-09-27 16:18:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100927161827-1yfgolc1oy9sjhi8
Tags: upstream-8.0.1
ImportĀ upstreamĀ versionĀ 8.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright IBM Corporation 2005
 
3
 * All Rights Reserved.
 
4
 *
 
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:
 
11
 *
 
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
 
14
 * Software.
 
15
 *
 
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.
 
23
 */
 
24
 
 
25
/**
 
26
 * \file interleave.c
 
27
 * 
 
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.
 
31
 *
 
32
 * \author Ian Romanick <idr@us.ibm.com>
 
33
 */
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
#include <time.h>
 
39
#include <GL/glew.h>
 
40
#include <GL/glut.h>
 
41
 
 
42
static int Width = 400;
 
43
static int Height = 300;
 
44
static const GLfloat Near = 5.0, Far = 25.0;
 
45
 
 
46
static const GLfloat t[][4] = {
 
47
   { 0.5,  0.0, 0.0, 1.0 },
 
48
 
 
49
   { 0.25, 0.5, 0.0, 1.0 },
 
50
   { 0.75, 0.5, 0.0, 1.0 },
 
51
 
 
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 },
 
55
};
 
56
 
 
57
static const GLfloat c_f[][4] = {
 
58
   { 1.0, 0.0, 0.0, 1.0 },
 
59
 
 
60
   { 0.0, 1.0, 0.0, 1.0 },
 
61
   { 0.0, 1.0, 0.0, 1.0 },
 
62
 
 
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 },
 
66
};
 
67
 
 
68
static const GLubyte c_ub[][4] = {
 
69
   { 0xff, 0x00, 0x00, 0xff },
 
70
 
 
71
   { 0x00, 0xff, 0x00, 0xff },
 
72
   { 0x00, 0xff, 0x00, 0xff },
 
73
 
 
74
   { 0x00, 0x00, 0xff, 0xff },
 
75
   { 0xff, 0x00, 0xff, 0xff },
 
76
   { 0x00, 0x00, 0xff, 0xff },
 
77
};
 
78
 
 
79
static const GLfloat n[][3] = {
 
80
   { 0.0, 0.0, -1.0 },
 
81
 
 
82
   { 0.0, 0.0, -1.0 },
 
83
   { 0.0, 0.0, -1.0 },
 
84
 
 
85
   { 0.0, 0.0, -1.0 },
 
86
   { 0.0, 0.0, -1.0 },
 
87
   { 0.0, 0.0, -1.0 },
 
88
};
 
89
 
 
90
static const GLfloat v[][4] = {
 
91
   {  0.0,  1.0, 0.0, 1.0, },
 
92
 
 
93
   { -0.5,  0.0, 0.0, 1.0, },
 
94
   {  0.5,  0.0, 0.0, 1.0, },
 
95
 
 
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, },
 
99
};
 
100
   
 
101
static const unsigned indicies[12] = {
 
102
   0, 1, 2,
 
103
   1, 3, 4,
 
104
   2, 4, 5,
 
105
   1, 4, 2
 
106
};
 
107
 
 
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] ) }
 
112
 
 
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] ) }
 
116
 
 
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] ) }
 
119
 
 
120
#define N3F   { n,    3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( n[0] ) }
 
121
 
 
122
struct interleave_info {
 
123
   const void * data;
 
124
   unsigned count;
 
125
   unsigned size;
 
126
   GLenum type;
 
127
   unsigned stride;
 
128
};
 
129
 
 
130
#define NUM_MODES      14
 
131
#define INVALID_MODE   14
 
132
#define INVALID_STRIDE 15
 
133
 
 
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 },
 
140
 
 
141
   { NONE, NONE, N3F,  V3F },
 
142
   { NONE, C4F,  N3F,  V3F },
 
143
 
 
144
   { T2F,  NONE, NONE, V3F },
 
145
   { T4F,  NONE, NONE, V4F },
 
146
 
 
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 },
 
152
};
 
153
 
 
154
const char * const mode_names[ NUM_MODES ] = {
 
155
   "GL_V2F",
 
156
   "GL_V3F",
 
157
   "GL_C4UB_V2F",
 
158
   "GL_C4UB_V3F",
 
159
   "GL_C3F_V3F",
 
160
   "GL_N3F_V3F",
 
161
   "GL_C4F_N3F_V3F",
 
162
   "GL_T2F_V3F",
 
163
   "GL_T4F_V4F",
 
164
   "GL_T2F_C4UB_V3F",
 
165
   "GL_T2F_C3F_V3F",
 
166
   "GL_T2F_N3F_V3F",
 
167
   "GL_T2F_C4F_N3F_V3F",
 
168
   "GL_T4F_C4F_N3F_V4F",
 
169
};
 
170
 
 
171
static unsigned interleave_mode = 0;
 
172
static GLboolean use_invalid_mode = GL_FALSE;
 
173
static GLboolean use_invalid_stride = GL_FALSE;
 
174
 
 
175
#define DEREF(item,idx) (void *) & ((char *)curr_info[item].data)[idx * curr_info[item].stride]
 
176
 
 
177
static void Display( void )
 
178
{
 
179
   const struct interleave_info * const curr_info = info[ interleave_mode ];
 
180
 
 
181
   /* 4 floats for 12 verticies for 4 data elements.
 
182
    */
 
183
   char data[ (sizeof( GLfloat ) * 4) * 12 * 4 ];
 
184
 
 
185
   unsigned i;
 
186
   unsigned offset;
 
187
   GLenum err;
 
188
   GLenum format;
 
189
   GLsizei stride;
 
190
 
 
191
 
 
192
   glClearColor(0.2, 0.2, 0.8, 0);
 
193
   glClear( GL_COLOR_BUFFER_BIT );
 
194
 
 
195
   glPushMatrix();
 
196
 
 
197
   glTranslatef(-1.5, 0, 0);
 
198
 
 
199
   glColor3fv( c_f[0] );
 
200
 
 
201
   if ( curr_info[0].data != NULL ) {
 
202
      glEnable( GL_TEXTURE_2D );
 
203
   }
 
204
   else {
 
205
      glDisable( GL_TEXTURE_2D );
 
206
   }
 
207
 
 
208
 
 
209
   offset = 0;
 
210
   glBegin(GL_TRIANGLES);
 
211
   for ( i = 0 ; i < 12 ; i++ ) {
 
212
      const unsigned index = indicies[i];
 
213
 
 
214
 
 
215
      /* Handle the vertex texture coordinate.
 
216
       */
 
217
      if ( curr_info[0].data != NULL ) {
 
218
         if ( curr_info[0].count == 2 ) {
 
219
            glTexCoord2fv( DEREF(0, index) );
 
220
         }
 
221
         else {
 
222
            glTexCoord4fv( DEREF(0, index) );
 
223
         }
 
224
 
 
225
         (void) memcpy( & data[ offset ], DEREF(0, index),
 
226
                        curr_info[0].size );
 
227
         offset += curr_info[0].size;
 
228
      }
 
229
 
 
230
 
 
231
      /* Handle the vertex color.
 
232
       */
 
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) );
 
237
            }
 
238
            else {
 
239
               glColor4fv( DEREF(1, index) );
 
240
            }
 
241
         }
 
242
         else {
 
243
            glColor4ubv( DEREF(1, index) );
 
244
         }
 
245
 
 
246
         (void) memcpy( & data[ offset ], DEREF(1, index), 
 
247
                        curr_info[1].size );
 
248
         offset += curr_info[1].size;
 
249
      }
 
250
 
 
251
      
 
252
      /* Handle the vertex normal.
 
253
       */
 
254
      if ( curr_info[2].data != NULL ) {
 
255
         glNormal3fv( DEREF(2, index) );
 
256
 
 
257
         (void) memcpy( & data[ offset ], DEREF(2, index),
 
258
                        curr_info[2].size );
 
259
         offset += curr_info[2].size;
 
260
      }
 
261
 
 
262
 
 
263
      switch( curr_info[3].count ) {
 
264
      case 2:
 
265
         glVertex2fv( DEREF(3, index) );
 
266
         break;
 
267
      case 3:
 
268
         glVertex3fv( DEREF(3, index) );
 
269
         break;
 
270
      case 4:
 
271
         glVertex4fv( DEREF(3, index) );
 
272
         break;
 
273
      }
 
274
 
 
275
      (void) memcpy( & data[ offset ], DEREF(3, index),
 
276
                     curr_info[3].size );
 
277
         offset += curr_info[3].size;
 
278
   }
 
279
   glEnd();
 
280
 
 
281
 
 
282
   glTranslatef(3.0, 0, 0);
 
283
 
 
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.
 
286
    */
 
287
   format = (use_invalid_mode)
 
288
     ? (rand() & ~0x2A00) : GL_V2F + interleave_mode;
 
289
   stride = (use_invalid_stride) ? -abs(rand()) : 0;
 
290
 
 
291
   (void) glGetError();
 
292
   glInterleavedArrays( format, stride, data );
 
293
   err = glGetError();
 
294
   if ( err ) {
 
295
      printf("glInterleavedArrays(0x%04x, %d, %p) generated the error 0x%04x\n",
 
296
             format, stride, data, err );
 
297
   }
 
298
   else {
 
299
      glDrawArrays( GL_TRIANGLES, 0, 12 );
 
300
   }
 
301
 
 
302
   glPopMatrix();
 
303
 
 
304
   glutSwapBuffers();
 
305
}
 
306
 
 
307
 
 
308
static void Reshape( int width, int height )
 
309
{
 
310
   GLfloat ar = (float) width / (float) height;
 
311
   Width = width;
 
312
   Height = height;
 
313
   glViewport( 0, 0, width, height );
 
314
   glMatrixMode( GL_PROJECTION );
 
315
   glLoadIdentity();
 
316
   glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
 
317
   glMatrixMode( GL_MODELVIEW );
 
318
   glLoadIdentity();
 
319
   glTranslatef( 0.0, 0.0, -15.0 );
 
320
}
 
321
 
 
322
 
 
323
static void Key( unsigned char key, int x, int y )
 
324
{
 
325
   (void) x;
 
326
   (void) y;
 
327
   switch (key) {
 
328
      case 27:
 
329
         exit(0);
 
330
         break;
 
331
   }
 
332
   glutPostRedisplay();
 
333
}
 
334
 
 
335
 
 
336
static void ModeMenu( int entry )
 
337
{
 
338
   if ( entry == INVALID_MODE ) {
 
339
      use_invalid_mode = GL_TRUE;
 
340
      use_invalid_stride = GL_FALSE;
 
341
   }
 
342
   else if ( entry == INVALID_STRIDE ) {
 
343
      use_invalid_mode = GL_FALSE;
 
344
      use_invalid_stride = GL_TRUE;
 
345
   }
 
346
   else {
 
347
      use_invalid_mode = GL_FALSE;
 
348
      use_invalid_stride = GL_FALSE;
 
349
      interleave_mode = entry;
 
350
   }
 
351
}
 
352
 
 
353
static void Init( void )
 
354
{
 
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, 
 
362
   };
 
363
 
 
364
   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
 
365
   printf("GL_VERSION = %s\n", ver_string);
 
366
 
 
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 );
 
372
 
 
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");
 
376
}
 
377
 
 
378
 
 
379
int main( int argc, char *argv[] )
 
380
{
 
381
   unsigned i;
 
382
 
 
383
   srand( time( NULL ) );
 
384
 
 
385
   glutInit( &argc, argv );
 
386
   glutInitWindowPosition( 0, 0 );
 
387
   glutInitWindowSize( Width, Height );
 
388
   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
 
389
   glutCreateWindow( "glInterleavedArrays test" );
 
390
   glewInit();
 
391
   glutReshapeFunc( Reshape );
 
392
   glutKeyboardFunc( Key );
 
393
   glutDisplayFunc( Display );
 
394
 
 
395
   glutCreateMenu( ModeMenu );
 
396
   for ( i = 0 ; i < NUM_MODES ; i++ ) {
 
397
      glutAddMenuEntry( mode_names[i], i);
 
398
   }
 
399
 
 
400
   glutAddMenuEntry( "Random invalid mode",   INVALID_MODE);
 
401
   glutAddMenuEntry( "Random invalid stride", INVALID_STRIDE);
 
402
 
 
403
   glutAttachMenu(GLUT_RIGHT_BUTTON);
 
404
 
 
405
   Init();
 
406
   glutMainLoop();
 
407
   return 0;
 
408
}