此示例绘制各种图形。玫红色的线会根据设置的回调进行变化。
执行命令:
// 此示例不需要mapNode,所以直接执行程序即可
// 透视投影
osgearth_drawblesd.exe
// 正射投影
osgearth_drawblesd.exe --ortho
// 抗锯齿,线条更平滑
osgearth_drawblesd.exe --smooth
// 将组件的node写入到 out.osgt文件,然后再从文件中将node读取出来,加入到场景中
osgearth_drawblesd.exe --serialize
透视投影和正射投影的初始状态:
正射投影拖动后的状态,远近的情况下,尺寸不发生变化。
透视投影拖动后的状态,近大远小。
主要学习:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LC "[drawables] "
using namespace osgEarth;
// 采用osgEarth的方法绘制
void addVerts(LineDrawable* line, double x, double y)
{
line->pushVertex(osg::Vec3(x, 0, y));
line->pushVertex(osg::Vec3(x + 5, 0, y));
line->pushVertex(osg::Vec3(x + 10, 0, y));
line->pushVertex(osg::Vec3(x + 10, 0, y + 5));
line->pushVertex(osg::Vec3(x + 10, 0, y + 10));
line->pushVertex(osg::Vec3(x + 5, 0, y + 10));
line->pushVertex(osg::Vec3(x, 0, y + 10));
line->pushVertex(osg::Vec3(x, 0, y + 5));
line->finish();
}
// 采用osgEarth的方法绘制
void addLotsOfVerts(LineDrawable* line)
{
for (int x = 0; x < 10; ++x)
{
for (int y = 0; y < 10; ++y)
{
line->pushVertex(osg::Vec3(x, 0, y));
}
}
line->finish();
}
// 采用osgEarth的方法绘制
LineDrawable* makeStar(double x, double y, double r)
{
LineDrawable* star = new LineDrawable(GL_LINES);
for(float i=0.0f; ipushVertex(osg::Vec3(x, 0, y));
star->pushVertex(osg::Vec3(x+(r*c-r*s), 0, y+(r*c+r*s)));
}
star->finish();
return star;
}
// 采用osgEarth的方法绘制
PointDrawable* makeGridOfPoints(double x, double y)
{
PointDrawable* grid = new PointDrawable();
for(float i=x; ipushVertex(osg::Vec3(i, 0, j));
}
}
grid->finish();
return grid;
}
// 采用osg的方法绘制
osg::Node* makeGeometryForImport(double x, double y)
{
osg::Geometry* geom = new osg::Geometry();
osg::Vec3Array* verts = new osg::Vec3Array();
verts->push_back(osg::Vec3(x, 0, y));
verts->push_back(osg::Vec3(x + 5, 0, y));
verts->push_back(osg::Vec3(x + 10, 0, y));
verts->push_back(osg::Vec3(x + 10, 0, y + 5));
verts->push_back(osg::Vec3(x + 10, 0, y + 10));
verts->push_back(osg::Vec3(x + 5, 0, y + 10));
verts->push_back(osg::Vec3(x, 0, y + 10));
verts->push_back(osg::Vec3(x, 0, y + 5));
geom->setVertexArray(verts);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1,1,1,1);
geom->setColorArray(colors);
geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, verts->size()));
geom->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(3.0f));
geom->getOrCreateStateSet()->setAttributeAndModes(new osg::LineStipple(1, 0xfff0));
return geom;
}
struct TestFirstCount : public osg::NodeCallback
{
void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
// 按照帧,每20帧,线条更新一次位置
if (nv->getFrameStamp()->getFrameNumber() % 20 == 0)
{
LineDrawable* line = (LineDrawable*)node;
unsigned total = line->getNumVerts();
unsigned first = line->getFirst();
line->setFirst( (first+1) % total );
line->setCount( 3 );// 绘制3个点
}
}
};
osg::Node* createDrawables()
{
// You need a viewport uniform for the lines to work.
// MapNode installs one automatically, but we're not using MapNode
// in this example.
// 本节不使用mapNode节点
osg::Group* group = new osg::Group();
group->addCullCallback(new InstallViewportSizeUniform());
float x = 10;
float y = 10;
// 定义一条连续线
LineDrawable* strip = new LineDrawable(GL_LINE_STRIP);
strip->setLineWidth(8);// 线宽
strip->setColor(osg::Vec4(1,1,1,1));//颜色
addVerts(strip, x, y);// 采用第一种方式绘制线
group->addChild(strip);
// 定义一条环线
x += 20;
LineDrawable* loop = new LineDrawable(GL_LINE_LOOP);
loop->setLineWidth(1);
loop->setColor(osg::Vec4(1,1,0,1));
addVerts(loop, x, y);
group->addChild(loop);
// 定义一条连续线
x += 20;
LineDrawable* stippled = new LineDrawable(GL_LINE_STRIP);
stippled->setLineWidth(4);
stippled->setStipplePattern(0xff00);// 线型
stippled->setColor(osg::Vec4(0,1,0,1));
addVerts(stippled, x, y);
group->addChild(stippled);
// 定义线段(每两个点连接)
x += 20;
LineDrawable* segments = new LineDrawable(GL_LINES);
segments->setLineWidth(3);
segments->setColor(osg::Vec4(0,1,1,1));
addVerts(segments, x, y);
group->addChild(segments);
// 定义一条连续线
x += 20;
LineDrawable* firstCount = new LineDrawable(GL_LINE_STRIP);
firstCount->setLineWidth(5);
firstCount->setColor(osg::Vec4(1,0,1,1));
addVerts(firstCount, x, y);
firstCount->addUpdateCallback(new TestFirstCount());// 此处对线设置回调方法
group->addChild(firstCount);
// 采用osg的方式定义线条geometry节点
x += 20;
osg::ref_ptr node = makeGeometryForImport(x, y);
LineGroup* lines = new LineGroup();// 采用lineGroup的方式,绘制线
lines->import(node.get());// 导入定义好的node图元
group->addChild(lines);
// 绘制很多点,大小颜色都默认
x += 20;
LineDrawable* points = new LineDrawable(GL_POINTS);
addVerts(points, x, y);
group->addChild(points);
// 绘制线段
x = 20;
y -= 20;
for(unsigned i=0; i<10; ++i)
{
LineDrawable* across = new LineDrawable(GL_LINES);
across->pushVertex(osg::Vec3(x, 0, y));
across->pushVertex(osg::Vec3(x+100, 0, y));
across->setLineWidth((float)(i+1));
across->finish();
group->addChild(across);
y -= (i+2);
}
// 绘制star
x = 20;
y -= 20;
LineDrawable* star = makeStar(x, y, 10);
star->setColor(osg::Vec4(1,1,1,1));
star->setLineWidth(1.0f);
group->addChild(star);
x += 40;
LineDrawable* star2 = makeStar(x, y, 10);
star2->setColor(osg::Vec4(1,.5,0,1));
star2->setLineWidth(2.0f);
group->addChild(star2);
x += 40;
LineDrawable* star3 = makeStar(x, y, 10);
star3->setColor(osg::Vec4(1,1,0,1));
star3->setLineWidth(3.0f);
group->addChild(star3);
// 绘制点网格
y -= 40;
x = 20;
PointDrawable* grid = makeGridOfPoints(x, y);
grid->setPointSize(3.0f);
grid->setColor(osg::Vec4(0,1,1,1));
group->addChild(grid);
// 绘制点网格
x += 50;
PointDrawable* grid2 = makeGridOfPoints(x, y);
grid2->setPointSize(20.0f);
GLUtils::setPointSmooth(grid2->getOrCreateStateSet(), 1);
group->addChild(grid2);
return group;
}
int
main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
osgViewer::Viewer viewer(arguments);
osg::ref_ptr node = createDrawables();
#ifdef OSG_GL3_AVAILABLE
// Sets up the State for GL3 mode
viewer.setRealizeOperation(new GL3RealizeOperation());
#endif
if (arguments.read("--ortho"))
{
viewer.realize();
double r = node->getBound().radius() * 1.2;
double ar = viewer.getCamera()->getViewport()->width() / viewer.getCamera()->getViewport()->height();
viewer.getCamera()->setProjectionMatrixAsOrtho(-r, +r, -r/ar, +r/ar, -r*2.0, +r*2.0);
}
if (arguments.read("--antialias") || arguments.read("--smooth"))
{
GLUtils::setLineSmooth(node->getOrCreateStateSet(), 1);// 配置线条抗锯齿
GLUtils::setPointSmooth(node->getOrCreateStateSet(), 1);// 配置点抗锯齿
node->getOrCreateStateSet()->setMode(GL_BLEND, 1);// 混合模式
}
if (arguments.read("--serialize"))// 序列化
{
const char* fileName = "out.osgt";
OE_NOTICE << "Writing to " << fileName << " ..." << std::endl;
if (!osgDB::writeNodeFile(*node.get(), fileName)) // 将组建好的node写入文件
{
OE_WARN << "serialize failed!\n";
return -1;
}
OE_NOTICE << "Reading from " << fileName << " ..." << std::endl;
node = osgDB::readRefNodeFile(fileName);// 从out.osgt文件中,读取node,并将其加入到场景中
if (!node.valid())
{
OE_WARN << "deserialize failed!\n";
return -1;
}
}
// Sets up global default uniform values needed by osgEarth
// 设置 osgEarth 所需的全局默认统一值
GLUtils::setGlobalDefaults(viewer.getCamera()->getOrCreateStateSet());
viewer.setSceneData(node.get());
// 设置事件处理器和操作器
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
return viewer.run();
}