billboards
适用于小草等的绘制
osg::BillBoard继承自osg::Geode,其下所有osg::Drawable面向观察者。旋转行为通过setMode()设置,分别为
- POINT_ROT_EYE 几何体z轴旋转到窗口y轴
- POINT_ROT_WORLD
- AXIAL_ROT
- setAxis()
锚点
billboard->addDrawable( child, osg::Vec3(1.0f, 0.0f, 0.0f) );
正向
setNormal()
默认法线是几何体的-y轴
示例
#include <osg/Billboard>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
osg::Geometry* createQuad()
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image =
osgDB::readImageFile("Images/osg256.png");
texture->setImage(image.get());
osg::ref_ptr<osg::Geometry> quad =
osg::createTexturedQuadGeometry(
osg::Vec3(-0.5f, 0.0f, -0.5f),
osg::Vec3(1.0f, 0.0f, 0.0f),
osg::Vec3(0.0f, 0.0f, 1.0f));
osg::StateSet* ss = quad->getOrCreateStateSet();
ss->setTextureAttributeAndModes(0, texture.get());
return quad.release();
}
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Billboard> geode = new osg::Billboard;
geode->setMode(osg::Billboard::POINT_ROT_EYE);
osg::Geometry* quad = createQuad();
for (unsigned int i = 0; i<10; ++i)
{
float id = (float)i;
geode->addDrawable(quad, osg::Vec3(-2.5f + 0.2f*id, id, 0.0f));
geode->addDrawable(quad, osg::Vec3(2.5f - 0.2f*id, id, 0.0f));
}
osg::StateSet* ss = geode->getOrCreateStateSet();
ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osgViewer::Viewer viewer;
viewer.setSceneData(geode.get());
return viewer.run();
}
说明
几何体z轴旋转到窗口y轴,几何体-y轴旋转到与视线重合
文字
osgText::Font
osg::ref_ptr<osgText::Font> g_font = osgText::readFontFile("fonts/arial.ttf");
osgText::Font3D
g_font3D = osgText::readFont3DFile("fonts/arial.ttf");
osgText::Text
继承osgText::TextBase,继承osg::Drawable
- setFont()
- setPosition()
- setCharacterSize()
- setText()
- wchar_t*和string都可以
- setAxisAlignment( osgText::TextBase::XY_PLANE )
osgText::Text3D
继承osgText::TextBase,继承osg::Drawable
示例–osgText::Text
#include <osg/Camera>
#include <osgDB/ReadFile>
#include <osgText/Font>
#include <osgText/Text>
#include <osgViewer/Viewer>
osg::ref_ptr<osgText::Font> g_font;
osg::Camera* createHUDCamera(double left, double right,
double bottom, double top)
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setAllowEventFocus(false);
camera->setProjectionMatrix(
osg::Matrix::ortho2D(left, right, bottom, top));
return camera.release();
}
osgText::Text* createText(const osg::Vec3& pos,
const std::string& content,
float size)
{
osg::ref_ptr<osgText::Text> text = new osgText::Text;
text->setFont(g_font.get());
text->setCharacterSize(size);
text->setAxisAlignment(osgText::TextBase::XY_PLANE);
text->setPosition(pos);
text->setText(content);
return text.release();
}
int main(int argc, char** argv)
{
g_font = osgText::readFontFile("fonts/arial.ttf");
osg::ref_ptr<osg::Geode> textGeode = new osg::Geode;
textGeode->addDrawable(createText(
osg::Vec3(150.0f, 500.0f, 0.0f),
"The Cessna monoplane",
20.0f)
);
textGeode->addDrawable(createText(
osg::Vec3(150.0f, 450.0f, 0.0f),
"Six-seat, low-wing and twin-engined",
15.0f)
);
osg::Camera* camera = createHUDCamera(0, 1024, 0, 768);
camera->addChild(textGeode.get());
camera->getOrCreateStateSet()->setMode(
GL_LIGHTING, osg::StateAttribute::OFF);
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(osgDB::readNodeFile("cessna.osg"));
root->addChild(camera);
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();
}
示例–osgText::Text3D
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgText/Font3D>
#include <osgText/Text3D>
#include <osgViewer/Viewer>
osg::ref_ptr<osgText::Font3D> g_font3D;
osgText::Text3D* createText3D(const osg::Vec3& pos,
const std::string& content,
float size, float depth)
{
osg::ref_ptr<osgText::Text3D> text = new osgText::Text3D;
text->setFont(g_font3D.get());
text->setCharacterSize(size);
text->setCharacterDepth(depth);
text->setAxisAlignment(osgText::TextBase::XZ_PLANE);
text->setPosition(pos);
text->setText(content);
return text.release();
}
int main(int argc, char** argv)
{
g_font3D = osgText::readFont3DFile("fonts/arial.ttf");
osg::ref_ptr<osg::Geode> textGeode = new osg::Geode;
textGeode->addDrawable(
createText3D(osg::Vec3(), "The Cessna", 20.0f, 10.0f));
osg::ref_ptr<osg::MatrixTransform> textNode = new
osg::MatrixTransform;
textNode->setMatrix(osg::Matrix::translate(0.0f, 0.0f, 10.0f));
textNode->addChild(textGeode.get());
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(osgDB::readNodeFile("cessna.osg"));
root->addChild(textNode.get());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();
}
粒子系统
用处
- smoke
- dust
- explosions
- fluid
- fire
- rain
osgParticle::Particle
osgParticle::ParticleSystem
继承osg::Drawable,粒子的几何
-
getDefaultParticleTemplate()
ps->getDefaultParticleTemplate().setShape(osgParticle::Particle::POINT);
osgParticle::RandomRateCounter
每一帧产生随机数目粒子
osg::ref_ptr<osgParticle::RandomRateCounter> rrc = new osgParticle::RandomRateCounter;
rrc->setRateRange( 500, 800 );
osgParticle::Emitter
定义粒子数目和属性,继承osg::Node
- setParticleSystem
- setCounter
osgParticle::ModularEmitter
继承osgParticle::Emitter
- osgParticle::Placer 指定每一个粒子的初始位置
- osgParticle::Shooter 指定每一个粒子的初始速度
- osgParticle::RadialShooter
- setThetaRange
- setPhiRange
- setInitialSpeedRange
- osgParticle::RadialShooter
- osgParticle::Counter 指定粒子数量
osgParticle::AccelOperator
-
setAcceleration()
-
setToGravity()
osg::ref_ptr<osgParticle::AccelOperator> accel = new osgParticle::AccelOperator; accel->setToGravity();
osgParticle::Program
管理每一个粒子生命周期中的位置、速度和属性,继承osg::Node
osgParticle::ModularProgram
- addOperator() osgParticle::Operator列表
- setParticleSystem()
osgParticle::ParticleSystemUpdater
重新计算
附加到父节点
root->addChild( emitter );
root->addChild( program );
root->addChild( updater ); // Added last

示例
#include <osg/MatrixTransform>
#include <osg/Point>
#include <osg/PointSprite>
#include <osg/Texture2D>
#include <osg/BlendFunc>
#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
#include <osgParticle/ModularEmitter>
#include <osgParticle/ModularProgram>
#include <osgParticle/AccelOperator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/Viewer>
osgParticle::ParticleSystem* createParticleSystem(
osg::Group* parent)
{
osg::ref_ptr<osgParticle::ParticleSystem> ps = new osgParticle::ParticleSystem;
ps->getDefaultParticleTemplate().setShape(osgParticle::Particle::POINT);
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc;
blendFunc->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(osgDB::readImageFile("Images/smoke.rgb"));
osg::StateSet* ss = ps->getOrCreateStateSet();
ss->setAttributeAndModes(blendFunc.get());
ss->setTextureAttributeAndModes(0, texture.get());
ss->setAttribute(new osg::Point(20.0f));
ss->setTextureAttributeAndModes(0, new osg::PointSprite);
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::ref_ptr<osgParticle::RandomRateCounter> rrc =
new osgParticle::RandomRateCounter;
rrc->setRateRange(500, 800);
osg::ref_ptr<osgParticle::ModularEmitter> emitter =
new osgParticle::ModularEmitter;
emitter->setParticleSystem(ps.get());
emitter->setCounter(rrc.get());
osg::ref_ptr<osgParticle::AccelOperator> accel =
new osgParticle::AccelOperator;
accel->setToGravity();
osg::ref_ptr<osgParticle::ModularProgram> program =
new osgParticle::ModularProgram;
program->setParticleSystem(ps.get());
program->addOperator(accel.get());
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(ps.get());
parent->addChild(emitter.get());
parent->addChild(program.get());
parent->addChild(geode.get());
return ps.get();
}
int main(int argc, char** argv)
{
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt->setMatrix(osg::Matrix::translate(1.0f, 0.0f, 0.0f));
osgParticle::ParticleSystem* ps = createParticleSystem(mt.get());
osg::ref_ptr<osgParticle::ParticleSystemUpdater> updater = new osgParticle::ParticleSystemUpdater;
updater->addParticleSystem(ps);
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild(updater.get());
root->addChild(mt.get());
root->addChild(osgDB::readNodeFile("axes.osg"));
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();
}
阴影
osgShadow::ShadowedScene
继承osg::Node
必须作为需要阴影节点的父节点
- setShadowTechnique
- setReceivesShadowTraversalMask
- setCastsShadowTraversalMask
投影技巧
-
osgShadow::ShadowMap
osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap; sm->setLight( source.get() ); sm->setTextureSize( osg::Vec2s(1024, 1024) ); sm->setTextureUnit( 1 ); -
osgShadow::StencilBuffer
-
…
示例
#include <osg/AnimationPath>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgShadow/ShadowedScene>
#include <osgShadow/ShadowMap>
#include <osgViewer/Viewer>
unsigned int rcvShadowMask = 0x1;
unsigned int castShadowMask = 0x2;
osg::AnimationPath* createAnimationPath(float radius, float time)
{
osg::ref_ptr<osg::AnimationPath> path = new osg::AnimationPath;
path->setLoopMode(osg::AnimationPath::LOOP);
unsigned int numSamples = 32;
float delta_yaw = 2.0f * osg::PI / ((float)numSamples - 1.0f);
float delta_time = time / (float)numSamples;
for (unsigned int i = 0; i<numSamples; ++i)
{
float yaw = delta_yaw * (float)i;
osg::Vec3 pos(sinf(yaw)*radius, cosf(yaw)*radius, 0.0f);
osg::Quat rot(-yaw, osg::Z_AXIS);
path->insert(delta_time * (float)i,osg::AnimationPath::ControlPoint(pos, rot));
}
return path.release();
}
int main(int argc, char** argv)
{
osg::ref_ptr<osg::MatrixTransform> groundNode = new osg::MatrixTransform;
groundNode->addChild(osgDB::readNodeFile("lz.osg"));
groundNode->setMatrix(osg::Matrix::translate(0.0f, 0.0f, -200.0f));
groundNode->setNodeMask(rcvShadowMask);
osg::ref_ptr<osg::MatrixTransform> cessnaNode = new osg::MatrixTransform;
cessnaNode->addChild(osgDB::readNodeFile("cessna.osg.0,0,90.rot"));
cessnaNode->setNodeMask(castShadowMask);
osg::ref_ptr<osg::AnimationPathCallback> apcb = new osg::AnimationPathCallback;
apcb->setAnimationPath(createAnimationPath(50.0f, 6.0f));
cessnaNode->setUpdateCallback(apcb.get());
osg::ref_ptr<osg::MatrixTransform> truckNode =
new osg::MatrixTransform;
truckNode->addChild(osgDB::readNodeFile("dumptruck.osg"));
truckNode->setMatrix(osg::Matrix::translate(0.0f, 0.0f, -100.0f));
truckNode->setNodeMask(rcvShadowMask | castShadowMask);
osg::ref_ptr<osg::LightSource> source = new osg::LightSource;
source->getLight()->setPosition(osg::Vec4(4.0, 4.0, 10.0,0.0));
source->getLight()->setAmbient(osg::Vec4(0.2, 0.2, 0.2, 1.0));
source->getLight()->setDiffuse(osg::Vec4(0.8, 0.8, 0.8, 1.0));
osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap;
sm->setLight(source.get());
sm->setTextureSize(osg::Vec2s(1024, 1024));
sm->setTextureUnit(1);
osg::ref_ptr<osgShadow::ShadowedScene> root =
new osgShadow::ShadowedScene;
root->setShadowTechnique(sm.get());
root->setReceivesShadowTraversalMask(rcvShadowMask);
root->setCastsShadowTraversalMask(castShadowMask);
root->addChild(groundNode.get());
root->addChild(cessnaNode.get());
root->addChild(truckNode.get());
root->addChild(source.get());
osgViewer::Viewer viewer;
viewer.setSceneData(root.get());
return viewer.run();
}
特殊效果
osgFX::Effect
继承osg::Group,只影响子节点
子类
- osgFX::Outline
- setWidth
- setColor
- addChild
注意:需要开启模板缓冲
osg::DisplaySettings::instance()->setMinimumNumStencilBits(1);
viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
示例
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgFX/Outline>
#include <osgViewer/Viewer>
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cessna.osg");
osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
outline->setWidth(8);
outline->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
outline->addChild(model.get());
osg::DisplaySettings::instance()->setMinimumNumStencilBits(1);
osgViewer::Viewer viewer;
viewer.getCamera()->setClearMask(
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
);
viewer.setSceneData(outline.get());
return viewer.run();
}
其它工具包

本文介绍了osg库中的一些特效使用,包括Billboard用于绘制小草,osgText模块用于创建2D和3D文字,osgParticle模块实现粒子系统如烟雾和爆炸,以及osgShadow模块如何创建阴影效果。此外,还提到了osgFX库中的特殊效果应用。
2400

被折叠的 条评论
为什么被折叠?



