OpenSceneGraph基础:光照

接着前篇进行(http://blog.csdn.net/boksic/article/details/44002155),现在考虑光照效果

主程序

转载请注明http://blog.csdn.net/boksic 如有疑问欢迎留言

和之前基本唯一的变化就是把窗口部分的操作放在初始化函数initCanvas里进行。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int main(int argc, const char* argv[]) {  
  2.   
  3.       
  4.     osg::Group *scene = startupScene();  
  5.   
  6.     osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;  
  7.     viewer->setSceneData(scene);   
  8.     initCanvas(viewer);  
  9.   
  10.     while (!viewer->done()) {  
  11.         viewer->frame();  
  12.         update(0.5); // do the update advancing 500ms  
  13.     }  
  14.     return 0;  
  15. }  

窗口初始化(initCanvas)

我们使用GraphicsContext类来对设备上下文进行操作,该类需要一个Traits结构来定义具体的窗口属性,例如窗口大小,窗口位置等。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void initCanvas(osg::ref_ptr<osgViewer::Viewer> viewer) {  
  2.     int x = 20;  
  3.     int y = 20;  
  4.     osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  5.     traits->x = x;  
  6.     traits->y = y;  
  7.     traits->width = width;  
  8.     traits->height = height;  
  9.     if (offScreen) {  
  10.         traits->windowDecoration = false;  
  11.         traits->doubleBuffer = true;  
  12.         traits->pbuffer = true;  
  13.     }  
  14.     else {  
  15.         traits->windowDecoration = true;  
  16.         traits->doubleBuffer = true;  
  17.         traits->pbuffer = false;  
  18.     }  
  19.     traits->windowName = "http://blog.csdn.net/boksic";  
  20.     traits->sharedContext = 0;  
  21.     traits->alpha = 8;  
  22.     traits->readDISPLAY();  
  23.     traits->setUndefinedScreenDetailsToDefaultScreen();  
  24.   
  25.     osg::GraphicsContext* _gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
  26.   
  27.     if (!_gc) {  
  28.         osg::notify(osg::NOTICE)  
  29.             << "Failed to create pbuffer, failing back to normal graphics window." << endl;  
  30.   
  31.         traits->pbuffer = false;  
  32.         _gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
  33.     }  
  34.   
  35. }  

Viewer内置了Camera对象来控制窗口,我们可以通过getCamera函数来对该对象进行操作,例如setClearColor设置清屏颜色。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. viewer->getCamera()->setGraphicsContext(_gc);  
  2. viewer->getCamera()->setViewport(new osg::Viewport(x, y, width, height));  
  3. viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1));  
  4.   
  5.   
  6. viewer->setCameraManipulator(new osgGA::TrackballManipulator);  
  7. viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);  
  8. viewer->realize();  
  9. viewer->setReleaseContextAtEndOfFrameHint(false);  



场景初始化(startup)

首先按前篇的方法建立几何图形:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //球  
  2. osg::Geode *sphere = new osg::Geode();  
  3. sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(-2, 0, 0), 1)));  
  4. //正方体  
  5. osg::Geode *cube = createCube();  
  6. cubeTransform = new osg::PositionAttitudeTransform();  
  7. cubeTransform->addChild(cube);  
  8. cubeTransform->setPosition(osg::Vec3(2, 0, -1));  
  9. //金字塔  
  10. osg::Geode *pyramid = createPyramid();  
  11. pyramidTransform = new osg::PositionAttitudeTransform();  
  12. pyramidTransform->addChild(pyramid);  
  13. pyramidTransform->setPosition(osg::Vec3(5, 0, -1));  
这里,球是按照osg内置函数建立模型,金子塔与之前相同,正方体则使用了setNormalBinding来绑定法向量用到了法向量(注意:与颜色索引一样,设置法线索引的setNormalIndices也已经被废除了),正方体的建立函数:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Geode *createCube() {  
  2.     // vertex array  
  3.     osg::Vec3Array *vertexArray = new osg::Vec3Array();  
  4.   
  5.     // bottom front left  
  6.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  7.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  8.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  9.     // bottom front right  
  10.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  11.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  12.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  13.     // bottom back right  
  14.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  15.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  16.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  17.     // bottom back left  
  18.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  19.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  20.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  21.   
  22.     // top front left  
  23.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  24.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  25.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  26.     // top front right  
  27.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  28.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  29.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  30.     // top back right  
  31.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  32.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  33.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  34.     // top back left  
  35.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  36.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  37.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  38.   
  39.   
  40.     // face array  
  41.     osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);  
  42.   
  43.     // bottom  
  44.     faceArray->push_back(0); // face 1  
  45.     faceArray->push_back(9);  
  46.     faceArray->push_back(3);  
  47.     faceArray->push_back(9); // face 2  
  48.     faceArray->push_back(6);  
  49.     faceArray->push_back(3);  
  50.     // top  
  51.     faceArray->push_back(21);  //face 3  
  52.     faceArray->push_back(12);  
  53.     faceArray->push_back(18);  
  54.     faceArray->push_back(12);  //face 4  
  55.     faceArray->push_back(15);  
  56.     faceArray->push_back(18);  
  57.     // left  
  58.     faceArray->push_back(22);  //face 5  
  59.     faceArray->push_back(10);  
  60.     faceArray->push_back(13);  
  61.     faceArray->push_back(10);  //face 6  
  62.     faceArray->push_back(1);  
  63.     faceArray->push_back(13);  
  64.     // right  
  65.     faceArray->push_back(16);  //face 7  
  66.     faceArray->push_back(4);  
  67.     faceArray->push_back(19);  
  68.     faceArray->push_back(4);  //face 8  
  69.     faceArray->push_back(7);  
  70.     faceArray->push_back(19);  
  71.     // front  
  72.     faceArray->push_back(14);  //face 9  
  73.     faceArray->push_back(2);  
  74.     faceArray->push_back(17);  
  75.     faceArray->push_back(2);   //face 10  
  76.     faceArray->push_back(5);  
  77.     faceArray->push_back(17);  
  78.     // back  
  79.     faceArray->push_back(20);  //face 11  
  80.     faceArray->push_back(8);  
  81.     faceArray->push_back(23);  
  82.     faceArray->push_back(8);   //face 12  
  83.     faceArray->push_back(11);  
  84.     faceArray->push_back(23);  
  85.   
  86.     // normal array  
  87.     osg::Vec3Array *normalArray = new osg::Vec3Array();  
  88.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  89.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  90.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  91.   
  92.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  93.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  94.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  95.   
  96.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  97.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  98.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  99.   
  100.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  101.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  102.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  103.   
  104.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  105.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  106.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  107.   
  108.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  109.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  110.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  111.   
  112.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  113.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  114.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  115.   
  116.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  117.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  118.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  119.   
  120.     osg::Geometry *geometry = new osg::Geometry();  
  121.     geometry->setVertexArray(vertexArray);  
  122.   
  123.     geometry->setNormalArray(normalArray);  
  124.     geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);  
  125.     geometry->addPrimitiveSet(faceArray);  
  126.   
  127.     osg::Geode *cube = new osg::Geode();  
  128.     cube->addDrawable(geometry);  
  129.     return cube;  
  130. }  


建立组节点,获取其渲染状态StateSet。StateSet保存了一系列Opengl的渲染属性和值,用于控制节点下图形的渲染,若要设置则需获取该对象的StateSet后进行操作。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. StateSet *lightStateSet;  
  2. Node *startup() {   
  3.         Group *scene = new Group();  
  4.     lightStateSet = scene->getOrCreateStateSet();  
  5. }  

建立材质属性

osg的Material 封装了OpenGL 的glMaterial()和glColorMaterial(),用法基本类似。而建立Material后再关联到图形的StateSet中即可试目标图形具有该材质属性。这里为球体和正方体赋予了该材质。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // create white material  
  2. osg::Material *material = new osg::Material();  
  3. material->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 1.0));  
  4. material->setSpecular(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  5. material->setAmbient(osg::Material::FRONT, osg::Vec4(0.1, 0.1, 0.1, 1.0));  
  6. material->setEmission(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  7. material->setShininess(osg::Material::FRONT, 25.0);  
  8.   
  9. // assign the material to the sphere and cube  
  10. sphere->getOrCreateStateSet()->setAttribute(material);  
  11. cube->getOrCreateStateSet()->setAttribute(material);  

设置光源

OSG使用Light对象来定义光源属性,Light的setLightNum函数是用来关联OpenGL的位置数GL_LIGHT0 到GL_LIGHT7的,所以需要赋予其一个唯一的值(uniqueLightNumber)。我们可以定义一个简单的光源生成函数

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int uniqueLightNumber = 0;  
  2. osg::Light *createLight(osg::Vec4 color)  
  3. {  
  4.     osg::Light *light = new osg::Light();  
  5.     // each light must have a unique number  
  6.     light->setLightNum(uniqueLightNumber++);  
  7.     // we set the light's position via a PositionAttitudeTransform object  
  8.     light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  9.     light->setDiffuse(color);  
  10.     light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));  
  11.     light->setAmbient(osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  12.   
  13.     return light;  
  14. }  

而Light对象需要放在LightSource的节点当中,可以通过LightSource来控制灯光的位置以及状态。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // Create Lights - Red, Green, Blue  
  2. osg::Vec4 lightColors[] = { osg::Vec4(1.0, 0.0, 0.0, 1.0), osg::Vec4(0.0, 1.0, 0.0, 1.0), osg::Vec4(0.0, 0.0, 1.0, 1.0) };  
  3.   
  4. osg::Group *root = new osg::Group();  
  5. lightStateSet = root->getOrCreateStateSet();  
  6.   
  7. osg::Geode *lightMarker[LIGHTS];  
  8. osg::LightSource *lightSource[LIGHTS];  
  9.   
  10.   
  11. for (int i = 0; i < LIGHTS; i++) {  
  12.     lightMarker[i] = new osg::Geode();  
  13.     lightMarker[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1)));  
  14.     lightMarker[i]->getOrCreateStateSet()->setAttribute(createSimpleMaterial(lightColors[i]));  
  15.   
  16.     lightSource[i] = new osg::LightSource();  
  17.     lightSource[i]->setLight(createLight(lightColors[i]));  
  18.     lightSource[i]->setLocalStateSetModes(osg::StateAttribute::ON);  
  19.     lightSource[i]->setStateSetModes(*lightStateSet, osg::StateAttribute::ON);  
  20.   
  21.     lightTransform[i] = new osg::PositionAttitudeTransform();  
  22.     lightTransform[i]->addChild(lightSource[i]);  
  23.     lightTransform[i]->addChild(lightMarker[i]);  
  24.     lightTransform[i]->setPosition(osg::Vec3(0, 0, 5));  
  25.     lightTransform[i]->setScale(osg::Vec3(0.1, 0.1, 0.1));  
  26.   
  27.     root->addChild(lightTransform[i]);  
  28. }  

最后不忘添加到组节点当中

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. root->addChild(sphere);  
  2. root->addChild(cubeTransform);  
  3. root->addChild(pyramidTransform);  

更新部分(update函数)

这里实现的是三个点光源做圆周运动

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void update(float dt) {  
  2.     myTimer += 0.01*dt;  
  3.     lightTransform[0]->setPosition(osg::Vec3(cos(myTimer), sin(myTimer), 0) * 4);  
  4.     lightTransform[1]->setPosition(osg::Vec3(0, cos(myTimer), sin(myTimer)) * 4);  
  5.     lightTransform[2]->setPosition(osg::Vec3(sin(myTimer), cos(myTimer), sin(myTimer)) * 4);  
  6. }  





最后附上完整代码

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <osgGA/TrackballManipulator>   
  2. #include <osg/PositionAttitudeTransform>  
  3. #include <osgGA/GUIEventHandler>  
  4. #include <osg/Material>  
  5. #include <osg/ShapeDrawable>  
  6. osg::Geode *createCube() {  
  7.     // vertex array  
  8.     osg::Vec3Array *vertexArray = new osg::Vec3Array();  
  9.   
  10.     // bottom front left  
  11.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  12.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  13.     vertexArray->push_back(osg::Vec3(-1, -1, 0));  
  14.     // bottom front right  
  15.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  16.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  17.     vertexArray->push_back(osg::Vec3(+1, -1, 0));  
  18.     // bottom back right  
  19.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  20.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  21.     vertexArray->push_back(osg::Vec3(+1, +1, 0));  
  22.     // bottom back left  
  23.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  24.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  25.     vertexArray->push_back(osg::Vec3(-1, +1, 0));  
  26.   
  27.     // top front left  
  28.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  29.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  30.     vertexArray->push_back(osg::Vec3(-1, -1, 2));  
  31.     // top front right  
  32.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  33.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  34.     vertexArray->push_back(osg::Vec3(+1, -1, 2));  
  35.     // top back right  
  36.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  37.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  38.     vertexArray->push_back(osg::Vec3(+1, +1, 2));  
  39.     // top back left  
  40.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  41.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  42.     vertexArray->push_back(osg::Vec3(-1, +1, 2));  
  43.   
  44.   
  45.     // face array  
  46.     osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);  
  47.   
  48.     // bottom  
  49.     faceArray->push_back(0); // face 1  
  50.     faceArray->push_back(9);  
  51.     faceArray->push_back(3);  
  52.     faceArray->push_back(9); // face 2  
  53.     faceArray->push_back(6);  
  54.     faceArray->push_back(3);  
  55.     // top  
  56.     faceArray->push_back(21);  //face 3  
  57.     faceArray->push_back(12);  
  58.     faceArray->push_back(18);  
  59.     faceArray->push_back(12);  //face 4  
  60.     faceArray->push_back(15);  
  61.     faceArray->push_back(18);  
  62.     // left  
  63.     faceArray->push_back(22);  //face 5  
  64.     faceArray->push_back(10);  
  65.     faceArray->push_back(13);  
  66.     faceArray->push_back(10);  //face 6  
  67.     faceArray->push_back(1);  
  68.     faceArray->push_back(13);  
  69.     // right  
  70.     faceArray->push_back(16);  //face 7  
  71.     faceArray->push_back(4);  
  72.     faceArray->push_back(19);  
  73.     faceArray->push_back(4);  //face 8  
  74.     faceArray->push_back(7);  
  75.     faceArray->push_back(19);  
  76.     // front  
  77.     faceArray->push_back(14);  //face 9  
  78.     faceArray->push_back(2);  
  79.     faceArray->push_back(17);  
  80.     faceArray->push_back(2);   //face 10  
  81.     faceArray->push_back(5);  
  82.     faceArray->push_back(17);  
  83.     // back  
  84.     faceArray->push_back(20);  //face 11  
  85.     faceArray->push_back(8);  
  86.     faceArray->push_back(23);  
  87.     faceArray->push_back(8);   //face 12  
  88.     faceArray->push_back(11);  
  89.     faceArray->push_back(23);  
  90.   
  91.     // normal array  
  92.     osg::Vec3Array *normalArray = new osg::Vec3Array();  
  93.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  94.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  95.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  96.   
  97.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  98.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  99.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  100.   
  101.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  102.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  103.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  104.   
  105.     normalArray->push_back(osg::Vec3(0, 0, -1));  
  106.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  107.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  108.   
  109.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  110.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  111.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  112.   
  113.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  114.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  115.     normalArray->push_back(osg::Vec3(+1, 0, 0));  
  116.   
  117.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  118.     normalArray->push_back(osg::Vec3(0, +1, 0));  
  119.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  120.   
  121.     normalArray->push_back(osg::Vec3(0, 0, +1));  
  122.     normalArray->push_back(osg::Vec3(0, -1, 0));  
  123.     normalArray->push_back(osg::Vec3(-1, 0, 0));  
  124.   
  125.     osg::Geometry *geometry = new osg::Geometry();  
  126.     geometry->setVertexArray(vertexArray);  
  127.   
  128.     geometry->setNormalArray(normalArray);  
  129.     geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);  
  130.     geometry->addPrimitiveSet(faceArray);  
  131.   
  132.     osg::Geode *cube = new osg::Geode();  
  133.     cube->addDrawable(geometry);  
  134.     return cube;  
  135. }  
  136.   
  137. osg::Geode *createPyramid(){  
  138.     // vertex array  
  139.     osg::Vec3Array *vertexArray = new osg::Vec3Array();  
  140.     vertexArray->push_back(osg::Vec3(-1, -1, 0)); // front left   
  141.     vertexArray->push_back(osg::Vec3(+1, -1, 0)); // front right   
  142.     vertexArray->push_back(osg::Vec3(+1, +1, 0)); // back right   
  143.     vertexArray->push_back(osg::Vec3(-1, +1, 0)); // back left   
  144.     vertexArray->push_back(osg::Vec3(0,0 ,  sqrt(2))); // peak  
  145.     vertexArray->push_back(osg::Vec3(0, 0, -sqrt(2))); // lower peak  
  146.   
  147.     // face array  
  148.     // give indices of vertices in counter-clockwise order  
  149.     osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);  
  150.     faceArray->push_back(0); // face 0  
  151.     faceArray->push_back(1);  
  152.     faceArray->push_back(4);  
  153.     faceArray->push_back(1); // face 1  
  154.     faceArray->push_back(2);  
  155.     faceArray->push_back(4);  
  156.     faceArray->push_back(2); // face 2  
  157.     faceArray->push_back(3);  
  158.     faceArray->push_back(4);  
  159.     faceArray->push_back(3); // face 3  
  160.     faceArray->push_back(0);  
  161.     faceArray->push_back(4);  
  162.     faceArray->push_back(0); // face 4  
  163.     faceArray->push_back(5);  
  164.     faceArray->push_back(1);  
  165.     faceArray->push_back(2); // face 5  
  166.     faceArray->push_back(1);  
  167.     faceArray->push_back(5);  
  168.     faceArray->push_back(3); // face 6  
  169.     faceArray->push_back(2);  
  170.     faceArray->push_back(5);  
  171.     faceArray->push_back(0); // face 7  
  172.     faceArray->push_back(3);  
  173.     faceArray->push_back(5);  
  174.   
  175.     // vertex color array  
  176.     osg::Vec4Array *colorArray = new osg::Vec4Array();  
  177.     colorArray->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //index 0 red  
  178.     colorArray->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //index 1 green  
  179.     colorArray->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //index 2 blue  
  180.     colorArray->push_back(osg::Vec4(1.0f, 0.0f, 1.0f, 1.0f)); //index 3 purple  
  181.     colorArray->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); //index 4 white  
  182.     colorArray->push_back(osg::Vec4(1.0f, 1.0f, 0.5f, 1.0f)); //index 5 white  
  183.   
  184.   
  185.     osg::Geometry *geometry = new osg::Geometry();  
  186.     geometry->setVertexArray(vertexArray);  
  187.     geometry->setColorArray(colorArray);  
  188.     geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);  
  189.     geometry->addPrimitiveSet(faceArray);  
  190.   
  191.     osg::Geode *pyramid = new osg::Geode();  
  192.     pyramid->addDrawable(geometry);  
  193.     return pyramid;  
  194. }  
  195.   
  196.   
  197. int uniqueLightNumber = 0;  
  198. osg::Light *createLight(osg::Vec4 color)  
  199. {  
  200.     osg::Light *light = new osg::Light();  
  201.     // each light must have a unique number  
  202.     light->setLightNum(uniqueLightNumber++);  
  203.     // we set the light's position via a PositionAttitudeTransform object  
  204.     light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  205.     light->setDiffuse(color);  
  206.     light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));  
  207.     light->setAmbient(osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  208.   
  209.     return light;  
  210. }  
  211. osg::Material *createSimpleMaterial(osg::Vec4 color)  
  212. {  
  213.     osg::Material *material = new osg::Material();  
  214.     material->setDiffuse(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  215.     material->setEmission(osg::Material::FRONT, color);  
  216.   
  217.     return material;  
  218. }  
  219.   
  220. int const LIGHTS = 3;  
  221. osg::PositionAttitudeTransform *cubeTransform;  
  222. osg::PositionAttitudeTransform *pyramidTransform;  
  223. osg::PositionAttitudeTransform *lightTransform[LIGHTS];   
  224. osg::StateSet *lightStateSet;  
  225. osg::Group * startupScene()  
  226. {  
  227.     //球  
  228.     osg::Geode *sphere = new osg::Geode();  
  229.     sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(-2, 0, 0), 1)));  
  230.     //正方体  
  231.     osg::Geode *cube = createCube();  
  232.     cubeTransform = new osg::PositionAttitudeTransform();  
  233.     cubeTransform->addChild(cube);  
  234.     cubeTransform->setPosition(osg::Vec3(2, 0, -1));  
  235.     //金字塔  
  236.     osg::Geode *pyramid = createPyramid();  
  237.     pyramidTransform = new osg::PositionAttitudeTransform();  
  238.     pyramidTransform->addChild(pyramid);  
  239.     pyramidTransform->setPosition(osg::Vec3(5, 0, -1));  
  240.   
  241.   
  242.     // create white material  
  243.     osg::Material *material = new osg::Material();  
  244.     material->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 1.0));  
  245.     material->setSpecular(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  246.     material->setAmbient(osg::Material::FRONT, osg::Vec4(0.1, 0.1, 0.1, 1.0));  
  247.     material->setEmission(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));  
  248.     material->setShininess(osg::Material::FRONT, 25.0);  
  249.   
  250.     // assign the material to the sphere and cube  
  251.     sphere->getOrCreateStateSet()->setAttribute(material);  
  252.     cube->getOrCreateStateSet()->setAttribute(material);  
  253.   
  254.     // Create Lights - Red, Green, Blue  
  255.     osg::Vec4 lightColors[] = { osg::Vec4(1.0, 0.0, 0.0, 1.0), osg::Vec4(0.0, 1.0, 0.0, 1.0), osg::Vec4(0.0, 0.0, 1.0, 1.0) };  
  256.   
  257.     osg::Group *root = new osg::Group();  
  258.     lightStateSet = root->getOrCreateStateSet();  
  259.   
  260.     osg::Geode *lightMarker[LIGHTS];  
  261.     osg::LightSource *lightSource[LIGHTS];  
  262.   
  263.   
  264.     for (int i = 0; i < LIGHTS; i++) {  
  265.         lightMarker[i] = new osg::Geode();  
  266.         lightMarker[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1)));  
  267.         lightMarker[i]->getOrCreateStateSet()->setAttribute(createSimpleMaterial(lightColors[i]));  
  268.   
  269.         lightSource[i] = new osg::LightSource();  
  270.         lightSource[i]->setLight(createLight(lightColors[i]));  
  271.         lightSource[i]->setLocalStateSetModes(osg::StateAttribute::ON);  
  272.         lightSource[i]->setStateSetModes(*lightStateSet, osg::StateAttribute::ON);  
  273.   
  274.         lightTransform[i] = new osg::PositionAttitudeTransform();  
  275.         lightTransform[i]->addChild(lightSource[i]);  
  276.         lightTransform[i]->addChild(lightMarker[i]);  
  277.         lightTransform[i]->setPosition(osg::Vec3(0, 0, 5));  
  278.         lightTransform[i]->setScale(osg::Vec3(0.1, 0.1, 0.1));  
  279.   
  280.         root->addChild(lightTransform[i]);  
  281.     }  
  282.   
  283.         root->addChild(sphere);  
  284.         root->addChild(cubeTransform);  
  285.         root->addChild(pyramidTransform);  
  286.         return root;  
  287. }  
  288.   
  289. float myTimer = 0;  
  290. void update(float dt) {  
  291.     myTimer += 0.01*dt;  
  292.     lightTransform[0]->setPosition(osg::Vec3(cos(myTimer), sin(myTimer), 0) * 4);  
  293.     lightTransform[1]->setPosition(osg::Vec3(0, cos(myTimer), sin(myTimer)) * 4);  
  294.     lightTransform[2]->setPosition(osg::Vec3(sin(myTimer), cos(myTimer), sin(myTimer)) * 4);  
  295. }   
  296.   
  297. const bool offScreen = false;  
  298. const int width = 640;  
  299. const int height = 480; ;  
  300. void initCanvas(osg::ref_ptr<osgViewer::Viewer> viewer) {  
  301.     int x = 20;  
  302.     int y = 20;  
  303.     osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  304.     traits->x = x;  
  305.     traits->y = y;  
  306.     traits->width = width;  
  307.     traits->height = height;  
  308.     if (offScreen) {  
  309.         traits->windowDecoration = false;  
  310.         traits->doubleBuffer = true;  
  311.         traits->pbuffer = true;  
  312.     }  
  313.     else {  
  314.         traits->windowDecoration = true;  
  315.         traits->doubleBuffer = true;  
  316.         traits->pbuffer = false;  
  317.     }  
  318.     traits->windowName = "http://blog.csdn.net/boksic";  
  319.     traits->sharedContext = 0;  
  320.     traits->alpha = 8;  
  321.     traits->readDISPLAY();  
  322.     traits->setUndefinedScreenDetailsToDefaultScreen();  
  323.   
  324.     osg::GraphicsContext* _gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
  325.   
  326.     if (!_gc) {  
  327.         osg::notify(osg::NOTICE)  
  328.             << "Failed to create pbuffer, failing back to normal graphics window." << endl;  
  329.   
  330.         traits->pbuffer = false;  
  331.         _gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
  332.     }  
  333.     viewer->getCamera()->setGraphicsContext(_gc);  
  334.     viewer->getCamera()->setViewport(new osg::Viewport(x, y, width, height));  
  335.     viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1));  
  336.   
  337.   
  338.     viewer->setCameraManipulator(new osgGA::TrackballManipulator);  
  339.     viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);  
  340.     viewer->realize();  
  341.     viewer->setReleaseContextAtEndOfFrameHint(false);  
  342. }  
  343.   
  344. int main(int argc, const char* argv[]) {      
  345.     osg::Group *scene = startupScene();  
  346.   
  347.     osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;  
  348.     viewer->setSceneData(scene);   
  349.     initCanvas(viewer);  
  350.   
  351.     while (!viewer->done()) {  
  352.         viewer->frame();  
  353.         update(0.5); // do the update advancing 500ms  
  354.     }  
  355.     return 0;  
  356. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值