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