(转)使用OpenGL显示图像(四)运用投影与相机视角
运用投影与相机视角
编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/projection.html
在OpenGL ES环境中,利用投影和相机视角可以让显示的绘图对象更加酷似于我们用肉眼看到的真实物体。该物理视角的仿真是对绘制对象坐标的进行数学变换实现的:
- 投影(Projection):这个变换会基于显示它们的GLSurfaceView的长和宽,来调整绘图对象的坐标。如果没有该计算,那么用OpenGL ES绘制的对象会由于其长宽比例和View窗口比例的不一致而发生形变。一个投影变换一般仅当OpenGL View的比例在渲染器的onSurfaceChanged()方法中建立或发生变化时才被计算。关于更多OpenGL ES投影和坐标映射的知识,可以阅读Mapping Coordinates for Drawn Objects。
- 相机视角(Camera View):这个变换会基于一个虚拟相机位置改变绘图对象的坐标。注意到OpenGL ES并没有定义一个实际的相机对象,取而代之的,它提供了一些辅助方法,通过对绘图对象的变换来模拟相机视角。一个相机视角变换可能仅在建立你的GLSurfaceView时计算一次,也可能根据用户的行为或者你的应用的功能进行动态调整。
这节课将解释如何创建一个投影和一个相机视角,并应用它们到GLSurfaceView中的绘制图像上。
定义一个投影
投影变换的数据会在GLSurfaceView.Renderer类的onSurfaceChanged()方法中被计算。下面的代码首先接收GLSurfaceView的高和宽,然后利用它并使用Matrix.frustumM()方法来填充一个投影变换矩阵(Projection Transformation Matrix):
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
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;
// 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);
}
应用投影和相机变换
为了使用在之前章节中结合了的相机视角变换和投影变换,我们首先为之前在Triangle类中定义的顶点着色器添加一个Matrix变量:
public class Triangle {
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}";
// Use to access and set the view transformation
private int mMVPMatrixHandle;
...
}
之后,修改图形对象的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);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
一旦我们正确地计算并应用了投影变换和相机视角变换,我们的图形就会以正确的比例绘制出来,它看上去会像是这样:

现在,应用已经可以通过正确的比例显示图形了,下面就为图形添加一些动画效果吧!
(转)使用OpenGL显示图像(四)运用投影与相机视角的更多相关文章
- opencv学习笔记(四)投影
opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: #include <cv.h> #include <highgui.h> using namespace ...
- Android OpenGL ES 开发(五): OpenGL ES 使用投影和相机视图
OpenGL ES环境允许你以更接近于你眼睛看到的物理对象的方式来显示你绘制的对象.物理查看的模拟是通过对你所绘制的对象的坐标进行数学变换完成的: Projection - 这个变换是基于他们所显示的 ...
- (转)使用OpenGL显示图像(五)添加移动
添加移动 编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/motion.html 转:http://hukai. ...
- (转)使用OpenGL显示图像(三)绘制Shapes
绘制形状 编写:jdneo - 原文:http://developer.android.com/training/graphics/opengl/draw.html 在定义了使用OpenGL绘制的形状 ...
- 【Android Developers Training】 65. 应用投影和相机视图
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- Android OpenGL ES(四)----调整屏幕的宽高比
1.宽高比问题 我们如今相当熟悉这样一个事实,在OpenGL里,我们要渲染的一切物体都要映射到X轴和Y轴上[-1,1]的范围内,对于Z轴也一样.这个范围内的坐标被称为归一化设备坐标,其独立于屏幕实际尺 ...
- opengl典型例程立方体投影与地图绘制
立方体投影 http://www.cnblogs.com/opengl/p/3790450.html 地图绘制 http://www.cnblogs.com/opengl/p/3790354.html
- 在Android中使用OpenGL ES开发第(四)节:相机预览
笔者之前写了三篇Android中使用OpenGL ES入门级的文章,从OpenGL ES的相关概念出发,分析了利用OpenGL ES实现3D绘图的重要的两个步骤:定义形状和绘制形状,简单的绘制了一个三 ...
- (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片
转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...
随机推荐
- 最强DE战斗力
最强DE战斗力 时间限制: 1 Sec 内存限制: 128 MB提交: 40 解决: 14[提交][状态] 题目描述 春秋战国时期,赵国地大物博,资源非常丰富,人民安居乐业.但许多国家对它虎视眈眈 ...
- [CSP-S模拟测试]:Emotional Flutter(贪心)
题目传送门(内部题51) 输入格式 第一行一个整数$t$表示数据组数.每组数据的第一行有三个整数$s,k,n$.第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度. 输出格式 ...
- [CSP-S模拟测试]:Miner(欧拉路)
题目背景 $And\ the\ universe\ said\ you\ are\ the\ daylight \\ And\ the\ universe\ said\ you\ are\ the\ ...
- appium 链接真机后,运行代码,但是APP并没有启动
要淡定,链接真机后,问题一下多出来这么多,还没有启动程序,就碰到接二连三的问题. 爽到家了.慢慢解决吧. 具体问题是这样的: # coding=utf-8from appium import webd ...
- Reciting(third)
It is subtly demonstrate in the portrayal that a teacher is teaching mathmatics in a certain class ...
- How many groups(DP)
题意: 定义:设M为数组a的子集(元素可以重复),将M中的元素排序,若排序后的相邻两元素相差不超过2,则M为a中的一个块,块的大小为块中的元素个数 给出长度为n的数组a,1<=n<=200 ...
- PAT_A1085#Perfect Sequence
Source: PAT A1085 Perfect Sequence (25 分) Description: Given a sequence of positive integers and ano ...
- 转载:LESS基本用法
转载出处:https://blog.csdn.net/qq_38209578/article/details/80566860 转载出处:https://blog.csdn.net/weixin_44 ...
- CTU Open 2018 Lighting /// 组合数递推 二进制
题目大意: 给定n k 给定一个数的二进制位a[] 求这个数加上 另一个二进制位<=n的数b 后 能得到多少个不同的 二进制位有k个1 的数 样例 input10 51000100111 out ...
- java虚拟机规范(se8)——class文件格式(七)
4.7.5 Exceptions 属性 Exceptions 属性是一个变长属性,它位于 method_info(§4.6)结构的属性表中. Exceptions 属性指出了一个方法需要检查的可能抛出 ...