OSG 光照
1、osg::Light
OSG将OpenGL中的glLight()作了一个light状态的类封装,用于保存灯光的模式与属性参数信息。
osg::Light类派生自osg::StateAttribute类,继承了对模式与属性参数信息的操作接口。
2.osg::LightSource
osg::LightSource 类直接继承自 osg::Group.作为一个灯光管理类,继承了osg::Group类的管理节点的接口;将灯光作为一个节点可以加入到场景图中进行渲染。
3.场景中使用光源的步骤:
1.指定场景模型的法线
2.允许光照并设置光照状态
3.指定光源属性并关联到场景图形
简单光源示例:
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/Camera>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/BoundingSphere>
#include <osg/BoundingBox>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
//向场景中添加光源
osg::ref_ptr<osg::Group> createLight(osg::ref_ptr<osg::Node> node)
{
osg::ref_ptr<osg::Group> lightRoot = new osg::Group();
lightRoot->addChild(node);
//开启光照
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
stateset = lightRoot->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);
//计算包围盒
osg::BoundingSphere bs;
node->computeBound();
bs = node->getBound();
//创建一个Light对象
osg::ref_ptr<osg::Light> light = new osg::Light();
light->setLightNum(0);
//设置方向
light->setDirection(osg::Vec3(0.0f, 0.0f, -1.0f));
//设置位置
light->setPosition(osg::Vec4(bs.center().x(), bs.center().y(), bs.center().z() + bs.radius(), 1.0f));
//设置环境光的颜色
light->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
//设置散射光颜色
light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
//设置恒衰减指数
light->setConstantAttenuation(1.0f);
//设置线形衰减指数
light->setLinearAttenuation(0.0f);
//设置二次方衰减指数
light->setQuadraticAttenuation(0.0f);
//创建光源
osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource();
lightSource->setLight(light.get());
lightRoot->addChild(lightSource.get());
return lightRoot.get();
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
//读取模型
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
//向场景中添加光源
root->addChild(createLight(node.get()));
//root->addChild(node.get());
//优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
//设置场景数据
viewer->setSceneData(root.get());
//初始化并创建窗口
viewer->realize();
//开始渲染
viewer->run();
return 0;
}