无法使用 VertexArrayObject 在 OpenGL 4.3 中显示纹理

Cannot show texture in OpenGL 4.3 using VertexArrayObject

从两天前开始,我就在敲这段代码。看起来创建缓冲区或纹理没有任何错误,但纹理不显示。

这是我的纹理加载代码:

struct image2d texImage = loadBMPImage(filePath);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texImage.width, texImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texImage.pixels);
free(texImage.pixels);

image2d结构就是这个

struct image2d{
    unsigned int width, height;
    unsigned char* pixels;
};

是的,我正在通过 glEnable()

启用 GL_TEXTURE_2D

然后我的网格是用这段代码绘制的

void MeshDraw(Mesh m, int renderType)
{
    glBindVertexArray(m.external->vao);
    glBindBuffer(GL_ARRAY_BUFFER, m.external->vbo);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, (void*)12);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.external->ibo);
    glDrawElements(GL_TRIANGLES, m.external->sizeFc * 3, GL_UNSIGNED_SHORT, 0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    return;
}

最后是我的顶点着色器

#version 430 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 inTexCoord;

uniform mat4 transform;

out vec2 texCoord;
out vec3 outPos;

void main(void)
{
    outPos = position;
    gl_Position = transform * vec4(position, 1.0);
    texCoord = inTexCoord;
}

这是我的片段着色器

#version 430 core

out vec4 drawColor;

in vec2 texCoord;
in vec3 outPos;

uniform sampler2D sampler;

void main(void)
{
    drawColor = texture(sampler, texCoord);
    //drawColor = vec4(clamp(outPos, 0.0, 1.0), 1.0);
}

如果您需要查看整个项目,我将其发布 here

如有任何帮助,我将不胜感激:)


附加代码(如果有人想看的话,也在下载中)

void initOpenGL()
{
    printf("OpenGL version: %s\n",glGetString(GL_VERSION));
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glFrontFace(GL_CW);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_FRAMEBUFFER_SRGB);
    return;
}

创建上下文并初始化 glew 后立即调用它。

void RenderGame(Game g)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    ShaderBind(g.external->sh);
    setUniformmat4(g.external->sh, "transform", TransformGetProjectedTransformation(g.external->transf));
    TextureBind(g.external->texture);
    MeshDraw(g.external->msh, GL_TRIANGLES);
    glFlush();
    glfwSwapBuffers(WindowGetHandler(g.external->window));
    return;
}

这是我的渲染方法。

您的纹理不是完整的 mipmap,但您仍在使用默认的 GL_NEAREST_MIPMAP_LINEAR 缩小过滤器,因此纹理采样将失败。

你尝试设置为GL_NEAREST,但是这个操作顺序是错误的:

glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);

在 GL 中,纹理采样器状态是纹理对象本身的一部分(现在也有单独的 sampler objects 可以覆盖该状态,但您似乎也没有使用它们),并且glTexParameteri() 在调用时影响 当前绑定的纹理对象 。我不知道当时是否绑定了某些纹理,或者根本 none - 但可以肯定的是,新纹理没有,所以它将坚持 GL_NEAREST_MIPMAP_LINEAR 的初始默认值...

解决方案看来@peppe 一直都是对的。为了一丝不苟,我使用 setuniform 调用将采样器设置为 0,它起作用了。问题是它没有按预期工作,这是因为加载位图文件的函数出错了。现在它就像一个魅力:)谢谢你们!