2010-09-21 38 views
1

以下文字有點長,因爲我想確保遇到類似問題的人,例如谷歌這個頁面可以很容易地跟蹤確切的問題和解決方案。但現在我的問題:Android OpenGL ES - 我無法使gluLookAt/glu工作

我最近開始在Android智能手機上編程OpenGL ES,並遇到了解gluPerspective和gluLookAt如何使用的問題。我認爲我明白他們做什麼,但我看不到我繪製的三角形。我在我的活動的onDrawFrame方法中運行以下代碼。所述活動實現帶有@Override標記的onDrawFrame的GLSurfaceView.Renderer。我的代碼是:

gl.glViewport(0, 0, screen_width, screen_height); 
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //set background to black 
gl.glClearDepthf(1.0f); 

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

gl.glMatrixMode(GL10.GL_PROJECTION); // Change PROJECTION matrix 
gl.glLoadIdentity(); 

float aspect_ratio = (float) screen_width/screen_height; 
GLU.gluPerspective(gl, 67, aspect_ratio, 1, 100); 

gl.glEnable(GL10.GL_DEPTH_TEST); 
gl.glMatrixMode(GL10.GL_MODELVIEW); // Change MODELVIEW matrix 
gl.glLoadIdentity(); 

GLU.gluLookAt(gl, 0, 0, 20, 0, 0, 0, 0, 1, 0); 

// make triangle with vertices (-2,0,0), (2,0,0), and (0,.5,0) 
float[] vertices = { -2f, 0, 0, 2f, 0, 0, 0, .5f, 0 }; 
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * 4); 
buffer.order(ByteOrder.nativeOrder()); 
FloatBuffer vertex_buffer = buffer.asFloatBuffer(); 
for (int i = 0; i < 9; i++) { 
    vertex_buffer.put(vertices[i]); 
} 

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex_buffer); 
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); 
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
gl.glDisable(GL10.GL_DEPTH_TEST); 

下面的幾點是關於我在上面的代碼中關於攝像頭設置的假定的簡短說明。如果我在以下解釋中遇到了問題,請糾正我,因爲這可能已經解決了我所有的問題!

  1. glMatrixMode(GL10.GL_PROJECTION)切換到改變相機矩陣(針對我加載單位矩陣直接事後)
  2. GLU.gluPerspective(GL,67,ASPECT_RATIO,1,100)設置一個透視投影在y維上具有67度視角的視野。使用「aspect_ration =(float)width/height」OpenGL計算x維中的視角。此外,「1」是近剪裁平面,而「100」是在這種情況下的遠剪裁平面的值。
  3. 據我所知無關緊要,在代碼gluLookAt被調用的地方,只要它是在實際繪圖之前完成的(我對此不確定)。在這個例子中,我首先轉換到MODELVIEW矩陣,加載一個單位矩陣,然後調用gluLookAt。 「GLU.gluLookAt(gl,0,0,0,0,0,0,0,1,0)」實際上由三個3元素向量組成。最初的一個(在本例中爲(0,0,20))設置相機在世界座標中的位置(即正Z軸上的20個單位,這意味着它在手機屏幕的正面「伸出」 )。第二個矢量確定相機看到的世界座標系中的點(在此示例中爲座標系的原點,即相機沿着負z軸看)。第三個矢量是向上矢量,它定義了攝像機座標系統的y軸方向(因此也是通過與攝像機位置到它所看點的矢量交叉乘積得到的x軸)。

三角形繪圖代碼是從教程中複製的(但我在其他教程中也發現了類似的代碼,所以我認爲這不是問題)。

據我所知,相機現在位於(0,0,20)上並朝向座標系的原點。它的繪製截止點開始於z值19並且最高達-80(相機在z軸點20並且沿着負z軸看;其觀看截錐在1和100處具有近平面和遠平面沿着這種情況下的負z軸))。因此,三角形應該是可見的,因爲其頂點位於z軸= 0平面(即xy平面)上的原點周圍,這明顯位於觀察截錐內。此外,所繪製的頂點按逆時針順序排列;在OpenGL中的默認值。

因此,經過這麼長時間的介紹後,我的一個簡單問題是:我搞砸了什麼,以致於這些代碼不能達到我期望的效果?

+0

你試過完全禁用深度測試嗎?你是否在任何地方設置頂點顏色或照明,例如你是否可以在黑色背景上畫一個黑色的三角形? – bosmacs 2010-09-21 20:33:17

+2

gluPerspective和gluLookAt都將當前矩陣(由glMatrixMode設置)相乘。儘管 – dave 2010-09-21 20:35:43

+0

我已經嘗試過禁用深度測試 - >沒有改變任何東西。我不設置頂點顏色或光照以儘可能簡化示例。有關我所嘗試的更多細節,請參閱brone的答案。 – delirium 2010-09-22 06:19:18

回答

2

我在查看更多教程後發現了答案(然後在之前使用的教程中也注意到了它)!感謝大家的答覆,他們對診斷OpenGL問題非常有幫助,將來肯定會對我有所幫助!

解決我的問題是...問題不是glulookat或gluperspective,但在我的情況下,FloatBuffer的內部位置。在for()之後,我沒有將變量vertex_buffer的位置設置爲0。緩衝區的位置設置爲0可以與至少兩個命令來完成:

  • vertex_buffer.rewind()
  • vertex_buffer.position(0)

據我所知,他們做同樣的事情。我很快測試了代碼中位置重置所屬的位置,並在我的示例代碼中,我可以在gl.glEnableClientState(GL10.GL_VERTEX_ARRAY)之後調用它,但是我必須在gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertex_buffer ),否則返回最初的問題。

我希望這可以幫助其他人有類似的問題或許只是一個短暫glulookat和gluperspective的;)

再次感謝您的建議!

5

我只用過PC,Mac和iOS上的OpenGL,但從我所知道的,代碼看起來很好。然後,我也總是這麼做,但是我仍然在空白屏幕上呆了一段時間,幾乎每次我從頭開始從事任何3D(無論API)......所以這裏有一些東西要嘗試,幾乎嘗試它們的順序。希望至少其中一個將是你還沒有嘗試過的東西!

  • 最後加上glFlush,因爲你實際上並沒有那麼多。例如,當你進行緩衝區交換時,你會認爲驅動程序會爲你做這件事,但似乎並沒有保證 - 例如,Mac OS X似乎並不總是如此。
  • 將背景設置爲非黑色。如果有東西是黑色的,你想看看它。
  • 禁用GL_LIGHTING。如果這是啓用的(我認爲它是默認的?),但你不提供法線,一切都會變黑。 (見上文)
  • 禁用GL_CULL_FACE。無論您如何仔細考慮清盤順序並不重要,您仍有可能錯誤地選擇了它。但是如果GL_CULL_FACE關閉,那變得不可能。
  • Disable GL_DEPTH_TEST。當我偶然輸入glClearDepth(0)時,這節省了我幾次。在這方面看起來你沒問題,但仍值得一試。
  • 虔誠地檢查glGetError後,每個API調用,以防萬一。 (assert(glGetError()==GL_NO_ERROR)會爲初學者做,但你真的想要有一個小循環,也打印gluErrorString的結果,以便更容易一眼看出什麼可能是錯誤的。)
  • 確保你做一個glBindBuffer來設置你的ARRAY_BUFFERARRAY_ELEMENT_BUFFER綁定爲0.要初始化一個VBO,你必須綁定它,所以如果你有某個地方設置了一個,它可能會讓它綁定。這會填滿你的glVertexPointer
  • 沿着最後幾條路線 - 明確建立更多的州。例如,在這種情況下,您可能需要glDisableClientState其他數組類型,以防萬一。根據文檔,GL開始禁用頂點數組,但這是值得消除的可能性。
+0

我測試了在最後添加glFlush,以及禁用CULL_FACE,DEPTH_TEST和LIGHTING。這樣做,我注意到一些奇怪的東西:幾秒鐘後,手機屏幕右上角的三角形顯示爲白色(可能有1/3是可見的,位於屏幕的外側)。奇怪的是,三角形只出現幾分之一秒,閃爍並輕微振動(即一個邊緣向上和向下移動),這些都沒有實現!然後三角形再次消失。我測試了我的原始代碼,它也發生在那裏,我從來沒有見過它。這可能是什麼? – delirium 2010-09-22 06:31:48

+0

其實我只注意到這個三角形似乎並不總是出現在右上角,而是在四處跳躍。然而,這很難說,因爲它只顯示一秒鐘。我在模擬器中運行代碼(之前在三星Galaxy S設備上),只是爲了檢查,而且也沒有顯示三角形。也許是因爲模擬器太慢了,我甚至沒有看到它閃爍。 – delirium 2010-09-22 06:32:33