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