Android---OpenGL ES之應用投影和攝像機視圖
在OpenGL ES環境中,投影和攝像視圖會讓你繪制的對象在顯示上更加接近眼睛所看到的物理對象。
這種物理視圖的模擬是通體對被繪制對象的坐標的數學變換來完成的:
投影---這種變換會基于被繪制的的對象所在的GLSurfaceView的寬度和 高度來調整坐標。如果不進行這種計算,用OpenGL ES所繪制的對象就會由于視圖窗口比例差異而發生不對稱的現象。
通常只有在OpenGL視圖被建立時,或者是你的渲染器的 onSurfaceChanged()方法中發生變化時,投影變換才會被計算。更多的有關OpenGL ES 投影和坐標映射的信息,請看“被繪制對象的坐標映射”。
攝像視圖---這種變換是基于一個虛擬的攝像機的位置來調整被繪制對象的坐標。重點 要注意的是,OpenGL ES不會定義一個實際的攝像機對象,而是提供一些實用的模擬攝像機的方法來轉換被繪制對象的顯示。只有在建立GLSurfaceView時,或者是基于用 戶操作或應用程序的功能的動態變化時,攝像機視圖變換才可能被計算一次。
本文主要介紹如何創建投影和攝像機視圖,并把它們應用到在GLSurfaceView中所繪制的圖形上。
定義投影
用于投影變換的數據是在GLSurfaceView.Renderer類的onSurfaceChanged()方法中被計算的。以下示例代碼要用到GLSurfaceView的高度和寬度,并使用Matrix.frustumM()方法來完成投影變換:
- @Override
- public void onSurfaceChanged(GL10unused, int width, int height) {
- GLES20.glViewport(0, 0, width, height);
- float ratio = (float) width / height;
- // this projection matrixis applied to object coordinates
- // in the onDrawFrame()method
- Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
- }
這段代碼填充了一個投影矩陣---mProjMatrix,然后你可以像下面的代碼示例那樣,在onDrawFrame()方法中,把它跟攝像機視圖變換結合到一起。
注意:通常,只使用投影變換,會讓你繪制的對象很空洞,因此為了讓它能夠在任何屏幕上顯示,必須同時使用攝像機視圖變換。
定義攝像機視圖
通過把添加攝像機視圖變換作為繪圖過程的一部分,來完成被繪制對象的變換處理。在以下示例代碼中,使用Matrix.setLookAtM()方法來計算攝像機視圖變換,然后把它跟前面的投影矩陣計算結合到一起。然后用這個組合的變換矩陣來繪制圖形。
- @Override
- public void onDrawFrame(GL10unused) {
- ...
- // Set the camera position(View matrix)
- Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
- // Calculate theprojection and view transformation
- Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
- // Draw shape
- mTriangle.draw(mMVPMatrix);
- }
應用投影和攝像機變換
為了使用我們以上介紹的投影和攝像機視圖的變換矩陣,需要編輯圖形對象draw()方法,讓它接收這個組合變換矩陣,并把它應用到圖形上去:
- publicvoid draw(float[] mvpMatrix){// pass inthe calculated transformation
- matrix
- ...
- // get handle to shape'stransformation matrix
- mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
- // Apply the projectionand view transformation
- GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
- // Draw the triangle
- GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
- ...
- }
本文譯自:http://developer.android.com/tra ... ngl/projection.html