我想创建一个动态网格类但是当我启用顶点颜色时我必须做错事。 在我的例子中,我有2个片段着色器(fragment.glsl - > solid red color / fragmentExp.glsl - > vertexColor)。接下来,我创建两个基元,一个三角形和一个立方体,并将这些数据放在两个网格中。
因此,当我使用纯色片段着色器并且不设置顶点颜色时,它可以正常工作。
以下是我的工作示例:
Program program;
program.LoadShader("Vertex", GL_VERTEX_SHADER, "shaders/vertex.glsl");
program.LoadShader("Fragment", GL_FRAGMENT_SHADER, "shaders/fragment.glsl");
program.AttachToProgram();
Program programExp;
programExp.LoadShader("Vertex", GL_VERTEX_SHADER, "shaders/vertex.glsl");
programExp.LoadShader("Fragment", GL_FRAGMENT_SHADER, "shaders/fragmentExp.glsl");
programExp.AttachToProgram();
GLfloat verticesTri[] = {
-0.1f, -0.5f, 0.0f,
-0.9f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
GLfloat verticesCube[] = {
0.1f, -0.5f, 0.0f,
0.9f, -0.5f, 0.0f,
0.1f, 0.5f, 0.0f,
0.9f, 0.5f, 0.0f
};
GLuint indicesTri[] = {
0, 1, 2
};
GLuint indicesCube[] = {
0, 1, 2,
2, 3, 1
};
GLfloat colorsTri[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
GLfloat colorsCube[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f
};
Mesh tri(program.GetProgram());
tri.SetVertices(verticesTri, sizeof(verticesTri));
tri.SetIndices(indicesTri, sizeof(indicesTri));
//tri.SetColors(colorsTri, sizeof(colorsTri));
tri.Init();
Mesh cube(program.GetProgram());
cube.SetVertices(verticesCube, sizeof(verticesCube));
cube.SetIndices(indicesCube, sizeof(indicesCube));
//cube.SetColors(colorsCube, sizeof(colorsCube));
cube.Init();
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
tri.Draw();
cube.Draw();
glfwSwapBuffers(window);
}
当我更改以下行时出现问题: 所以现在网格中有vertexColors并使用了vertexColor片段着色器。
结果我得到了黑屏。 我究竟做错了什么?它已经对我的网格类做了一些事情......
Mesh tri(programExp.GetProgram());
tri.SetVertices(verticesTri, sizeof(verticesTri));
tri.SetIndices(indicesTri, sizeof(indicesTri));
tri.SetColors(colorsTri, sizeof(colorsTri));
tri.Init();
Mesh cube(programExp.GetProgram());
cube.SetVertices(verticesCube, sizeof(verticesCube));
cube.SetIndices(indicesCube, sizeof(indicesCube));
cube.SetColors(colorsCube, sizeof(colorsCube));
cube.Init();
最后是我的通用网格类:
#include "header\mesh.h"
Mesh::Mesh(GLuint program)
{
this->program = program;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
}
Mesh::~Mesh()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteBuffers(1, &CBO);
}
void Mesh::SetVertices(GLfloat* vertices, unsigned long long size)
{
numVetices = size;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
}
void Mesh::SetIndices(GLuint* indices, unsigned long long size)
{
numIndices = size;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW);
}
void Mesh::SetColors(GLfloat* colors, unsigned long long size)
{
numColors = size;
glGenBuffers(1, &CBO);
glBindBuffer(GL_ARRAY_BUFFER, CBO);
glBufferData(GL_ARRAY_BUFFER, size, colors, GL_STATIC_DRAW);
}
void Mesh::Init()
{
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(1);
}
void Mesh::Draw()
{
glUseProgram(program);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
这是我的顶点着色器和我的片段着色器:
#version 400
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 col;
out vec3 color;
void main()
{
gl_Position = vec4(pos, 1.0);
color = col;
};
#version 400
in vec3 col;
out vec3 color;
void main()
{
color = col;
};
答案 0 :(得分:0)
glVertexAttribPointer
始终在当前绑定的GL_ARRAY_BUFFER
上运行。在你的初始化函数中,如果没有颜色,这是VBO,当有颜色时,这是CBO。要解决此问题,您必须在设置顶点属性之前绑定正确的缓冲区。 (请注意,只有在颜色可用时才应设置颜色属性绑定。)
void Mesh::Init()
{
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, CBO);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glEnableVertexAttribArray(1);
}