用OpenInventor实现的NeHe OpenGL教程-第十一课
这节课我们将创建一个以正弦波方式飘动的旗帜。读者将看到实现这种效果并不像想象中那样的困难。至少说使用OpenInventor来实现还是比较容易的。^_^ 。
和前面的程序一样,我们在程序开始的部分定义了一些全局变量,这些变量的作用和NeHe教程中定义的变量有相同的作用。
SoCoordinate3* g_FlagCoords = NULL; //旗帜的顶点坐标节点
SoRotation* g_pXRotation = NULL; //绕X轴旋转的旋转节点
SoRotation* g_pYRotation = NULL; //绕Y轴旋转的旋转节点
SoRotation* g_pZRotation = NULL; //绕Z轴旋转的旋转节点
和NeHe教程一样,我们使用points数组来存放网格各顶点独立的x,y,z坐标。这里网格由45×45点形成。
float points[45][45][3];
float xrot = 0.0f;//绕X轴旋转的角度
float yrot = 0.0f;//绕Y轴旋转的角度
float zrot = 0.0f;//绕Z轴旋转的角度
const float piover180 = 0.0174532925f;//角度和弧度之间的转换因子
在函数BuildScene中,我们编写如下的代码。
void BuildScene(void)
{
在NeHe教程中,旗帜的前面使用框线方式显示,后面使用正常的填充方式显示。OpenInventor虽然也提供了使用框线方式显示的方法。但它只能同时设置前面和后面,不能分别单独设置。因此我们需要调用OpenGL函数。和前面的课程类似我们要向场景中增加一个SoCallback节点,这个节点的作用是可以在它的回调函数中调用OpenGL函数。
SoCallback *pGlCallback = new SoCallback();
pGlCallback->setCallback(GlCB, NULL); //设置用户自定义回调函数GLCB
g_pOivSceneRoot->addChild(pGlCallback);
向场景中增加绕X,Y,Z轴旋转的旋转节点。
g_pXRotation = new SoRotation;
g_pOivSceneRoot->addChild(g_pXRotation);
g_pYRotation = new SoRotation;
g_pOivSceneRoot->addChild(g_pYRotation);
g_pZRotation = new SoRotation;
g_pOivSceneRoot->addChild(g_pZRotation);
向场景中增加纹理节点
SoTexture2 *pTexture = new SoTexture2;
pTexture->filename.setValue("../Data/Tim.png");
pTexture->model = SoTexture2::DECAL;
g_pOivSceneRoot->addChild(pTexture);
定义旗帜的顶点数据和纹理数据,计算方法和NeHe教程相同
g_FlagCoords = new SoCoordinate3;
SoTextureCoordinate2 *FlagTexCoord = new SoTextureCoordinate2;
for(int x = 0; x < 45; x++)
{
for(int y = 0; y < 45; y++)
{
points[x][y][0] = float((x / 5.0f) - 4.5f);
points[x][y][1] = float((y / 5.0f) - 4.5f);
points[x][y][2] = float(sin((((x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));
g_FlagCoords->point.set1Value( x * 45 + y,points[x][y][0],
points[x][y][1],
points[x][y][2]);
FlagTexCoord->point.set1Value(x * 45 + y,float(x) / 45.0, float(y) / 45.0f);
}
}
g_pOivSceneRoot->addChild(FlagTexCoord);
g_pOivSceneRoot->addChild(g_FlagCoords);
定义网隔节点,显示旗帜
SoQuadMesh *pQuadMesh = new SoQuadMesh;
pQuadMesh->verticesPerRow = 45;
pQuadMesh->verticesPerColumn = 45;
g_pOivSceneRoot->addChild(pQuadMesh);
设置定时器来使旗帜飘动起来。读者可以参考第九节课程中的内容
SoTimerSensor * Timer = new SoTimerSensor(TimerSensorCB, NULL);
Timer->setInterval(0.001);
Timer->schedule();
}
下面我们编写SoCallback节点的响应函数,在OpenInventor遍历到SoCallback节点时会调用这个函数。在这个函数中,我们可以调用OpenGL命令,因为这时OpenGL Context是合法的。
void GlCB(void *data, SoAction *action)
{
if (action->isOfType(SoGLRenderAction::getClassTypeId()))
{
glPolygonMode( GL_BACK, GL_FILL );//背面采用填充方式
glPolygonMode( GL_FRONT, GL_LINE );//前面采用线框方式
}
}
下面的代码是定时器响应函数,定时器会每个一段时间调用一次这个函数,我们在这个函数中使旗帜运动起来。计算方法和NeHe教程中是相同的。
void TimerSensorCB(void * data, SoSensor *)
{
static int wiggle_count = 0;
if( wiggle_count == 2 )
{
for( int y = 0; y < 45; y++ )
{
float hold = points[0][y][2];
for( int x = 0; x < 44; x++)
{
points[x][y][2] = points[x+1][y][2];
}
points[44][y][2] = hold;
}
for(int x = 0; x < 45; x++)
{
for(int y = 0; y < 45; y++)
g_FlagCoords->point.set1Value( x * 45 + y,points[x][y][0],
points[x][y][1],
points[x][y][2]);
}
wiggle_count = 0;
}
wiggle_count++;
g_pXRotation->rotation.setValue(SbVec3f(1,0,0),xrot);
g_pYRotation->rotation.setValue(SbVec3f(0,1,0),yrot);
g_pZRotation->rotation.setValue(SbVec3f(0,0,1),zrot);
xrot += 0.3f * piover180;
yrot += 0.2f * piover180;
zrot += 0.4f * piover180;
}
现在编译运行我们程序,屏幕上会显示一个不断旋转的飘动旗帜。效果和NeHe第十一课是相同的。
后记
OpenInventor是一种基于OpenGL的面向对象的三维图形软件开发包。使用这个开发包,程序员可以快速、简洁地开发出各种类型的交互式三维图形软件。这里不对OpenInventor做详细的介绍,读者如果感兴趣,可以阅读我的blog中的这篇文章《
OpenInventor 简介》。
NeHe教程是目前针对初学者来说最好的OpenGL教程,它可以带领读者由浅入深,循序渐进地掌握OpenGL编程技巧。到目前为止(2007年11月),NeHe教程一共有48节。我的计划是使用OpenInventor来实现所有48节课程同样的效果。目的是复习和巩固OpenGL的知识,同时与各位读者交流OpenInventor的使用技巧。
读者可以在遵循GNU协议的条件下自由使用、修改本文的代码。水平的原因,代码可能不是最优化的,我随时期待读者的指正和交流。转载请注明。谢谢。
我的联系方式:
分享到:
相关推荐
OpenGL-Coin3 用Open Inventor实现NEHE的Open GL47教程经典学习例程
(VC++ 2003) Open Inventor Coin3D Nehe教程 代码
OpenGL Inventor 入门,提高必看. //**全系列相关Open Inventor请到我的空间下载**//
NEHE中文教程.OpenGL 入门,提高必看. //**全系列相关Open Inventor请到我的空间下载**//
许多软件厂商也纷纷以OpenGL为基础开发出自己的产品,其中比较著名的产品包括动画制作软件Soft Image和3D Studio MAX、仿真软件Open Inventor、VR软件World Tool Kit、CAM软件ProEngineer、GIS软ARC/INFO等等。...
Open Inventor Open Inventor7
Open Inventor-Coin3D开发环境-中国网游开发中心- OGDEV.NET-学者园地
本程序是利用open inventor的核心组件库coin3d编写平台是vc实现选择功能
Appinventor2 游戏源码--仿像素鸟 (包含资源文件,如图片 音效等)
其不同时期编制的同一Open Inventor程序代码都可利用OpenGL的最新发展技术,并能最大限度地发挥所使用的计算机软硬件性能。另外,Open Inventor还能够完美支持VRML 97、三维音效、三维纹理和多处理器的并行渲染技术...
OpenInventor核心库coin3D,学习指导书《Mentor》
如何在MFC程序中使用Open Inventor, OpenGL Inventor 入门,提高必看. //**全系列相关Open Inventor请到我的空间下载**//
其不同时期编制的同一Open Inventor程序代码都可利用OpenGL的最新发展技术,并能最大限度地发挥所使用的计算机软硬件性能。另外,Open Inventor还能够完美支持VRML 97、三维音效、三维纹理和多处理器的并行渲染技术...
许多软件厂商也纷纷以OpenGL为基础开发出自己的产品,其中比较著名的产品包括动画制作软件Soft Image和3D Studio MAX、仿真软件Open Inventor、VR软件World Tool Kit、CAM软件ProEngineer、GIS软ARC/INFO等等。...
阎锋欣等编写OpenInventor程序设计——从入门到精通的源代码,由于只能上传小于20M的文件,所以我将整个源...OpenInventor_code2.rar为第10章到15章的代码以及一些说明文档,解压后请查看文件:“光盘使用说明.doc”。
其不同时期编制的同一Open Inventor程序代码都可利用OpenGL的最新发展技术,并能最大限度地发挥所使用的计算机软硬件性能。另外,Open Inventor还能够完美支持VRML 97、三维音效、三维纹理和多处理器的并行渲染技术...
基于Open Inventor的虚拟场景实现
其不同时期编制的同一Open Inventor程序代码都可利用OpenGL的最新发展技术,并能最大限度地发挥所使用的计算机软硬件性能。另外,Open Inventor还能够完美支持VRML 97、三维音效、三维纹理和多处理器的并行渲染技术...
aia源码--Appinventor2 游戏--俄罗斯方块
The Inventor Mentor:Programming Object-Oriented 3D Graphics