您的位置:首页 > 运维架构

OpenSceneGraph基础:光照

2015-03-02 20:10 281 查看
效果:



接着前篇进行(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内置函数建立模型,金子塔与之前相同,正方体则使用了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。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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: