【问题标题】:OpenGL rendering a list of GL_POINTSOpenGL 渲染一个 GL_POINTS 列表
【发布时间】:2014-02-27 01:52:01
【问题描述】:

我目前正在尝试在屏幕上渲染一个点列表,但我得到的只是以下,一个与我的相机一起移动并停留在屏幕中心的点。

生成的点列表随每一帧而变化,并在世界空间坐标中定义。我想知道下面的代码哪里出了问题,以及在不使用立即模式调用的情况下绘制这样的动态点列表的最佳实践是什么。大多数在线资源在绘制点时参考glBegin()和glEnd()。

 void RenderPoints(const CamInfo & camInfo, const std::vector<vec4>& listofpoints )
{
Shader->Use();
Shader->setUniform("MVP",camInfo.proj * camInfo.view);
Shader->setUniform("Color",glm::vec3(0.0f,1.0f,1.0f));
glGenVertexArrays( 1, &M_VAO );
glBindVertexArray( M_VAO );


glGenBuffers( 1, &M_VBO );
glBindBuffer( GL_ARRAY_BUFFER, M_VBO ); 
glBufferData( GL_ARRAY_BUFFER, listofpoints.size()*sizeof(glm::vec4), NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0,  listofpoints.size()*sizeof(glm::vec4), (const GLvoid*)(&listofpoints[0]) );
GLuint pos_location = glGetAttribLocation(Shader->GetProgramID(), "position");
glEnableVertexAttribArray(pos_location ); 
glVertexAttribPointer( pos_location, 4, GL_FLOAT, GL_FALSE, 0, 0 );
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glGenBuffers(1, &M_IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, M_IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_vertex_indices.size()*sizeof(GLuint), (const GLvoid*)(&m_vertex_indices[0]), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glPointSize(10.0f);
glBindVertexArray(M_VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, M_IBO);
glDrawElements(GL_POINTS,m_vertex_indices.size(),GL_UNSIGNED_INT,&m_vertex_indices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glBindVertexArray(0);
Shader->Disable();

}

【问题讨论】:

  • 你应该调试更多。您将颜色设置为青色 (0,1,1),但点为白色。这很令人费解。也许你的规模或矩阵是错误的。

标签: opengl opengl-3


【解决方案1】:

您正在为顶点索引使用缓冲区,但将索引数组的地址(或者可能是 std::vector 的地址?)传递给glDrawElements。当缓冲区绑定到GL_ELEMENT_ARRAY_BUFFER 时,glDrawElements 的第四个参数是该缓冲区的偏移量,因此在您的情况下,您应该传递 0:

glDrawElements(GL_POINTS, m_vertex_indices.size(), GL_UNSIGNED_INT, 0);

【讨论】:

    【解决方案2】:

    你不能这样做:

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    

    通过解除绑定顶点缓冲区之前,您解除了顶点数组的绑定,您告诉顶点数组不要记录适当的缓冲区。当您使用glBindVertexArray(0) 取消绑定顶点数组时,状态机应该处于您调用glDrawElements 时的状态(关于顶点缓冲区)。这意味着您在绘制调用期间没有绑定顶点缓冲区,因此它可能使用随机值(如果您使用glGetError 进行检查,可能会产生错误。

    尝试交换这两行。

    【讨论】: