用OpenInventor實現的NeHe OpenGL教程-第二十四課

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: < [email protected] > < [email protected] >

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

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

 
發佈了55 篇原創文章 · 獲贊 15 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章