minmag.c revision 32001f49
1/*
2 * Test minification vs. magnification filtering.
3 * Draw two quads with different filtering modes:
4 *
5 *    +--------------------------+  +--------------------------+
6 *    |   MagFilter = GL_LINEAR  |  |  MagFilter = GL_LINEAR   |
7 *    |   MinFilter = GL_LINEAR  |  |  MinFilter = GL_NEAREST  |
8 *    +--------------------------+  +--------------------------+
9 *
10 * They should look different when the quad is smaller than the level 0
11 * texture size (when minifying).
12 */
13
14#include <assert.h>
15#include <math.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <GL/glew.h>
20#include "glut_wrap.h"
21
22
23static GLint Width = 1000, Height = 500;
24
25
26static GLint TexWidth = 256, TexHeight = 256;
27static GLfloat Zpos = 5;
28static GLboolean MipMap = 0*GL_TRUE;
29static GLboolean LinearFilter = GL_TRUE;
30
31
32static void
33redraw(void)
34{
35   GLfloat w = 1.0;
36   GLfloat h = 1.0;
37
38   glClear( GL_COLOR_BUFFER_BIT );
39
40   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
41
42   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
43
44   glPushMatrix();
45   glTranslatef(-1.5, 0, -Zpos);
46      glBegin(GL_POLYGON);
47      glTexCoord2f(0, 0);  glVertex2f(-w, -h);
48      glTexCoord2f(1, 0);  glVertex2f( w, -h);
49      glTexCoord2f(1, 1);  glVertex2f( w,  h);
50      glTexCoord2f(0, 1);  glVertex2f(-w,  h);
51      glEnd();
52   glPopMatrix();
53
54   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
55
56   glPushMatrix();
57   glTranslatef(1.5, 0, -Zpos);
58      glBegin(GL_POLYGON);
59      glTexCoord2f(0, 0);  glVertex2f(-w, -h);
60      glTexCoord2f(1, 0);  glVertex2f( w, -h);
61      glTexCoord2f(1, 1);  glVertex2f( w,  h);
62      glTexCoord2f(0, 1);  glVertex2f(-w,  h);
63      glEnd();
64   glPopMatrix();
65
66   glutSwapBuffers();
67}
68
69
70static void
71init(void)
72{
73   GLubyte color[10][4] = {
74      { 0, 0, 0, 0 },
75      { 1, 0, 0, 0 },
76      { 0, 1, 0, 0 },
77      { 0, 0, 1, 0 },
78      { 0, 1, 1, 0 },
79      { 1, 0, 1, 0 },
80      { 1, 1, 0, 0 },
81      { 1, 0, 0, 0 },
82      { 0, 1, 0, 0 },
83      { 0, 0, 1, 0 }
84   };
85   GLubyte *texImage;
86
87   printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
88   printf("Left quad should be linear filtered and right should be nearest filtered.\n");
89   printf("Press z/Z to change quad distance.\n");
90
91   texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
92   assert(texImage);
93
94   {
95      GLint level = 0;
96      GLint w = TexWidth, h = TexHeight;
97      while (1) {
98         int i, j;
99
100         for (i = 0; i < h; i++) {
101            for (j = 0;j < w; j++) {
102               if (w==1 || h==1 || (((i / 2) ^ (j / 2)) & 1)) {
103                  /*if (j < i) {*/
104                  texImage[(i*w+j) * 4 + 0] = 255;
105                  texImage[(i*w+j) * 4 + 1] = 255;
106                  texImage[(i*w+j) * 4 + 2] = 255;
107                  texImage[(i*w+j) * 4 + 3] = 255;
108               }
109               else {
110                  texImage[(i*w+j) * 4 + 0] = color[level][0] * 255;
111                  texImage[(i*w+j) * 4 + 1] = color[level][1] * 255;
112                  texImage[(i*w+j) * 4 + 2] = color[level][2] * 255;
113                  texImage[(i*w+j) * 4 + 3] = color[level][3] * 255;
114               }
115            }
116         }
117
118         glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0,
119                      GL_RGBA, GL_UNSIGNED_BYTE, texImage);
120
121         printf("Texture level %d: %d x %d\n", level, w, h);
122         if (!MipMap)
123            break;
124
125         if (w == 1 && h == 1)
126            break;
127         if (w > 1)
128            w /= 2;
129         if (h > 1)
130            h /= 2;
131         level++;
132      }
133   }
134
135   free(texImage);
136
137   glClearColor(0.25, 0.25, 0.25, 1.0);
138   glEnable(GL_TEXTURE_2D);
139
140   glViewport(0, 0, Width, Height);
141}
142
143
144
145static void
146Reshape(int width, int height)
147{
148   float ar = (float) width /height;
149   Width = width;
150   Height = height;
151   glViewport(0, 0, width, height);
152   glMatrixMode(GL_PROJECTION);
153   glLoadIdentity();
154   glFrustum(-ar, ar, -1.0, 1.0, 5.0, 2500.0);
155   glMatrixMode(GL_MODELVIEW);
156   glLoadIdentity();
157   glTranslatef(0.0, 0.0, -15.0);
158}
159
160
161static void
162Key(unsigned char key, int x, int y)
163{
164   (void) x;
165   (void) y;
166   switch (key) {
167   case 'z':
168      Zpos--;
169      break;
170   case 'Z':
171      Zpos++;
172      break;
173   case 'f':
174      LinearFilter = !LinearFilter;
175      break;
176   case 27:
177      exit(0);
178      break;
179   }
180   glutPostRedisplay();
181}
182
183
184int
185main(int argc, char *argv[])
186{
187   glutInit(&argc, argv);
188   glutInitWindowPosition(0, 0);
189   glutInitWindowSize(Width, Height);
190   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
191   glutCreateWindow(argv[0]);
192   glewInit();
193   glutReshapeFunc(Reshape);
194   glutKeyboardFunc(Key);
195   glutDisplayFunc(redraw);
196   init();
197   glutMainLoop();
198   return 0;
199}
200