1. 程式人生 > >OpenGL ES (8): 使用投影檢視和相機檢視

OpenGL ES (8): 使用投影檢視和相機檢視

1.簡介

OpenGL ES允許你以接近於你眼睛看到的物理物件的方式來顯示你繪製的物件。物理檢視的模擬是通過對你繪製的物件的座標進行數學變換完成的:

  • Projection — 這個變換是基於他們所顯示的GLSurfaceView的寬和高來調整繪製物件的座標的。沒有這個計算變換,通過OpenGL繪製的形狀會在不同顯示視窗變形。這個投影變化通常只會在OpenGL view的比例被確定或者在你渲染器的onSurfaceChanged()方法中被計算。
  • Camera View — 這個換是基於虛擬的相機的位置來調整繪製物件座標的。需要著重注意的是,OpenGL ES並沒有定義一個真實的相機物件,而是提供一個實用方法,通過變換繪製物件的顯示來模擬一個相機。相機檢視變換可能只會在你的GLSurfaceView被確定時被計算,或者基於使用者操作或你應用程式的功能來動態改變。

本次描述怎樣建立投影和相機檢視並將其應用的到你的GLSurfaceView的繪製物件上。

2.定義投影

投影變化的資料是在你GLSurfaceView.Renderer類的onSurfaceChanged()方法中被計算的。下面的示例程式碼是獲取GLSurfaceView的高和寬,並通過Matrix.frustumM()方法用它們填充到投影變換矩陣中。


private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

上面的程式碼填充有一個投影矩陣mProjectionMatrix,可以在onFrameDraw()方法中與下面的相機檢視mViewMatrix結合在一起,組成新的矩陣mMVPMatrix。

注意:如果僅僅只把投影矩陣應用的到你繪製的物件中,通常你只會得到一個非常空的顯示。一般情況下,你還必須為你螢幕上顯示的任何內容應用相機檢視

3.定義相機檢視

在下面的程式碼中,通過Matrix.setLookAtM()方法計算相機檢視變換mViewMatrix,然後將其與之前的投影矩陣mProjectionMatrix結合到一起。合併後的矩陣mMVPMatrix接下來會傳遞給繪製的圖形。

@Override
public void onDrawFrame(GL10 unused) {
    // Set the camera position (View matrix)
//得到相機檢視變換
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
//結合
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    //新的矩陣mMVPMatrix傳入,繪製圖形
    mTriangle.draw(mMVPMatrix);
}

4.應用投影和相機變換

為了使用投影和相機檢視變換的合併矩陣,首先要在之前Triangle類程式碼中新增一個矩陣變數

public class Triangle {
    ...

    private int mMVPMatrixHandle;
    public void draw(float[] mvpMatrix) {
    ... //Program 座標 等等

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//應用相機檢視變換和投影矩陣
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}

這樣繪製出來的圖形就不會變形了。