效果:
接着前篇进行(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; }
我们使用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->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);
首先按前篇的方法建立几何图形:
//球 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内置函数建立模型,金子塔与之前相同,正方体则使用了setNormalBinding来绑定法向量用到了法向量(注意:与颜色索引一样,设置法线索引的setNormalIndices也已经被废除了),正方体的建立函数:
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 *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; }
// 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);
这里实现的是三个点光源做圆周运动
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; }