2014-09-30 315 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