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