osgkeyboard例子中包含的内容:
(1)显示文本osgText.
(2)在viewer中添加事件处理:GUIEventHandler.
解析如下:
class KeyboardModel : public osg::Referenced
{
public:
KeyboardModel() { createKeyboard(); }
osg::Group* getScene() { return _scene.get(); }
void keyChange(int key,int value);//每当用户按下或松开按钮时调用
protected:
~KeyboardModel() {}
osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height);
osg::Switch* addKey(int key,osg::Switch* sw);
void createKeyboard();//构造函数中调用
typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
osg::ref_ptr<osg::Group> _scene;//场景节点
KeyModelMap _keyModelMap;//map(字符ID,开关节点),如_keyModelMap["P"] = switch
osg::ref_ptr<osgText::Text> _inputText;//显示的文本(会随着按键而改变)
};
void KeyboardModel::keyChange(int key,int value)
{
// toggle the keys graphical representation on or off via osg::Swithc
KeyModelMap::iterator itr = _keyModelMap.find(key);
if (itr!=_keyModelMap.end())
{
itr->second->setSingleChildOn(value);
//itr->second即找到的switch,例_keyModelMap["P"] = switch,则switch只打开一个(setSingleChildOn()),
//当按下"P"时,由于KeyboardEventHandler::handle()中_keyboardModel->keyChange(ea.getKey(),1);表示显示
//的索引值是1(即第2个红色的),否则如果按键松开,则显示的索引值是0(第一个白色的).
}
if (value)//只有当用户按下某个键时,value=1.
{
// when a key is pressed add the new data to the text field
if (key>0 && key<256)
{
// just add ascii characters right now...
_inputText->getText().push_back(key);//直接将输入的字符添加,会显示出来
_inputText->update();
}
else if (key==osgGA::GUIEventAdapter::KEY_Return)
{
_inputText->getText().push_back('/n');//换行
_inputText->update();
}
else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
{
if (!_inputText->getText().empty())
{
_inputText->getText().pop_back();//删除
_inputText->update();
}
}
}
}
osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
{
osg::Geode* geodeUp = new osg::Geode;//第1个字符(白色)
{
osgText::Text* textUp = new osgText::Text;
textUp->setFont("fonts/arial.ttf");
textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));//(白色)
textUp->setCharacterSize(height);
textUp->setPosition(pos);
textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
textUp->setAlignment(osgText::Text::LEFT_CENTER);
textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
textUp->setText(text);
geodeUp->addDrawable(textUp);
}
osg::Geode* geodeDown = new osg::Geode;//第2个字符(红色)
{
osgText::Text* textDown = new osgText::Text;
textDown->setFont("fonts/arial.ttf");
textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));//(红色)
textDown->setCharacterSize(height);
textDown->setPosition(pos);
textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
textDown->setAlignment(osgText::Text::LEFT_CENTER);
textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
textDown->setText(text);
geodeDown->addDrawable(textDown);
}
osg::Switch* model = new osg::Switch;//开关节点,添加2个Geode,且每次只能一个打开,即只显示一个
model->addChild(geodeUp,true);
model->addChild(geodeDown,false);
_scene->addChil