一步一步学android OpenGL ES2.0编程(4)


应用投影和相机视口

OpenGLES环境中,投影和相机视口使你绘制的对象以更接近物理对象的样子显示。这是通过对坐标精确的数学变换实现的。

  • 投影-这种变换跟据所在GLSurfaceView的宽和高调整对象的坐标。如果没有此变换,对象会被不规则的视口扭曲。投射变换一般只需要在OpenGLview创建或发生变化时调用,代码写在rendereronSurfaceChanged()方法中。

  • 相机视口-此变换基于一个虚拟相机的位置调整对象的坐标。注意OpenGLES并没有定义一个真的相机对象,而是提供了一些工具方法变换绘制对象的显示来模拟一个相机。一个相机视口的变换可能只在创建GLSurfaceView时调用,或跟据用户动作动态调用。

本文讲解了如何创建一个投影和一个相机视口然后应用到GLSurfaceView的形状绘制过程。

定义一个投影


投影变换的数据是在GLSurfaceView.Renderer 类的 onSurfaceChanged() 方法中计算。下面的例子跟据GLSurfaceView 的宽和高,使用Matrix.frustumM()方法计算出了一个投影变换Matrix

@Override
publicvoid 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() 方法中与一个相机视口变换结合。

: 只对你的对象应用一个投影变换一般会导制什么也看不到。通常,你必须也对其应用一个视口变换才能看到东西。

定义一个相机视口


再定义一个相机视口变换以使对绘制对象的变换处理变得完整。在下面的例子中,使用方法Matrix.setLookAtM()计算相机视口变换,然后结合前面所计算的投影矩阵。结合后的变换矩阵之后传给要绘制的对象。

@Override
publicvoid 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);
}

应用投影和相机视口变换


为了使用前面的合并后的投影和相机视口变换矩阵,修改你的图形对象的方法draw(),接受结果矩阵并应用到你的形状上:

publicvoid draw(float[] mvpMatrix){// 传递计算出的变换矩阵
...

// 获得形状的变换矩阵的handle
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,"uMVPMatrix");

// 应用投影和视口变换
GLES20.glUniformMatrix4fv(mMVPMatrixHandle,1,false, mvpMatrix,0);

// 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0, vertexCount);
...
}

一旦你正确的计算和应用了投影和视口变换,你的图像将出现在正确的位置,看起来像下面这样:

 

1.应用了投影和视口变换后绘制的三角形

现在你拥有了一个正确显示你的形状的应用了,是让你的图形动起来的时候了...嘿嘿...


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM