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

这样绘制出来的图形就不会变形了。

猜你喜欢

转载自blog.csdn.net/qq_38261174/article/details/83049745