使用OpenGL

问题描述

我正在尝试在迷你OpenGL程序中使用纹理。由于使用OpenGL需要大量重复的代码,因此我将代码抽象为一个类。但我在窗户上看不到任何东西。 OpenGL不会引发任何错误。我正在使用stb_image.h中的https://github.com/nothings/stb/处理图像文件。我做错了什么?我正在使用Ubuntu 20.04。

类声明:

class texture {
protected:
    unsigned int textureid;
    unsigned char* localbuf;
    int length,width,pixelbit;
    std::string srcpath;
public:
    texture(std::string file);
    ~texture();
    int getwidth() const;
    int getlength() const;
    void bind(unsigned int slot = 0) const;
    void unbind() const;
};

类实现:

texture::texture(std::string file) {
    srcpath = file;

    stbi_set_flip_vertically_on_load(1);
    localbuf = stbi_load(file.c_str(),&width,&length,&pixelbit,4);

    glcall(glGenTextures(1,&textureid));
    glcall(glBindTexture(GL_TEXTURE_2D,textureid));

    glcall(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR));
    glcall(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE));
    glcall(glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE));

    glcall(glTexImage2D(GL_TEXTURE_2D,GL_RGBA8,length,GL_RGBA,GL_UNSIGNED_BYTE,localbuf))

    glcall(glBindTexture(GL_TEXTURE_2D,0));

    if (localbuf) stbi_image_free(localbuf);
}

texture::~texture() {
    glcall(glDeleteTextures(1,&textureid));
}

void texture::bind(unsigned int slot) const {
    glcall(glActiveTexture(GL_TEXTURE0 + slot));
    glcall(glBindTexture(GL_TEXTURE_2D,textureid));
}

void texture::unbind() const {
    glcall(glBindTexture(GL_TEXTURE_2D,0));
}

int texture::getwidth() const {
    return width;
}

int texture::getlength() const {
    return length;
}

顶点着色器:

#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texpos;
out vec2 v_texpos;
void main() {
    gl_Position = position;
    v_texpos = texpos;
};

片段着色器:

#version 330 core
layout(location = 0) out vec4 color;
in vec2 v_texpos; 
uniform sampler2D u_texture;
void main() {
    vec4 texcolor = texture2D(u_texture,v_texpos);
    color = texcolor;
};

main功能

int main() {
    ...
    texture mytexture("path/to/image/file.png");
    texture.bind();
    gluniform1i(glGetUniformlocation(shader,"u_texture"),0);
    ...
    while (window_open) {
        ...
        glDrawElements(...);
        ...
    }
    ...
}

解决方法

我正在使用类来处理顶点的布局。在该类的实现中,存在这样的循环:

for (int i = 0; i < ...; i++) {
    ...
    glEnableVertexAttribArray(i);
    ...
}

以上是正确的,但是我以前通过输入0而不是i来犯错,

glEnableVertexAttribArray(0);

当我不处理纹理时,此循环运行一次,并且i的值为0。但是,当开始处理纹理时,此循环运行了两次,并且i并非总是0,从而导致错误。