應用投影和相機視口
在OpenGLES環境中,投影和相機視口使你繪制的對象以更接近物理對象的樣子顯示。這是通過對坐標精確的數學變換實現的。
-
投影-這種變換跟據所在
GLSurfaceView
的寬和高調整對象的坐標。如果沒有此變換,對象會被不規則的視口扭曲。投射變換一般只需要在OpenGLview創建或發生變化時調用,代碼寫在renderer的onSurfaceChanged()
方法中。 -
相機視口-此變換基於一個虛擬相機的位置調整對象的坐標。注意OpenGLES並沒有定義一個真的相機對象,而是提供了一些工具方法變換繪制對象的顯示來模擬一個相機。一個相機視口的變換可能只在創建
GLSurfaceView
時調用,或跟據用戶動作動態調用。
本文講解了如何創建一個投影和一個相機視口然后應用到GLSurfaceView
的形狀繪制過程。
定義一個投影
投影變換的數據是在GLSurfaceView.Renderer
類的 onSurfaceChanged()
方法中計算。下面的例子跟據GLSurfaceView
的寬和高,使用Matrix.frustumM()
方法計算出了一個投影變換Matrix
:
@Override publicvoid onSurfaceChanged(GL10 unused,int width,int height){ GLES20.glViewport(0,0, width, height); float ratio =(float) width / height; // 此投影矩陣在onDrawFrame()中將應用到對象的坐標 Matrix.frustumM(mProjMatrix,0,-ratio, ratio,-1,1,3,7); }
以下代碼產生了一個投影矩陣mProjMatrix
,你可以把它在 onDrawFrame()
方法中與一個相機視口變換結合。
注: 只對你的對象應用一個投影變換一般會導制什么也看不到。通常,你必須也對其應用一個視口變換才能看到東西。
定義一個相機視口
再定義一個相機視口變換以使對繪制對象的變換處理變得完整。在下面的例子中,使用方法Matrix.setLookAtM()
計算相機視口變換,然后結合前面所計算的投影矩陣。結合后的變換矩陣之后傳給要繪制的對象。
@Override publicvoid onDrawFrame(GL10 unused){ ... // 設置相機的位置(視口矩陣) Matrix.setLookAtM(mVMatrix,0,0,0,-3,0f,0f,0f,0f,1.0f,0.0f); // 計算投影和視口變換 Matrix.multiplyMM(mMVPMatrix,0, mProjMatrix,0, mVMatrix,0); // 繪制形狀 mTriangle.draw(mMVPMatrix); }
應用投影和相機視口變換
為了使用前面的合並后的投影和相機視口變換矩陣,修改你的圖形對象的方法draw()
,接受結果矩陣並應用到你的形狀上:
publicvoid draw(float[] mvpMatrix){// 傳遞計算出的變換矩陣 ... // 獲得形狀的變換矩陣的handle mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,"uMVPMatrix"); // 應用投影和視口變換 GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,false, mvpMatrix,0); // 繪制三角形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0, vertexCount); ... }
一旦你正確的計算和應用了投影和視口變換,你的圖像將出現在正確的位置,看起來像下面這樣:
圖1.應用了投影和視口變換后繪制的三角形
現在你擁有了一個正確顯示你的形狀的應用了,是讓你的圖形動起來的時候了...嘿嘿...