osg--几种效果

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

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::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();
}

其它工具包

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值