[英]Android OpenGL ES - I can't make gluLookAt/gluPerspective work
以下文字有些冗長,因為我想確保遇到類似問題的人(例如google這個頁面)可以輕松地跟蹤確切的問題及其解決方案。 但是現在我的問題:
我最近開始在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);
接下來的幾點是關於我在上面的代碼中大概了解的相機設置的簡短說明。 如果在以下說明中出現問題,請糾正我,因為這可能已經解決了我所有的問題!
三角形繪圖代碼是從一個教程中復制的(但是我在其他教程中也找到了類似的代碼,因此我認為這不是問題)。
據我所知,相機現在位於(0,0,20)上,並朝着坐標系的原點方向看。 它的繪圖視錐線從z值19開始,一直延伸到-80(相機在z軸點20處並沿負z軸看;其視錐線的近視平面和遠視平面分別為1和100(均分別在這種情況下沿z軸的負方向)。 因此,三角形應該是可見的,因為其頂點位於z軸= 0平面(即xy平面)上的原點周圍,該平面明顯位於視錐中。 此外,繪制的頂點按逆時針順序排列; OpenGL中的默認設置。
因此,在對問題進行了漫長的介紹之后,我的簡單問題是:我搞砸了什么,以致於該代碼無法達到我的期望?
我只在PC,Mac和iOS上使用過OpenGL,但據我所知,代碼看起來還不錯。 再說一次,我的也總是這樣做,但是我仍然有一段時間會出現空白屏幕,幾乎任何時候我都可以從頭開始進行任何3D操作(無論API如何)...所以這里有些事情可以嘗試,嘗試它們的順序。 希望其中至少有一個是您尚未嘗試過的東西!
glFlush
,因為實際上並沒有畫那么多。 您可能認為驅動程序會在執行緩沖區交換時為您執行此操作,但是似乎無法保證這一點-例如,Mac OS X並不總是如此。 GL_LIGHTING
。 如果啟用了此功能(我認為默認情況下是?),但您沒有提供法線,則所有內容都會變黑。 (往上看。) GL_CULL_FACE
。 仔細考慮繞線順序並不重要,仍然有可能您弄錯了。 但是,如果GL_CULL_FACE
關閉,則不可能。 GL_DEPTH_TEST
。 當我偶然輸入glClearDepth(0)
時,這為我節省了很多時間。 在這方面看來您還可以,但是仍然值得一試。 glGetError
API調用后,請glGetError
檢查glGetError
,以防萬一。 ( assert(glGetError()==GL_NO_ERROR
)對於初學者來說是有用的,但是您確實希望有一個gluErrorString
,也可以打印出gluErrorString
的結果,以便一眼就可以看出問題所在。) glBindBuffer
將ARRAY_BUFFER
和ARRAY_ELEMENT_BUFFER
綁定設置為0。要初始化VBO,必須將其綁定,因此,如果某處設置了VBO,則可能會使其綁定。 這將glVertexPointer
您的glVertexPointer
。 glDisableClientState
為其他數組類型,以防萬一。 根據文檔,GL會在禁用頂點數組的情況下啟動,但這是值得消除的可能性。 在查看了更多教程之后,我找到了答案(然后在之前使用的教程中也注意到了它)! 感謝大家的回答,它們在診斷OpenGL問題方面非常有幫助,將來一定會對我有幫助!
解決我的問題的方法是...問題不是glulookat或gluperspective,而是我的情況是FloatBuffer的內部位置。 在for(0 <i <9)循環之后,我沒有將變量vertex_buffer的位置設置為0。 至少可以通過以下兩個命令將緩沖區的位置設置為0:
據我所知,他們做同樣的事情。 我很快測試了位置重置在代碼中的位置,在示例代碼中可以在gl.glEnableClientState(GL10.GL_VERTEX_ARRAY)之后調用它,但是我必須在gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertex_buffer ),否則返回最初的問題。
我希望這對其他有類似問題的人有所幫助,或者也許只是出於空洞和窺探;)
再次感謝您的建議!
對於OpenGL ES用戶
就我而言,我不得不寫
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl,45,1,1.5f,50);
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
不只是
GLU.gluPerspective(gl,45,1,1.5f,50);
在onSurfaceChanged
方法中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.