199 lines
4.6 KiB
C
199 lines
4.6 KiB
C
/*
|
|
* Test minification vs. magnification filtering.
|
|
* Draw two quads with different filtering modes:
|
|
*
|
|
* +--------------------------+ +--------------------------+
|
|
* | MagFilter = GL_LINEAR | | MagFilter = GL_LINEAR |
|
|
* | MinFilter = GL_LINEAR | | MinFilter = GL_NEAREST |
|
|
* +--------------------------+ +--------------------------+
|
|
*
|
|
* They should look different when the quad is smaller than the level 0
|
|
* texture size (when minifying).
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <GL/glut.h>
|
|
|
|
|
|
static GLint Width = 1000, Height = 500;
|
|
|
|
|
|
static GLint TexWidth = 256, TexHeight = 256;
|
|
static GLfloat Zpos = 5;
|
|
static GLboolean MipMap = 0*GL_TRUE;
|
|
static GLboolean LinearFilter = GL_TRUE;
|
|
|
|
|
|
static void
|
|
redraw(void)
|
|
{
|
|
GLfloat w = 1.0;
|
|
GLfloat h = 1.0;
|
|
|
|
glClear( GL_COLOR_BUFFER_BIT );
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glPushMatrix();
|
|
glTranslatef(-1.5, 0, -Zpos);
|
|
glBegin(GL_POLYGON);
|
|
glTexCoord2f(0, 0); glVertex2f(-w, -h);
|
|
glTexCoord2f(1, 0); glVertex2f( w, -h);
|
|
glTexCoord2f(1, 1); glVertex2f( w, h);
|
|
glTexCoord2f(0, 1); glVertex2f(-w, h);
|
|
glEnd();
|
|
glPopMatrix();
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glPushMatrix();
|
|
glTranslatef(1.5, 0, -Zpos);
|
|
glBegin(GL_POLYGON);
|
|
glTexCoord2f(0, 0); glVertex2f(-w, -h);
|
|
glTexCoord2f(1, 0); glVertex2f( w, -h);
|
|
glTexCoord2f(1, 1); glVertex2f( w, h);
|
|
glTexCoord2f(0, 1); glVertex2f(-w, h);
|
|
glEnd();
|
|
glPopMatrix();
|
|
|
|
glutSwapBuffers();
|
|
}
|
|
|
|
|
|
static void
|
|
init(void)
|
|
{
|
|
GLubyte color[10][4] = {
|
|
{ 0, 0, 0, 0 },
|
|
{ 1, 0, 0, 0 },
|
|
{ 0, 1, 0, 0 },
|
|
{ 0, 0, 1, 0 },
|
|
{ 0, 1, 1, 0 },
|
|
{ 1, 0, 1, 0 },
|
|
{ 1, 1, 0, 0 },
|
|
{ 1, 0, 0, 0 },
|
|
{ 0, 1, 0, 0 },
|
|
{ 0, 0, 1, 0 }
|
|
};
|
|
GLubyte *texImage;
|
|
|
|
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
|
printf("Left quad should be linear filtered and right should be nearest filtered.\n");
|
|
printf("Press z/Z to change quad distance.\n");
|
|
|
|
texImage = (GLubyte*) malloc(4 * TexWidth * TexHeight * sizeof(GLubyte));
|
|
assert(texImage);
|
|
|
|
{
|
|
GLint level = 0;
|
|
GLint w = TexWidth, h = TexHeight;
|
|
while (1) {
|
|
int i, j;
|
|
|
|
for (i = 0; i < h; i++) {
|
|
for (j = 0;j < w; j++) {
|
|
if (w==1 || h==1 || (((i / 2) ^ (j / 2)) & 1)) {
|
|
/*if (j < i) {*/
|
|
texImage[(i*w+j) * 4 + 0] = 255;
|
|
texImage[(i*w+j) * 4 + 1] = 255;
|
|
texImage[(i*w+j) * 4 + 2] = 255;
|
|
texImage[(i*w+j) * 4 + 3] = 255;
|
|
}
|
|
else {
|
|
texImage[(i*w+j) * 4 + 0] = color[level][0] * 255;
|
|
texImage[(i*w+j) * 4 + 1] = color[level][1] * 255;
|
|
texImage[(i*w+j) * 4 + 2] = color[level][2] * 255;
|
|
texImage[(i*w+j) * 4 + 3] = color[level][3] * 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0,
|
|
GL_RGBA, GL_UNSIGNED_BYTE, texImage);
|
|
|
|
printf("Texture level %d: %d x %d\n", level, w, h);
|
|
if (!MipMap)
|
|
break;
|
|
|
|
if (w == 1 && h == 1)
|
|
break;
|
|
if (w > 1)
|
|
w /= 2;
|
|
if (h > 1)
|
|
h /= 2;
|
|
level++;
|
|
}
|
|
}
|
|
|
|
free(texImage);
|
|
|
|
glClearColor(0.25, 0.25, 0.25, 1.0);
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glViewport(0, 0, Width, Height);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
Reshape(int width, int height)
|
|
{
|
|
float ar = (float) width /height;
|
|
Width = width;
|
|
Height = height;
|
|
glViewport(0, 0, width, height);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glFrustum(-ar, ar, -1.0, 1.0, 5.0, 2500.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glTranslatef(0.0, 0.0, -15.0);
|
|
}
|
|
|
|
|
|
static void
|
|
Key(unsigned char key, int x, int y)
|
|
{
|
|
(void) x;
|
|
(void) y;
|
|
switch (key) {
|
|
case 'z':
|
|
Zpos--;
|
|
break;
|
|
case 'Z':
|
|
Zpos++;
|
|
break;
|
|
case 'f':
|
|
LinearFilter = !LinearFilter;
|
|
break;
|
|
case 27:
|
|
exit(0);
|
|
break;
|
|
}
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
glutInit(&argc, argv);
|
|
glutInitWindowPosition(0, 0);
|
|
glutInitWindowSize(Width, Height);
|
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
|
glutCreateWindow(argv[0]);
|
|
glutReshapeFunc(Reshape);
|
|
glutKeyboardFunc(Key);
|
|
glutDisplayFunc(redraw);
|
|
init();
|
|
glutMainLoop();
|
|
return 0;
|
|
}
|