OpenSceneGraph基础:光照

效果:

接着前篇进行(),现在考虑光照效果

主程序

转载请注明 如有疑问欢迎留言

和之前基本唯一的变化就是把窗口部分的操作放在初始化函数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 = "";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 arrayosg::Vec3Array *vertexArray = new osg::Vec3Array();// bottom front leftvertexArray->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 rightvertexArray->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 rightvertexArray->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 leftvertexArray->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 leftvertexArray->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 rightvertexArray->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 rightvertexArray->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 leftvertexArray->push_back(osg::Vec3(-1, +1, 2));vertexArray->push_back(osg::Vec3(-1, +1, 2));vertexArray->push_back(osg::Vec3(-1, +1, 2));// face arrayosg::DrawElementsUInt *faceArray = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);// bottomfaceArray->push_back(0); // face 1faceArray->push_back(9);faceArray->push_back(3);faceArray->push_back(9); // face 2faceArray->push_back(6);faceArray->push_back(3);// topfaceArray->push_back(21); //face 3faceArray->push_back(12);faceArray->push_back(18);faceArray->push_back(12); //face 4faceArray->push_back(15);faceArray->push_back(18);// leftfaceArray->push_back(22); //face 5faceArray->push_back(10);faceArray->push_back(13);faceArray->push_back(10); //face 6faceArray->push_back(1);faceArray->push_back(13);// rightfaceArray->push_back(16); //face 7faceArray->push_back(4);faceArray->push_back(19);faceArray->push_back(4); //face 8faceArray->push_back(7);faceArray->push_back(19);// frontfaceArray->push_back(14); //face 9faceArray->push_back(2);faceArray->push_back(17);faceArray->push_back(2); //face 10faceArray->push_back(5);faceArray->push_back(17);// backfaceArray->push_back(20); //face 11faceArray->push_back(8);faceArray->push_back(23);faceArray->push_back(8); //face 12faceArray->push_back(11);faceArray->push_back(23);// normal arrayosg::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中即可试目标图形具有该材质属性。这里为球体和正方体赋予了该材质。

更重要的是心理上的完全自由和放松,

OpenSceneGraph基础:光照

相关文章:

你感兴趣的文章:

标签云: