用OpenInventor实现的NeHe OpenGL教程-第五课
这节课将在第四课的基础上进行扩展,创建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个顶点颜色
const float 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个顶点颜色
const float 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协议的条件下自由使用、修改本文的代码。水平的原因,代码可能不是最优化的,我随时期待读者的指正和交流。转载请注明。谢谢。
我的联系方式:
Blog: < http://blog.csdn.net/RobinHao >
Site: < http://www.openinventor.cn >