使用glDrawArrays()绘制内容时遇到问题,此处没有其他问题可以帮我解决。代码应该绘制一个球体,但是对于一个简单的立方体,我用“顶点”填充“m_vertices”。 我的守则如下:
首先是init函数。
init()
{
m_shader.compileShaders("Shaders/colorShading.vert", "Shaders/colorShading.frag");
m_shader.addAttribute("position");
m_shader.addAttribute("normal");
m_shader.linkShaders();
//setup VAO and VBO
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
//init VAO
glBindVertexArray(m_vao);
//bind Buffer used by VAO
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
//enable needed AttributeArrays
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
//position attribute pointer
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBuffer), (void*)offsetof(VertexBuffer, vertex));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, sizeof(VertexBuffer), (void*)offsetof(VertexBuffer, normal));
//release VAO
glBindVertexArray(0);
//release VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Set-Up a static scene
// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
glm::mat4 projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 view = glm::lookAt(
glm::vec3(4, 3, 3), // Camera is at (4,3,3), in World Space
glm::vec3(0, 0, 0), // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Model Matrix
glm::mat4 model = glm::mat4(1.0f);
//set ModelViewProjection-Matrix of this object
m_mvp = projection * view * model;
}
此函数用于设置绘制对象所需的所有内容。 然后有一个更新功能:
update()
{
//update Sphere and get current vertices
//currently setting vertices for a cube
m_sphere->updateSphere(m_vertices);
//m_vertices is passed in per reference
//it stores 6 quads based on 2 triangles (36 vertices)
//the vertices are stored counter clockwise
//update VBO
//bind buffer
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
//orphan the buffer
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(VertexBuffer), nullptr, GL_STATIC_DRAW);
//upload data
glBufferSubData(GL_ARRAY_BUFFER, 0, m_vertices.size() * sizeof(VertexBuffer), &m_vertices[0]);
//release buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
更新功能更新VBO。这是必要的,因为最终的Sphere应该实现LevelOfDetail。 最后是绘制功能:
draw()
{
glEnable(GL_DEPTH_TEST);
//activate shader
m_shader.use();
//set-up the mvp-uniform
GLuint matrixID = m_shader.getUniformLocation("MVP");
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &m_mvp[0][0]);
//draw Planet
glBindVertexArray(m_vao);
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
glBindVertexArray(0);
//deactivate shader
m_shader.unuse();
glDisable(GL_DEPTH_TEST);
}
此函数应该只绑定/设置着色器并绘制对象。 问题是它没有绘制对象,我不明白为什么。 如果有人能够发现我的错误并解释我在这里做错了什么,我将非常感激。
编辑:
根据要求,我添加了我的代码,它填充了多维数据集数据:
static const std::vector<GLfloat> g_vertex_buffer_data = {
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
updateSphere(std::vector<VertexBuffer> &vertices)
{
if(!vertices.empty())
vertices.clear();
for (int i = 0; i < g_vertex_buffer_data.size();)
{
VertexBuffer buffer;
glm::vec3 vertex(g_vertex_buffer_data[i], g_vertex_buffer_data[i+1], g_vertex_buffer_data[i+2]);
buffer.setVertex(vertex);
buffer.setNormal(glm::normalize(vertex));
vertices.emplace_back(buffer);
i += 3;
}
}
VertexBuffer结构:
struct Vector3 {
float x;
float y;
float z;
};
struct VertexBuffer {
Vector3 vertex;
Vector3 normal;
void setVertex(glm::vec3 vec)
{
vertex.x = vec.x;
vertex.y = vec.y;
vertex.z = vec.z;
}
void setNormal(glm::vec3 vec)
{
normal.x = vec.x;
normal.y = vec.y;
normal.z = vec.z;
}
};
我的着色器类已经在其他几个项目中进行了测试,并且工作得很好。我假设我错过了管理VAO和VBO或立方体数据。但我可能完全错了。
我纠正了VAO一代,这是我的坏事,我想知道为什么我没有看到这一点。但这并没有解决这个问题。
在项目的主循环中清除颜色和深度缓冲区。我应该在对象的每次绘制调用中清除它们吗?