OpenGL - 如何让这个程序适用于大于1x1的纹理?

时间:2017-11-05 03:13:52

标签: c opengl textures texture-mapping texture2d

我正在编写一个概念证明程序,以便更熟悉纹理,但它的行为奇怪,因为它适用于1x1纹理,但对其他所有纹理都不适用。我多次扫描程序并查看每个函数的参数,但无法理解为什么它适用于1x1纹理(或较大纹理中的第一个像素),但显示白色正方形。

这是使用glTexImage2D的宽度和高度参数(1,1)和(2,2)分别运行的相同程序的图片。

texture width, height -> 1,1 texture width, height -> 2,2

这是显示白色方块的代码(而预期会绘制2x2红色,绿色,蓝色,黄色主要纹理)。

  

注意in(Comment, Arg)宏与Arg相同,它仅在此特定程序中使用,因为记住glTexImage2D的参数非常棘手。< / p>

#include <GL/glut.h>

// | reminder decorator macro.
#define in(Comment, Arg) Arg

GLubyte bm[16] = {
    0xff, 0x00, 0x00, 0xff,
    0x00, 0xff, 0x00, 0xff,
    0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0x00, 0xff
};

GLuint tex;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);           

    glBindTexture(GL_TEXTURE_2D, tex);

    glLoadIdentity();

    // | make the square smaller to contrast our target from the background.
    glScalef(.5f, .5f, 1.f);

    glBegin(GL_TRIANGLE_FAN);
        glTexCoord2f(0.f, 0.f);
        glVertex2f(-1.f, 1.f);
        glTexCoord2f(0.f, 1.f);
        glVertex2f(1.f, 1.f);
        glTexCoord2f(1.f, 1.f);
        glVertex2f(1.f, -1.f);
        glTexCoord2f(1.f, 0.f);
        glVertex2f(-1.f, -1.f);
    glEnd();

    glFlush();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutCreateWindow("");

    glEnable(GL_TEXTURE_2D);        
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D (
        in(target, GL_TEXTURE_2D), 
        in(level, 0), 
        in(internalFormat, GL_RGBA), 
        in(width, 2), 
        in(height, 2), 
        in(border, 0), 
        in(format, GL_RGBA), 
        in(type, GL_UNSIGNED_BYTE), 
        in(data, bm)
    );
    glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

如果我将in(width, 2)更改为in(width, 1)而将in(height, 2)更改为in(height, 1),则会显示红色方块,并更改bm数组的前三个值,它会按预期将此颜色映射到多维数据集。

#include <GL/glut.h>

// | reminder decorator macro.
#define in(Comment, Arg) Arg

GLubyte bm[16] = {
    0xff, 0x00, 0x00, 0xff,
    0x00, 0xff, 0x00, 0xff,
    0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0x00, 0xff
};

GLuint tex;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);           

    glBindTexture(GL_TEXTURE_2D, tex);

    glLoadIdentity();

    // | make the square smaller to contrast our target from the background.
    glScalef(.5f, .5f, 1.f);

    glBegin(GL_TRIANGLE_FAN);
        glTexCoord2f(0.f, 0.f);
        glVertex2f(-1.f, 1.f);
        glTexCoord2f(0.f, 1.f);
        glVertex2f(1.f, 1.f);
        glTexCoord2f(1.f, 1.f);
        glVertex2f(1.f, -1.f);
        glTexCoord2f(1.f, 0.f);
        glVertex2f(-1.f, -1.f);
    glEnd();

    glFlush();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutCreateWindow("");

    glEnable(GL_TEXTURE_2D);        
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D (
        in(target, GL_TEXTURE_2D), 
        in(level, 0), 
        in(internalFormat, GL_RGBA), 
        in(width, 1), 
        in(height, 1), 
        in(border, 0), 
        in(format, GL_RGBA), 
        in(type, GL_UNSIGNED_BYTE), 
        in(data, bm)
    );
    glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

有人可以解释发生了什么以及如何解决这个问题吗?

  

解决方案:将tex传递给glTexParameteri而不是GL_TEXTURE_2D(旁注:以及glVertex2f中的拼写错误1.1到1.f)

#include <GL/glut.h>

// | reminder decorator macro.
#define in(Comment, Arg) Arg

GLubyte bm[16] = {
    0xff, 0x00, 0x00, 0xff,
    0x00, 0xff, 0x00, 0xff,
    0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0x00, 0xff
};

GLuint tex;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);           

    glBindTexture(GL_TEXTURE_2D, tex);

    glLoadIdentity();

    // | make the square smaller to contrast our target from the background.
    glScalef(.5f, .5f, 1.f);

    glBegin(GL_TRIANGLE_FAN);
        glTexCoord2f(0.f, 0.f);
        glVertex2f(-1.f, 1.f);
        glTexCoord2f(1.f, 0.f);
        glVertex2f(1.f, 1.f);
        glTexCoord2f(1.f, 1.f);
        glVertex2f(1.f, -1.f);
        glTexCoord2f(0.f, 1.f);
        glVertex2f(-1.f, -1.f);
    glEnd();

    glFlush();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutCreateWindow("");

    glEnable(GL_TEXTURE_2D);        
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D (
        in(target, GL_TEXTURE_2D), 
        in(level, 0), 
        in(internalFormat, GL_RGBA), 
        in(width, 2), 
        in(height, 2), 
        in(border, 0), 
        in(format, GL_RGBA), 
        in(type, GL_UNSIGNED_BYTE), 
        in(data, bm)
    );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

solved

1 个答案:

答案 0 :(得分:3)

指定2x2纹理时,纹理不是mipmap-complete,而是使用mip-mapping缩小滤镜。根据规范,您得到的结果是正确的结果。

您的错误在于您尝试设置非mipmapping GL_NEAREST过滤器:

glTexParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameter期望纹理绑定点,即GL_TEXTURE_2D,而不是纹理名称。因此,此调用将生成GL_INVALID_ENUM错误,并且没有其他影响。