OpenGL 3.3不会渲染任何纹理(黑色纹理、C++、GLFW/SOIL)



我目前正在学习OpenGL 3.3,使用C++和GLFW(以及用于加载图像文件以创建纹理的SOIL)。我已经实现了一个批量渲染系统,它获取顶点信息,将VBO数据映射到缓冲区变量,将提交的顶点信息写入每个帧的缓冲区,并渲染所述帧。

render.cpp如下所示:http://pastebin.com/N6nWdew6而VertexData结构在renderer.hpp中定义为:

struct VertexData {
    VertexData()
        :   vertex(glm::vec3(0.0f, 0.0f, 0.0f)),
            color(glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)),
            texCoord(glm::vec2(0.0f, 0.0f)),
            tid(0) {};
    VertexData(glm::vec3 vertex, glm::vec4 color, glm::vec2 texCoord, GLuint tid)
        :   vertex(vertex),
            color(color),
            texCoord(texCoord),
            tid(tid) {};
    ~VertexData() {};
    glm::vec3   vertex;
    glm::vec4   color;
    glm::vec2   texCoord;
    GLuint      tid;
};

现在,提交和渲染实际的顶点、颜色信息、纹理坐标等似乎可以工作,但纹理仍然没有得到渲染,我得到的只是一个黑色的正方形。主循环中实际提交的最重要部分如下(警告:看起来很糟糕,只是为了测试目的;我试图尽我所能缩短它):

[...]
/*Static variables in the window class, just for testing purposes*/
Shader*                 Window::_exampleShader = nullptr;
Texture*                Window::_exampleTexture = nullptr;
Renderer::VertexData    Window::vA;
Renderer::VertexData    Window::vB;
Renderer::VertexData    Window::vC;
Renderer::VertexData    Window::vD;
[...]
/*Initialization in the window constructor*/
_exampleShader  = new Shader("../src/glsl/basicVertex.glsl", "../src/glsl/basicFragment.glsl");
_exampleTexture = new Texture("../res/test.png");
/*TOP LEFT*/
vA.vertex       = glm::vec3(-0.5f, 0.5f, 0.0f);
vA.color        = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
vA.texCoord     = glm::vec2(0.0f, 1.0f);
vA.tid          = _exampleTexture->getTextureID();
/*TOP RIGHT*/
vB.vertex       = glm::vec3(0.5f, 0.5f, 0.0f);
vB.color        = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
vB.texCoord     = glm::vec2(1.0f, 1.0f);
vB.tid          = _exampleTexture->getTextureID();
/*BOTTOM LEFT*/
vC.vertex       = glm::vec3(-0.5f, -0.5f, 0.0f);
vC.color        = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
vC.texCoord     = glm::vec2(0.0f, 0.0f);
vC.tid          = _exampleTexture->getTextureID();
/*BOTTOM RIGHT*/
vD.vertex       = glm::vec3(0.5f, -0.5f, 0.0f);
vD.color        = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
vD.texCoord     = glm::vec2(1.0f, 0.0f);
vD.tid          = _exampleTexture->getTextureID();
[...]
/*Submission in the main loop*/
_exampleShader->bind();
_exampleTexture->bind();
_exampleShader->setUniformMat4("model_matrix", glm::mat4(1.0f));
_exampleShader->setUniformMat4("view_matrix", glm::lookAt(glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f)));
_exampleShader->setUniformMat4("projection_matrix", glm::perspective(ConversionUtils::convertFOV(90.0f), getAspectRatio(), 0.0001f, 100.0f));
Renderer::begin();      
    Renderer::submit(vC);
    Renderer::submit(vA);
    Renderer::submit(vB);
    Renderer::submit(vC);
    Renderer::submit(vD);
    Renderer::submit(vB);
Renderer::end();
glfwSwapBuffers(_window);
[...]

如您所见,我创建了一些示例顶点数据,并在每帧中提交这些数据。现在,最后几段代码是我的顶点和片段着色器:

顶点着色器:

#version 330 core
layout(location = 0) in vec3 v_vertex;
layout(location = 1) in vec4 v_color;
layout(location = 2) in vec2 v_texCoord;
layout(location = 3) in uint v_tid;
out vec4 f_color;
out vec2 f_texCoord;
flat out uint f_tid;
uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
void main() {
    f_color     = v_color;
    f_texCoord  = v_texCoord;
    f_tid       = v_tid;
    mat4 mvp = projection_matrix * view_matrix * model_matrix;
    gl_Position = mvp * vec4(v_vertex, 1.0);
}

片段着色器:

#version 330 core
in vec4 f_color;
in vec2 f_texCoord;
flat in uint f_tid;
out vec4 color;
uniform sampler2D texSampler;
void main() {
    color = texture(texSampler, f_texCoord);
}

这就是我的工作。现在,我已经在谷歌上搜索了很多,甚至在OpenGL频道@freenode上询问过,但没有人能帮我。我通过使用核心3.3配置文件,甚至是前向兼容的配置文件,删除了不推荐使用的功能,尽管我不应该这样做。我已经检查过的其他东西:

  • 我只使用了一个具有有效GL上下文的线程,所以"将OGL对象打包到C++类中"可能没有问题
  • 着色器和纹理都是绑定的;由于默认情况下纹理采样器和活动纹理为0,因此也不会造成任何问题
  • 我实际上正在正确加载test.png(如果你感兴趣的话,texture.cpp:http://pastebin.com/hWGTCe5C)
  • 我没有使用不推荐使用的功能afaik,即使使用不推荐功能的SOIL函数也没有被调用;通过SDL2和SDL2_image加载图像,这是我在切换库之前所做的,也导致了同样的问题
  • 着色器获取有效的纹理坐标(通过将它们作为颜色输出到我正在渲染的正方形进行测试)
  • 着色器和编译器都没有给我任何警告/错误,尽管设置了-Wall编译器标志,glGetError()也没有帮助

其他可能有用的信息:我已经在英特尔和英伟达GPU上测试了这一点,它们在Antergos(Arch)Linux上使用了最新的驱动程序(一个在Wayland上,一个在X11上)。64位体系结构。图书馆的最新版本(GLFW3、SOIL、GLEW和GLM)。使用Clang++编译。Valgrind也没有给我任何有用的输出。

我和IRC聊天室的想法都快用完了——是什么原因导致了这种情况?

正如@RetoKoradi在评论中所说,您实际上没有向纹理传递任何参数,因此您的纹理并不完整。

试着在texture.cpp中添加一些类似的内容:

glBindTexture(GL_TEXTURE_2D, texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, your_internal_format, width, height, 0, your_format, your_type, texture_pointer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, your_behavior);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, your_behavior);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

你可以在这里找到更多关于纹理完整性的信息:OpenGL常见错误。请注意,@RetoKoradi所指的问题在这个链接中得到了解决。

最新更新