Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 1 | /* $Id: texwrap.c,v 1.3 2002/10/17 17:39:37 brianp Exp $ */ |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 2 | |
| 3 | /* |
| 4 | * Test texture wrap modes. |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 5 | * Press 'b' to toggle texture image borders. You should see the same |
| 6 | * rendering whether or not you're using borders. |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 7 | * |
| 8 | * Brian Paul March 2001 |
| 9 | */ |
| 10 | |
| 11 | |
| 12 | #define GL_GLEXT_PROTOTYPES |
| 13 | #include <stdio.h> |
| 14 | #include <stdlib.h> |
| 15 | #include <math.h> |
| 16 | #include <GL/glut.h> |
| 17 | |
| 18 | |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 19 | #ifndef GL_CLAMP_TO_BORDER |
| 20 | #define GL_CLAMP_TO_BORDER 0x812D |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 21 | #endif |
| 22 | |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 23 | #ifndef GL_MIRRORED_REPEAT |
| 24 | #define GL_MIRRORED_REPEAT 0x8370 |
| 25 | #endif |
| 26 | |
| 27 | #ifndef GL_ATI_texture_mirror_once |
| 28 | #define GL_MIRROR_CLAMP_ATI 0x8742 |
| 29 | #define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 |
| 30 | #endif |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 31 | |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 32 | #define BORDER_TEXTURE 1 |
| 33 | #define NO_BORDER_TEXTURE 2 |
| 34 | |
| 35 | #define SIZE 8 |
| 36 | static GLubyte BorderImage[SIZE+2][SIZE+2][4]; |
| 37 | static GLubyte NoBorderImage[SIZE][SIZE][4]; |
| 38 | static GLuint Border = 1; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 39 | |
| 40 | |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 41 | #define WRAP_MODE(m) { m , # m, GL_TRUE, 1.0, { NULL, NULL } } |
| 42 | #define WRAP_EXT(m,e1,e2,v) { m , # m, GL_FALSE, v, { e1, e2 } } |
| 43 | |
| 44 | struct wrap_mode { |
| 45 | GLenum mode; |
| 46 | const char * name; |
| 47 | GLboolean supported; |
| 48 | GLfloat version; |
| 49 | const char * extension_names[2]; |
| 50 | }; |
| 51 | |
| 52 | static struct wrap_mode modes[] = { |
| 53 | WRAP_MODE( GL_REPEAT ), |
| 54 | WRAP_MODE( GL_CLAMP ), |
| 55 | WRAP_EXT ( GL_CLAMP_TO_EDGE, "GL_EXT_texture_edge_clamp", |
| 56 | "GL_SGIS_texture_edge_clamp", |
| 57 | 1.2 ), |
| 58 | WRAP_EXT ( GL_CLAMP_TO_BORDER, "GL_ARB_texture_border_clamp", |
| 59 | "GL_SGIS_texture_border_clamp", |
| 60 | 1.3 ), |
| 61 | WRAP_EXT ( GL_MIRRORED_REPEAT, "GL_ARB_texture_mirrored_repeat", |
| 62 | "GL_IBM_texture_mirrored_repeat", |
| 63 | 1.4 ), |
| 64 | WRAP_EXT ( GL_MIRROR_CLAMP_ATI, "GL_ATI_texture_mirror_once", |
| 65 | NULL, |
| 66 | 999.0 ), |
| 67 | WRAP_EXT ( GL_MIRROR_CLAMP_TO_EDGE_ATI, "GL_ATI_texture_mirror_once", |
| 68 | NULL, |
| 69 | 999.0 ), |
| 70 | { 0 } |
| 71 | }; |
| 72 | |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 73 | static void |
| 74 | PrintString(const char *s) |
| 75 | { |
| 76 | while (*s) { |
| 77 | glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); |
| 78 | s++; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | |
| 83 | static void Display( void ) |
| 84 | { |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 85 | GLint i, j; |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 86 | GLint offset; |
| 87 | GLfloat version; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 88 | |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 89 | /* Fill in the extensions that are supported. |
| 90 | */ |
| 91 | |
| 92 | version = atof( (char *) glGetString( GL_VERSION ) ); |
| 93 | for ( i = 0 ; modes[i].mode != 0 ; i++ ) { |
| 94 | if ( ((modes[i].extension_names[0] != NULL) |
| 95 | && glutExtensionSupported(modes[i].extension_names[0])) |
| 96 | || ((modes[i].extension_names[1] != NULL) |
| 97 | && glutExtensionSupported(modes[i].extension_names[1])) ) { |
| 98 | modes[i].supported = GL_TRUE; |
| 99 | } |
| 100 | else if ( !modes[i].supported && (modes[i].version <= version) ) { |
| 101 | fprintf( stderr, "WARNING: OpenGL library meets minimum version\n" |
| 102 | " requirement for %s, but the\n" |
| 103 | " extension string is not advertised.\n" |
| 104 | " (%s%s%s)\n", |
| 105 | modes[i].name, |
| 106 | modes[i].extension_names[0], |
| 107 | (modes[i].extension_names[1] != NULL) |
| 108 | ? " or " : "", |
| 109 | (modes[i].extension_names[1] != NULL) |
| 110 | ? modes[i].extension_names[1] : "" ); |
| 111 | modes[i].supported = GL_TRUE; |
| 112 | } |
| 113 | } |
| 114 | |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 115 | |
| 116 | glClearColor(0.5, 0.5, 0.5, 1.0); |
| 117 | glClear( GL_COLOR_BUFFER_BIT ); |
| 118 | |
| 119 | #if 0 |
| 120 | /* draw texture as image */ |
| 121 | glDisable(GL_TEXTURE_2D); |
| 122 | glWindowPos2iMESA(1, 1); |
| 123 | glDrawPixels(6, 6, GL_RGBA, GL_UNSIGNED_BYTE, (void *) TexImage); |
| 124 | #endif |
| 125 | |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 126 | glBindTexture(GL_TEXTURE_2D, Border ? BORDER_TEXTURE : NO_BORDER_TEXTURE); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 127 | |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 128 | |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 129 | /* loop over min/mag filters */ |
| 130 | for (i = 0; i < 2; i++) { |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 131 | offset = 0; |
| 132 | |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 133 | if (i) { |
| 134 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 135 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 136 | } |
| 137 | else { |
| 138 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 139 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 140 | } |
| 141 | |
| 142 | /* loop over border modes */ |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 143 | for (j = 0; j < modes[j].mode != 0; j++) { |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 144 | const GLfloat x0 = 0, y0 = 0, x1 = 140, y1 = 140; |
| 145 | const GLfloat b = 0.2; |
| 146 | const GLfloat s0 = -b, t0 = -b, s1 = 1.0+b, t1 = 1.0+b; |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 147 | |
| 148 | if ( modes[j].supported != GL_TRUE ) |
| 149 | continue; |
| 150 | |
| 151 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, modes[j].mode); |
| 152 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, modes[j].mode); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 153 | |
| 154 | glPushMatrix(); |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 155 | glTranslatef(offset * 150 + 10, i * 150 + 40, 0); |
| 156 | offset++; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 157 | |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 158 | glEnable(GL_TEXTURE_2D); |
| 159 | glColor3f(1, 1, 1); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 160 | glBegin(GL_POLYGON); |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 161 | glTexCoord2f(s0, t0); glVertex2f(x0, y0); |
| 162 | glTexCoord2f(s1, t0); glVertex2f(x1, y0); |
| 163 | glTexCoord2f(s1, t1); glVertex2f(x1, y1); |
| 164 | glTexCoord2f(s0, t1); glVertex2f(x0, y1); |
| 165 | glEnd(); |
| 166 | |
| 167 | /* draw red outline showing bounds of texture at s=0,1 and t=0,1 */ |
| 168 | glDisable(GL_TEXTURE_2D); |
| 169 | glColor3f(1, 0, 0); |
| 170 | glBegin(GL_LINE_LOOP); |
| 171 | glVertex2f(x0 + b * (x1-x0) / (s1-s0), y0 + b * (y1-y0) / (t1-t0)); |
| 172 | glVertex2f(x1 - b * (x1-x0) / (s1-s0), y0 + b * (y1-y0) / (t1-t0)); |
| 173 | glVertex2f(x1 - b * (x1-x0) / (s1-s0), y1 - b * (y1-y0) / (t1-t0)); |
| 174 | glVertex2f(x0 + b * (x1-x0) / (s1-s0), y1 - b * (y1-y0) / (t1-t0)); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 175 | glEnd(); |
| 176 | |
| 177 | glPopMatrix(); |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | glDisable(GL_TEXTURE_2D); |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 182 | glColor3f(1, 1, 1); |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 183 | offset = 0; |
| 184 | for (i = 0; i < modes[i].mode != 0; i++) { |
| 185 | if ( modes[i].supported ) { |
| 186 | glWindowPos2iMESA( offset * 150 + 10, 5 + ((offset & 1) * 15) ); |
| 187 | PrintString(modes[i].name); |
| 188 | offset++; |
| 189 | } |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 190 | } |
| 191 | |
| 192 | glutSwapBuffers(); |
| 193 | } |
| 194 | |
| 195 | |
| 196 | static void Reshape( int width, int height ) |
| 197 | { |
| 198 | glViewport( 0, 0, width, height ); |
| 199 | glMatrixMode( GL_PROJECTION ); |
| 200 | glLoadIdentity(); |
| 201 | glOrtho(0, width, 0, height, -1, 1); |
| 202 | glMatrixMode( GL_MODELVIEW ); |
| 203 | glLoadIdentity(); |
| 204 | } |
| 205 | |
| 206 | |
| 207 | static void Key( unsigned char key, int x, int y ) |
| 208 | { |
| 209 | (void) x; |
| 210 | (void) y; |
| 211 | switch (key) { |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 212 | case 'b': |
| 213 | Border = !Border; |
| 214 | printf("Texture Border Size = %d\n", Border); |
| 215 | break; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 216 | case 27: |
| 217 | exit(0); |
| 218 | break; |
| 219 | } |
| 220 | glutPostRedisplay(); |
| 221 | } |
| 222 | |
| 223 | |
| 224 | static void Init( void ) |
| 225 | { |
| 226 | static const GLubyte border[4] = { 0, 255, 0, 255 }; |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 227 | static const GLfloat borderf[4] = { 0, 1.0, 0, 1.0 }; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 228 | GLint i, j; |
| 229 | |
| 230 | for (i = 0; i < SIZE+2; i++) { |
| 231 | for (j = 0; j < SIZE+2; j++) { |
| 232 | if (i == 0 || j == 0 || i == SIZE+1 || j == SIZE+1) { |
| 233 | /* border color */ |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 234 | BorderImage[i][j][0] = border[0]; |
| 235 | BorderImage[i][j][1] = border[1]; |
| 236 | BorderImage[i][j][2] = border[2]; |
| 237 | BorderImage[i][j][3] = border[3]; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 238 | } |
| 239 | else if ((i + j) & 1) { |
| 240 | /* white */ |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 241 | BorderImage[i][j][0] = 255; |
| 242 | BorderImage[i][j][1] = 255; |
| 243 | BorderImage[i][j][2] = 255; |
| 244 | BorderImage[i][j][3] = 255; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 245 | } |
| 246 | else { |
| 247 | /* black */ |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 248 | BorderImage[i][j][0] = 0; |
| 249 | BorderImage[i][j][1] = 0; |
| 250 | BorderImage[i][j][2] = 0; |
| 251 | BorderImage[i][j][3] = 0; |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 252 | } |
| 253 | } |
| 254 | } |
| 255 | |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 256 | glBindTexture(GL_TEXTURE_2D, BORDER_TEXTURE); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 257 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1, |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 258 | GL_RGBA, GL_UNSIGNED_BYTE, (void *) BorderImage); |
| 259 | |
Brian Paul | 77ff5e0 | 2001-04-12 20:50:26 +0000 | [diff] [blame] | 260 | for (i = 0; i < SIZE; i++) { |
| 261 | for (j = 0; j < SIZE; j++) { |
| 262 | if ((i + j) & 1) { |
| 263 | /* white */ |
| 264 | NoBorderImage[i][j][0] = 255; |
| 265 | NoBorderImage[i][j][1] = 255; |
| 266 | NoBorderImage[i][j][2] = 255; |
| 267 | NoBorderImage[i][j][3] = 255; |
| 268 | } |
| 269 | else { |
| 270 | /* black */ |
| 271 | NoBorderImage[i][j][0] = 0; |
| 272 | NoBorderImage[i][j][1] = 0; |
| 273 | NoBorderImage[i][j][2] = 0; |
| 274 | NoBorderImage[i][j][3] = 0; |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | glBindTexture(GL_TEXTURE_2D, NO_BORDER_TEXTURE); |
| 280 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, SIZE, 0, |
| 281 | GL_RGBA, GL_UNSIGNED_BYTE, (void *) NoBorderImage); |
| 282 | glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderf); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | |
| 286 | int main( int argc, char *argv[] ) |
| 287 | { |
| 288 | glutInit( &argc, argv ); |
| 289 | glutInitWindowPosition( 0, 0 ); |
Brian Paul | bc36ee2 | 2002-10-17 17:39:37 +0000 | [diff] [blame^] | 290 | glutInitWindowSize( 800, 355 ); |
Brian Paul | 0bc933a | 2001-03-26 19:45:57 +0000 | [diff] [blame] | 291 | glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); |
| 292 | glutCreateWindow(argv[0]); |
| 293 | glutReshapeFunc( Reshape ); |
| 294 | glutKeyboardFunc( Key ); |
| 295 | glutDisplayFunc( Display ); |
| 296 | Init(); |
| 297 | glutMainLoop(); |
| 298 | return 0; |
| 299 | } |