| /* |
| * 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; |
| } |