include readtex.h
[profile/ivi/mesa.git] / progs / demos / multiarb.c
1
2 /*
3  * GL_ARB_multitexture demo
4  *
5  * Command line options:
6  *    -info      print GL implementation information
7  *
8  *
9  * Brian Paul  November 1998  This program is in the public domain.
10  * Modified on 12 Feb 2002 for > 2 texture units.
11  */
12
13
14 #include <math.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <GL/glut.h>
19
20 #include "readtex.h"
21
22 #define TEXTURE_1_FILE "../images/girl.rgb"
23 #define TEXTURE_2_FILE "../images/reflect.rgb"
24
25 #define TEX0 1
26 #define TEX7 8
27 #define ANIMATE 10
28 #define QUIT 100
29
30 static GLboolean Animate = GL_TRUE;
31 static GLint NumUnits = 1;
32 static GLboolean TexEnabled[8];
33
34 static GLfloat Drift = 0.0;
35 static GLfloat drift_increment = 0.005;
36 static GLfloat Xrot = 20.0, Yrot = 30.0, Zrot = 0.0;
37
38
39 static void Idle( void )
40 {
41    if (Animate) {
42       GLint i;
43
44       Drift += drift_increment;
45       if (Drift >= 1.0)
46          Drift = 0.0;
47
48       for (i = 0; i < NumUnits; i++) {
49          glActiveTextureARB(GL_TEXTURE0_ARB + i);
50          glMatrixMode(GL_TEXTURE);
51          glLoadIdentity();
52          if (i == 0) {
53             glTranslatef(Drift, 0.0, 0.0);
54             glScalef(2, 2, 1);
55          }
56          else if (i == 1) {
57             glTranslatef(0.0, Drift, 0.0);
58          }
59          else {
60             glTranslatef(0.5, 0.5, 0.0);
61             glRotatef(180.0 * Drift, 0, 0, 1);
62             glScalef(1.0/i, 1.0/i, 1.0/i);
63             glTranslatef(-0.5, -0.5, 0.0);
64          }
65       }
66       glMatrixMode(GL_MODELVIEW);
67
68       glutPostRedisplay();
69    }
70 }
71
72
73 static void DrawObject(void)
74 {
75    GLint i;
76    GLint j;
77    static const GLfloat   tex_coords[] = {  0.0,  0.0,  1.0,  1.0,  0.0 };
78    static const GLfloat   vtx_coords[] = { -1.0, -1.0,  1.0,  1.0, -1.0 };
79
80    if (!TexEnabled[0] && !TexEnabled[1])
81       glColor3f(0.1, 0.1, 0.1);  /* add onto this */
82    else
83       glColor3f(1, 1, 1);  /* modulate this */
84
85    glBegin(GL_QUADS);
86
87    /* Toggle between the vector and scalar entry points.  This is done purely
88     * to hit multiple paths in the driver.
89     */
90    if ( Drift > 0.49 ) {
91       for (j = 0; j < 4; j++ ) {
92          for (i = 0; i < NumUnits; i++)
93             glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i, 
94                                  tex_coords[j], tex_coords[j+1]);
95          glVertex2f( vtx_coords[j], vtx_coords[j+1] );
96       }
97    }
98    else {
99       for (j = 0; j < 4; j++ ) {
100          for (i = 0; i < NumUnits; i++)
101             glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + i, & tex_coords[j]);
102          glVertex2fv( & vtx_coords[j] );
103       }
104    }
105
106    glEnd();
107 }
108
109
110
111 static void Display( void )
112 {
113    static GLint T0 = 0;
114    static GLint Frames = 0;
115    GLint t;
116
117    glClear( GL_COLOR_BUFFER_BIT );
118
119    glPushMatrix();
120       glRotatef(Xrot, 1.0, 0.0, 0.0);
121       glRotatef(Yrot, 0.0, 1.0, 0.0);
122       glRotatef(Zrot, 0.0, 0.0, 1.0);
123       glScalef(5.0, 5.0, 5.0);
124       DrawObject();
125    glPopMatrix();
126
127    glutSwapBuffers();
128
129    Frames++;
130
131    t = glutGet(GLUT_ELAPSED_TIME);
132    if (t - T0 >= 250) {
133       GLfloat seconds = (t - T0) / 1000.0;
134       drift_increment = 2.2 * seconds / Frames;
135       T0 = t;
136       Frames = 0;
137    }
138 }
139
140
141 static void Reshape( int width, int height )
142 {
143    glViewport( 0, 0, width, height );
144    glMatrixMode( GL_PROJECTION );
145    glLoadIdentity();
146    glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
147    /*glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );*/
148    glMatrixMode( GL_MODELVIEW );
149    glLoadIdentity();
150    glTranslatef( 0.0, 0.0, -70.0 );
151 }
152
153
154 static void ModeMenu(int entry)
155 {
156    if (entry >= TEX0 && entry <= TEX7) {
157       /* toggle */
158       GLint i = entry - TEX0;
159       TexEnabled[i] = !TexEnabled[i];
160       glActiveTextureARB(GL_TEXTURE0_ARB + i);
161       if (TexEnabled[i])
162          glEnable(GL_TEXTURE_2D);
163       else
164          glDisable(GL_TEXTURE_2D);
165       printf("Enabled: ");
166       for (i = 0; i < NumUnits; i++)
167          printf("%d ", (int) TexEnabled[i]);
168       printf("\n");
169    }
170    else if (entry==ANIMATE) {
171       Animate = !Animate;
172    }
173    else if (entry==QUIT) {
174       exit(0);
175    }
176
177    glutPostRedisplay();
178 }
179
180
181 static void Key( unsigned char key, int x, int y )
182 {
183    (void) x;
184    (void) y;
185    switch (key) {
186       case 27:
187          exit(0);
188          break;
189    }
190    glutPostRedisplay();
191 }
192
193
194 static void SpecialKey( int key, int x, int y )
195 {
196    float step = 3.0;
197    (void) x;
198    (void) y;
199
200    switch (key) {
201       case GLUT_KEY_UP:
202          Xrot += step;
203          break;
204       case GLUT_KEY_DOWN:
205          Xrot -= step;
206          break;
207       case GLUT_KEY_LEFT:
208          Yrot += step;
209          break;
210       case GLUT_KEY_RIGHT:
211          Yrot -= step;
212          break;
213    }
214    glutPostRedisplay();
215 }
216
217
218 static void Init( int argc, char *argv[] )
219 {
220    GLuint texObj[8];
221    GLint size, i;
222
223    const char *exten = (const char *) glGetString(GL_EXTENSIONS);
224    if (!strstr(exten, "GL_ARB_multitexture")) {
225       printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n");
226       exit(1);
227    }
228
229    glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &NumUnits);
230    printf("%d texture units supported\n", NumUnits);
231    if (NumUnits > 8)
232       NumUnits = 8;
233
234    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
235    printf("%d x %d max texture size\n", size, size);
236
237    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
238
239    for (i = 0; i < NumUnits; i++) {
240       if (i < 2)
241          TexEnabled[i] = GL_TRUE;
242       else
243          TexEnabled[i] = GL_FALSE;
244    }
245
246    /* allocate two texture objects */
247    glGenTextures(NumUnits, texObj);
248
249    /* setup the texture objects */
250    for (i = 0; i < NumUnits; i++) {
251
252       glActiveTextureARB(GL_TEXTURE0_ARB + i);
253       glBindTexture(GL_TEXTURE_2D, texObj[i]);
254
255       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
256       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
257
258       if (i == 0) {
259          if (!LoadRGBMipmaps(TEXTURE_1_FILE, GL_RGB)) {
260             printf("Error: couldn't load texture image\n");
261             exit(1);
262          }
263       }
264       else if (i == 1) {
265          if (!LoadRGBMipmaps(TEXTURE_2_FILE, GL_RGB)) {
266             printf("Error: couldn't load texture image\n");
267             exit(1);
268          }
269       }
270       else {
271          /* checker */
272          GLubyte image[8][8][3];
273          GLint i, j;
274          for (i = 0; i < 8; i++) {
275             for (j = 0; j < 8; j++) {
276                if ((i + j) & 1) {
277                   image[i][j][0] = 50;
278                   image[i][j][1] = 50;
279                   image[i][j][2] = 50;
280                }
281                else {
282                   image[i][j][0] = 25;
283                   image[i][j][1] = 25;
284                   image[i][j][2] = 25;
285                }
286             }
287          }
288          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0,
289                       GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) image);
290       }
291
292       /* Bind texObj[i] to ith texture unit */
293       if (i < 2)
294          glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
295       else
296          glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
297
298       if (TexEnabled[i])
299          glEnable(GL_TEXTURE_2D);
300    }
301
302    glShadeModel(GL_FLAT);
303    glClearColor(0.3, 0.3, 0.4, 1.0);
304
305    if (argc > 1 && strcmp(argv[1], "-info")==0) {
306       printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
307       printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
308       printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
309       printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
310    }
311 }
312
313
314 int main( int argc, char *argv[] )
315 {
316    GLint i;
317
318    glutInit( &argc, argv );
319    glutInitWindowSize( 300, 300 );
320    glutInitWindowPosition( 0, 0 );
321    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
322    glutCreateWindow(argv[0] );
323
324    Init( argc, argv );
325
326    glutReshapeFunc( Reshape );
327    glutKeyboardFunc( Key );
328    glutSpecialFunc( SpecialKey );
329    glutDisplayFunc( Display );
330    glutIdleFunc( Idle );
331
332    glutCreateMenu(ModeMenu);
333
334    for (i = 0; i < NumUnits; i++) {
335       char s[100];
336       sprintf(s, "Toggle Texture %d", i);
337       glutAddMenuEntry(s, TEX0 + i);
338    }
339    glutAddMenuEntry("Toggle Animation", ANIMATE);
340    glutAddMenuEntry("Quit", QUIT);
341    glutAttachMenu(GLUT_RIGHT_BUTTON);
342
343    glutMainLoop();
344    return 0;
345 }