用OpenInventor实现的NeHe OpenGL教程-第四课

来源:互联网 发布:网络教育药学收费 编辑:程序博客网 时间:2024/05/05 15:42

用OpenInventor实现的NeHe OpenGL教程-第四课

 

       这节课将在第三课的基础上讨论如何旋转物体。我们希望三角形沿Y轴旋转,四边形沿着X轴旋转。我们只需要在上节课的基础上增加几行代码就可以了。

 

       和上节的代码不同,我们在函数BuildScene中,要先创建一个SoLightModel节点,这个节点的作用是设置当前光照模型,我们将当前的光照模型设置为BASE_COLOR。这样做的原因需要稍微详细说明一下。OpenInventor缺省情况下使用Phong类型的光照模型。在Phong类型的光照模型下,物体的颜色,亮度是与当前灯光的距离和方向有关的。一个平面的法向向量与光线方向的夹角越大,平面就越亮,反之则越暗。读者可以试验将这几条代码去掉,观察程序运行的效果,你会发现物体在旋转过程中会逐渐变暗,然后又逐渐变亮。我们将当前的光照模型设置为BASE_COLOR,就是让OpenInventor在计算物体的颜色的时候,不要考虑灯光的因素,只考虑物体本身的颜色。这样当物体旋转时,亮度始终如一。效果和NeHe教程中的完全一致。

 

void BuildScene(void)

{

     SoLightModel *pSoLightModel = new SoLightModel;

     pSoLightModel->model = SoLazyElement::BASE_COLOR;

     g_pOivSceneRoot->addChild(pSoLightModel);

 

    接下来的代码还是和上节不同,这次我们要创建一个SoSeparator节点,SoSeparator节点是一个容器节点,它可以将其它节点保存在自己的节点之下。它的一个最主要的作用是可以屏蔽其子节点的属性。例如,我们知道在场景中增加上一个SoTranslation节点后,其后的所有节点都要收到这个SoTranslation节点的影响。很多时候,我们希望这个SoTranslation节点只影响场景中某些物体。这时我们可以使用SoSeparator节点,将所有互相影响的节点作为它的子节点,让节点的作用范围只局限在SoSeparator节点内,不会对外面的节点产生影响。更多有关SoSeparator节点的知识,请读者查阅《The Inventor Mentor》一书中第三章的内容。

   

     SoSeparator *pTriangleSep = new SoSeparator;

     g_pOivSceneRoot->addChild(pTriangleSep);

 

       下面的代码和上节一样,创建了一个SoTranslation节点,用来平移物体到屏幕的左边,唯一不同的是,这个SoTranslation节点是增加到pTriangleSep节点之下的,而不是增加到g_pOivSceneRoot根节点之下。

 

     SoTranslation *TriangleTrans = new SoTranslation;

     TriangleTrans->translation.setValue(-1.5f,0.0f,-6.0f);

     pTriangleSep->addChild(TriangleTrans);

 

       下面的代码是让三角形沿着Y轴旋转。我们创建了一个SoRotor节点,SoRotor节点是一种称为“引擎”的节点,它内部有一个定时器,可以按照一定的时间间隔修改自身的旋转矩阵,这样就可以使物体旋转起来。更多有关SoRotor节点的知识,请读者查阅《The Inventor Mentor》一书中第十三章的“产生动画效果的节点”内容。我们设置SoRotor节点的旋转方式为,绕Y轴(0,1,0),逆时针旋转,速度为0.2。

 

     SoRotor *pTriangleRotor = new SoRotor;

     pTriangleRotor->rotation.setValue(SbVec3f(0,1,0),1);

     pTriangleRotor->speed = 0.2f;

     pTriangleSep->addChild(pTriangleRotor);

 

       剩下的代码和上节都一样了,在屏幕的左面画了一个彩色渐变的三角形。唯一不同的是,创建的节点都增加到pTriangleSep节点之下。

 

       旋转四边形的代码和旋转三角形基本一致。不过是旋转轴由Y轴变成了X轴而已。不过下面的代码需要注意。在上节课中,QuadTrans的平移量是(3.0f,0.0f,0.0f)。在本节中我们修改为(1.5f,0.0f,-6.0f)。这和NeHe教程中是一致的。原因就是因为我们使用了Separator节点,屏蔽了前面的SoTranslation节点。因此我们要向右移动1.5个单位时,只需要指定1.5即可,而不需要在考虑前面的平移了。

 

     SoTranslation *QuadTrans = new SoTranslation;

     QuadTrans->translation.setValue(1.5f,0.0f,-6.0f);

     pQuadSep->addChild(QuadTrans);

 

       现在编译运行我们程序,屏幕上左边会显示一个沿着Y轴旋转的三角形,右边会显示一个沿着X轴旋转的四边形。效果和NeHe第四课是相同的。

 

本课的完整代码下载。(VC 2003 + Coin2.5)

 

 

 

后记

OpenInventor是一种基于OpenGL的面向对象的三维图形软件开发包。使用这个开发包,程序员可以快速、简洁地开发出各种类型的交互式三维图形软件。这里不对OpenInventor做详细的介绍,读者如果感兴趣,可以阅读我的blog中的这篇文章《OpenInventor 简介》。

 

NeHe教程是目前针对初学者来说最好的OpenGL教程,它可以带领读者由浅入深,循序渐进地掌握OpenGL编程技巧。到目前为止(2007年11月),NeHe教程一共有48节。我的计划是使用OpenInventor来实现所有48节课程同样的效果。目的是复习和巩固OpenGL的知识,同时与各位读者交流OpenInventor的使用技巧。

 

       因为篇幅的限制,我不会介绍NeHe教程中OpenGL的实现过程,因为NeHe的教程已经讲解的很清楚了,目前网络中也有NeHe的中文版本。我将使用VC 2003作为主要的编译器。程序框架采用和NeHe一样的Win32程序框架,不使用MFC。程序也可以在VC Express,VC 2005/2008中编译。我采用的OpenInventor开发环境是Coin,这是一个免费开源的OpenInventor开发库。文章《OpenInventor-Coin3D开发环境》介绍了如何在VC中使用Coin。我使用的Coin版本是2.5。读者可以到www.coin3d.org中免费下载。

 

       读者可以在遵循GNU协议的条件下自由使用、修改本文的代码。水平的原因,代码可能不是最优化的,我随时期待读者的指正和交流。转载请注明。谢谢。

我的联系方式:

E-mail: < openinventor@gmail.com > < openinventor@126.com >

Blog: < http://blog.csdn.net/RobinHao >

Site: < http://www.openinventor.cn >

0 0
原创粉丝点击