blob: 7751afd46b1d72492bea19bc759c158263a18a6c [file] [log] [blame]
Brian Paul95e67dc2003-02-04 02:35:00 +00001/* $Id: texwrap.c,v 1.5 2003/02/04 02:35:00 brianp Exp $ */
Brian Paul0bc933a2001-03-26 19:45:57 +00002
3/*
4 * Test texture wrap modes.
Brian Paul77ff5e02001-04-12 20:50:26 +00005 * Press 'b' to toggle texture image borders. You should see the same
6 * rendering whether or not you're using borders.
Brian Paul0bc933a2001-03-26 19:45:57 +00007 *
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 Paulbc36ee22002-10-17 17:39:37 +000019#ifndef GL_CLAMP_TO_BORDER
20#define GL_CLAMP_TO_BORDER 0x812D
Brian Paul0bc933a2001-03-26 19:45:57 +000021#endif
22
Brian Paulbc36ee22002-10-17 17:39:37 +000023#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 Paul0bc933a2001-03-26 19:45:57 +000031
Brian Paul77ff5e02001-04-12 20:50:26 +000032#define BORDER_TEXTURE 1
33#define NO_BORDER_TEXTURE 2
34
35#define SIZE 8
36static GLubyte BorderImage[SIZE+2][SIZE+2][4];
37static GLubyte NoBorderImage[SIZE][SIZE][4];
38static GLuint Border = 1;
Brian Paul0bc933a2001-03-26 19:45:57 +000039
40
Brian Paulbc36ee22002-10-17 17:39:37 +000041#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
44struct wrap_mode {
45 GLenum mode;
46 const char * name;
47 GLboolean supported;
48 GLfloat version;
49 const char * extension_names[2];
50};
51
52static 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 Paul0bc933a2001-03-26 19:45:57 +000073static void
74PrintString(const char *s)
75{
76 while (*s) {
77 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
78 s++;
79 }
80}
81
82
83static void Display( void )
84{
Karl Schultz53d30c52002-10-18 17:47:35 +000085 GLenum i, j;
Brian Paulbc36ee22002-10-17 17:39:37 +000086 GLint offset;
87 GLfloat version;
Brian Paul0bc933a2001-03-26 19:45:57 +000088
Brian Paulbc36ee22002-10-17 17:39:37 +000089 /* 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 Paul0bc933a2001-03-26 19:45:57 +0000115
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);
Brian Paul95e67dc2003-02-04 02:35:00 +0000122 glWindowPos2iARB(1, 1);
Brian Paul0bc933a2001-03-26 19:45:57 +0000123 glDrawPixels(6, 6, GL_RGBA, GL_UNSIGNED_BYTE, (void *) TexImage);
124#endif
125
Brian Paul77ff5e02001-04-12 20:50:26 +0000126 glBindTexture(GL_TEXTURE_2D, Border ? BORDER_TEXTURE : NO_BORDER_TEXTURE);
Brian Paul0bc933a2001-03-26 19:45:57 +0000127
Brian Paulbc36ee22002-10-17 17:39:37 +0000128
Brian Paul0bc933a2001-03-26 19:45:57 +0000129 /* loop over min/mag filters */
130 for (i = 0; i < 2; i++) {
Brian Paulbc36ee22002-10-17 17:39:37 +0000131 offset = 0;
132
Brian Paul0bc933a2001-03-26 19:45:57 +0000133 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 Paulbc36ee22002-10-17 17:39:37 +0000143 for (j = 0; j < modes[j].mode != 0; j++) {
Brian Paul77ff5e02001-04-12 20:50:26 +0000144 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 Paulbc36ee22002-10-17 17:39:37 +0000147
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 Paul0bc933a2001-03-26 19:45:57 +0000153
154 glPushMatrix();
Brian Paulbc36ee22002-10-17 17:39:37 +0000155 glTranslatef(offset * 150 + 10, i * 150 + 40, 0);
156 offset++;
Brian Paul0bc933a2001-03-26 19:45:57 +0000157
Brian Paul77ff5e02001-04-12 20:50:26 +0000158 glEnable(GL_TEXTURE_2D);
159 glColor3f(1, 1, 1);
Brian Paul0bc933a2001-03-26 19:45:57 +0000160 glBegin(GL_POLYGON);
Brian Paul77ff5e02001-04-12 20:50:26 +0000161 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 Paul0bc933a2001-03-26 19:45:57 +0000175 glEnd();
176
177 glPopMatrix();
178 }
179 }
180
181 glDisable(GL_TEXTURE_2D);
Brian Paul77ff5e02001-04-12 20:50:26 +0000182 glColor3f(1, 1, 1);
Brian Paulbc36ee22002-10-17 17:39:37 +0000183 offset = 0;
184 for (i = 0; i < modes[i].mode != 0; i++) {
185 if ( modes[i].supported ) {
Brian Paul95e67dc2003-02-04 02:35:00 +0000186 glWindowPos2iARB( offset * 150 + 10, 5 + ((offset & 1) * 15) );
Brian Paulbc36ee22002-10-17 17:39:37 +0000187 PrintString(modes[i].name);
188 offset++;
189 }
Brian Paul0bc933a2001-03-26 19:45:57 +0000190 }
191
192 glutSwapBuffers();
193}
194
195
196static 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
207static void Key( unsigned char key, int x, int y )
208{
209 (void) x;
210 (void) y;
211 switch (key) {
Brian Paul77ff5e02001-04-12 20:50:26 +0000212 case 'b':
213 Border = !Border;
214 printf("Texture Border Size = %d\n", Border);
215 break;
Brian Paul0bc933a2001-03-26 19:45:57 +0000216 case 27:
217 exit(0);
218 break;
219 }
220 glutPostRedisplay();
221}
222
223
224static void Init( void )
225{
226 static const GLubyte border[4] = { 0, 255, 0, 255 };
Brian Paul77ff5e02001-04-12 20:50:26 +0000227 static const GLfloat borderf[4] = { 0, 1.0, 0, 1.0 };
Brian Paul0bc933a2001-03-26 19:45:57 +0000228 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 Paul77ff5e02001-04-12 20:50:26 +0000234 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 Paul0bc933a2001-03-26 19:45:57 +0000238 }
239 else if ((i + j) & 1) {
240 /* white */
Brian Paul77ff5e02001-04-12 20:50:26 +0000241 BorderImage[i][j][0] = 255;
242 BorderImage[i][j][1] = 255;
243 BorderImage[i][j][2] = 255;
244 BorderImage[i][j][3] = 255;
Brian Paul0bc933a2001-03-26 19:45:57 +0000245 }
246 else {
247 /* black */
Brian Paul77ff5e02001-04-12 20:50:26 +0000248 BorderImage[i][j][0] = 0;
249 BorderImage[i][j][1] = 0;
250 BorderImage[i][j][2] = 0;
251 BorderImage[i][j][3] = 0;
Brian Paul0bc933a2001-03-26 19:45:57 +0000252 }
253 }
254 }
255
Brian Paul77ff5e02001-04-12 20:50:26 +0000256 glBindTexture(GL_TEXTURE_2D, BORDER_TEXTURE);
Brian Paul0bc933a2001-03-26 19:45:57 +0000257 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1,
Brian Paul77ff5e02001-04-12 20:50:26 +0000258 GL_RGBA, GL_UNSIGNED_BYTE, (void *) BorderImage);
259
Brian Paul77ff5e02001-04-12 20:50:26 +0000260 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 Paul0bc933a2001-03-26 19:45:57 +0000283}
284
285
286int main( int argc, char *argv[] )
287{
288 glutInit( &argc, argv );
289 glutInitWindowPosition( 0, 0 );
Brian Paulbc36ee22002-10-17 17:39:37 +0000290 glutInitWindowSize( 800, 355 );
Brian Paul0bc933a2001-03-26 19:45:57 +0000291 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}