OpenGL 3.3 没有渲染纹理(黑色纹理,C++,GLFW/SOIL)
OpenGL 3.3 no texture gets rendered (black texture, C++, GLFW/SOIL)
我目前正在学习使用 C++ 和 GLFW(以及用于加载图像文件以创建纹理的 SOIL)的 OpenGL 3.3。我已经实现了一个批处理渲染系统,它获取顶点信息,将 VBO 数据映射到缓冲区变量,将提交的顶点信息每帧写入该缓冲区并渲染所述帧。
renderer.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 上下文的线程,因此 "packaging an OGL object in a C++ class"
可能没有问题
- 着色器和纹理都被绑定;由于默认情况下纹理采样器和活动纹理为 0,因此应该不会造成任何问题
- 我实际上正在正确加载 test.png(texture.cpp 如果您感兴趣:http://pastebin.com/hWGTCe5C)
- 据我所知,我没有使用过时的功能,甚至没有调用使用过时功能的 SOIL 函数;我在切换库之前通过 SDL2 和 SDL2_image 加载图像导致了同样的问题
- 着色器获得有效的纹理坐标(通过将它们作为颜色输出到我正在渲染的正方形进行测试)
- 着色器和编译器都没有给我任何 warnings/errors,尽管设置了 -Wall 编译器标志,glGetError() 也没有帮助
其他可能有用的信息:我已经在 Intel 和 Nvidia 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 Common Mistakes。请注意,@RetoKoradi 所指的问题已在 link.
中解决
我目前正在学习使用 C++ 和 GLFW(以及用于加载图像文件以创建纹理的 SOIL)的 OpenGL 3.3。我已经实现了一个批处理渲染系统,它获取顶点信息,将 VBO 数据映射到缓冲区变量,将提交的顶点信息每帧写入该缓冲区并渲染所述帧。
renderer.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 上下文的线程,因此 "packaging an OGL object in a C++ class" 可能没有问题
- 着色器和纹理都被绑定;由于默认情况下纹理采样器和活动纹理为 0,因此应该不会造成任何问题
- 我实际上正在正确加载 test.png(texture.cpp 如果您感兴趣:http://pastebin.com/hWGTCe5C)
- 据我所知,我没有使用过时的功能,甚至没有调用使用过时功能的 SOIL 函数;我在切换库之前通过 SDL2 和 SDL2_image 加载图像导致了同样的问题
- 着色器获得有效的纹理坐标(通过将它们作为颜色输出到我正在渲染的正方形进行测试)
- 着色器和编译器都没有给我任何 warnings/errors,尽管设置了 -Wall 编译器标志,glGetError() 也没有帮助
其他可能有用的信息:我已经在 Intel 和 Nvidia 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 Common Mistakes。请注意,@RetoKoradi 所指的问题已在 link.
中解决