OpenGL导入3DS专题

    最近一直在研究如何将3D模型导入OpenGL,略微有些进展,在附录部分把它记录下,希望能起到抛砖引玉的作用,有不足的地方,请大家指出。

1. 简述

    如果想把做场景做的复杂,导入3D模型是一个必不可少的过程,网络上有很多方法,但是笔者找了很久,也许能力欠缺,找到的方法都不尽如人意,现在在此进行总结,希望对后来的同学有所帮助。

2. 模型转换

    关于选取读取模型的格式,笔者使用的是3DS,至于为什么选这种格式,一个是因为网络上有读取3DS文件的类;二是因为3DS文件可以由3DSMAX转换而来,资源丰富,便于使用。

2.1 3DSMAX

    相信这款软件大家都耳熟能详,笔者使用的是3ds Max 2014,至于有人问为什么使用如此高的版本,我在这里做出的解释是有些网络上的资源使用的是高版本,对于3DSMAX来说,低版本打开高版本有些困难,为了方便就使用了高版本(机器配置不好的同学建议还是使用低版本)。

    下面介绍下如何使用:

    网络上下下来的有很多是.max文件,在这里我们要把它转换成3DS文件,首先我们打开.max文件,如图1:

 OpenGL导入3DS专题_第1张图片

图1 打开.max文件

    这里使用的模型是刺客信条的主角,很帅吧。打开模型后,我们需要进行很重要的优化,非常重要,否则你导入OpenGL后会非常卡。

    在3DSMAX中按数字“7”键(注意,不是小键盘7),然后会显示模型文件的面数和顶点数,如图2:

OpenGL导入3DS专题_第2张图片

图2 显示出点面数

    为了保证导入时候的速度,减少点面数是十分有必要的,但是记住不能使图像变得太粗糙,这里我们开始优化操作。笔者使用的是最基本的优化操作ProOptimizer。先全选所有对象,然后再选择右边的按钮,之后选择修改器列表,在下拉列表中找到ProOptimizer。

    如图3所示:

OpenGL导入3DS专题_第3张图片

图3 ProOptimizer

    之后我们要进行点面优化。很傻瓜话的一个插件,具体操作可以百度,在这里笔者只说下简单的过程。优化级别里,100%就是需要保留的顶点数,点击计算,就可以看到计算前后的点面数。接下来说最好勾选的几个选项,如图4所示:

OpenGL导入3DS专题_第4张图片     OpenGL导入3DS专题_第5张图片

图4 推荐勾选的几个选项

    另外需要说明的是,ProOptimizer操作可进行多次叠加。笔者建议的是最好进行多次微调,而不是一次性进行大幅度调整。读者自己慢慢体会。

    在进行优化之后,我们需要把模型另存为3DS格式。选择文件->导出->导出。

    如图5(1)所示:

OpenGL导入3DS专题_第6张图片

图5(1) 导出3DS

    之后我们选择需要导出到的文件夹,这里我们最好选择之前.max文件所在的目录。下拉列表中选择*.3ds格式。

    如图5(2)所示:

OpenGL导入3DS专题_第7张图片

图5(2) 保存3ds格式

    然后勾选保持MAX的纹理坐标,点确定(很重要)。这样,我们成功的转换了个3DS文件。

2.2 3DS文件的加工处理

    接下来,我们用Deep Exploration 6.3打开3ds文件。如果你刚刚把3ds文件保存在.max文件的目录下,恭喜你,你不用再贴纹理了,否则,你还需要自己一个一个贴纹理。下面是有无纹理的对比。

    如图6所示:

OpenGL导入3DS专题_第8张图片   OpenGL导入3DS专题_第9张图片

图6 有无纹理比较

    网络上有很多人卡在这一步,如果没有纹理应该怎么贴呢?总的来说,出现纹理缺失有很多原因,有些是因为作者没有把纹理全部打包,有些则是因为导出过程出错,需要自己手动加载。对于前一种情况,自求多福吧,对于后一种情况,我们需要自己手动把纹理加上。

    假设我们现在缺少头部纹理,我们需要到下载的文件里头找纹理。现在我们直接双击头部,在弹出对话框中选择属性,然后选择漫反射,再选择浏览,找到纹理后点确定。

    如图7所示:

OpenGL导入3DS专题_第10张图片

图7 选择纹理

    添加纹理之后的图像如图8所示:

OpenGL导入3DS专题_第11张图片

图8 添加纹理之后的图像

    然后点确定,纹理就添加完毕了。

    这里我们需要注意一个问题,网络上有非常非常多人卡在这一步,就是为什么纹理全部添加完毕之后,导入过程还一直出错。原因就是,在3ds文件中,每个纹理槽都必须对应一个纹理(请容许我称呼它为纹理槽),否则导入过程中就会提示找不到文件,因为读入过程中OpenGL会读入3ds文件的材质(就是纹理槽),但是找不到纹理文件,指针就会为NULL,这时候自然而然就会报错了。

    此时,我们有两种解决方案。第一种,从代码入手,自动忽略为NULL的纹理。第二种,我们从文件入手。这里我将会详细说明如何从文件入手,至于代码方面,网络上各种3ds导入类,质量参差不齐,不太好做统一说明。

我们点开场景标签,再打开材料文件夹,这里你会发现一些有趣的东西。

    如图9所示:

OpenGL导入3DS专题_第12张图片

图9 材料文件夹

    这里就是纹理和纹理槽相对应的地方(请再次容许我称呼它为纹理槽),有些文件名左侧的小球上有感叹号,有些那个小球是灰色的。如果我们想成功导入3ds文件的话,这两种情况是不允许出现的,我们只容许一个小球上出现灰色,那就是,其他的坚决不容许。先说明下,有感叹号的小球是因为纹理槽指定了纹理,但是系统找不到纹理文件,灰色小球是因为纹理槽根本没有纹理。再次强调,这两种情况千万不能出现!!对于前者,能找到纹理最好,否则就直接删掉它,至于灰色小球,直接删掉吧,除非你能找到合适的纹理给他贴上(这里删除纹理推荐使用3D Exploration)。

    还需注意一定的是,如果读者发现有个别文件无法读入纹理,但是也不报错,请注意,max文件中是否包含了一种叫做多维子材质的纹理,如果有这样的纹理,需要进行材质分解,所需要的工具笔者会打包给大家。

假设以上的步骤大家都处理好了,下面我们可以进行保存了。保存纹理和新的3ds到同一个目录下(最好新建一个目录)。

    具体设置如图10所示:

 OpenGL导入3DS专题_第13张图片

图10 推荐设置

    这样,我们就成功保存了可以导入OpenGL的3ds文件。

3.导入OpenGL

    终于到了激动人心的一环,小伙伴。做到这一步,如果人品没问题的话,都可以成功的导入3ds。但是,比较遗憾的是,由于不同的人用的导入代码不同,我这里只能介绍我所使用和修改的3DS导入类,因为进行了封装,使用起来还是很方便的,有兴趣的同学可以联系我。

3.1 放置文件

    3ds文件和纹理文件分别放在data\models和data\textures目录下。

3.2 修改代码

    首先,我们需要修改GLBase.h文件,添加进新的3DS文件所在的路径。

    如图11所示:

OpenGL导入3DS专题_第14张图片

图11 写入文件名

    然后在静态模型类的头文件Static3DS.h中用模型类定义个g_CKXT对象。

    如图12所示:

OpenGL导入3DS专题_第15张图片

图12 定义“刺客信条”对象

    接下来在Static3DS.cpp中初始化g_CKXT对象,写入坐标和缩放比例与文件名。缩放比例与坐标需要进行多次调整。

    具体代码如图13所示:

OpenGL导入3DS专题_第16张图片

图13 初始化3DS模型

    接着根据3DS文件进行数据初始化。

    如图14所示:

OpenGL导入3DS专题_第17张图片

图14 初始化3DS模型中的数据

    接着进行渲染3DS模型。

    如图15所示:

OpenGL导入3DS专题_第18张图片

图15 渲染

    至此,3DS文件已经成功导入。效果如图16所示:

OpenGL导入3DS专题_第19张图片

图16 导入后的模型

后记

    经历了半个月左右的周折,计算机图形学作业基本完成。首先,感谢读者能够耐心读完,附录部分算是笔者收获最多的地方,网络上目前没有一个比较完整关于3DS文件导入OpenGL的解决方案,所以才写了这篇附录,希望能为后来者提供方便;其次,笔者深知毫无技术含量,但是还是写了好多,算是无知无畏吧。以后需要学习的东西还有好多,笔者也需知耻而后勇。



    最后要说的是,请原谅我的排版。


你可能感兴趣的:(计算机图形)