#include "osgHead.h"
#include <osgText/Text>
//创建简易四边形
osg::Geometry*CreateSimpleQuad(osg::Vec3 vecCenter,float fWidth,float fheight,osg::Vec4 vecColor)
{
osg::ref_ptr<osg::Geometry>geom=new osg::Geometry;
osg::ref_ptr<osg::Vec3Array>v3a=new osg::Vec3Array;
v3a->push_back(vecCenter+osg::Vec3(fWidth/2,fheight/2,0));
v3a->push_back(vecCenter+osg::Vec3(-fWidth/2,fheight/2,0));
v3a->push_back(vecCenter+osg::Vec3(-fWidth/2,-fheight/2,0));
v3a->push_back(vecCenter+osg::Vec3(fWidth/2,-fheight/2,0));
osg::ref_ptr<osg::Vec4Array>v4a=new osg::Vec4Array;
v4a->push_back(vecColor);
geom->setColorArray(v4a.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
geom->setVertexArray(v3a.get());
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
return geom.release();
}
//创建屏幕平面显示的节点
osg::Geode* CreateScreenGeode(osg::Group*pGroup,int nWidth=1280,int nHeight=800)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
// turn lighting off for the text and disable depth test to ensure its always ontop.
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
// or disable depth test, and make sure that the hud is drawn after everything
// else so that it always appears ontop.
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
stateset->setRenderBinDetails(12,"RenderBin");
// create the hud.
osg::ref_ptr<osg::MatrixTransform> modelview_abs = new osg::MatrixTransform;
modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
modelview_abs->setMatrix(osg::Matrix::identity());
modelview_abs->addChild(geode);
osg::ref_ptr<osg::Projection> projection = new osg::Projection;
projection->setMatrix(osg::Matrix::ortho2D(0,nWidth,0,nHeight));
projection->addChild(modelview_abs);
pGroup->addChild(projection);
return geode.release();
}
//创建字体
osgText::Text* CreateText(std::string strText,osg::Vec3& vecPos,osg::Vec4 color=osg::Vec4(1.0,1.0,1.0,1.0),float size=20,std::string strFont=std::string("simhei.ttf"),osgText::Text::AlignmentType nAlign=osgText::Text::CENTER_BOTTOM)
{
setlocale(LC_ALL,"chs");//设定环境
const char* bz2=strText.c_str();
int nSize=mbstowcs(NULL,bz2,0);//字符转换
wchar_t*wbz2=new wchar_t[nSize+1];
mbstowcs(wbz2,bz2,(nSize+1));
osgText::String wText2(wbz2);
delete wbz2;
osg::ref_ptr<osgText::Text> text=new osgText::Text;
text->setText(wText2);
osg::ref_ptr<osgText::Font>font=new osgText::Font();
font=osgText::readFontFile(strFont);
text->setFont(font.get());
if(size>0)
text->setCharacterSize(size); //设定大小
else if(size==0)
text->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS); //根据屏幕坐标自动缩放
else
text->setCharacterSizeMode(osgText::TextBase::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);//根据视点自动缩放
text->setColor(color);
text->setPosition(vecPos);
text->setAlignment(nAlign);
text->setAxisAlignment(osgText::Text::SCREEN);
return text.release();
}
//画扇体
osg::Node* DrawSector(osg::Vec3 vecCenter, float radius, float height, float startAngle, float endAngle, float delta,osg::Vec4 vecColor,std::string strText=std::string(""))
{
osg::ref_ptr<osg::Geode> geode=new osg::Geode;//扇体节点
osg::Quat qu;//扇体外移
qu.makeRotate((startAngle+endAngle)/2.0,osg::Vec3(0,0,1));
osg::Matrix ma;
ma.makeRotate(qu);
vecCenter+=osg::Vec3(1,0,0)*delta*ma;
if (!strText.empty())
{
osg::Vec3 vecText=vecCenter+osg::Vec3(1,0,0)*radius*ma*0.6+osg::Vec3(0,0,height*1.2);
geode->addDrawable(CreateText(strText,vecText));
}
osg::ref_ptr<osg::Vec3Array> v3Qu=new osg::Vec3Array;//记录侧边顶点
osg::ref_ptr<osg::Vec3Array>v3Tr=new osg::Vec3Array;//扇形顶点
v3Qu->push_back(vecCenter);
v3Qu->push_back(vecCenter+osg::Vec3(0,0,height));
v3Tr->push_back(vecCenter+osg::Vec3(0,0,height));
float curAngle=startAngle;
while(1)
{
osg::Vec3 down=vecCenter+osg::Vec3(radius*cos(curAngle),radius*sin(curAngle),0);
osg::Vec3 top=down+osg::Vec3(0,0,height);
v3Qu->push_back(down);
v3Qu->push_back(top);
v3Tr->push_back(top);
if (endAngle>curAngle)
{
if(endAngle>curAngle+0.03)//小扇形顶角为0.03弧度
curAngle+=0.03;
else
curAngle=endAngle;
}
else
break;
}
v3Qu->push_back(vecCenter);
v3Qu->push_back(vecCenter+osg::Vec3(0,0,height));
osg::ref_ptr<osg::Vec4Array>v4Qu=new osg::Vec4Array;
v4Qu->push_back(vecColor);
osg::ref_ptr<osg::Geometry> geomQu=new osg::Geometry;
geomQu->setVertexArray(v3Qu.get());
geomQu->setColorArray(v4Qu.get());
geomQu->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::ref_ptr<osg::Vec4Array>v4Tri=new osg::Vec4Array;
v4Tri->push_back(vecColor);
osg::ref_ptr<osg::Geometry>geomTri=new osg::Geometry;
geomTri->setColorArray(v4Tri.get());
geomTri->setVertexArray(v3Tr.get());
geomTri->setColorBinding(osg::Geometry::BIND_OVERALL);
geomQu->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,v3Qu->size()));
geomTri->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,0,v3Tr->size()));
osg::StateSet* stateset =new osg::StateSet; //透明属性设置
stateset->setMode(GL_BLEND,osg::StateAttribute::ON); //Alpha混合开启
stateset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF ); //取消深度测试
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED );
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinDetails(11, "RenderBin");
geomQu->setStateSet(stateset);
geomTri->setStateSet(stateset);
geode->addDrawable(geomQu.get());
geode->addDrawable(geomTri.get());
geode->addDescription(std::string("sector"));
return geode.release();
}
int main()
{
osg::ref_ptr<osg::Vec4Array> v4a=new osg::Vec4Array;
v4a->push_back(osg::Vec4(0.8,0.0,0.0,0.7));
v4a->push_back(osg::Vec4(0.3,0.5,0.33,0.7));
v4a->push_back(osg::Vec4(0.0,0.8,0.1,0.7));
v4a->push_back(osg::Vec4(0.2,0.1,0.8,0.7));
osg::ref_ptr<osg::Group>pRoot=new osg::Group;
int i=0;
pRoot->addChild(DrawSector(osg::Vec3(0,0,0),100,10,0,0.4*osg::PI,5,v4a->at(i++),std::string("20.0%")));
pRoot->addChild(DrawSector(osg::Vec3(0,0,0),100,10,0.4*osg::PI,0.7*osg::PI,5,v4a->at(i++),std::string("15.0%")));
pRoot->addChild(DrawSector(osg::Vec3(0,0,0),100,10,0.7*osg::PI,1.3*osg::PI,5,v4a->at(i++),std::string("25.0%")));
pRoot->addChild(DrawSector(osg::Vec3(0,0,0),100,10,1.3*osg::PI,2.0*osg::PI,5,v4a->at(i++),std::string("35.0%")));
int nWidth=1280;
int nHeight=800;
int wRect=100,hRect=40;
std::string strCaption[]={"第一部分","第二部分","第三部分","第四部分"};
osg::ref_ptr<osg::Geode>geoScreen=CreateScreenGeode(pRoot,nWidth,nHeight);
for (i=1;i<=4;i++)
{
geoScreen->addDrawable(CreateSimpleQuad(osg::Vec3(20+wRect/2,nHeight-i*hRect,0),wRect,hRect*0.8,v4a->at(i-1)));
geoScreen->addDrawable(CreateText(strCaption[i-1],osg::Vec3(20+wRect*1.2,nHeight-i*hRect,0),v4a->at(i-1),hRect*0.8,std::string("simhei.ttf"),osgText::Text::LEFT_CENTER));
}
osgViewer::Viewer viewer;
viewer.setSceneData(pRoot);
viewer.setUpViewInWindow(100,100,640,500);
viewer.run();
return 0;
}