Android---OpenGL ES之应用投影和摄像机视图

本文译自:http://developer.android.com/training/graphics/opengl/projection.html

在OpenGL ES环境中,投影和摄像视图会让你绘制的对象在显示上更加接近眼睛所看到的物理对象。这种物理视图的模拟是通体对被绘制对象的坐标的数学变换来完成的:

投影---这种变换会基于被绘制的的对象所在的GLSurfaceView的宽度和高度来调整坐标。如果不进行这种计算,用OpenGL ES所绘制的对象就会由于视图窗口比例差异而发生不对称的现象。通常只有在OpenGL视图被建立时,或者是你的渲染器的onSurfaceChanged()方法中发生变化时,投影变换才会被计算。更多的有关OpenGL ES 投影和坐标映射的信息,请看“被绘制对象的坐标映射”。

摄像视图---这种变换是基于一个虚拟的摄像机的位置来调整被绘制对象的坐标。重点要注意的是,OpenGL ES不会定义一个实际的摄像机对象,而是提供一些实用的模拟摄像机的方法来转换被绘制对象的显示。只有在建立GLSurfaceView时,或者是基于用户操作或应用程序的功能的动态变化时,摄像机视图变换才可能被计算一次。

本文主要介绍如何创建投影和摄像机视图,并把它们应用到在GLSurfaceView中所绘制的图形上。

定义投影

用于投影变换的数据是在GLSurfaceView.Renderer类的onSurfaceChanged()方法中被计算的。以下示例代码要用到GLSurfaceView的高度和宽度,并使用Matrix.frustumM()方法来完成投影变换:

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

    float ratio = (float) width / height;

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

这段代码填充了一个投影矩阵---mProjMatrix,然后你可以像下面的代码示例那样,在onDrawFrame()方法中,把它跟摄像机视图变换结合到一起。

注意:通常,只使用投影变换,会让你绘制的对象很空洞,因此为了让它能够在任何屏幕上显示,必须同时使用摄像机视图变换。

定义摄像机视图

通过把添加摄像机视图变换作为绘图过程的一部分,来完成被绘制对象的变换处理。在以下示例代码中,使用Matrix.setLookAtM()方法来计算摄像机视图变换,然后把它跟前面的投影矩阵计算结合到一起。然后用这个组合的变换矩阵来绘制图形。

@Override
public
void onDrawFrame(GL10unused) {
    ...

    // Set the camera position(View matrix)
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Calculate theprojection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

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

应用投影和摄像机变换

为了使用我们以上介绍的投影和摄像机视图的变换矩阵,需要编辑图形对象draw()方法,让它接收这个组合变换矩阵,并把它应用到图形上去:

publicvoid draw(float[] mvpMatrix){// pass inthe calculated transformation matrix
   
...

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

    // Apply the projectionand view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

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

一旦你正确的计算并应用了这个投影和摄像机视图的变换,那么你的图形对象就会按照正确的比例来显示了:

Android---OpenGL ES之应用投影和摄像机视图_第1张图片

图1.使用投影和摄像机视图绘制的三角形

 

你可能感兴趣的:(Android---OpenGL ES之应用投影和摄像机视图)