圖片和圖形之應用投影和相機視圖(13)

原文

概要


在OpenGL ES環境中,投影和相機視圖允許您以更接近您用眼睛看物體的方式顯示繪製的對象。這種物理觀察的模擬是通過繪製物體座標的數學變換完成的:

  • 投影 - 此變換根據GLSurfaceView所顯示的位置的寬度和高度來調整繪製對象的座標。沒有這個計算,OpenGL ES繪製的對象就會被視圖窗口的不平等比例所歪曲。投影轉換通常只需在onSurfaceChanged()渲染器的方法中建立或更改OpenGL視圖的比例時進行計算。有關OpenGL ES投影和座標映射的更多信息,請參閱 繪製繪製對象的映射座標。
  • 相機視圖 - 此變換根據虛擬相機位置調整繪製對象的座標。需要注意的是,OpenGL ES並未定義實際的相機對象,而是通過轉換繪製對象的顯示來提供模擬相機的實用方法。攝像機視圖轉換可能只在您建立時計算一次 GLSurfaceView,或者可能會根據用戶操作或應用程序的功能動態更改。

本課介紹如何創建投影和相機視圖並將其應用於繪製在您的圖形中的圖形GLSurfaceView。

定義投影


投影變換的數據是用onSurfaceChanged() 你GLSurfaceView.Renderer班級的方法計算的。以下示例代碼將使用該方法的高度和寬度GLSurfaceView並使用它來填充投影轉換:MatrixMatrix.frustumM()

// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
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;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

此代碼填充投影矩陣,mProjectionMatrix然後您可以將該onDrawFrame()方法與方法中的相機視圖轉換組合在一起,如下一節所示。

注意:只需將投影轉換應用於繪圖對象通常會導致非常空的顯示。一般來說,您還必須應用相機視圖轉換才能在屏幕上顯示任何內容。

定義攝像機視圖


通過在渲染器中添加相機視圖轉換作爲繪圖過程的一部分來完成轉換繪製對象的過程。在下面的示例代碼中,使用該Matrix.setLookAtM() 方法計算相機視圖變換,然後與之前計算的投影矩陣結合使用。然後將組合的變換矩陣傳遞給繪製的形狀。

@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);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    // Draw shape
    mTriangle.draw(mMVPMatrix);
}

應用投影和相機轉換


爲了使用預覽部分中顯示的組合投影和攝影機視圖變換矩陣,首先將一個矩陣變量添加到類中以前定義的頂點着色器中Triangle:

public class Triangle {

    private final String vertexShaderCode =
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "void main() {" +
        // the matrix must be included as a modifier of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

    // Use to access and set the view transformation
    private int mMVPMatrixHandle;

    ...
}

接下來,修改draw()圖形對象的方法以接受組合的變換矩陣並將其應用於形狀:

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    ...

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Pass the projection and view transformation to the shader
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

一旦正確計算並應用了投影和相機視圖轉換,您的圖形對象將按照正確的比例繪製,並應如下所示:
圖片和圖形之應用投影和相機視圖(13)
圖1.應用投影和相機視圖繪製的三角形。
現在您已經有了一個以正確比例顯示您的形狀的應用程序,現在可以將動作添加到您的形狀中了。

Lastest Update:2018.04.25

聯繫我

QQ:94297366
微信打賞:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公衆號推薦:

圖片和圖形之應用投影和相機視圖(13)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章