您不能直接使用glDrawArrays
来绘制索引。您需要以正确的顺序将它们组合在一起。
创建一个三角形索引列表并使用glDrawElements
。
另请注意,您的循环应该从i = 0
到i <= total
,因为您想在球体的两个极点上创建顶点坐标。
另请参见如何将纹理映射到使用参数方程呈现的球体的点基元上
GLint layers = 100;
GLint circumferenceTiles = 100;
std::vector<GLfloat> sphereVertices;
va.reserve( (layers+1)*(circumferenceTiles+1)*3 );
for ( int i = 0; i <= layers; ++ i )
{
GLfloat lon = map(i, 0, layers, -M_PI, M_PI);
GLfloat lon_sin = std::sin( lon );
GLfloat lon_cos = std::cos( lon );
for ( int j = 0; j <= circumferenceTiles; j ++ )
{
GLfloat lat = map(j, 0, circumferenceTiles, -M_PI/2, M_PI/2);
GLfloat lat_sin = std::sin( lat);
GLfloat lat_cos = std::cos( lat);
va.push_back( lon_cos * lat_cos );
va.push_back( lon_cos * lat_sin );
va.push_back( lon_sin );
}
}
您可以通过将圆盘叠起来来创建三角形:
![enter image description here](https://istack.dev59.com/xXCMS.gif)
std::vector<GLuint> ia;
ia.reserve( layers*circumferenceTiles*6 );
for ( GLuint il = 0; il < layers; ++ il )
{
for ( GLuint ic = 0; ic < circumferenceTiles; ic ++ )
{
GLuint i0 = il * (circumferenceTiles+1) + ic;
GLuint i1 = i0 + 1;
GLuint i3 = i0 + circumferenceTiles+1;
GLuint i2 = i3 + 1;
int faces[]{ i0, i1, i2, i0, i2, i3 };
ia.insert(ia.end(), faces+(il==0?3:0), faces+(il==layers-1?3:6));
}
}
指定顶点数组对象:
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
GLuint vbo;
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, sphereVertices.size()*sizeof(GLfloat), sphereVertices.data(),
GL_STATIC_DRAW );
GLuint ibo;
glGenBuffers( 1, &ibo );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, ia.size()*sizeof(GLuint), ia.data(), GL_STATIC_DRAW );
GLuint v_attr_inx = 0;
glVertexAttribPointer( v_attr_inx , 3, GL_FLOAT, GL_FALSE, 0, 0 );
glEnableVertexAttribArray( v_attr_inx );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
绘制球体:
glBindVertexArray( vao );
glDrawElements( GL_TRIANGLES, (GLsizei)ia.size(), GL_UNSIGNED_INT, 0 );
glBindVertexArray( 0 );