3 * Test texture wrap modes.
4 * Press 'b' to toggle texture image borders. You should see the same
5 * rendering whether or not you're using borders.
7 * Brian Paul March 2001
18 #ifndef GL_CLAMP_TO_BORDER
19 #define GL_CLAMP_TO_BORDER 0x812D
22 #ifndef GL_MIRRORED_REPEAT
23 #define GL_MIRRORED_REPEAT 0x8370
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
32 #define BORDER_TEXTURE 1
33 #define NO_BORDER_TEXTURE 2
34 #define COLOR_TEX_CORNERS 0
37 static GLubyte BorderImage
[SIZE
+2][SIZE
+2][4];
38 static GLubyte NoBorderImage
[SIZE
][SIZE
][4];
39 static GLuint Border
= 0;
43 #define WRAP_MODE(m) { m , # m, GL_TRUE, 1.0, { NULL, NULL } }
44 #define WRAP_EXT(m,e1,e2,v) { m , # m, GL_FALSE, v, { e1, e2 } }
51 const char * extension_names
[2];
54 static struct wrap_mode modes
[] = {
55 WRAP_MODE( GL_REPEAT
),
56 WRAP_MODE( GL_CLAMP
),
57 WRAP_EXT ( GL_CLAMP_TO_EDGE
, "GL_EXT_texture_edge_clamp",
58 "GL_SGIS_texture_edge_clamp",
60 WRAP_EXT ( GL_CLAMP_TO_BORDER
, "GL_ARB_texture_border_clamp",
61 "GL_SGIS_texture_border_clamp",
63 WRAP_EXT ( GL_MIRRORED_REPEAT
, "GL_ARB_texture_mirrored_repeat",
64 "GL_IBM_texture_mirrored_repeat",
66 WRAP_EXT ( GL_MIRROR_CLAMP_EXT
, "GL_ATI_texture_mirror_once",
67 "GL_EXT_texture_mirror_clamp",
69 WRAP_EXT ( GL_MIRROR_CLAMP_TO_BORDER_EXT
, "GL_EXT_texture_mirror_clamp",
72 WRAP_EXT ( GL_MIRROR_CLAMP_TO_EDGE_EXT
, "GL_ATI_texture_mirror_once",
73 "GL_EXT_texture_mirror_clamp",
75 { 0, NULL
, GL_FALSE
, 0.0, { NULL
, NULL
} }
79 PrintString(const char *s
)
82 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
88 static void Display( void )
94 /* Fill in the extensions that are supported.
97 version
= atof( (char *) glGetString( GL_VERSION
) );
98 for ( i
= 0 ; modes
[i
].mode
!= 0 ; i
++ ) {
99 if ( ((modes
[i
].extension_names
[0] != NULL
)
100 && glutExtensionSupported(modes
[i
].extension_names
[0]))
101 || ((modes
[i
].extension_names
[1] != NULL
)
102 && glutExtensionSupported(modes
[i
].extension_names
[1])) ) {
103 modes
[i
].supported
= GL_TRUE
;
105 else if ( !modes
[i
].supported
&& (modes
[i
].version
<= version
) ) {
106 fprintf( stderr
, "WARNING: OpenGL library meets minimum version\n"
107 " requirement for %s, but the\n"
108 " extension string is not advertised.\n"
111 modes
[i
].extension_names
[0],
112 (modes
[i
].extension_names
[1] != NULL
)
114 (modes
[i
].extension_names
[1] != NULL
)
115 ? modes
[i
].extension_names
[1] : "" );
116 modes
[i
].supported
= GL_TRUE
;
121 glClearColor(0.5, 0.5, 0.5, 1.0);
122 glClear( GL_COLOR_BUFFER_BIT
);
125 /* draw texture as image */
126 glDisable(GL_TEXTURE_2D
);
127 glWindowPos2iARB(1, 1);
128 glDrawPixels(6, 6, GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) TexImage
);
131 glBindTexture(GL_TEXTURE_2D
, Border
? BORDER_TEXTURE
: NO_BORDER_TEXTURE
);
134 /* loop over min/mag filters */
135 for (i
= 0; i
< 2; i
++) {
139 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
140 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
143 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
144 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
147 /* loop over border modes */
148 for (j
= 0; modes
[j
].mode
!= 0; j
++) {
149 const GLfloat x0
= 0, y0
= 0, x1
= (TILE_SIZE
- 10), y1
= (TILE_SIZE
- 10);
150 const GLfloat b
= 1.2;
151 const GLfloat s0
= -b
, t0
= -b
, s1
= 1.0+b
, t1
= 1.0+b
;
153 if ( modes
[j
].supported
!= GL_TRUE
)
156 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, modes
[j
].mode
);
157 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, modes
[j
].mode
);
160 glTranslatef(offset
* TILE_SIZE
+ 10, i
* TILE_SIZE
+ 40, 0);
163 glEnable(GL_TEXTURE_2D
);
166 glTexCoord2f(s0
, t0
); glVertex2f(x0
, y0
);
167 glTexCoord2f(s1
, t0
); glVertex2f(x1
, y0
);
168 glTexCoord2f(s1
, t1
); glVertex2f(x1
, y1
);
169 glTexCoord2f(s0
, t1
); glVertex2f(x0
, y1
);
172 /* draw red outline showing bounds of texture at s=0,1 and t=0,1 */
173 glDisable(GL_TEXTURE_2D
);
175 glBegin(GL_LINE_LOOP
);
176 glVertex2f(x0
+ b
* (x1
-x0
) / (s1
-s0
), y0
+ b
* (y1
-y0
) / (t1
-t0
));
177 glVertex2f(x1
- b
* (x1
-x0
) / (s1
-s0
), y0
+ b
* (y1
-y0
) / (t1
-t0
));
178 glVertex2f(x1
- b
* (x1
-x0
) / (s1
-s0
), y1
- b
* (y1
-y0
) / (t1
-t0
));
179 glVertex2f(x0
+ b
* (x1
-x0
) / (s1
-s0
), y1
- b
* (y1
-y0
) / (t1
-t0
));
186 glDisable(GL_TEXTURE_2D
);
189 for (i
= 0; modes
[i
].mode
!= 0; i
++) {
190 if ( modes
[i
].supported
) {
191 glWindowPos2iARB( offset
* TILE_SIZE
+ 10, 5 + ((offset
& 1) * 15) );
192 PrintString(modes
[i
].name
);
201 static void Reshape( int width
, int height
)
203 glViewport( 0, 0, width
, height
);
204 glMatrixMode( GL_PROJECTION
);
206 glOrtho(0, width
, 0, height
, -1, 1);
207 glMatrixMode( GL_MODELVIEW
);
212 static void Key( unsigned char key
, int x
, int y
)
219 printf("Texture Border Size = %d\n", Border
);
229 static void Init( void )
231 static const GLubyte border
[4] = { 0, 255, 0, 255 };
232 static const GLfloat borderf
[4] = { 0, 1.0, 0, 1.0 };
235 for (i
= 0; i
< SIZE
+2; i
++) {
236 for (j
= 0; j
< SIZE
+2; j
++) {
237 if (i
== 0 || j
== 0 || i
== SIZE
+1 || j
== SIZE
+1) {
239 BorderImage
[i
][j
][0] = border
[0];
240 BorderImage
[i
][j
][1] = border
[1];
241 BorderImage
[i
][j
][2] = border
[2];
242 BorderImage
[i
][j
][3] = border
[3];
244 else if ((i
+ j
) & 1) {
246 BorderImage
[i
][j
][0] = 255;
247 BorderImage
[i
][j
][1] = 255;
248 BorderImage
[i
][j
][2] = 255;
249 BorderImage
[i
][j
][3] = 255;
253 BorderImage
[i
][j
][0] = 0;
254 BorderImage
[i
][j
][1] = 0;
255 BorderImage
[i
][j
][2] = 0;
256 BorderImage
[i
][j
][3] = 0;
261 glBindTexture(GL_TEXTURE_2D
, BORDER_TEXTURE
);
262 #ifdef TEST_PBO_DLIST
263 /* test fetching teximage from PBO in display list */
265 GLuint b
= 42, l
= 10;
267 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER
, b
);
268 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER
, sizeof(BorderImage
),
269 BorderImage
, GL_STREAM_DRAW
);
271 glNewList(l
, GL_COMPILE
);
272 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
+2, SIZE
+2, 1,
273 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) 0/* BorderImage*/);
276 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER
, 0);
279 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
+2, SIZE
+2, 1,
280 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) BorderImage
);
283 for (i
= 0; i
< SIZE
; i
++) {
284 for (j
= 0; j
< SIZE
; j
++) {
285 #if COLOR_TEX_CORNERS
286 if (i
== 0 && j
== 0) {
287 /* lower-left texel = RED */
288 NoBorderImage
[i
][j
][0] = 255;
289 NoBorderImage
[i
][j
][1] = 0;
290 NoBorderImage
[i
][j
][2] = 0;
291 NoBorderImage
[i
][j
][3] = 255;
293 else if (i
== 0 && j
== SIZE
-1) {
294 /* lower-right corner = GREEN */
295 NoBorderImage
[i
][j
][0] = 0;
296 NoBorderImage
[i
][j
][1] = 255;
297 NoBorderImage
[i
][j
][2] = 0;
298 NoBorderImage
[i
][j
][3] = 255;
300 else if (i
== SIZE
-1 && j
== 0) {
301 /* upper-left corner = BLUE */
302 NoBorderImage
[i
][j
][0] = 0;
303 NoBorderImage
[i
][j
][1] = 0;
304 NoBorderImage
[i
][j
][2] = 255;
305 NoBorderImage
[i
][j
][3] = 255;
307 else if (i
== SIZE
-1 && j
== SIZE
-1) {
308 /* upper-right corner = YELLOW */
309 NoBorderImage
[i
][j
][0] = 255;
310 NoBorderImage
[i
][j
][1] = 255;
311 NoBorderImage
[i
][j
][2] = 0;
312 NoBorderImage
[i
][j
][3] = 255;
318 NoBorderImage
[i
][j
][0] = 255;
319 NoBorderImage
[i
][j
][1] = 255;
320 NoBorderImage
[i
][j
][2] = 255;
321 NoBorderImage
[i
][j
][3] = 255;
325 NoBorderImage
[i
][j
][0] = 0;
326 NoBorderImage
[i
][j
][1] = 0;
327 NoBorderImage
[i
][j
][2] = 0;
328 NoBorderImage
[i
][j
][3] = 0;
333 glBindTexture(GL_TEXTURE_2D
, NO_BORDER_TEXTURE
);
334 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
, SIZE
, 0,
335 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) NoBorderImage
);
336 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_BORDER_COLOR
, borderf
);
340 int main( int argc
, char *argv
[] )
342 glutInit( &argc
, argv
);
343 glutInitWindowPosition( 0, 0 );
344 glutInitWindowSize( 1000, 270 );
345 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
346 glutCreateWindow(argv
[0]);
348 glutReshapeFunc( Reshape
);
349 glutKeyboardFunc( Key
);
350 glutDisplayFunc( Display
);