【发布时间】:2020-07-01 17:38:09
【问题描述】:
我无法使用不支持 OpenGL 3.3 或任何高于 3.1 的笔记本电脑。这是有问题的,因为我对这个版本并不完全熟悉,所以我正在学习如何再次使用这些东西。我的问题是,由于某种原因,我的片段着色器只输出白色。我不太确定出了什么问题,但我觉得这与我设置 VBO 数据的方式有关,因为这在我的代码中最近发生了变化。现在,我正在尝试将我的旧渲染引擎(用 OpenGL 3.3 编写)转换为 OpenGL 3.1。这是因为我的旧笔记本电脑设置的限制。这就是为什么我为 Vertex 使用结构,其中包括 BiTangent 和 Tangent 值。
我的代码:
struct Vertex {
// Position
glm::vec3 Position;
// Normals
glm::vec3 Normal;
// Texture Coordinates
glm::vec2 TexCoords;
// BiTangent
glm::vec3 BiTangent;
// Tangent
glm::vec3 Tangent;
};
struct Texture {
unsigned int id;
int number;
};
class Mesh {
std::vector<Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<Texture> textures;
unsigned int VAO, VBO[5], EBO;
public:
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture> textures) {
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
setupMesh();
};
void setupMesh() {
glGenVertexArrays(1, &VAO);
glGenBuffers(4, VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
int stride = 14;
// Position
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// Normal
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)3);
glEnableVertexAttribArray(1);
// Texture Coordinates
glBindBuffer(GL_ARRAY_BUFFER, VBO[2]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)6);
glEnableVertexAttribArray(2);
// BiTangent
glBindBuffer(GL_ARRAY_BUFFER, VBO[3]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)8);
glEnableVertexAttribArray(3);
// Tangent
glBindBuffer(GL_ARRAY_BUFFER, VBO[4]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)11);
glEnableVertexAttribArray(4);
// Element Buffer Object
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// Unbind
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
};
void Draw(ShaderProgram shader) {
for (int i = 0; i < textures.size(); i++) {
// Give textures the proper id and bind them
glActiveTexture(GL_TEXTURE0 + textures[i].number);
glBindTexture(GL_TEXTURE_2D, textures[i].id);
}
// Draw
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
// Unbind
glBindVertexArray(0);
}
};
顶点着色器:
#version 140 core
in vec3 aPos;
in vec3 aColor;
in vec2 aTexCoords;
in vec3 aBiTangent;
in vec3 aTangent;
out vec3 Color;
void main(void){
Color = vec3(aColor);
gl_Position = vec4(aPos, 1.0);
}
片段着色器:
#version 140 core
out vec4 FragColor;
//precision highp float;
in vec3 Color;
void main(void)
{
FragColor = vec4(1.0, 0.8, 0.8, 1.0);
}
我尝试手动设置颜色以覆盖显示法线,但输出仍然是白色。
编辑:
如果我可以生成一个 VBO 而不是 4 个,那将很有用。我的问题是在使用一个 VBO 时我应该如何从着色器访问顶点数据。
【问题讨论】:
-
"[...] 我的问题是在使用一个 VBO 时我应该如何从着色器访问顶点数据。" - 没有区别在着色器代码中,只是顶点规范不同。
-
这部分代码没有更明显的问题。如果它仍然不起作用,那么其他地方还有另一个错误。
-
您确定要使用已编译的着色器程序调用 glUseProgram 以使其处于活动状态吗?您使用我们看不到的 ShaderProgram 对象调用 Draw,因此很难知道。以我的经验,白色输出通常是因为没有绑定任何程序。
-
嘿!我不记得我是如何修复它的,但我很久以前就想通了。看着这个,我可能应该删除或存档或对这个问题做任何事情,因为它似乎非常没用。我确实记得解决方案是相当明显的,而且它位于代码的不同部分。我认为这可能是因为没有调用 glUseProgram(),但我不能肯定地说。无论如何,感谢您提供帮助:) 我会在 24 小时左右删除这个问题
-
所以,没关系,因为我无法删除它
标签: c++ opengl glsl shader glm-math