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

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

      

 

這節課我們將學習使用環境紋理映射。這種映射方式可以讓物體表面看上去像鏡子一樣反射周圍的環境。這節課的代碼是在前面第十八節課程的基礎上修改的。閱讀NeHe教程我們可以發現,利用OpenGL顯示環境紋理是比較容易的,同樣在OpenInventor中使用環境紋理也是非常的簡單。我們只需要創建一個SoTextureCoordinateEnvironment節點就可以了。

 

       和以前的代碼一樣,我們將在函數BuildScene中創建場景數據。

void BuildScene(void)

{

//創建背景場景

     SoSeparator *pBackgroundSep = new SoSeparator;

     g_pOivSceneRoot->addChild(pBackgroundSep);

 

     SoTranslation *pTranslation = new SoTranslation;

     pBackgroundSep->addChild(pTranslation);

     pTranslation->translation.setValue(0,0,-24);

 

     SoTexture2 *pTexture = new SoTexture2;

     pTexture->filename.setValue("../Data/BG.PNG");

     pBackgroundSep->addChild(pTexture);

 

     SoCoordinate3 *pCoords = new SoCoordinate3;

     pBackgroundSep->addChild(pCoords);

     pCoords->point.set1Value(0,-13.3f, -10.0f,  10.0f);

     pCoords->point.set1Value(1, 13.3f, -10.0f,  10.0f);

     pCoords->point.set1Value(2, 13.3f,  10.0f,  10.0f);

     pCoords->point.set1Value(3,-13.3f,  10.0f,  10.0f);

 

     SoTextureCoordinate2 *pTexCoord = new SoTextureCoordinate2;

     pBackgroundSep->addChild(pTexCoord);

     pTexCoord->point.set1Value(0,0.0f, 0.0f);

     pTexCoord->point.set1Value(1,1.0f, 0.0f);

     pTexCoord->point.set1Value(2,1.0f, 1.0f);

     pTexCoord->point.set1Value(3,0.0f, 1.0f);

 

     int32_t NumVertices[] = { 4 };

     SoFaceSet *FaceSet = new SoFaceSet;

     FaceSet->numVertices.setValues(0, 1, NumVertices);

     pBackgroundSep->addChild(FaceSet);

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

     //創建幾何體場景,基本上和第十八課一樣

     g_pZTranslation = new SoTranslation;

     g_pOivSceneRoot->addChild(g_pZTranslation);

 

     g_pXRotor = new SoRotor;

     g_pXRotor->speed = 0.0f;

     g_pXRotor->rotation.setValue(SbVec3f(1,0,0),0.001f);

     g_pOivSceneRoot->addChild(g_pXRotor);

 

     g_pYRotor = new SoRotor;

     g_pYRotor->rotation.setValue(SbVec3f(0,1,0),0.001f);

     g_pYRotor->speed = 0.0f;

     g_pOivSceneRoot->addChild(g_pYRotor);

 

     g_pPointLight = new SoPointLight;

     g_pPointLight->color.setValue(1.0f, 1.0f, 1.0f);

     g_pPointLight->intensity = 1.0;

     g_pPointLight->location.setValue(0.0f, 0.0f, 4.0f);

     g_pOivSceneRoot->addChild(g_pPointLight);

 

     g_pTextureComplexity = new SoComplexity;

     g_pTextureComplexity->value = 1.0;

     g_pTextureComplexity->textureQuality = 1.0;

     g_pOivSceneRoot->addChild(g_pTextureComplexity);

 

     g_pTexture = new SoTexture2;

     g_pTexture->filename.setValue("../Data/Reflect.PNG");

     g_pTexture->model = SoTexture2::DECAL;

     g_pOivSceneRoot->addChild(g_pTexture);

 

     //這裏是本課程的關鍵,定義環境紋理節點

     SoTextureCoordinateEnvironment *pTexPlane = new SoTextureCoordinateEnvironment;

     g_pOivSceneRoot->addChild(pTexPlane);

 

     SoRotation *pRotation = new SoRotation;

     pRotation->rotation.setValue(SbVec3f(1,0,0),3.14159 / 2.0);

     g_pOivSceneRoot->addChild(pRotation);

 

     g_pSceneSwitch = new SoSwitch;

     SoSeparator *pCubeSep = new SoSeparator;

     pCubeSep->addChild(new SoCube);

     g_pSceneSwitch->addChild(pCubeSep);

 

     SoSeparator *pCylinderSep = new SoSeparator;

     SoCylinder *pCylinder = new SoCylinder;

     pCylinder->radius = 1.0f;

     pCylinder->height = 3.0f;

     pCylinder->parts = SoCylinder::SIDES;

     pCylinderSep->addChild(pCylinder);

     g_pSceneSwitch->addChild(pCylinderSep);

 

     SoSeparator *pSphereSep = new SoSeparator;

     SoSphere *pSphere = new SoSphere;

     pSphere->radius = 1.3f;

     pSphereSep->addChild(pSphere);

     g_pSceneSwitch->addChild(pSphereSep);

        

     SoSeparator *pConeSep = new SoSeparator;

     SoCone *pCone = new SoCone;

     pCone->bottomRadius = 1.0f;

     pCone->height = 3.0f;

     pCone->parts = SoCone::SIDES;

     pConeSep->addChild(pCone);

     g_pSceneSwitch->addChild(pConeSep);

 

     g_pSceneSwitch->whichChild = 0;

     g_pOivSceneRoot->addChild(g_pSceneSwitch);

}

剩下的代碼和第十八節課程都相同了。

 

       現在編譯運行我們程序,屏幕上顯示一個反射周圍環境立方體。按下左右方向鍵,立方體將繞Y軸旋轉。按下上下方向鍵,立方體將繞X軸旋轉。按下PnUp/PnDn鍵,立方體將放大或縮小。按下F鍵,立方體的紋理品質將發生變化。按下L鍵將打開或關閉燈光。按下空格鍵將顯示不同的幾何體。效果和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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章