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