图片和图形之应用投影和相机视图(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)

转载于:https://blog.51cto.com/4789781/2120586

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值