2014-09-30 440 views
1

我已经学会了如何使用OpenGL从各种教程中绘制立方体。现代OpenGL:绘制球体和圆柱体

对于立方体,我们认为每个面都由两个三角形组成,然后适当地设置顶点和颜色缓冲区。这些缓冲区然后被发送到着色器代码。

我们如何画一个球体和圆柱体?所有在线教程都专注于绘制立方体。

为球体或圆柱体设置顶点缓冲区似乎并不重要;我无法像三维立方体那样从三角形“构造”它们。

回答

1

对于气缸,在cylindrical coordinates中工作很方便:(角度,半径,高度)。您将计算两个多边形(恒定角度增量,固定半径,两个高度值),并创建:基础的两组三角形和侧表面的一组矩形(分成两部分)。

对于球体,您将使用球面坐标:(倾斜,仰角,半径)。通过改变两个角度(一次一个),您将描述球体上的平行线和经线。这些定义了一个网格,使每个瓦片是一个四边形(除了在两极);沿对角线分割以获得三角形。

2

下面是绘制球体时使用的一些代码。

注意:此代码使用C++和GLM数学库。

// Calc The Vertices 
for (int i = 0; i <= Stacks; ++i){ 

    float V = i/(float) Stacks; 
    float phi = V * glm::pi <float>(); 

    // Loop Through Slices 
    for (int j = 0; j <= Slices; ++j){ 

     float U = j/(float) Slices; 
     float theta = U * (glm::pi <float>() * 2); 

     // Calc The Vertex Positions 
     float x = cosf (theta) * sinf (phi); 
     float y = cosf (phi); 
     float z = sinf (theta) * sinf (phi); 

     // Push Back Vertex Data 
     vertices.push_back (glm::vec3 (x, y, z) * Radius); 
    } 
} 

// Calc The Index Positions 
for (int i = 0; i < Slices * Stacks + Slices; ++i){ 

    indices.push_back (i); 
    indices.push_back (i + Slices + 1); 
    indices.push_back (i + Slices); 

    indices.push_back (i + Slices + 1); 
    indices.push_back (i); 
    indices.push_back (i + 1); 
} 

该算法创建所谓的UV球体。 “切片”和“堆栈”是X轴和Y轴上的细分数。

+0

它溢出索引范围。 – Ruslan 2017-05-10 20:55:59

+0

这发生在哪里? 代码从不访问任何数组元素,只添加到数组中。 它如何溢出索引范围,如果它从来没有被访问过的第一个地方? – 2017-05-11 09:57:20

+0

当'i = Slices * Stacks + Slices-1'时,您可以将'i + Slices + 1'推入索引。由于您有'(Stacks + 1)*(Slices + 1)'顶点的总数,当您有'Slices> Stacks'时,'i + Slices + 1'的索引将指向顶点集合的末尾之外。这不会导致C++代码中的UB,但会导致在OpenGL代码中('glDrawElements'等)。在实践中,你会得到随机的三角形伸出你的球体。 – Ruslan 2017-05-11 11:38:37