这节课将在第四课的基础上进行扩展,创建3D物体。我们将三角形变为3D的三棱锥形,把四边形变为立方体。同时三棱锥沿Y轴旋转,四边形沿着(1,1,1)方向旋转。 和上节的代码一样,我们在函数BuildScene中,要先创建一个SoLightModel节点,将当前的光照模型设置为BASE_COLOR。 void BuildScene(void){ SoLightModel *pSoLightModel = new SoLightModel; pSoLightModel->model = SoLazyElement::BASE_COLOR; g_pOivSceneRoot->addChild(pSoLightModel); 接下来创建一个SoSeparator节点,用来存储以后的属性、形体节点。 SoSeparator *pTriangleSep = new SoSeparator; g_pOivSceneRoot->addChild(pTriangleSep); 下面的代码和上节一样,创建了一个SoTranslation节点,用来平移物体到屏幕的左边。 SoTranslation *TriangleTrans =new SoTranslation; TriangleTrans->translation.setValue(-1.5f,0.0f,-6.0f); pTriangleSep->addChild(TriangleTrans); 和上节的代码一样,我们创建了一个SoRotor节点,让三棱锥沿着Y轴旋转。 SoRotor *pTriangleRotor = new SoRotor; pTriangleRotor->rotation.setValue(SbVec3f(0,1,0),1); pTriangleRotor->speed = 0.2f; pTriangleSep->addChild(pTriangleRotor); 接下来我们要创建三棱锥物体了。其实创建三棱锥和创建2D的三角形的代码很类似,不同之处就是三棱锥需要更多的顶点、颜色数据而已。创建过程和上节的代码基本一致。顶点坐标和颜色值都和NeHe教程中的数值一样。 //先创建材质绑定节点,将材质颜色绑定到每个顶点上。 SoMaterialBinding *TriangleMaterialBinding =new SoMaterialBinding; TriangleMaterialBinding->value = SoMaterialBinding::PER_VERTEX; pTriangleSep->addChild(TriangleMaterialBinding); //定义每个顶点的颜色,一共12个顶点颜色 constfloat TriangleColors[][3] = { { 1.0f, 0.0f, 0.0f}, { 0.0f,1.0f,0.0f}, { 0.0f,0.0f,1.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f,0.0f,1.0f}, { 0.0f,1.0f,0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f,1.0f,0.0f}, { 0.0f,0.0f,1.0f}, { 1.0f,0.0f,0.0f}, { 0.0f,0.0f,1.0f},{ 0.0f,1.0f,0.0f} }; SoMaterial *TriangleMaterials =new SoMaterial; TriangleMaterials->diffuseColor.setValues(0, 12, TriangleColors); pTriangleSep->addChild(TriangleMaterials); //定义12个顶点的坐标值 float TriangleVertices[][3] = { {0.0f, 1.0f, 0.0f}, {-1.0f,-1.0f, 1.0f}, { 1.0f,-1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {1.0f,-1.0f, 1.0f}, { 1.0f,-1.0f, -1.0f}, {0.0f, 1.0f, 0.0f},{1.0f,-1.0f, -1.0f},{ -1.0f,-1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f,-1.0f, -1.0f}, { -1.0f,-1.0f, 1.0f} }; SoCoordinate3 *TriangleCoords =new SoCoordinate3; TriangleCoords->point.setValues(0, 12, TriangleVertices); pTriangleSep->addChild(TriangleCoords); SoFaceSet *pFaceSet = new SoFaceSet; pTriangleSep->addChild(pFaceSet); 创建立方体和创建三棱锥稍微有些不同。因为OpenInventor已经提供了立方体形体节点,所以我们可以直接创建一个SoCube节点,而不必像创建三棱锥那样创建每个面了。 //创建立方体的Separator容器 SoSeparator *pQuadSep = new SoSeparator; g_pOivSceneRoot->addChild(pQuadSep); //定义平移节点,将立方体向右平移1.5单位,向内平移7个单位 SoTranslation *QuadTrans = new SoTranslation; QuadTrans->translation.setValue(1.5f,0.0f,-7.0f); pQuadSep->addChild(QuadTrans); //定义旋转节点,沿着方向(1,1,1)旋转 SoRotor *pQuadRotor = new SoRotor; pQuadRotor->rotation.setValue(SbVec3f(1,1,1),-1); pQuadRotor->speed = 0.15f; pQuadSep->addChild(pQuadRotor); //定义材质绑定节点,将材质颜色绑定到每个面上。 SoMaterialBinding *QuadMaterialBinding =new SoMaterialBinding; QuadMaterialBinding->value = SoMaterialBinding::PER_FACE; pQuadSep->addChild(QuadMaterialBinding); //定义每个顶点的颜色,一共6个顶点颜色 constfloat QuadColors[][3] ={{ 0.0f,1.0f,0.0f },{ 1.0f,0.5f,0.0f },{ 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f },{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.1f } }; SoMaterial *QuadMaterials = new SoMaterial; QuadMaterials->diffuseColor.setValues(0,6,QuadColors); pQuadSep->addChild(QuadMaterials); //构造一个缺省大小的(2×2×2)的立方体 pQuadSep->addChild(new SoCube); 现在编译运行我们程序,屏幕上左边会显示一个沿着Y轴旋转的三棱锥,右边会显示一个沿着(1,1,1)方向旋转的立方体。效果和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 >