2011-05-13 103 views
3

我想在iOS上用OpenGL ES 1.1呈現地球儀(球體上有地圖)。用OpenGL ES繪製地球儀

我可以繪製球體,並映射邊界,但有一個問題:在我看來並不面向前方的線條也正在屏幕上繪製。就像這樣:

Globe with lines on the back being shown

在圖片中,你可以看到,美國呈現就好了,但你可以看到澳大利亞呈現在後面。它不應該顯示,因爲它位於地球的後面,全球的黑色和紫色條紋不透明。

有關我應該調整哪些參數以獲得合適的地球儀的任何想法?

如果有幫助,我可以發佈相關部分的代碼。只要問問我哪一部分會更新這個問題。

非常感謝提前。

更新:這是我在用的球渲染:

glEnableClientState(GL_VERTEX_ARRAY); 
glPolygonOffset(-1.0f, -1.0f); 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
int x, y; 
GLfloat curR, curG, curB; 
curR = curG = curB = 0.15f; 
for (y=0; y<EARTH_LAT_RES; y++) { 
    if (y%10 == 0) { 
     glColor4f(curR, curG, curB, 1.0f); 
     curR = curR == 0.15f ? 0.6f : 0.15f; 
     curB = curB == 0.15f ? 0.6f : 0.15f; 
    } 
    for (x=0; x<EARTH_LON_RES; x++) { 
     Vertex3D vs[4]; 
     vs[1] = vertices[x][y]; 
     vs[0] = vertices[x][y+1]; 
     vs[3] = vertices[x+1][y]; 
     vs[2] = vertices[x+1][y+1]; 
     glVertexPointer(3, GL_FLOAT, 0, vs); 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
    } 
} 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glDisable(GL_POLYGON_OFFSET_FILL); 
glDisableClientState(GL_VERTEX_ARRAY); 

這是我使用的渲染邊界線是什麼:

// vxp is a data structure with vertex arrays that represent 
// border lines 
int i; 
glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glEnableClientState(GL_VERTEX_ARRAY); 
for (i=0; i<vxp->nFeatures; i++) 
{ 
    glVertexPointer(3, GL_FLOAT, 0, vxp->pFeatures[i].pVerts); 
    glDrawArrays(GL_LINE_STRIP, 0, vxp->pFeatures[i].nVerts); 
} 
glDisableClientState(GL_VERTEX_ARRAY); 
glDisable(GL_BLEND); 

這些都是我使用的設置在之前渲染任何對象:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glEnable(GL_DEPTH_TEST); /* enable depth testing; required for z-buffer */ 
glEnable(GL_CULL_FACE); /* enable polygon face culling */ 
glCullFace(GL_BACK); 
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); 
glFrustumf (-1.0, 1.0, -1.5, 1.5, -1.0, 1.0); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
+0

因此,您已將各種邊界定義爲幾何,您正在做一些數學將其座標映射到地球表面,然後繪製爲GL_LINES(或線循環或其他線基元)?你有什麼鑲嵌的東西嗎? – Tommy 2011-05-13 11:13:29

+0

@Tommy:是的。究竟。我將座標映射到地球表面並使用GL_LINE_STRIP繪製它們。我甚至不知道如何做鑲嵌... :-) – 2011-05-13 11:15:27

+0

你能分享你的vxp數據嗎?我正在處理類似的問題,但對於Android平臺... – 2014-02-03 12:07:06

回答

5

顯而易見的方法是,如果不妨礙代碼的其餘部分,則以不可見的方式將球體繪製爲實體對象以填充深度緩衝區,然後讓深度測試找出哪些線是可見的。您可以使用glPolygonOffset將實現特定的「少量」添加到用於深度計算的值,以避免深度緩衝區戰鬥。所以它會是這樣的:

// add a small bit of offset, so that lines that should be visible aren't 
// clipped due to depth rounding errors; note that ES allows GL_POLYGON_OFFSET_FILL 
// but not GL_POLYGON_OFFSET_LINE, so we're going to push the polygons back a bit 
// in terms of values written to the depth buffer, rather than the more normal 
// approach of pulling the lines forward a bit 
glPolygonOffset(-1.0, -1.0); 
glEnable(GL_POLYGON_OFFSET_FILL); 

// disable writes to the colour buffer 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 

drawSolidPolygonalSphere(); 

// enable writing again 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 

// disable the offset 
glDisable(GL_POLYGON_OFFSET_FILL); 

drawVectorMap(); 

因此,這將值留在深度緩衝區,就好像地球是堅實的。如果這是不可接受的,那麼我能想到的唯一選擇就是在CPU上進行可視性計算。您可以使用glGet獲取當前的視圖矩陣,直接從您將它們映射到球體的方式(它將只是它們相對於中心的位置)確定每個頂點的法線,然後繪製任何至少有一個線的線頂點返回從相機到點和法線的矢量點積的負值。

+0

@Tommy:非常感謝您的回答。我用我用來渲染球體的代碼更新了這個問題。我添加了你的建議,但是我仍然遇到了我提到的問題(可以看到回顯的全球線條)。這很奇怪,因爲當我在普通的OpenGL中使用類似的代碼時,我沒有這種效果...... – 2011-05-13 12:00:23

+0

你確定你有一個深度緩衝區? – Tommy 2011-05-13 15:18:23

+0

@Tommy:謝謝你的幫助。我在相關部分中添加了這個問題。我不知道這是否足夠。正如你所期望的那樣,在渲染球體和線條之前,我正在設置緩衝區,視圖和其他相關的東西**。 – 2011-05-13 15:21:09