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
36 static GLubyte BorderImage
[SIZE
+2][SIZE
+2][4];
37 static GLubyte NoBorderImage
[SIZE
][SIZE
][4];
38 static GLuint Border
= 0;
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 } }
50 const char * extension_names
[2];
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",
59 WRAP_EXT ( GL_CLAMP_TO_BORDER
, "GL_ARB_texture_border_clamp",
60 "GL_SGIS_texture_border_clamp",
62 WRAP_EXT ( GL_MIRRORED_REPEAT
, "GL_ARB_texture_mirrored_repeat",
63 "GL_IBM_texture_mirrored_repeat",
65 WRAP_EXT ( GL_MIRROR_CLAMP_EXT
, "GL_ATI_texture_mirror_once",
66 "GL_EXT_texture_mirror_clamp",
68 WRAP_EXT ( GL_MIRROR_CLAMP_TO_BORDER_EXT
, "GL_EXT_texture_mirror_clamp",
71 WRAP_EXT ( GL_MIRROR_CLAMP_TO_EDGE_EXT
, "GL_ATI_texture_mirror_once",
72 "GL_EXT_texture_mirror_clamp",
78 PrintString(const char *s
)
81 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
87 static void Display( void )
93 /* Fill in the extensions that are supported.
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
;
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"
110 modes
[i
].extension_names
[0],
111 (modes
[i
].extension_names
[1] != NULL
)
113 (modes
[i
].extension_names
[1] != NULL
)
114 ? modes
[i
].extension_names
[1] : "" );
115 modes
[i
].supported
= GL_TRUE
;
120 glClearColor(0.5, 0.5, 0.5, 1.0);
121 glClear( GL_COLOR_BUFFER_BIT
);
124 /* draw texture as image */
125 glDisable(GL_TEXTURE_2D
);
126 glWindowPos2iARB(1, 1);
127 glDrawPixels(6, 6, GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) TexImage
);
130 glBindTexture(GL_TEXTURE_2D
, Border
? BORDER_TEXTURE
: NO_BORDER_TEXTURE
);
133 /* loop over min/mag filters */
134 for (i
= 0; i
< 2; i
++) {
138 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
139 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
142 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
143 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
146 /* loop over border modes */
147 for (j
= 0; modes
[j
].mode
!= 0; j
++) {
148 const GLfloat x0
= 0, y0
= 0, x1
= (TILE_SIZE
- 10), y1
= (TILE_SIZE
- 10);
149 const GLfloat b
= 1.2;
150 const GLfloat s0
= -b
, t0
= -b
, s1
= 1.0+b
, t1
= 1.0+b
;
152 if ( modes
[j
].supported
!= GL_TRUE
)
155 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, modes
[j
].mode
);
156 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, modes
[j
].mode
);
159 glTranslatef(offset
* TILE_SIZE
+ 10, i
* TILE_SIZE
+ 40, 0);
162 glEnable(GL_TEXTURE_2D
);
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
);
171 /* draw red outline showing bounds of texture at s=0,1 and t=0,1 */
172 glDisable(GL_TEXTURE_2D
);
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
));
185 glDisable(GL_TEXTURE_2D
);
188 for (i
= 0; modes
[i
].mode
!= 0; i
++) {
189 if ( modes
[i
].supported
) {
190 glWindowPos2iARB( offset
* TILE_SIZE
+ 10, 5 + ((offset
& 1) * 15) );
191 PrintString(modes
[i
].name
);
200 static void Reshape( int width
, int height
)
202 glViewport( 0, 0, width
, height
);
203 glMatrixMode( GL_PROJECTION
);
205 glOrtho(0, width
, 0, height
, -1, 1);
206 glMatrixMode( GL_MODELVIEW
);
211 static void Key( unsigned char key
, int x
, int y
)
218 printf("Texture Border Size = %d\n", Border
);
228 static void Init( void )
230 static const GLubyte border
[4] = { 0, 255, 0, 255 };
231 static const GLfloat borderf
[4] = { 0, 1.0, 0, 1.0 };
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) {
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];
243 else if ((i
+ j
) & 1) {
245 BorderImage
[i
][j
][0] = 255;
246 BorderImage
[i
][j
][1] = 255;
247 BorderImage
[i
][j
][2] = 255;
248 BorderImage
[i
][j
][3] = 255;
252 BorderImage
[i
][j
][0] = 0;
253 BorderImage
[i
][j
][1] = 0;
254 BorderImage
[i
][j
][2] = 0;
255 BorderImage
[i
][j
][3] = 0;
260 glBindTexture(GL_TEXTURE_2D
, BORDER_TEXTURE
);
261 #ifdef TEST_PBO_DLIST
262 /* test fetching teximage from PBO in display list */
264 GLuint b
= 42, l
= 10;
266 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER
, b
);
267 glBufferDataARB(GL_PIXEL_UNPACK_BUFFER
, sizeof(BorderImage
),
268 BorderImage
, GL_STREAM_DRAW
);
270 glNewList(l
, GL_COMPILE
);
271 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
+2, SIZE
+2, 1,
272 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) 0/* BorderImage*/);
275 glBindBufferARB(GL_PIXEL_UNPACK_BUFFER
, 0);
278 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
+2, SIZE
+2, 1,
279 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) BorderImage
);
282 for (i
= 0; i
< SIZE
; i
++) {
283 for (j
= 0; j
< SIZE
; j
++) {
286 NoBorderImage
[i
][j
][0] = 255;
287 NoBorderImage
[i
][j
][1] = 255;
288 NoBorderImage
[i
][j
][2] = 255;
289 NoBorderImage
[i
][j
][3] = 255;
293 NoBorderImage
[i
][j
][0] = 0;
294 NoBorderImage
[i
][j
][1] = 0;
295 NoBorderImage
[i
][j
][2] = 0;
296 NoBorderImage
[i
][j
][3] = 0;
301 glBindTexture(GL_TEXTURE_2D
, NO_BORDER_TEXTURE
);
302 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SIZE
, SIZE
, 0,
303 GL_RGBA
, GL_UNSIGNED_BYTE
, (void *) NoBorderImage
);
304 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_BORDER_COLOR
, borderf
);
308 int main( int argc
, char *argv
[] )
310 glutInit( &argc
, argv
);
311 glutInitWindowPosition( 0, 0 );
312 glutInitWindowSize( 1000, 270 );
313 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
314 glutCreateWindow(argv
[0]);
316 glutReshapeFunc( Reshape
);
317 glutKeyboardFunc( Key
);
318 glutDisplayFunc( Display
);