位置: 编程技术 - 正文

Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

编辑:rootadmin

推荐整理分享Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

我们现在准备好在代码中添加透视投影了。Android的Matrix类为它准备了两个方法------frustumM()和perspectiveM()。不幸的是,frustumM()的个缺陷,它会影响某些类型的投影,而perspectiveM()只是从Android的ICS版本开始才被引入,在早期的Android版本里并没有这个方法。我们可以简单地支持ICS及其以上的版本,但是这样会丢掉很大一部分市场,一些用户依然运行早期的Android版本。

作为替代,我们可以创建我们自己的方法来实现投影矩阵。

1.创建自己的perspectiveM

在工具包中创建新的类MatrixHelper,在开始处加入如下方法签名:

public static void perspectiveM(float[] m,float yFovInDegress,float aspect,float n,float f){

计算焦距

我们要做的第一件事就是计算焦距,这将基于在Y轴上的视野。就在方法签名之后加入如下代码:

final float angleInRadians=(float)(yFovInDegress*Math.PI/.0);final float a=(float)(1.0/Math.tan(angleInRadians/2.0));

我们使用Java的Math类计算那个正切函数,因为它需要弧度角,所以我们把视野从度转换为弧度。接着计算焦距。

输出矩阵

我们现在可以更具上一节的数学证明直接写出矩阵,增加如下代码:

m[0]=a/aspect;m[1]=0f;m[2]=0f;m[3]=0f;m[4]=0f;m[5]=a;m[6]=0f;m[7]=0f;m[8]=0f;m[9]=0f;m[]=-((f&#;n)/(f-n));m[]=-1f;m[]=0f;m[]=0f;m[]=-((2f*f*n)/(f-n));m[]=0f;

这就是把矩阵数据存到了参数m定义的浮点数组中,这个数组需要至少个元素。OpenGL把矩阵数据按照以列为主的顺序存储,这就意味着我们一次写一列数据,而不是一次写一行。前四个&#;是第一列,下一组四个数是第二列,以此类推。

2.开始使用投影矩阵

我们现在将转而使用那个透视投影矩阵了。打开你的渲染类,并从onSurfaceChanged()去掉所有的代码,只保留glViewPort()调用,加入如下代码:

MatrixHelper.perspectiveM(projectionMatrix, , (float) width / (float) height, 1f, f);

这会用度的视野创建一个透视投影。 这个视椎体从Z&#;为-1的位置开始,在Z&#;为-的位置结束。

加入MatrixHelper的导入后,继续前面的程序运行,你可以会发现桌面不见了,因为我们没有给桌子指定Z的位置,默认情况下Z在为0的位置。因为这个视椎体是从Z&#;为-1的位置开始的,除非把它移动到那个距离内,否则我们无法看到桌子。

不要硬编码Z的&#;,在使用投影矩阵进行投影之前,让我们使用一个平移矩阵把桌子移出来。依照惯例,我们把这个矩阵称为模型矩阵。

利用模型矩阵移动物体

在类的顶部加入如下矩阵的定义:

private final float[] modelMatrix=new float[];

我们要使用这个矩阵把桌面移动到那个距离内。在onSurfaceChanged()结尾处,加入如下代码:

Matrix.setIdentityM(modelMatrix, 0);Matrix.translateM(modelMatrix,0,0f,0f,-2f);

这就是把模型矩阵设为单位矩阵,在沿着Z轴平移-2。当我们把桌面的坐标与这个矩阵相乘的时候,那些坐标最终会沿着Z轴负方向移动2个单位。

相乘一次还是相乘两次

我们现在要做一个选择:我们依然需要把这个矩阵应用于每个顶点,因此第一个选项是给顶点着色器新增一个额外的矩阵。我们把每个顶点都与这个模型矩阵相乘,让它们沿着Z轴负方向移动2个单位,接下来把每个顶点与投影矩阵相乘。这样,OpenGL就可以做透视除法,并把这些顶点变换到归一化设备坐标了。

如果不想这么麻烦,还有一个更好的方式:我们可以把模型矩阵与投影矩阵相乘,得到一个矩阵,然后把这个矩阵传递给顶点着色器。通过这种方式我们就可以在着色器中仅保留一个矩阵。

选择适当的顺序

为了弄清楚我们应该使用那种顺序,让我们看一下只使用投影矩阵的数学运算:

VerteXeye代表场景中的顶点与投影矩阵相乘之前的位置。我们一旦加入模型矩阵来移动那个桌子,这个数学运算看起来就像这样。

VerteXmodel代表顶点在模型矩阵放进场景中之前的位置。把这两个表达式合并在一起,最后得到的公式如下:

Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

为了使用一个矩阵替换这两个矩阵,我们不得不把投影矩阵乘以模型矩阵,就是把投影矩阵放在左边,把模型矩阵放在右边。

更新代码使用一个矩阵

让我们把这个新的矩阵代码封装一下,把下面的代码加到onSurfaceChanged()中的translate()调用后面:

final float[] temp=new float[];Matrix.multiplyMM(temp,0,projectionMatrix,0,modelMatrix,0);System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);

不论什么时候把两个矩阵相乘,都需要一个临时变量来存储其结果。如果尝试直接写入这个结果,这个结果将是未定义的。

我们首先创建了一个临时的浮点数组用来存储其临时结果;然后调用multiplyMM()把投影矩阵和模型矩阵相乘,其结果存进这个临时数组。下一步,我们调用System.arraycopy()把结果存回projectMatrix,它现在包含模型矩阵与投影矩阵的组合效应。

如果我们现在运行这个程序,会发现这依然是个平面的桌面。

3.增加旋转

既然我们已经有一个配置好的投影矩阵和一个可以移动的桌子的模型矩阵,那么我们需要做的就是旋转这张桌子,以便可以从某个角度观察它。如果使用旋转矩阵,我们只需要一行代码就可以做到。我们还从来没有用过旋转,现在花一些时间了解一下这些旋转是怎么工作的。

需要弄清楚一件时是我们需要围绕哪个轴旋转以及旋转多少度。让我们再看下图:

要搞清楚一个物体是怎么围绕一个给定的轴旋转,我们将使用右手坐标规则:伸出你的右手,握拳,让大拇指指向正轴方向。倘若是一个正角度的旋转,卷曲的手指会告诉你一个物体是怎么围绕那个轴旋转的。观察上图,当你把大拇指指向X轴正方向时,看看旋转的方向是怎么跟随手指的绕轴线卷曲的。

分别用X轴,Y轴和Z轴试一下这个旋转。如果绕Y轴旋转,桌子会绕着它的顶端和低端水平旋转。如果绕着Z轴旋转,桌子会在一个圆圈内旋转。我们想要做的是让桌子绕着X轴向后旋转,因为这会让桌子看起来更有层次。

旋转矩阵

我们将使用一个旋转矩阵去做实际的旋转。旋转矩阵使用正弦和余弦三角函数把旋转转换成缩放因子。下面就是绕X轴旋转所用矩阵定义:

然后是绕Y轴旋转所用的矩阵:

最后,还有一个绕Z轴旋转所用的矩阵:

把所有矩阵合并为一个通用的旋转矩阵,使其可以基于任意一个角度和向量旋转,这也是可能的。

作为一个测试,让我们试试绕着X轴旋转。我们从一个点开始,它在原点上面一个单位,也就是Y&#;是1。把它绕X轴旋转度。首先,让我们准备这个旋转矩阵:

让把这个矩阵与这个点的位置向量相乘,看看得到了什么:

这个点从(0,1,0)被移动到了(0,0,1)。如果我们回过头来看一下上面那个旋转坐标轴,并对X轴使用右手规则,我们可以看到正向旋转是如何把一个点沿着一个绕X轴的圈移动的。

4.在代码中加入旋转

我们现在准备好把这个旋转加入代码了。回到onSurfaceChanged(),调整那个平移矩阵,并加入一个旋转矩阵,如下:

Matrix.translateM(modelMatrix,0,0f,0f,-2.5f);Matrix.rotateM(modelMatrix,0,-f,1f,0f,0f);

我们把这张桌子放得更远了一点,因为我们一旦把它旋转了,它的底部会距离我们更近。我们接着把它绕X轴旋转-度,这会让桌子处于一个很好的角度,就像我们站在它前面一样。

这张桌子现在看起来应该如下图所示:

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android GBK与UTF-8 1.远程设备编码格式是GBK,因此Stringtest="你好";send(test.getBytes("GBK"));2.从远程设备中接收数据Stringstr=newString(receive().getBytes("UTF-8"),"UTF-8");tv.setText(str);用此

Android之TextView的样式类Span的使用详解 Android中的TextView是个显示文字的的UI类,在现实中的需求中,文字有各式各样的样式,TextView本身没有属性去设置实现,我们可以通过Android提供的Spannable

仿微信主界面导航栏图标字体颜色的变化 在所有的移动产品中,微信的界面做的很简洁,简单,我对微信主界面影响最深的就是微信底部导航栏的图标,以及字体颜色的变化,一直都想实现以

标签: Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

本文链接地址:https://www.jiuchutong.com/biancheng/370999.html 转载请保留说明!

上一篇:Android 中IO 操作数据总结(android aidl in out)

下一篇:Android GBK与UTF-8

  • 财税新闻稿
  • 收到稳岗补贴怎么做会计分录小企业会计准则
  • 美团收取的佣金怎么开票
  • 出租场地属于什么营业范畴
  • 一般纳税人所得税是季报还是月报
  • 买赠活动怎么账务处理
  • 开具的红字发票金税三期怎么报税?
  • 公司注销后会计凭证保管年限
  • 免费的产品
  • 以固定资产增资子公司 可以溢价么
  • 利用发票管税的意义
  • 企业向关联方借款是否可以无偿
  • 提供服务的发票可以抵扣税款吗?
  • 培训费增值税专用发票
  • 收到员工补缴的公积金怎么入账
  • 成本费用总额包括信用减值损失吗
  • 电子申报是什么
  • 免税单位无租使用房产怎么缴纳房产税
  • 发票货物或应税劳务名称怎么修改
  • w10系统怎么打印文件
  • 车间机物料消耗属于间接生产费用吗
  • 小规模纳税人买车可以抵税吗
  • 固定资产折旧方法的选择
  • system idle process是什么进程(CPU的空闲率)
  • 笔记本电脑连无线网老是掉线怎么回事
  • 索尼笔记本电脑官网
  • vue blob下载文件
  • win10怎么显示隐藏的硬盘
  • 笔记本默认网关不可用怎么修复
  • 工程事故赔偿协议书怎么写
  • 企业收购特殊税种有哪些
  • 收入支出如何结转
  • 3gwifi怎么用
  • 企业法人看病费用能报销吗
  • 长期债权投资收回的利息 现金流量表
  • 进货返利怎么入账
  • 内置天线手机
  • 外籍个人取得的现金住房补贴所得免征个人所得税吗
  • 科罗拉多州位置
  • React hooks中 useState踩坑-=--异步问题
  • 税收协定与国内税法发生冲突
  • 万字短文
  • 简单聊聊太平天国
  • torchaudio教程
  • 路由vue-router
  • 企业签发银行承兑汇票支付采购款
  • 其他应收应付如何平账
  • 新会计准则基本准则
  • 一般纳税人跨年冲红报年度所得税怎么做
  • 消费税计税分录
  • 生产成本结转分录是什么
  • 金蝶建账初始数据修改
  • 以前年度未处理往来账怎么叫
  • 出口退税后发生退货补缴怎么算增值税
  • 房地产竣工验收后结转收入和成本
  • 汇兑损益财务费用借方
  • 赠送电影票文案
  • 营业外支出包括
  • 销售使用过的汽车增值税税率
  • 旅游,饮食业会议内容
  • sysbench内存性能测试
  • mysql中文乱码解决的命令
  • mysql进阶之路
  • 微软雅黑可以免费用吗
  • 怎么操作win10系统
  • centos7如何添加永久静态路由
  • win8系统怎么更改无线网络IP
  • linux系统的翻译软件
  • zmweb.exe是什么进程
  • os x yosemite10.10.4beta2更新了哪些内容 os x yosemite性能增强和bug修复以及下载
  • win8.1无线网
  • cocos2dx 教程
  • OpenGL Tips: 在Visual C++中调用FreeGLUT
  • Linux删除大量文件
  • shell脚本获取进程pid
  • jquery怎么实现单页面
  • jquery的核心理念
  • 注销外经证需要身份证吗
  • 报考国税
  • 办理增值税一般纳税人所需资料
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设