osgUtil.StateToCompile是一个用于生成OpenGL显示列表的OpenSceneGraph的工具类。
StateToCompile将给定的场景图输出到OpenGL显示列表中。显示列表是一种在渲染时优化性能的机制,其将渲染指令预编译并保存到显存中,以便在需要渲染时检索和执行。
StateToCompile基于Visitor设计模式,你需要向其提供一个用于处理每个节点的Visitor对象。例如,你可以创建一个继承自osg::NodeVisitor的类,并重写其apply(osg::Geode&)方法:
class CompileVisitor : public osg::NodeVisitor
{
public:
void apply(osg::Geode& geode) override
{
if (_compileStateset.get())
{
geode.setStateSet(_compileStateset);
glNewList(_listId, GL_COMPILE);
for (unsigned int i = 0; i < geode.getNumDrawables(); ++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
if (drawable)
{
drawable->drawImplementation(getRenderInfo());
}
}
glEndList();
}
traverse(geode);
}
void setCompileStateset(osg::StateSet* stateset)
{
_compileStateset = stateset;
}
GLuint getListId() const
{
return _listId;
}
protected:
osg::ref_ptr<osg::StateSet> _compileStateset;
GLuint _listId = 0;
};
在这个例子中,我们向StateToCompile提供了一个Visitor对象,该Visitor会将所有的Drawable绘制命令收集到一个OpenGL显示列表中。
下面是一份使用StateToCompile的简单示例代码:
#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osgUtil/StateToCompile>
osg::ref_ptr<osg::Group> createSceneGraph()
{
auto group = new osg::Group();
auto shape = new osg::Box(osg::Vec3(0, 0, 0), 1.0);
auto drawable = new osg::ShapeDrawable(shape);
auto geode = new osg::Geode();
geode->addDrawable(drawable);
group->addChild(geode);
return group;
}
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Group> root = createSceneGraph();
osgUtil::StateToCompile stateToCompile;
CompileVisitor compileVisitor;
compileVisitor.setCompileStateset(root->getOrCreateStateSet());
stateToCompile.setVisitor(&compileVisitor);
stateToCompile.compileGraph(*root);
GLuint listId = compileVisitor.getListId();
osgViewer::Viewer viewer;
viewer.setSceneData(root);
viewer.realize();
while (!viewer.done())
{
glCallList(listId);
viewer.frame();
}
return 0;
}