接着前篇进行(http://blog.csdn.net/boksic/article/details/44002155),现在考虑光照效果
主程序
转载请注明http://blog.csdn.net/boksic 如有疑问欢迎留言
和之前基本唯一的变化就是把窗口部分的操作放在初始化函数initCanvas里进行。
- int main(int argc, const char* argv[]) {
- osg::Group *scene = startupScene();
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
- viewer->setSceneData(scene);
- initCanvas(viewer);
- while (!viewer->done()) {
- viewer->frame();
- update(0.5); // do the update advancing 500ms
- }
- return 0;
- }
窗口初始化(initCanvas)
我们使用GraphicsContext类来对设备上下文进行操作,该类需要一个Traits结构来定义具体的窗口属性,例如窗口大小,窗口位置等。
- void initCanvas(osg::ref_ptr<osgViewer::Viewer> viewer) {
- int x = 20;
- int y = 20;
- osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
- traits->x = x;
- traits->y = y;
- traits->width = width;
- traits->height = height;
- if (offScreen) {
- traits->windowDecoration = false;
- traits->doubleBuffer = true;
- traits->pbuffer = true;
- }
- else {
- traits->windowDecoration = true;
- traits->doubleBuffer = true;
- traits->pbuffer = false;
- }
- traits->windowName = "http://blog.csdn.net/boksic";
- traits->sharedContext = 0;
- traits->alpha = 8;
- traits->readDISPLAY();
- traits->setUndefinedScreenDetailsToDefaultScreen();
- osg::GraphicsContext* _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
- if (!_gc) {
- osg::notify(osg::NOTICE)
- << "Failed to create pbuffer, failing back to normal graphics window." << endl;
- traits->pbuffer = false;
- _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
- }
- }
Viewer内置了Camera对象来控制窗口,我们可以通过getCamera函数来对该对象进行操作,例如setClearColor设置清屏颜色。
- viewer->getCamera()->setGraphicsContext(_gc);
- viewer->getCamera()->setViewport(new osg::Viewport(x, y, width, height));
- viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1));
- viewer->setCameraManipulator(new osgGA::TrackballManipulator);
- viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
- viewer->realize();
- viewer->setReleaseContextAtEndOfFrameHint(false);
场景初始化(startup)
首先按前篇的方法建立几何图形:
- //球
- osg::Geode *sphere = new osg::Geode();
- sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(-2, 0, 0), 1)));
- //正方体
- osg::Geode *cube = createCube();
- cubeTransform = new osg::PositionAttitudeTransform();
- cubeTransform->addChild(cube);
- cubeTransform->setPosition(osg::Vec3(2, 0, -1));
- //金字塔
- osg::Geode *pyramid = createPyramid();
- pyramidTransform = new osg::PositionAttitudeTransform();
- pyramidTransform->addChild(pyramid);
- pyramidTransform->setPosition(osg::Vec3(5, 0, -1));
- osg::Geode *createCube() {
- // vertex array
- osg::Vec3Array *vertexArray = new osg::Vec3Array();
- // bottom front left
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- // bottom front right
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- // bottom back right
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- // bottom back left
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- // top front left
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- // top front right
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- // top back right
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- // top back left
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- // face array
- osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
- // bottom
- faceArray->push_back(0); // face 1
- faceArray->push_back(9);
- faceArray->push_back(3);
- faceArray->push_back(9); // face 2
- faceArray->push_back(6);
- faceArray->push_back(3);
- // top
- faceArray->push_back(21); //face 3
- faceArray->push_back(12);
- faceArray->push_back(18);
- faceArray->push_back(12); //face 4
- faceArray->push_back(15);
- faceArray->push_back(18);
- // left
- faceArray->push_back(22); //face 5
- faceArray->push_back(10);
- faceArray->push_back(13);
- faceArray->push_back(10); //face 6
- faceArray->push_back(1);
- faceArray->push_back(13);
- // right
- faceArray->push_back(16); //face 7
- faceArray->push_back(4);
- faceArray->push_back(19);
- faceArray->push_back(4); //face 8
- faceArray->push_back(7);
- faceArray->push_back(19);
- // front
- faceArray->push_back(14); //face 9
- faceArray->push_back(2);
- faceArray->push_back(17);
- faceArray->push_back(2); //face 10
- faceArray->push_back(5);
- faceArray->push_back(17);
- // back
- faceArray->push_back(20); //face 11
- faceArray->push_back(8);
- faceArray->push_back(23);
- faceArray->push_back(8); //face 12
- faceArray->push_back(11);
- faceArray->push_back(23);
- // normal array
- osg::Vec3Array *normalArray = new osg::Vec3Array();
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- osg::Geometry *geometry = new osg::Geometry();
- geometry->setVertexArray(vertexArray);
- geometry->setNormalArray(normalArray);
- geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
- geometry->addPrimitiveSet(faceArray);
- osg::Geode *cube = new osg::Geode();
- cube->addDrawable(geometry);
- return cube;
- }
建立组节点,获取其渲染状态StateSet。StateSet保存了一系列Opengl的渲染属性和值,用于控制节点下图形的渲染,若要设置则需获取该对象的StateSet后进行操作。
- StateSet *lightStateSet;
- Node *startup() {
- Group *scene = new Group();
- lightStateSet = scene->getOrCreateStateSet();
- }
建立材质属性
osg的Material 封装了OpenGL 的glMaterial()和glColorMaterial(),用法基本类似。而建立Material后再关联到图形的StateSet中即可试目标图形具有该材质属性。这里为球体和正方体赋予了该材质。
- // create white material
- osg::Material *material = new osg::Material();
- material->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 1.0));
- material->setSpecular(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));
- material->setAmbient(osg::Material::FRONT, osg::Vec4(0.1, 0.1, 0.1, 1.0));
- material->setEmission(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));
- material->setShininess(osg::Material::FRONT, 25.0);
- // assign the material to the sphere and cube
- sphere->getOrCreateStateSet()->setAttribute(material);
- cube->getOrCreateStateSet()->setAttribute(material);
设置光源
OSG使用Light对象来定义光源属性,Light的setLightNum函数是用来关联OpenGL的位置数GL_LIGHT0 到GL_LIGHT7的,所以需要赋予其一个唯一的值(uniqueLightNumber)。我们可以定义一个简单的光源生成函数
- int uniqueLightNumber = 0;
- osg::Light *createLight(osg::Vec4 color)
- {
- osg::Light *light = new osg::Light();
- // each light must have a unique number
- light->setLightNum(uniqueLightNumber++);
- // we set the light's position via a PositionAttitudeTransform object
- light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
- light->setDiffuse(color);
- light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
- light->setAmbient(osg::Vec4(0.0, 0.0, 0.0, 1.0));
- return light;
- }
而Light对象需要放在LightSource的节点当中,可以通过LightSource来控制灯光的位置以及状态。
- // Create Lights - Red, Green, Blue
- 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) };
- osg::Group *root = new osg::Group();
- lightStateSet = root->getOrCreateStateSet();
- osg::Geode *lightMarker[LIGHTS];
- osg::LightSource *lightSource[LIGHTS];
- for (int i = 0; i < LIGHTS; i++) {
- lightMarker[i] = new osg::Geode();
- lightMarker[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1)));
- lightMarker[i]->getOrCreateStateSet()->setAttribute(createSimpleMaterial(lightColors[i]));
- lightSource[i] = new osg::LightSource();
- lightSource[i]->setLight(createLight(lightColors[i]));
- lightSource[i]->setLocalStateSetModes(osg::StateAttribute::ON);
- lightSource[i]->setStateSetModes(*lightStateSet, osg::StateAttribute::ON);
- lightTransform[i] = new osg::PositionAttitudeTransform();
- lightTransform[i]->addChild(lightSource[i]);
- lightTransform[i]->addChild(lightMarker[i]);
- lightTransform[i]->setPosition(osg::Vec3(0, 0, 5));
- lightTransform[i]->setScale(osg::Vec3(0.1, 0.1, 0.1));
- root->addChild(lightTransform[i]);
- }
最后不忘添加到组节点当中
- root->addChild(sphere);
- root->addChild(cubeTransform);
- root->addChild(pyramidTransform);
更新部分(update函数)
这里实现的是三个点光源做圆周运动
- void update(float dt) {
- myTimer += 0.01*dt;
- lightTransform[0]->setPosition(osg::Vec3(cos(myTimer), sin(myTimer), 0) * 4);
- lightTransform[1]->setPosition(osg::Vec3(0, cos(myTimer), sin(myTimer)) * 4);
- lightTransform[2]->setPosition(osg::Vec3(sin(myTimer), cos(myTimer), sin(myTimer)) * 4);
- }
最后附上完整代码
- #include <osgGA/TrackballManipulator>
- #include <osg/PositionAttitudeTransform>
- #include <osgGA/GUIEventHandler>
- #include <osg/Material>
- #include <osg/ShapeDrawable>
- osg::Geode *createCube() {
- // vertex array
- osg::Vec3Array *vertexArray = new osg::Vec3Array();
- // bottom front left
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- vertexArray->push_back(osg::Vec3(-1, -1, 0));
- // bottom front right
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- vertexArray->push_back(osg::Vec3(+1, -1, 0));
- // bottom back right
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- vertexArray->push_back(osg::Vec3(+1, +1, 0));
- // bottom back left
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- vertexArray->push_back(osg::Vec3(-1, +1, 0));
- // top front left
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- vertexArray->push_back(osg::Vec3(-1, -1, 2));
- // top front right
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- vertexArray->push_back(osg::Vec3(+1, -1, 2));
- // top back right
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- vertexArray->push_back(osg::Vec3(+1, +1, 2));
- // top back left
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- vertexArray->push_back(osg::Vec3(-1, +1, 2));
- // face array
- osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
- // bottom
- faceArray->push_back(0); // face 1
- faceArray->push_back(9);
- faceArray->push_back(3);
- faceArray->push_back(9); // face 2
- faceArray->push_back(6);
- faceArray->push_back(3);
- // top
- faceArray->push_back(21); //face 3
- faceArray->push_back(12);
- faceArray->push_back(18);
- faceArray->push_back(12); //face 4
- faceArray->push_back(15);
- faceArray->push_back(18);
- // left
- faceArray->push_back(22); //face 5
- faceArray->push_back(10);
- faceArray->push_back(13);
- faceArray->push_back(10); //face 6
- faceArray->push_back(1);
- faceArray->push_back(13);
- // right
- faceArray->push_back(16); //face 7
- faceArray->push_back(4);
- faceArray->push_back(19);
- faceArray->push_back(4); //face 8
- faceArray->push_back(7);
- faceArray->push_back(19);
- // front
- faceArray->push_back(14); //face 9
- faceArray->push_back(2);
- faceArray->push_back(17);
- faceArray->push_back(2); //face 10
- faceArray->push_back(5);
- faceArray->push_back(17);
- // back
- faceArray->push_back(20); //face 11
- faceArray->push_back(8);
- faceArray->push_back(23);
- faceArray->push_back(8); //face 12
- faceArray->push_back(11);
- faceArray->push_back(23);
- // normal array
- osg::Vec3Array *normalArray = new osg::Vec3Array();
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, -1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(+1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, +1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- normalArray->push_back(osg::Vec3(0, 0, +1));
- normalArray->push_back(osg::Vec3(0, -1, 0));
- normalArray->push_back(osg::Vec3(-1, 0, 0));
- osg::Geometry *geometry = new osg::Geometry();
- geometry->setVertexArray(vertexArray);
- geometry->setNormalArray(normalArray);
- geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
- geometry->addPrimitiveSet(faceArray);
- osg::Geode *cube = new osg::Geode();
- cube->addDrawable(geometry);
- return cube;
- }
- osg::Geode *createPyramid(){
- // vertex array
- osg::Vec3Array *vertexArray = new osg::Vec3Array();
- vertexArray->push_back(osg::Vec3(-1, -1, 0)); // front left
- vertexArray->push_back(osg::Vec3(+1, -1, 0)); // front right
- vertexArray->push_back(osg::Vec3(+1, +1, 0)); // back right
- vertexArray->push_back(osg::Vec3(-1, +1, 0)); // back left
- vertexArray->push_back(osg::Vec3(0,0 , sqrt(2))); // peak
- vertexArray->push_back(osg::Vec3(0, 0, -sqrt(2))); // lower peak
- // face array
- // give indices of vertices in counter-clockwise order
- osg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
- faceArray->push_back(0); // face 0
- faceArray->push_back(1);
- faceArray->push_back(4);
- faceArray->push_back(1); // face 1
- faceArray->push_back(2);
- faceArray->push_back(4);
- faceArray->push_back(2); // face 2
- faceArray->push_back(3);
- faceArray->push_back(4);
- faceArray->push_back(3); // face 3
- faceArray->push_back(0);
- faceArray->push_back(4);
- faceArray->push_back(0); // face 4
- faceArray->push_back(5);
- faceArray->push_back(1);
- faceArray->push_back(2); // face 5
- faceArray->push_back(1);
- faceArray->push_back(5);
- faceArray->push_back(3); // face 6
- faceArray->push_back(2);
- faceArray->push_back(5);
- faceArray->push_back(0); // face 7
- faceArray->push_back(3);
- faceArray->push_back(5);
- // vertex color array
- osg::Vec4Array *colorArray = new osg::Vec4Array();
- colorArray->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //index 0 red
- colorArray->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //index 1 green
- colorArray->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //index 2 blue
- colorArray->push_back(osg::Vec4(1.0f, 0.0f, 1.0f, 1.0f)); //index 3 purple
- colorArray->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); //index 4 white
- colorArray->push_back(osg::Vec4(1.0f, 1.0f, 0.5f, 1.0f)); //index 5 white
- osg::Geometry *geometry = new osg::Geometry();
- geometry->setVertexArray(vertexArray);
- geometry->setColorArray(colorArray);
- geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
- geometry->addPrimitiveSet(faceArray);
- osg::Geode *pyramid = new osg::Geode();
- pyramid->addDrawable(geometry);
- return pyramid;
- }
- int uniqueLightNumber = 0;
- osg::Light *createLight(osg::Vec4 color)
- {
- osg::Light *light = new osg::Light();
- // each light must have a unique number
- light->setLightNum(uniqueLightNumber++);
- // we set the light's position via a PositionAttitudeTransform object
- light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
- light->setDiffuse(color);
- light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
- light->setAmbient(osg::Vec4(0.0, 0.0, 0.0, 1.0));
- return light;
- }
- osg::Material *createSimpleMaterial(osg::Vec4 color)
- {
- osg::Material *material = new osg::Material();
- material->setDiffuse(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));
- material->setEmission(osg::Material::FRONT, color);
- return material;
- }
- int const LIGHTS = 3;
- osg::PositionAttitudeTransform *cubeTransform;
- osg::PositionAttitudeTransform *pyramidTransform;
- osg::PositionAttitudeTransform *lightTransform[LIGHTS];
- osg::StateSet *lightStateSet;
- osg::Group * startupScene()
- {
- //球
- osg::Geode *sphere = new osg::Geode();
- sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(-2, 0, 0), 1)));
- //正方体
- osg::Geode *cube = createCube();
- cubeTransform = new osg::PositionAttitudeTransform();
- cubeTransform->addChild(cube);
- cubeTransform->setPosition(osg::Vec3(2, 0, -1));
- //金字塔
- osg::Geode *pyramid = createPyramid();
- pyramidTransform = new osg::PositionAttitudeTransform();
- pyramidTransform->addChild(pyramid);
- pyramidTransform->setPosition(osg::Vec3(5, 0, -1));
- // create white material
- osg::Material *material = new osg::Material();
- material->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 1.0));
- material->setSpecular(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));
- material->setAmbient(osg::Material::FRONT, osg::Vec4(0.1, 0.1, 0.1, 1.0));
- material->setEmission(osg::Material::FRONT, osg::Vec4(0.0, 0.0, 0.0, 1.0));
- material->setShininess(osg::Material::FRONT, 25.0);
- // assign the material to the sphere and cube
- sphere->getOrCreateStateSet()->setAttribute(material);
- cube->getOrCreateStateSet()->setAttribute(material);
- // Create Lights - Red, Green, Blue
- 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) };
- osg::Group *root = new osg::Group();
- lightStateSet = root->getOrCreateStateSet();
- osg::Geode *lightMarker[LIGHTS];
- osg::LightSource *lightSource[LIGHTS];
- for (int i = 0; i < LIGHTS; i++) {
- lightMarker[i] = new osg::Geode();
- lightMarker[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1)));
- lightMarker[i]->getOrCreateStateSet()->setAttribute(createSimpleMaterial(lightColors[i]));
- lightSource[i] = new osg::LightSource();
- lightSource[i]->setLight(createLight(lightColors[i]));
- lightSource[i]->setLocalStateSetModes(osg::StateAttribute::ON);
- lightSource[i]->setStateSetModes(*lightStateSet, osg::StateAttribute::ON);
- lightTransform[i] = new osg::PositionAttitudeTransform();
- lightTransform[i]->addChild(lightSource[i]);
- lightTransform[i]->addChild(lightMarker[i]);
- lightTransform[i]->setPosition(osg::Vec3(0, 0, 5));
- lightTransform[i]->setScale(osg::Vec3(0.1, 0.1, 0.1));
- root->addChild(lightTransform[i]);
- }
- root->addChild(sphere);
- root->addChild(cubeTransform);
- root->addChild(pyramidTransform);
- return root;
- }
- float myTimer = 0;
- void update(float dt) {
- myTimer += 0.01*dt;
- lightTransform[0]->setPosition(osg::Vec3(cos(myTimer), sin(myTimer), 0) * 4);
- lightTransform[1]->setPosition(osg::Vec3(0, cos(myTimer), sin(myTimer)) * 4);
- lightTransform[2]->setPosition(osg::Vec3(sin(myTimer), cos(myTimer), sin(myTimer)) * 4);
- }
- const bool offScreen = false;
- const int width = 640;
- const int height = 480; ;
- void initCanvas(osg::ref_ptr<osgViewer::Viewer> viewer) {
- int x = 20;
- int y = 20;
- osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
- traits->x = x;
- traits->y = y;
- traits->width = width;
- traits->height = height;
- if (offScreen) {
- traits->windowDecoration = false;
- traits->doubleBuffer = true;
- traits->pbuffer = true;
- }
- else {
- traits->windowDecoration = true;
- traits->doubleBuffer = true;
- traits->pbuffer = false;
- }
- traits->windowName = "http://blog.csdn.net/boksic";
- traits->sharedContext = 0;
- traits->alpha = 8;
- traits->readDISPLAY();
- traits->setUndefinedScreenDetailsToDefaultScreen();
- osg::GraphicsContext* _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
- if (!_gc) {
- osg::notify(osg::NOTICE)
- << "Failed to create pbuffer, failing back to normal graphics window." << endl;
- traits->pbuffer = false;
- _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
- }
- viewer->getCamera()->setGraphicsContext(_gc);
- viewer->getCamera()->setViewport(new osg::Viewport(x, y, width, height));
- viewer->getCamera()->setClearColor(osg::Vec4(0, 0, 0, 1));
- viewer->setCameraManipulator(new osgGA::TrackballManipulator);
- viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
- viewer->realize();
- viewer->setReleaseContextAtEndOfFrameHint(false);
- }
- int main(int argc, const char* argv[]) {
- osg::Group *scene = startupScene();
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
- viewer->setSceneData(scene);
- initCanvas(viewer);
- while (!viewer->done()) {
- viewer->frame();
- update(0.5); // do the update advancing 500ms
- }
- return 0;
- }