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

来源:互联网 发布:华策影视工资待遇知乎 编辑:程序博客网 时间:2024/05/23 13:05

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

      

 

NeHe教程在这节课中向我们介绍了如何读取显卡支持的OpenGL的扩展,如何使用Targa(TGA)图像文件作为纹理,以及如何利用OpenGL的剪裁区域来滚动屏幕文字。

 

OpenInventor中没有相关的函数来获取OpenGL的扩展信息,我们只能通过直接调用OpenGL来获得这些信息。OpenInventor的纹理节点自动支持使用Targa(TGA)图像文件作为纹理,所以我们不必像NeHe教程中那样分析TGA文件格式了。

 

下面这个函数是根据输入的字符串来创建纹理字符场景,这个函数在前面的课程中已经使用过多次,这里就不在详细介绍了

SoSeparator* OivPrint(int x, int y, int set, const char *fmt,...)

{

..........................

}

 

       我们将在函数BuildScene中创建场景数据。

void BuildScene(void)

{

     SoEventCallback* pEventCallback = new SoEventCallback;

     pEventCallback->addEventCallback(SoKeyboardEvent::getClassTypeId(),KeyboardEventCB,g_pOivSceneRoot);

     g_pOivSceneRoot->addChild(pEventCallback);

     ///////////////////////////////////////////////////////////////////////////////////

//构造线框场景

     SoCoordinate3 *pLineCoords = new SoCoordinate3;

     pLineCoords->point.set1Value(0,TX(639),TY(417),0);

     pLineCoords->point.set1Value(1,TX(0)  ,TY(417),0);

     pLineCoords->point.set1Value(2,TX(0)  ,TY(480),0);

     pLineCoords->point.set1Value(3,TX(639),TY(480),0);

     pLineCoords->point.set1Value(4,TX(639),TY(128),0);

     pLineCoords->point.set1Value(5,TX(0)  ,TY(128),0);

     pLineCoords->point.set1Value(6,TX(639),TY(128),0);

     pLineCoords->point.set1Value(7,TX(639),TY(1),0);

     pLineCoords->point.set1Value(8,TX(0)  ,TY(1),0);

     pLineCoords->point.set1Value(9,TX(0)  ,TY(417),0);

     g_pOivSceneRoot->addChild(pLineCoords);

 

     SoLineSet *pLineSet = new SoLineSet;

     pLineSet->numVertices.set1Value(0,10);

     g_pOivSceneRoot->addChild(pLineSet);

     /////////////////////////////////////////////////////////////////////////////////////

     SoComplexity *pTextureComplexity = new SoComplexity;

     pTextureComplexity->textureQuality = 1.0;

     g_pOivSceneRoot->addChild(pTextureComplexity);

    

     //这里我们直接使用tga文件作为纹理节点的输入图像文件

     SoTexture2 *pFontTexture = new SoTexture2;

     pFontTexture->filename.setValue("../Data/Font.tga");

     pFontTexture->model = SoTexture2::MODULATE;

     g_pOivSceneRoot->addChild(pFontTexture);

 

     SoBaseColor *pBrightRedColor = new SoBaseColor;

     pBrightRedColor->rgb.setValue(1.0f,0.5f,0.5f);

     g_pOivSceneRoot->addChild(pBrightRedColor);

     g_pOivSceneRoot->addChild(OivPrint(TX(50),TY(56),1,"Renderer"));

     g_pOivSceneRoot->addChild(OivPrint(TX(80),TY(88),1,"Vendor"));

     g_pOivSceneRoot->addChild(OivPrint(TX(66),TY(120),1,"Version"));

 

     SoBaseColor *pBrightBlueColor = new SoBaseColor;

     pBrightBlueColor->rgb.setValue(0.5f,0.5f,1.0f);

     g_pOivSceneRoot->addChild(pBrightBlueColor);

     g_pOivSceneRoot->addChild(OivPrint(TX(192),TY(472),1,"NeHe Productions"));

 

     //通过回调函数来获得OpenGL的扩展信息。

     SoCallback *pGlInfoCallback = new SoCallback();

     pGlInfoCallback->setCallback(GlInfoCB, NULL);

     g_pOivSceneRoot->addChild(pGlInfoCallback);

}

 

    下面的函数用于获得OpenGL的扩展信息

void GlInfoCB(void *data, SoAction *action)

{

     if (action->isOfType(SoGLRenderAction::getClassTypeId()))

     {

         static bool bBuild = false;

         if(!bBuild)

         {

              bBuild = true;

              if(g_pOivSceneRoot)

              {

                   SoBaseColor *pOrangeColor = new SoBaseColor;

                   pOrangeColor->rgb.setValue(1.0f,0.7f,0.4f);

                   g_pOivSceneRoot->addChild(pOrangeColor);

                   g_pOivSceneRoot->addChild(OivPrint(TX(200),TY(56),1,

(char *)glGetString(GL_RENDERER)));

                   g_pOivSceneRoot->addChild(OivPrint(TX(200),TY(88),1,

(char *)glGetString(GL_VENDOR)));

                   g_pOivSceneRoot->addChild(OivPrint(TX(200),TY(120),1,

(char *)glGetString(GL_VERSION)));

 

                   g_pGLExtensionTrans = new SoTranslation;

                   g_pOivSceneRoot->addChild(g_pGLExtensionTrans);

                   SoBaseColor *pYellowColor = new SoBaseColor;

                   pYellowColor->rgb.setValue(1.0f,1.0f,0.5f);

                   g_pOivSceneRoot->addChild(pYellowColor);

 

                   SoCallback *pGlEnableScissorCallback = new SoCallback();

                   pGlEnableScissorCallback->setCallback(GlScissorCB, 0);

                   g_pOivSceneRoot->addChild(pGlEnableScissorCallback);

 

                   char* text=(char *)malloc(strlen((char *)glGetString(GL_EXTENSIONS)) + 1);               strcpy (text,(char *)glGetString(GL_EXTENSIONS));                                          int  cnt = 0;

                   char *token = strtok(text," ");                                                          while(token != NULL)                                                                     {

                       cnt++;                 // Increase The Counter

                       if (cnt > maxtokens)   // Is 'maxtokens' Less Than 'cnt'

                            maxtokens = cnt;   // If So, Set 'maxtokens' Equal To 'cnt'

 

                       g_pOivSceneRoot->addChild(

OivPrint(TX(10),TY(40 + 96 + (cnt * 36)),0,"%2i  %s",cnt,token));

                            token = strtok(NULL," ");   // Search For The Next Token

                   }

                   free(text);                          // Free Allocated Memory

 

                   SoCallback *pGlDisableScissorCallback = new SoCallback();

                   pGlDisableScissorCallback->setCallback(GlScissorCB, (void *)1);

                   g_pOivSceneRoot->addChild(pGlDisableScissorCallback);

              }

         }

     }

}

 

 

       现在编译运行我们程序,屏幕会显示出用户所使用的OpenGL驱动程序中提供的扩展函数。按下上下方向键,可以滚动显示这些文字。效果和NeHe第二十四是相同的。

 

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

 

 

后记

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

 

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

 

       因为篇幅的限制,我不会介绍NeHe教程中OpenGL的实现过程,因为NeHe的教程已经讲解的很清楚了,目前网络中也有NeHe的中文版本。我将使用VC 2003作为主要的编译器。程序框架采用和NeHe一样的Win32程序框架,不使用MFC。程序也可以在VC ExpressVC 2005/2008中编译。我采用的OpenInventor开发环境是Coin,这是一个免费开源的OpenInventor开发库。文章 OpenInventorCoin3D开发环境 介绍了如何在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 >

 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 中兴手机重启死机开不了机怎么办 太胖了太自卑了该怎么办 儿子因为长的胖特别自卑怎么办? 苹果ld叫我检查身份信息怎么办 我家墙让对面给漂水了怎么办 如果你流落到荒岛上你会怎么办 手机迅雷下载版权方不给下载怎么办 白色有彩色花纹的衣服染色了怎么办 载兰花假如下雪和打霜怎么办 皇室战争你的队友离开了对战怎么办 海岛奇兵发现求救信号第三个怎么办 海岛奇兵勋章太多对手太强怎么办 鱼为什么换缸鱼翅黑了怎么办 鱼丸捕鱼大作战换手机了怎么办 2o岁j'j小怎么办 为什么小米5s指纹不能用怎么办 cs录屏软件运行内存太大了怎么办 可是没有他我怎么办啊是什么电视剧 可是没有他我怎么办啊是哪个电视剧 手机太卡了打字打不了了怎么办 梦幻西游的将军令没有电了怎么办 将军令全部的序列号都忘记了怎么办 船员证被公司压着想自己换证怎么办 电子录入系统中无法打开影像怎么办 火车票退票后说银行退款失败怎么办 苹果4s玩游戏闪退怎么办 买了二手房原房主不迁户口怎么办 苹果禁反忘记工id密码了怎么办 玩英雄联盟用腾讯游戏平台卡怎么办 游戏代练接单了没有给我账号怎么办 华为手机进入设置立即闪退怎么办 股东发现公司有做假账现象怎么办 中国在服役期间有纹身被发现怎么办 脚碰了肿了紫了怎么办 外阴出血了怎么办去医院检查没问题 三个半月宝宝体检脚有的紧怎么办 肛门被红枣核刺了一个洞怎么办 肛门里面有棉签上的棉花怎么办 孩子裤子沾屎怎么洗下来怎么办 做完痔疮手术后有点肛门狭窄怎么办 孕妇做b超宝宝不配合怎么办