转自:http://blog.sina.com.cn/s/blog_5d76edd801016nuf.html
要在OSG的三维场景中添加界面元素,找了个《OSG Cookbook》上的例子,学习并分析一下:
int main(int argc, char * argv[])
{
osgViewer::Viewer viewer;
//新建一个
WindowManager,这个是必须的。其中定义了整个UI系统的大小和基本属性。
osg::ref_ptr<osgWidget::WindowManager> wm = new osgWidget::WindowManager(&viewer, 1024.f, 768.f, 0xf0000000);
//创建一个正射投影的相机
osg::Camera *camera = wm->createParentOrthoCamera();
//添加tabs, 代码见下面
wm->addChild(createSimpleTabs(100.f, 100.f));
wm->resizeAllWindows();
osg::ref_ptr<osg::Group> root =
new osg::Group;
root->addChild(osgDB::readNodeFile("cow.osg"));
//把创建出来的camera加到root上
root->addChild(camera);
viewer.setSceneData(root.get());
viewer.setUpViewInWindow(50, 50, 1024, 768);
//添加事件回调
viewer.addEventHandler(new osgWidget::MouseHandler(wm.get()));
viewer.addEventHandler(new osgWidget::KeyboardHandler(wm.get()));
viewer.addEventHandler(new osgWidget::ResizeHandler(wm.get(), camera));
viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm.get(), camera));
return viewer.run();
}
osgWidget::Window* createSimpleTabs(float winX, float winY)
{
//osgWidget有三种基本类型的widget:box,canvas,table。box是线性排列子widget,table是grid状排列;canvas可以在任意坐标渲染子widget没有限制。
osg::ref_ptr<osgWidget::Canvas> contents = new osgWidget::Canvas("contents");
osg::ref_ptr<osgWidget::Box> tabs = new osgWidget::Box("tabs", osgWidget::Box::HORIZONTAL);//水平的box
for (unsigned int i = 0; i < 3; i++)
{
osg::Vec4 color(0.0f, (float)i/3.0f, 0.0f, 1.0f);//green
std::stringstream ss, ss2;
ss << "Tab-" << i;
ss2 << "Tab content:" << std::endl << "Hello Tab-" << i;
//创建内容标签widget,层设置为MIDDLE(层数值大的显示在上面),设置原点为(0,0)
//enum Layer { LAYER_TOP = 100, LAYER_HIGH = 75, LAYER_MIDDLE = 50, LAYER_LOW = 25, LAYER_BG = 0 };
osgWidget::Label *content = createLabel(ss.str(), ss2.str(), 10.0f, color);
content->setLayer(osgWidget::Widget::LAYER_MIDDLE, i);
contents->addWidget(content, 0.0f, 0.0f);
//创建tab,响应鼠标点击的时间,并设置回调函数
tabPressed
osgWidget::Label *tab = createLabel(ss.str(), ss.str(), 20.0f, color);
tab->setEventMask(osgWidget::EVENT_MOUSE_PUSH);
//回调函数、事件类型、数据
tab->addCallback(new osgWidget::Callback(
&tabPressed, osgWidget::EVENT_MOUSE_PUSH, content));
tabs->addWidget(tab);
}
//垂直的box,作为最外层的容器
osg::ref_ptr<osgWidget::Box> main = new osgWidget::Box("main", osgWidget::Box::VERTICAL);
main->setOrigin(winX, winY);//设置原点
main->attachMoveCallback();//增加鼠标拖动的callback
main->addWidget(contents->embed());
main->addWidget(tabs->embed());
main->addWidget(createLabel("title", "Tabs Demo!", 15.0f,
osg::Vec4(0.0f, 0.4f, 1.0f, 1.0f)));//这是个标题,可以注意到,这里添加的顺序是从下到上的
return main.release();
}
//创建标签widget
osgWidget::Label* createLabel(const std::string &name,
const std::string &text, float size, const osg::Vec4 &color)
{
osg::ref_ptr<osgWidget::Label> label = new osgWidget::Label(name);
label->setLabel(text);
label->setFont("fonts/arial.ttf");
label->setFontSize(size);
label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
label->setColor(color);//标签背景颜色
label->addSize(10.0f, 10.0f);
label->setCanFill(true);
return label.release();
}