Merge remote branch 'origin/master' into lp-binning
[mesa.git] / progs / tests / mipmap_limits.c
1 /* Test GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL
2 * Brian Paul
3 * 10 May 2006
4 */
5
6
7 /* Copyright (c) Mark J. Kilgard, 1994. */
8
9 /*
10 * (c) Copyright 1993, Silicon Graphics, Inc.
11 * ALL RIGHTS RESERVED
12 * Permission to use, copy, modify, and distribute this software for
13 * any purpose and without fee is hereby granted, provided that the above
14 * copyright notice appear in all copies and that both the copyright notice
15 * and this permission notice appear in supporting documentation, and that
16 * the name of Silicon Graphics, Inc. not be used in advertising
17 * or publicity pertaining to distribution of the software without specific,
18 * written prior permission.
19 *
20 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
21 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
22 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
23 * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
24 * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
25 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
26 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
27 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
28 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
29 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
31 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
32 *
33 * US Government Users Restricted Rights
34 * Use, duplication, or disclosure by the Government is subject to
35 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
36 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
37 * clause at DFARS 252.227-7013 and/or in similar or successor
38 * clauses in the FAR or the DOD or NASA FAR Supplement.
39 * Unpublished-- rights reserved under the copyright laws of the
40 * United States. Contractor/manufacturer is Silicon Graphics,
41 * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
42 *
43 * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
44 */
45 /* mipmap.c
46 * This program demonstrates using mipmaps for texture maps.
47 * To overtly show the effect of mipmaps, each mipmap reduction
48 * level has a solidly colored, contrasting texture image.
49 * Thus, the quadrilateral which is drawn is drawn with several
50 * different colors.
51 */
52 #include <stdlib.h>
53 #include <stdio.h>
54 #include <GL/glew.h>
55 #include <GL/glut.h>
56
57 #include "readtex.h"
58
59 #define TEXTURE_FILE "../images/girl.rgb"
60
61 static GLint BaseLevel = 0, MaxLevel = 9;
62 static GLfloat MinLod = -1, MaxLod = 9;
63 static GLfloat LodBias = 0.0;
64 static GLboolean NearestFilter = GL_TRUE;
65 static GLuint texImage, texColor, texCurrent;
66
67
68 static void
69 InitValues(void)
70 {
71 BaseLevel = 0;
72 MaxLevel = 9;
73 MinLod = -1;
74 MaxLod = 9;
75 LodBias = 0.0;
76 NearestFilter = GL_TRUE;
77 }
78
79
80 static void
81 MakeImage(int level, int width, int height, const GLubyte color[4])
82 {
83 const int makeStripes = 0;
84 GLubyte img[512 * 512 * 3];
85 int i, j;
86 for (i = 0; i < height; i++) {
87 for (j = 0; j < width; j++) {
88 int k = (i * width + j) * 3;
89 int p = (i / 8) & makeStripes;
90 if (p == 0) {
91 img[k + 0] = color[0];
92 img[k + 1] = color[1];
93 img[k + 2] = color[2];
94 }
95 else {
96 img[k + 0] = 0;
97 img[k + 1] = 0;
98 img[k + 2] = 0;
99 }
100 }
101 }
102
103 glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, width, height, 0,
104 GL_RGB, GL_UNSIGNED_BYTE, img);
105 }
106
107
108 static void
109 makeImages(int image)
110 {
111 #define WIDTH 512
112 #define HEIGHT 512
113 if (glutExtensionSupported("GL_SGIS_generate_mipmap") && image) {
114 /* test auto mipmap generation */
115 GLint width, height, i;
116 GLenum format;
117 GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format);
118 if (!image) {
119 printf("Error: could not load texture image %s\n", TEXTURE_FILE);
120 exit(1);
121 }
122 /* resize */
123 if (width != WIDTH || height != HEIGHT) {
124 GLubyte *newImage = malloc(WIDTH * HEIGHT * 4);
125 gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
126 WIDTH, HEIGHT, GL_UNSIGNED_BYTE, newImage);
127 free(image);
128 image = newImage;
129 }
130 printf("Using GL_SGIS_generate_mipmap\n");
131 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
132 glTexImage2D(GL_TEXTURE_2D, 0, format, WIDTH, HEIGHT, 0,
133 format, GL_UNSIGNED_BYTE, image);
134 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
135 free(image);
136
137 /* make sure mipmap was really generated correctly */
138 width = WIDTH;
139 height = HEIGHT;
140 for (i = 0; i < 10; i++) {
141 GLint w, h;
142 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
143 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
144 printf("Level %d size: %d x %d\n", i, w, h);
145 width /= 2;
146 height /= 2;
147 }
148 }
149 else {
150 static const GLubyte colors[10][3] = {
151 {128, 128, 128},
152 {0, 255, 255},
153 {255, 255, 0},
154 {255, 0, 255},
155 {255, 0, 0},
156 {0, 255, 0},
157 {0, 0, 255},
158 {0, 255, 255},
159 {255, 255, 0},
160 {255, 255, 255}
161 };
162 int i, sz = 512;
163
164 for (i = 0; i < 10; i++) {
165 MakeImage(i, sz, sz, colors[i]);
166 printf("Level %d size: %d x %d\n", i, sz, sz);
167 sz /= 2;
168 }
169 }
170 }
171
172 static void
173 myinit(void)
174 {
175 InitValues();
176
177 glEnable(GL_DEPTH_TEST);
178 glDepthFunc(GL_LESS);
179 glShadeModel(GL_FLAT);
180
181 glTranslatef(0.0, 0.0, -3.6);
182
183 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
184 glGenTextures(1, &texImage);
185 glBindTexture(GL_TEXTURE_2D, texImage);
186 makeImages(1);
187 glGenTextures(1, &texColor);
188 glBindTexture(GL_TEXTURE_2D, texColor);
189 makeImages(0);
190
191 texCurrent = texImage;
192
193 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
194 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
195 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
196 glEnable(GL_TEXTURE_2D);
197 }
198
199 static void
200 display(void)
201 {
202 GLfloat tcm = 1.0;
203 glBindTexture(GL_TEXTURE_2D, texCurrent);
204
205 printf
206 ("BASE_LEVEL=%d MAX_LEVEL=%d MIN_LOD=%.2g MAX_LOD=%.2g Bias=%.2g Filter=%s\n",
207 BaseLevel, MaxLevel, MinLod, MaxLod, LodBias,
208 NearestFilter ? "NEAREST" : "LINEAR");
209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel);
210 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel);
211
212 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, MinLod);
213 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, MaxLod);
214
215 if (NearestFilter) {
216 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
217 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
218 GL_NEAREST_MIPMAP_NEAREST);
219 }
220 else {
221 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
222 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
223 GL_LINEAR_MIPMAP_LINEAR);
224 }
225
226 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, LodBias);
227
228 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229 glBegin(GL_QUADS);
230 glTexCoord2f(0.0, 0.0);
231 glVertex3f(-2.0, -1.0, 0.0);
232 glTexCoord2f(0.0, tcm);
233 glVertex3f(-2.0, 1.0, 0.0);
234 glTexCoord2f(tcm * 3000.0, tcm);
235 glVertex3f(3000.0, 1.0, -6000.0);
236 glTexCoord2f(tcm * 3000.0, 0.0);
237 glVertex3f(3000.0, -1.0, -6000.0);
238 glEnd();
239 glFlush();
240 }
241
242 static void
243 myReshape(int w, int h)
244 {
245 glViewport(0, 0, w, h);
246 glMatrixMode(GL_PROJECTION);
247 glLoadIdentity();
248 gluPerspective(60.0, 1.0 * (GLfloat) w / (GLfloat) h, 1.0, 30000.0);
249 glMatrixMode(GL_MODELVIEW);
250 glLoadIdentity();
251 }
252
253
254 static void
255 usage(void)
256 {
257 printf("usage:\n");
258 printf(" b/B decrease/increase GL_TEXTURE_BASE_LEVEL\n");
259 printf(" m/M decrease/increase GL_TEXTURE_MAX_LEVEL\n");
260 printf(" n/N decrease/increase GL_TEXTURE_MIN_LOD\n");
261 printf(" x/X decrease/increase GL_TEXTURE_MAX_LOD\n");
262 printf(" l/L decrease/increase GL_TEXTURE_LOD_BIAS\n");
263 printf(" f toggle nearest/linear filtering\n");
264 printf(" t toggle texture color/image\n");
265 printf(" SPACE reset values\n");
266 }
267
268 static void
269 key(unsigned char k, int x, int y)
270 {
271 (void) x;
272 (void) y;
273 switch (k) {
274 case 'b':
275 BaseLevel--;
276 if (BaseLevel < 0)
277 BaseLevel = 0;
278 break;
279 case 'B':
280 BaseLevel++;
281 if (BaseLevel > 10)
282 BaseLevel = 10;
283 break;
284 case 'm':
285 MaxLevel--;
286 if (MaxLevel < 0)
287 MaxLevel = 0;
288 break;
289 case 'M':
290 MaxLevel++;
291 if (MaxLevel > 10)
292 MaxLevel = 10;
293 break;
294 case 'l':
295 LodBias -= 0.25;
296 break;
297 case 'L':
298 LodBias += 0.25;
299 break;
300 case 'n':
301 MinLod -= 0.25;
302 break;
303 case 'N':
304 MinLod += 0.25;
305 break;
306 case 'x':
307 MaxLod -= 0.25;
308 break;
309 case 'X':
310 MaxLod += 0.25;
311 break;
312 case 'f':
313 NearestFilter = !NearestFilter;
314 break;
315 case 't':
316 if (texCurrent == texColor)
317 texCurrent = texImage;
318 else
319 texCurrent = texColor;
320 break;
321 case ' ':
322 InitValues();
323 /* fall-through */
324 case 'u':
325 usage();
326 break;
327 case 27: /* Escape */
328 exit(0);
329 break;
330 default:
331 return;
332 }
333 glutPostRedisplay();
334 }
335
336
337 int
338 main(int argc, char **argv)
339 {
340 glutInit(&argc, argv);
341 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
342 glutInitWindowSize(600, 600);
343 glutCreateWindow(argv[0]);
344 glewInit();
345 myinit();
346 glutReshapeFunc(myReshape);
347 glutDisplayFunc(display);
348 glutKeyboardFunc(key);
349 usage();
350 glutMainLoop();
351 return 0; /* ANSI C requires main to return int. */
352 }