2013-01-16 54 views
2

我想在沒有任何引擎的情況下在純OpenGL ES 2.0中繪製球體。我寫下面的代碼:Draw Sphere - 頂點順序

int GenerateSphere (int Slices, float radius, GLfloat **vertices, GLfloat **colors) { 
srand(time(NULL)); 
int i=0, j = 0; 
int Parallels = Slices ; 
float tempColor = 0.0f;  
int VerticesCount = (Parallels + 1) * (Slices + 1); 
float angleStep = (2.0f * M_PI)/((float) Slices); 

// Allocate memory for buffers 
if (vertices != NULL) { 
    *vertices = malloc (sizeof(GLfloat) * 3 * VerticesCount); 
} 
if (colors != NULL) { 
    *colors = malloc(sizeof(GLfloat) * 4 * VerticesCount); 
} 

for (i = 0; i < Parallels+1; i++) { 
    for (j = 0; j < Slices+1 ; j++) { 

     int vertex = (i * (Slices + 1) + j) * 3; 

     (*vertices)[vertex + 0] = radius * sinf (angleStep * (float)i) * 
        sinf (angleStep * (float)j); 
     (*vertices)[vertex + 1] = radius * cosf (angleStep * (float)i); 
     (*vertices)[vertex + 2] = radius * sinf (angleStep * (float)i) * 
         cosf (angleStep * (float)j); 
     if (colors) { 
       int colorIndex = (i * (Slices + 1) + j) * 4; 
       tempColor = (float)(rand()%100)/100.0f; 

       (*colors)[colorIndex + 0] = 0.0f; 
       (*colors)[colorIndex + 1] = 0.0f; 
       (*colors)[colorIndex + 2] = 0.0f; 
       (*colors)[colorIndex + (rand()%4)] = tempColor; 
       (*colors)[colorIndex + 3] = 1.0f; 
      } 
     } 
    } 
    return VerticesCount; 
} 

我用下面的代碼繪製它:

glDrawArrays(GL_TRIANGLE_STRIP, 0, userData->numVertices); 

凡userData-> numVertices - VerticesCount從功能GenerateSphere。 但在屏幕上繪製系列三角形,這些不是球體近似! 我想,我需要計算頂點並使用OpenGL ES 2.0函數glDrawElements()(包含數組,包含數字頂點)。但是在屏幕上繪製的一系列三角形不是球體近似。 如何繪製球體近似值?如何指定順序頂點(OpenGL ES 2.0術語中的索引)?

+0

我一般使用的功能esGenSphere從GLES2編程指南。然而,書中的那個(和svn)會產生錯誤的texcoord y;這在https://github.com/laanwj/etna_viv/blob/master/native/lib/esShapes.c中得到解決。它生成頂點和索引。 – wump

回答

11

開始之前與OpenGL ES的東西,這裏有一些建議:

避免腹脹CPU/GPU性能

通過渲染形狀刪除計算的激烈週期離線時使用其他程序將肯定有幫助。這些程序將提供有關形狀/網格的額外細節,除了導出包含形狀等的點[x,y,z]的合成集合外。

我經歷了所有這些痛苦的方式,因爲我一直試圖搜索用於渲染球體等的算法,然後嘗試優化它們。我只是想在未來節省你的時間。只需使用Blender,然後使用您最喜愛的編程語言來解析從Blender導出的obj文件,我使用Perl。下面是渲染球以下步驟:(使用glDrawElements因爲obj的文件中包含指數的陣列)

1) Download and install Blender. 

image-1

2) From the menu, add sphere and then reduce the number of rings and segments. 

image-2

3) Select the entire shape and triangulate it. 

image-3

4) Export an obj file and parse it for the meshes. 

image-4

您應該能夠掌握從該文件渲染球體的邏輯:http://pastebin.com/4esQdVPP。它適用於Android,但概念相同。 希望這有助於。

+1

感謝您的回答! 這是個好建議!但..如何獲得攪拌機的紋理座標? 我找不到(我以前沒有用攪拌機) 非常感謝! – Simplex

+1

http://www.youtube.com/watch?v=A3M21GqAgHM這是在攪拌器增加紋理 – GLES

+1

我你的文章的要點達成一致。我最喜歡的視頻。但是,只需在初始化時調用GenerateSphere調用一次即可構建頂點/索引緩衝區。這在初始化過程中仍會產生一些開銷,但在最終的渲染性能方面沒有任何區別。 – wump

0

我掙扎着球體和其他幾何形狀。我曾在這一段時間,創建一個Objective-C類來創建座標,法線和紋理座標都使用索引和非索引機制,班裏就在這裏:

http://www.whynotsometime.com/Why_Not_Sometime/Code_Snippets.html

什麼有趣的是,生成的表示幾何的三角形將降低分辨率(在生成座標之前設置分辨率屬性)。此外,您可以使用GL_LINE_STRIP而不是GL_TRIANGLES來查看更多。

我同意從窩囊廢,既然計算座標通常發生一次,並沒有使用很多CPU週期的註釋。此外,有時一個人只想繪製一個球或世界或...