Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

投影とカメラビューの適用

OpenGL ES 環境では、投影とカメラビューを使用すると、物理オブジェクトと視覚的に近く見える描画オブジェクトを表示できます。この物体の視覚化は、描画オブジェクトの座標の数学的変換を使ってシミュレートされます。

  • 投影 - この変換は、表示される GLSurfaceView の幅と高さに基づいて、描画オブジェクトの座標を調整します。この計算を行わないと、OpenGL ES によって描画されたオブジェクトのビュー ウィンドウの比率が不均衡になり、歪みが生じます。通常、レンダラの onSurfaceChanged() メソッドで OpenGL ビューの比率が確立または変更される場合にのみ、投影変換を計算する必要があります。OpenGL ES の投影と座標マッピングの詳細については、描画オブジェクトの座標のマッピングをご覧ください。
  • カメラビュー - この変換は、仮想カメラの位置に基づいて描画オブジェクトの座標を調整します。なお、OpenGL ES は実際のカメラ オブジェクトを定義しませんが、描画オブジェクトの表示を変換して、カメラをシミュレートするユーティリティ メソッドが用意されています。カメラビューの変換は、GLSurfaceView の確立時に 1 回だけ計算されるか、ユーザーの操作やアプリケーションの機能に基づいて動的に変更されます。

このレッスンでは、投影とカメラビューを作成し、GLSurfaceView で描画した図形に適用する方法について説明します。

投影の定義

投影変換のデータは、GLSurfaceView.Renderer クラスの onSurfaceChanged() メソッドで計算されます。次のサンプルコードは GLSurfaceView の高さと幅を取得、使用し、Matrix.frustumM() メソッドを使用して投影変換の Matrix を投入します。

Kotlin

    // vPMatrix is an abbreviation for "Model View Projection Matrix"
    private val vPMatrix = FloatArray(16)
    private val projectionMatrix = FloatArray(16)
    private val viewMatrix = FloatArray(16)

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)

        val ratio: Float = width.toFloat() / height.toFloat()

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

Java

    // vPMatrix is an abbreviation for "Model View Projection Matrix"
    private final float[] vPMatrix = new float[16];
    private final float[] projectionMatrix = new float[16];
    private final float[] viewMatrix = 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(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
    }
    

このコードは投影行列 mProjectionMatrix を投入します。これは、次のセクションで示す onDrawFrame() メソッドでカメラビュー変換と結合できます。

注: 描画オブジェクトに投影変換を適用すると、通常はほとんど何も表示されません。一般に、画面に何かを表示するにはカメラビュー変換も適用する必要があります。

カメラビューの定義

描画オブジェクトの変換処理を完了するには、カメラビュー変換をレンダラの描画プロセスの一部として追加します。次のサンプルコードでは、Matrix.setLookAtM() メソッドを使用してカメラビュー変換を計算し、以前に計算された投影行列と結合しています。組み合わされた変換行列は描画図形に渡されます。

Kotlin

    override fun onDrawFrame(unused: GL10) {
        ...
        // Set the camera position (View matrix)
        Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)

        // Calculate the projection and view transformation
        Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)

        // Draw shape
        triangle.draw(vPMatrix)
    

Java

    @Override
    public void onDrawFrame(GL10 unused) {
        ...
        // Set the camera position (View matrix)
        Matrix.setLookAtM(viewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0);

        // Draw shape
        triangle.draw(vPMatrix);
    }
    

投影とカメラ変換の適用

プレビュー セクションに表示される投影とカメラビューの変換行列を結合して使用するには、まず Triangle クラスで以前に定義した頂点シェーダーに行列変数を追加します。

Kotlin

    class Triangle {

        private val 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 var vPMatrixHandle: Int = 0

        ...
    }
    

Java

    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 vPMatrixHandle;

        ...
    }
    

次に、グラフィック オブジェクトの draw() メソッドを変更し、結合された変換行列を受け取って図形に適用します。

Kotlin

    fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix

        // get handle to shape's transformation matrix
        vPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix")

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

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

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(positionHandle)
    }
    

Java

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

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

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

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

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

投影とカメラビューの変換を正しく計算して適用すると、グラフィック オブジェクトは正しい比率で描画され、次のようになります。

図 1. 投影とカメラビューが適用された三角形の描画。

図形を正しい比率で表示するアプリケーションを作成できたので、続いて図形にモーションを追加しましょう。