vrml        这里,我们首先释出编译好的读取wrl文件的程序,如左图所示,是打开的一个CASIA-3D-Face数据库的三维模型文件,使用Opengl进行了绘制。这个程序还提供了一些快捷键,使我们可以方便的移动模型和视角,如ASDW等。

        这里提供了一个编译好的demo的下载链接,请注意,程序必须运行在64位的Windows上,你需要打开prototxt文件,修改你需要打开的wrl文件的目录,由于使用静态库进行编译,你不需要相关环境(Opengl protobuf glog等),但是你可能需要安装VC2013Runtime X64

        当然,你也可以使用此博客中的代码,编译其它版本的程序,下面的内容会默认你已经了解了本博客前两节的内容,对wrl文件的格式和本文读取wrl文件的方式有所了解。在本程序的icp类中包含了OpenGL的相关内容,参考了 LeheOpenGL  的代码设计,如果你对OpenGL还不太了解,推荐经典入门教程:Nehe的OpenGL教程。不多说了,开始吧。

 OpenGL基础篇

1.glViewport

        这个函数有四个参数,以像素为单位指定了视口大小,前两个参数为视口坐下角的位置(默认为(0,0)),后两个参数指定了视口的宽和高。glViewport可以被用来设置一个比打开窗口更小的绘制区域,比如3DMax中的多视口建模,可以打开多个绘图窗口,对于每个视口独立渲染。

        多视口程序不能在窗口resize/reshape时直接调用glViewport,而应该在此时记下窗口大小,然后在绘制场景时多次调用glViewport设置每个视口的位置和大小。对于每个视口,应分别调用glMatrixMode(GL_PROJECTION)和glMatrixMode(GL_MODELVIEW)以设置投影和建模矩阵。

2.gluPerspective

        有一篇博客讲的太好了,以下是博主个人的总结:

        把opengl的视角比作一个相机,第一个参数fovy是视场角,第二个参数是实际窗口的横纵比,后两个参数是视场范围,就是有一个最近能看到的平面zNear和一个最远能看到的平面zFar,正如人在看景物时太近或太远都会看不清一样(光学系统都有景深),在opengl中也是同样的道理。

3.gluLookAt

        前面讲到OpenGL正如一个相机,如果说glViewport是在调节相机拍摄相片的大小,gluPerspective是在调节相机的镜头,那么gluLookAt就是在放置相机了。

        这个API乍看上去有三组参数:第一组参数是在以坐标方式指定放置相机的位置,第二组参数是在指定相机对准的位置点,也就是简介给出了相机的朝向,而第三组参数则是在指定相机本身的姿态,以向量方式规定了相机的Up方向,如(0,1,0)就是正立观看,(1,0,0)就是把相机躺着放置地面上,(0,-1,0)就是把相机倒过来180度,图像就是倒立的了。当然也可以解算出相机的 pitch轴 yaw轴 roll轴 的方位角。

4.glBegin

        与我们眼中的世界不同,计算机的三维世界没有曲面 没有曲线,都是点云 直线段和三角形。glBegin就开始绘制以定点方式指定绘制图形了。由于OpenGL是一组状态机,所以着色器在处理图元时会参照之前的设置,下面给出glBegin的图元绘制方式和glBegin/glEnd间的着色器设置API。

绘制篇

1.VRML格式

左图是我们处理的wrl文件的结点结构,可以在vrmlpad3.0中进行查看,文件指定了模型三维世界的各种信息。

node

        VRML语言的格式再前两篇博客中已经介绍过了,这里只介绍编程上的处理。在处理VRML语言时,每个顶点都按顺序由一个索引值,比如最开头的点index=0,第二个点index=1……,而计算机的世界是由三角形构成的,于是在openGL绘制图形时,就会使用这些点的索引,从点云数据中找到三个点作为三角形的顶点,查看下面的wrl文件你可能会更清楚一些:

在索引中-1代表当前绘制面的结束,-1之前的各个点构成一个多边形,之所以本文件中每个多边形都是三角形,这也是为了方便OpenGL直接使用三角形图元的方式进行绘制。

2.数据转储

在前一篇博客中,已经使用wrl类将wrl文件中需要的数据读入内存中了,下面我们正式开始介绍绘制三维图形的icp类。

为了方便使用索引,我们将各个顶点的颜色 法向量 位置 等信息转储到一个特殊的结构体中:

3.Opengl绘制

在opengl中,需要预先初始化光照 视角 位置等信息,我们注意到wrl文件中给出了viewpoint,于是我们的初始化过程如下:

        好了,这样我们几乎配置好opengl了,直接使用三角图元方式进行绘制即可,于是我们不加解释的给出下面的绘图函数,其中一些涉及opengl的问题已经在这篇博客的第一节进行了解释。

        连同上一节博客,本文就实现了一个VRML解释器。

        See You Next Chapter!

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注