写在前面的话:笔者新手学习OpenSceneGraph3.4.0(OSG),并且C++的基础较差,OpenGL的基础也较差,都没有系统性科学性地学习过。由于毕业论文需要,所以突击学习,在网上各种论坛和各种博客里找不到太多有价值的参考代码,OSG本身的源码又看不懂。总之,想了很多办法,最近取得一点学习进展,现将osgViewer知识点代码所学积累都公布出来,供小白使用。如果觉得有点用请留言给我加油,或者建议、改进都可以。谢谢。
#include <osgViewer/Viewer>
#include <osgDb/ReadFile>
#include <osgGA/GUIEventAdapter>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Material>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/Image>
#include <osg/LineWidth>
#include <iostream>
// 构建一个带纹理的盒子出来
osg::ref_ptr<osg::Geode> CreateBox()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
// ===================================================================================================
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
// 设置精度
hints->setDetailRatio(0.5);
osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0,0.0,0.0),1.0,10.0,10.0),hints.get());
osg::ref_ptr<osg::Material> material = new osg::Material;
osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
osg::Image* image = osgDB::readImageFile("myimage.jpg");
// ==================================================================================
// 设置颜色
shape->setColor(osg::Vec4(0.5, 0.5, 0.5, 0.1));
// 设置材质
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 1.0, 1.0, 0.5));
material->setShininess(osg::Material::FRONT_AND_BACK, 6.0);
// 设置纹理
if (image)
{
texture2D->setImage(image);
}
// ==================================================================================
// ====================================================================================================
geode->getOrCreateStateSet()->setAttributeAndModes(material.get(), osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
// ====================================================================================================
geode->addDrawable(shape.get());
return geode;
}
// 创建简单图元
osg::ref_ptr<osg::Node> CreateSimple()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
// ========================================================
// 申请一些顶点
osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array;
// 申请颜色
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
// 申请法向量
osg::ref_ptr<osg::Vec3Array> norms = new osg::Vec3Array;
// 限制线宽
osg::ref_ptr<osg::LineWidth> width = new osg::LineWidth;
// ========================================================
geode->addDrawable(geom.get());
// 打开透明度
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
// 设置线宽
width->setWidth(15.0);
geode->getOrCreateStateSet()->setAttributeAndModes(width.get(), osg::StateAttribute::ON);
// 设置顶点
geom->setVertexArray(coords.get());
// 顶点的关联方式
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::Mode::LINE_LOOP, 0, 4));
// 设置颜色
geom->setColorArray(colors.get());
geom->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_VERTEX);
// 设置法向量
geom->setNormalArray(norms.get());
geom->setNormalBinding(osg::Geometry::AttributeBinding::BIND_OVERALL);
// 设置顶点坐标
coords->push_back(osg::Vec3(-10.0f,0.0f,-10.0f));
coords->push_back(osg::Vec3(10.0f, 0.0f, -10.0f));
coords->push_back(osg::Vec3(10.0f, 0.0f, 10.0f));
coords->push_back(osg::Vec3(-10.0f, 0.0f, 10.0f));
// 颜色
colors->push_back(osg::Vec4f(1.0, 0.0, 0.0, 0.5));
colors->push_back(osg::Vec4f(0.0, 1.0, 0.0, 0.5));
colors->push_back(osg::Vec4f(0.0, 0.0, 1.0, 0.5));
colors->push_back(osg::Vec4f(1.0, 1.0, 0.0, 0.5));
// 压入一个法向量
norms->push_back(osg::Vec3(0.0,-1.0,0.0));
return geode;
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> group = new osg::Group;
group->addChild(osgDB::readNodeFile("glider.osg"));
group->addChild(CreateSimple());
viewer->setSceneData(group.get());
return viewer->run();
}