(三)高级篇____12、用OpenGL ES绘制图像——允许预览和相机视图

原文链接:http://docs.eoeandroid.com/training/graphics/opengl/projection.html

负责人:liris

目录

 [隐藏

应用投影和相机视图 - Applying Projection and Camera Views

在OpenGL ES环境里,投影和相机视图可以用一种更接近你肉眼所见的方式来显示绘图对象。这种对物理视图的仿真,是通过为绘图对象的坐标进行换算实现的:

  • 投影 – 这种变换会根据显示区域的 GLSurfaceView 的宽高来校准绘制对象的坐标。如果不进行这种计算,在不等比例的视图下,通过OpenGL ES绘制的对象会扭曲变形。投影变换一般只需要在渲染器的 onSurfaceChanged() 方法建立时,或在变更OpenGL的视图比例时进行计算。如果想要了解更多关于OpenGL ES的投影和坐标映射的资料,请参考 Mapping Coordinates for Drawn Objects 。
  • 相机视图 – 这种变换会根据虚拟相机的位置来校准绘制对象的坐标。需要注意的是,OpenGL ES并没有定义一个真实的相机对象,而是提供了通用的方法,通过变换绘制对象的显示来模拟相机。相机视图变换只在建立 GLSurfaceView 的时候计算一次,并会根据用户的操作或者应用的功能而动态地变更。

这节课介绍如何创建一个投影和相机视图,并应用到 GLSurfaceView 所绘制的图形中。

 

定义一个投影 - Define a Projection

投影变换的数据是在你的 GLSurfaceView.Renderer 类的 onSurfaceChanged() 方法中计算的。下面的示例代码从 GLSurfaceView 中获得高和宽,并通过 Matrix.frustumM() 方法填入一个投影变换的 Matrix 中。 

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);
 
    float ratio = (float) width / height;
 
    //在onDrawFrame()方法中,这个投影矩阵被应用到对象坐标中
 
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

这段代码填写了一个投影矩阵 mProjMatrix,下一节将会介绍,如何使用 onDrawFrame() 方法把该矩阵和相机视图变换进行结合。

注意:如果仅仅将一个投影变换应用到你的绘制对象中,通常只会显示一片空白。一般来说,你还需要应用一个相机视图变换才能实现屏幕的显示。

定义一个相机视图 - Define a Camera View

作为绘制过程的一部分,添加一个相机视图变换,绘制对象的变换就完成了。下面的示例代码中,先使用 Matrix.setLookAtM() 方法计算相机视图变换,然后与之前计算好的投影矩阵结合,再将合并后的变换矩阵传给目标绘制图形。 

@Override
public void onDrawFrame(GL10 unused) {
    ...
 
    //设置相机位置(视图矩阵)
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
 
    //计算投影和视图变换
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
 
    //绘制图形
    mTriangle.draw(mMVPMatrix);
}

应用投影和相机变换 - Apply Projection and Camera Transformations

修改你的图形对象的 draw() 方法来接收合并后的变换矩阵,并应用于该图形,即可使用前文提到的合并后的投影和相机视图变换矩阵了。 

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    ...
 
    //获得图形变换矩阵的句柄
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
 
    //应用投影和视图变换
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
 
    //绘制三角形
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    ...
}

正确地计算并应用投影和相机视图变换后,你的图形对象就会以适当的比例绘制出来,如下所示:

ogl-triangle-projected.png

图1.应用投影和相机视图绘制的三角形

既然你的应用已经可以显示出适当比例的图形了,那么是时候为你的图形添加动作了。

posted @ 2014-07-31 13:51  ╰→劉じ尛鶴  阅读(220)  评论(0)    收藏  举报