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

时间:2015-07-25 12:05:38

标签: c opengl texture2d

两天前,我对这段代码感到震惊。似乎没有任何类型的错误创建缓冲区或纹理,但纹理不显示。

这是我的纹理加载代码:

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

这是我的渲染方法。

2 个答案:

答案 0 :(得分:0)

您的纹理不是mipmap-complete,但您仍在使用默认的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()会在调用时影响当前绑定的纹理对象。我不知道当时是否绑定了某些纹理,或者根本没有绑定 - 但当然,新纹理不是,所以它会坚持GL_NEAREST_MIPMAP_LINEAR的初始默认值...

答案 1 :(得分:0)

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