【Android Developers Training】 65. 应用投影

系统 2064 0

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接: http://developer.android.com/training/graphics/opengl/projection.html


在OpenGL ES环境中,投影和相机视图允许你显示绘图对象时,可以以一个更加酷似于你用肉眼看到的真实物体。这个物理视图的仿真是使用绘制对象坐标的数学变换实现的:

  • 投影(Projection) - 这个变换会基于显示它们的 GLSurfaceView 的长和宽,来调整绘图对象的坐标。如果没有这个计算,那么用OpenGL ES绘制的对象会由于视图窗口比例的不匹配而发生形变。一个投影变换一般仅需要在渲染器的 onSurfaceChanged() 方法中, OpenGL视图的比例 建立时或发生变化时才被计算。关于更多OpenGL ES投影和坐标映射的知识,可以阅读 Mapping Coordinates for Drawn Objects
  • 相机视图(camera view) - 这个变化会基于一个虚拟相机位置改变绘图对象的坐标。注意到OpenGL ES并没有定义一个实际的相机对象,但是取而代之的,它提供了一些辅助方法,通过变化绘图对象的显示来模拟相机。一个相机视图变换可能仅在你建立你的 GLSurfaceView 时计算一次,也可能根据用户的行为或者你的应用的功能进行动态调整。

这节课将解释如何创建一个投影和一个相机视图,并应用它们到 GLSurfaceView 中的绘制图像上。


一). 定义一个投影

投影变换的数据会在你的 GLSurfaceView.Renderer 类中的 onSurfaceChanged() 方法中被计算。下面的代码首先接收 GLSurfaceView 的高和宽,然后用它来填充一个投影变换矩阵( Matrix ),使用 Matrix.frustumM() 方法:

      
        @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() 将它和一个相机视图变换结合起来。

Note:

在你的绘图对象上只应用一个投影变换会导致一个看上去很空的显示。一般而言,你必须同时为每一个要在屏幕上显示的任何东西实现一个相机视图。


二). 定义一个相机视图

通过添加一个相机视图变换作为绘图过程的一部分,以此来完成你的绘图对象变换的所有步骤。在下面的代码中,使用 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);

}
      
    

三). 应用投影和相机变换

为了使用在之前章节中结合了的相机视图变换和投影变换,修改你的图形对象的 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);

    ...

}
      
    

一旦你正确地计算了投影变换和相机视图变换,并应用了它们,你的图形就会以正确的比例画出,看上去会像是这样:

图1. 应用了投影变换和相机视图变换的三角形

现在你有了一个能以正确的比例显示你的图形的应用了,下面就该为图形添加一些动画效果了!

【Android Developers Training】 65. 应用投影和相机视图


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论