Android OpenGL显示任意3D模型文件

来源:互联网 发布:社交网络的社会价值 编辑:程序博客网 时间:2024/05/16 17:23


本来这周二准备发篇我自己写的文章的,但周末通宵看Ti6比赛,导致体力透支,最终没能写成。这里先恭喜一下Wings战队斩获Dota2国际邀请赛冠军,中国战队第三次插旗西雅图,同时912万美元的奖金也一夜造成了五位新的千万富翁。搞得我都快没心思写代码了,也想去组支战队了。


那么今天仍然是发投稿文章,下周二再给大家带来我自己写的文章。


很早之前就有朋友留言希望能有OpenGL相关文章,终于等到了一篇投稿。本篇huachao1001 的第二篇投稿,之前他已经跟大家分享过《图标无缝变形切换》。本文内容属于进阶教程,基础的教程可以访问他的博客,查看他之前的文章。


huachao1001 的博客地址:

http://blog.csdn.net/huachao1001


序言


前面两篇文章(这里指投稿作者的博客文章)我们介绍了 OpenGL 相关的基本知识,现在我们已经会绘制基本的图案了,但是还远远不能满足我们的需求。我们要做的是显示任意的模型,这也是本文所要做的事情。在阅读本文之前,请先确保你已经看过我前面两篇文章:


  • 【Android OpenGL入门】

  • 【Android OpenGL 显示基本图形及相关概念解读】


这两篇文章在作者的博客当中都能找到。


虽然标题是说显示任意3D文件,但是本文主要是以 STL格式文件 为例。其他的格式本质上都是一样的,只是解析部分的代码不同而已。接下来我们开始学习~


STL文件


它是标准的3D文件格式,一般3D打印机都是支持打印 STL文件,关于 STL文件 的格式、以及相关介绍请参考百度百科:【stl格式】。当然了,我在代码的注释中也会进行相关解释。


解析准备


首先,在解析 STL文件 格式之前,我们需要进行构思。我们无非就是把 STL文件 中的三角形的顶点信息提取出来。因此我们的主要目标就是把所有点信息读取出来。


但是,3D模型的坐标位置很随机,大小也随机。而不同的模型所处的位置不同,为了能够让模型处于手机显示中心,我们必须对模型进行移动、放缩处理。使得任意大小、任意位置的模型都能在我们的 GLSurfaceView 中以“相同”的大小显示。


因此,我们不仅仅要读取顶点信息,而且还要获取模型的边界信息。我们想象成一个立方体,这个立方体刚好包裹住模型。即我们要 读取x、y、z三个方向上的最大值最小值


开始解析


首先,我们定义一个 Model类,用于表示一个模型对象:




接下来就是将 stl文件 转换成 Model对象,我们定义一个 STLReader类





注意到,我们需要 频繁的将byte数组转为short、float类型,我们直接把这些函数装到一个 工具类Util 中:




为了更好的表示三维坐标系下的一个点,我们定义 Point类


public class Point {
   public float x;
   public float y;
   public float z;
   
   public Point(float x, float y, float z) {
       this.x = x;
       this.y = y;
       this.z = z;    }}


编写Render


上一节我们只是拿数据而已,还没开始绘制,真正的大招现在才开始。因为我们目标是显示任意模型,因此,必须把模型移动到我们的“视野”中,才能看得到(当然了,如果图形本身就是在我们的视野中,那就不一定需要这样的操作了)。废话不多说,直接看源码:




MainActivity 中不断调用旋转函数:




最后一步


一切看起来都已经完成了,但似乎少了点什么。啊哈~,少了 STL文件,其实网上有很多STL模型文件免费下载,大家可以随便搜索。我下载了一个胡巴的模型:




下载完成后,运行如下:




看到结果是不是觉得很失望?貌似看不到轮廓,其实,主要是跟灯光有关,我们程序中没有设置灯光。我们知道,我们在真实世界中看到物体主要是物体表面发生漫反射。我们所看到的物体跟光源的位置、物体的材质等等有关。另外,也可以通过贴纹理来做到。但是到目前为止,我们还没有这些知识,代码里面也没有涉及到这些,因此我们这能看到当前这个样子。后面我们会继续深入学习相关知识,欢迎关注~


点击下方 阅读原文 可以下载源码。






如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。


欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:


原创粉丝点击