osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;提高帧率
前言
当我使用osg绘制场景的时候,绘制大量相同图元的时候时候,如果不设置背面剔除的话,当顶点数量达到上百万个很多显卡都吃不消,帧率会掉的很快,我的显卡是NVIDIA GeForce GTX 1660 Ti
运行下面一段代码
//Geometry->Drawable->Node->Object->Referenced//AlphaFunc->StateAttribute->Object->Referenced//StateAttributeCallback->Callback->Object->Referenced//ClearNode->Group->Node->Object->Referenced//CoordinateSystemNode->Group->Node->Object->Referenced//Billboard->Geode->Group->Node->Object->Referenced//Image->BufferData->Object->Referenced//Texture1D/Texture2D/Texture2DArray/Texture3D->Texture->TextureAttribute->StateAttribute->Object->Referenced//Group->Node->Object->Referenced//Geode->Group->Node->Object->Referenced//Geometry->Drawable->Node->Object->Referenced//AlphaFunc->StateAttribute->Object->Referenced//StateAttributeCallback->Callback->Object->Referenced//ClearNode->Group->Node->Object->Referenced//CoordinateSystemNode->Group->Node->Object->Referenced//Billboard->Geode->Group->Node->Object->Referenced//Image->BufferData->Object->Referenced//Texture1D/Texture2D/Texture2DArray/Texture3D->Texture->TextureAttribute->StateAttribute->Object->Referenced//DrawArrays->PrimitiveSet->BufferData->Object->Object->Referenced//MatrixTransform->Transform->Group->Node->Object->Referenced//StateSet->Object//StateAttribute->Object//hadeModel->StateAttribute->Object//CullFace->StateAttribute->Object//PolygonMode->StateAttribute->Object#include "osg/Group"#include "osg/Geode"#include "osg/Geometry"#include "osg/Point"#include "osg/Drawable"#include "osg/StateAttribute"#include "osg/StateSet"#include "osg/Material"#include "osg/MatrixTransform"#include "osg/Matrix"#include "osg/LightSource"#include "osg/Light"#include "osgDB/ReadFile"#include "osgDB/WriteFile"#include "osg/Notify"#include "osg/CullFace"#include "osgViewer/Viewer"#include "osgUtil/Optimizer"using namespace osg;using namespace std;osg::ref_ptr createLightPoint(){ osg::ref_ptr geom = new osg::Geometry(); // Don't throw away single-vertex primitives. //边界盒 osg::BoundingBox bBox(-.1f, -.1f, -.1f, .1f, .1f, .1f); geom->setInitialBound(bBox); osg::ref_ptr v = new osg::Vec3Array(); geom->setVertexArray(v.get()); v->push_back(osg::Vec3f(0.f, 0.f, 0.f)); osg::ref_ptr c = new osg::Vec4Array(); geom->setColorArray(c.get()); geom->setColorBinding(osg::Geometry::BIND_OVERALL); //BIND_OVERALL:这个光源都是颜色绑定方式对应唯一的颜色:红色 c->push_back(osg::Vec4f(1.f, 0.f, 0.f, 1.f)); geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, 1)); //基本图元是绘制点 //Geode是叶子节点,把Geometry加入到叶子节点中 osg::ref_ptr geode = new osg::Geode; geode->addDrawable(geom.get()); //设置状态属性 osg::ref_ptr state = geode->getOrCreateStateSet(); state->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); osg::ref_ptr pt = new osg::Point(); pt->setSize(10.f); state->setAttribute(pt.get()); return (geode.release()); //return (geode);}osg::ref_ptr createPlane(){ osg::ref_ptr geom = new osg::Geometry(); //顶点 osg::ref_ptr v = new osg::Vec3Array(); geom->setVertexArray(v.get()); int x, y; for (y = -10; y <= 10; y++) { for (x = -10; x <= 10; x++) { v->push_back(osg::Vec3((float)x * .5f, (float)y * .5f, 0.f)); } } //法线 osg::ref_ptr n = new osg::Vec3Array(); geom->setNormalArray(n.get()); geom->setNormalBinding(osg::Geometry::BIND_OVERALL); n->push_back(osg::Vec3(0.f, 0.f, 1.f)); //颜色 osg::ref_ptr c = new osg::Vec4Array(); geom->setColorArray(c.get()); geom->setColorBinding(osg::Geometry::BIND_OVERALL); c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f)); const int len(21); int idx(0); int numStrips(len - 1); while (numStrips--) { GLushort indices[len + len]; int vert(0); while (vert < len) { indices[2 * vert + 0] = idx + len; indices[2 * vert + 1] = idx; vert++; idx++; } //geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, len + len, indices)); geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP, len + len, indices)); } return (geom.release());}//1.指定几何体法线//2.允许光照并设置光照状态//3.指定光源属性并关联到场景图形//4.指定物体表面材质属性//5.只有光源并没有阴影,阴影需要sogShadow来创建osg::ref_ptr createSceneGraph(){ // Create the root node and set state for the entire subgraph. osg::ref_ptr group = new osg::Group(); osg::ref_ptr root = new osg::Node(); { osg::ref_ptr state = group->getOrCreateStateSet(); state->setMode(GL_LIGHTING, osg::StateAttribute::ON); state->setMode(GL_LIGHT0, osg::StateAttribute::ON); state->setMode(GL_LIGHT1, osg::StateAttribute::ON); } // Represent the two light sources with a shared point. // Each light's position is 0,0,0 in object coordinates. The // two parent MatrixTransforms translate the lights, and the // shared point, to their actual positions. //osg::ref_ptr lightPoint = new osg::Geode; osg::ref_ptr lightPoint = createLightPoint(); { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(-3.f, 2.f, 5.f)); mt->setMatrix(*refM); // Create a mostly red light osg::ref_ptr light = new osg::Light; light->setLightNum(0); light->setPosition(osg::Vec4(0.f, 0.f, 0.f, 1.f)); light->setDiffuse(osg::Vec4(1.f, .5f, .5f, 1.f)); light->setSpecular(osg::Vec4(1.f, .8f, .8f, 1.f)); //设置光源:第一个光源 osg::ref_ptr ls = new osg::LightSource; group->addChild(mt.get()); //mt->setMatrix(*m); mt->addChild(ls.get()); ls->setLight(light.get()); ls->addChild(lightPoint.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(3.f, -2.f, 3.f)); mt->setMatrix(*refM); // Create a mostly blue light osg::ref_ptr light = new osg::Light; light->setLightNum(1); light->setPosition(osg::Vec4(0.f, 0.f, 0.f, 1.f)); light->setDiffuse(osg::Vec4(.5f, .5f, 1.f, 1.f)); light->setSpecular(osg::Vec4(.8f, .8f, 1.f, 1.f)); //设置光源:第二个光源 osg::ref_ptr ls = new osg::LightSource; group->addChild(mt.get()); mt->addChild(ls.get()); ls->setLight(light.get()); ls->addChild(lightPoint.get()); } // Create a single instance of the lozenge geometry (read from disk). // Multiply parent it to six MatrixTransform nodes, each with their // own StateSet to change the material properties of the lozenge. osg::ref_ptr lozenge = osgDB::readNodeFile("lozenge.osg"); if (!lozenge.valid()) { osg::notify(osg::FATAL) << "Unload to load date file. Exiting." << std::endl; return nullptr; } { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(-1.f, -1.f, 1.f)); mt->setMatrix(*refM); //设置属性 osg::ref_ptr state = new osg::StateSet; state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(0.f, 0.f, 0.f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.f, 1.f, 1.f, 1.f)); mat->setShininess(osg::Material::FRONT, 128.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(1.f, -1.f, 1.f)); mt->setMatrix(*refM); //设置属性 osg::ref_ptr state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; // Just use the object's primary color for ambient and // diffuse (uses the OpenGL color material feature). mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); state->setAttribute(mat.get()); mat->setDiffuse(osg::Material::FRONT, osg::Vec4(.4f, .3f, 0.f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(.8f, .8f, .1f, 1.f)); mat->setShininess(osg::Material::FRONT, 20.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(-1.f, 0.f, 1.f)); mt->setMatrix(*refM); osg::ref_ptr state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(.4f, .3f, 0.f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(.8f, .8f, 1.f, 1.f)); mat->setShininess(osg::Material::FRONT, 20.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(1.f, 0.f, 1.f)); mt->setMatrix(*refM); //设置属性 osg::ref_ptr state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(.1f, .2f, .5f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(.9f, .9f, 1.f, 1.f)); mat->setShininess(osg::Material::FRONT, 10.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; //osg::Matrix 没有继承Referenced 所以不能用智能指针 osg::Matrix m; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(-1.f, 1.f, 1.f)); mt->setMatrix(*refM); osg::ref_ptr state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(.2f, .9f, .9f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.f, 1.f, 1.f, 1.f)); mat->setShininess(osg::Material::FRONT, 96.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } { osg::ref_ptr mt = new osg::MatrixTransform; osg::ref_ptr refM = new osg::RefMatrix; refM->makeTranslate(osg::Vec3(1.f, 1.f, 1.f)); mt->setMatrix(*refM); osg::ref_ptr state = mt->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.f, 1.f, 1.f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(0.f, 0.f, 0.f, 1.f)); mat->setShininess(Material::FRONT, 0.f); state->setAttribute(mat.get()); mt->addChild(lozenge.get()); group->addChild(mt.get()); } osg::ref_ptr planeGeode = new osg::Geode; planeGeode->addDrawable(createPlane()); { osg::ref_ptr state = new osg::StateSet; state = planeGeode->getOrCreateStateSet(); //背面剔除 osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get()); osg::ref_ptr mat = new osg::Material; mat->setDiffuse(osg::Material::FRONT, osg::Vec4(.6f, .5f, .2f, 1.f)); mat->setSpecular(osg::Material::FRONT, osg::Vec4(.4f, .4f, .4f, 1.f)); mat->setShininess(osg::Material::FRONT, 128.f); state->setAttribute(mat.get()); /*osg::ref_ptr cf = new osg::CullFace; state->setAttributeAndModes(cf.get());*/ } group->addChild(planeGeode.get()); return group.release();}int main(int argc, char** argv){ osg::ref_ptr root = createSceneGraph(); if (!root.valid()) { osg::notify(osg::FATAL) << "Failed in createSceneGraph()." << std::endl; return (1); } //每次执行writeNodeFile都会往lozenge.osg文件中写入顶点,默认是追加写入,所以lozenge.osg文件会越来越大,直到显卡崩溃 std::string out("lozenge.osg"); if (!(osgDB::writeNodeFile(*(root.get()), out))) { osg::notify(osg::FATAL) << "Failed in osgDB::writeNodeFile()." << std::endl; return (1); } osg::notify(osg::ALWAYS) << "Successfully wrote \"" << out << "\". Execute \"osgviewer " << out << "\" to view." << endl; osgViewer::Viewer viewer; auto node = osgDB::readNodeFile("lozenge.osg"); osgUtil::Optimizer opt; opt.optimize(node); //node->setUseDisplayList(false); auto geom = node->asGeometry(); //geom->setUseVertexArrayObject(true); viewer.setSceneData(node); return viewer.run();}
工程源码
工程源码-
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~