饭后温柔

汉堡与老干妈同嚼 有可乐味
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Ogre中的Overlay第一个TextArea首次渲染时不能显示的问题

Posted on 2011-04-30 18:18  饭后温柔  阅读(797)  评论(0)    收藏  举报

项目中使用Ogre画一些物件的tag时遇到一些tag不能正常显示的问题。几经折腾,感觉应该是属于Ogre的bug。

Google之,找到官网论坛上的一个report:

http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59197

看来蛮多同学遇到了一样的问题。目前对ogre不熟,不敢确定是否自己的原因。该bug的表现就是第一次加入的TextArea不能正常渲染,不管你有多少个overlay。必须场景被刷新(viewport改变,拉伸一下窗口),才能看到该tag。

report中提到bug可能的所在代码。有人给了一个dirty fix,在渲染循环中强制提前刷新一次。

View Code
bool first = true;

while(mRunning)
{
//Pump messages in all registered RenderWindow windows
Ogre::WindowEventUtilities::messagePump();
mRoot
->renderOneFrame(); // Ignore whatever the frame listeners return basically.

if(first)
{
first
= false;

// Simple hack to make sure all text area overlay elements are shown correctly..

Ogre::OverlayManager
& om = Ogre::OverlayManager::getSingleton();

Ogre::OverlayManager::OverlayMapIterator omi
= om.getOverlayIterator();
while(omi.hasMoreElements())
{
Ogre::Overlay
* overlay = omi.getNext();
Ogre::Overlay::Overlay2DElementsIterator o2dei
= overlay->get2DElementsIterator();
while(o2dei.hasMoreElements())
{
Ogre::OverlayElement
* oe = o2dei.getNext();
oe
->setCaption(oe->getCaption());
}

}
}
}

我自己的选择是建了一个“空白”节点,加入一个“空白”的overlay并添加textArea。这个overlay中最好载入所有你需要用到的字体,一个textArea一个字体。

惭愧,今后有时间再追这个bug。

备忘,测试代码。

View Code
#ifndef __OgreApplication_H__
#define __OgreApplication_H__
#include
"stdafx.h"

using namespace Ogre;
using namespace std;


class MyAapplicaton : public RenderTargetListener
{
public:
class MyRenderListener : public Ogre::RenderTargetListener
{
public:
std::vector
<Overlay*> m_overlayList;
public:
MyRenderListener() {}
void preViewportUpdate(const RenderTargetViewportEvent& evt)
{
std::vector
<Overlay*>::iterator it;
for (it = m_overlayList.begin(); it != m_overlayList.end(); ++it)
{
(
*it)->show();
}
}
void postViewportUpdate(const RenderTargetViewportEvent& evt)
{

}
void addOverlay(Overlay* _overlay)
{
m_overlayList.push_back(_overlay);
}
};


protected:
Root
* m_root;
SceneManager
* m_sceneManger;
Ogre::RenderWindow
* m_window;
Ogre::Viewport
* m_viewport;
Ogre::Camera
* m_camera;
Ogre::Overlay
* m_overlay;
MyRenderListener m_preViewportRenderListener;


public:
MyAapplicaton()
{
m_root
= NULL;
m_sceneManger
= NULL;
}
~MyAapplicaton()
{
delete m_root;
}

public:
void LoadResources()
{
ConfigFile cf;
cf.load(
"resources_d.cfg");
Ogre::String sectionName, typeName, dataname;
ConfigFile::SectionIterator sectionIter
= cf.getSectionIterator();

while (sectionIter.hasMoreElements())
{
sectionName
= sectionIter.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap
*settings = sectionIter.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName
= i->first;
dataname
= i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname, typeName, sectionName);
}
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}

int startup()
{
m_root
= new Root("plugins_d.cfg");
if (!m_root->showConfigDialog())
{
return -1;
}

m_window
= m_root->initialise(true, "My Application");
m_sceneManger
= m_root->createSceneManager(ST_GENERIC);

m_camera
= m_sceneManger->createCamera("Camera");
m_camera
->setPosition(Vector3(0, 0, 50));
m_camera
->lookAt(Vector3(0, 0, 0));
m_camera
->setNearClipDistance(5);

m_viewport
= m_window->addViewport(m_camera);
//m_viewport->setBackgroundColour(ColourValue(0.0, 0.0, 0.0));
m_viewport->setOverlaysEnabled(true);
m_camera
->setAutoAspectRatio( Real( m_viewport->getActualWidth()) / Real(m_viewport->getActualHeight()) );

LoadResources();
createScene();
m_root
->startRendering();
return 0;

}

void createScene( void )
{
//Entity* ent = m_sceneManger->createEntity("sinbad.mesh");
//SceneNode* node = m_sceneManger->createSceneNode("node1");
//m_sceneManger->getRootSceneNode()->addChild(node);
//node->attachObject(ent);

OverlayManager
* pOverlayManager = OverlayManager::getSingletonPtr();
Ogre::String name
= "MyPanel";

//TextAreaOverlayElement *nameArea, *valuesArea;
//OverlayElement* element = pOverlayManager->createOverlayElementFromTemplate("SdkTrays/ParamsPanel","BorderPanel", name);
//OverlayContainer* container = (OverlayContainer*)element;
//nameArea = (TextAreaOverlayElement*)container->getChild(container->getName()+"/ParamsPanelNames");
//valuesArea = (TextAreaOverlayElement*)container->getChild(container->getName() + "/ParamsPanelValues");
//element->setHeight(nameArea->getTop()*2*10+10);
//element->setWidth(200);
////element->setColour(ColourValue(0, 0, 0));
//nameArea->setLeft(10);
//nameArea->setTop(10);
//nameArea->setCaption("i am very very very am very very very am very very very am very very very am very very very sleepy");
//nameArea->show();

//Overlay* pOverlay = OverlayManager::getSingletonPtr()->create("overlay");
//
//pOverlay->add2D(container);
//pOverlay->show();
//////////////////////////////////////////////////////////////////////////

OverlayContainer
* container_root = (OverlayContainer*)pOverlayManager->createOverlayElementFromTemplate("SdkTrays/TextBox", "BorderPanel", name);

container_root
->setHeight(480);
container_root
->setWidth(480);


TextAreaOverlayElement
* element_textarea = (TextAreaOverlayElement*)container_root->getChild(container_root->getName()+ "/TextBoxText");
element_textarea
->setFontName("StarWars");
element_textarea
->setCaption("hi, girl! my name is god");
element_textarea
->setWidth(320);
element_textarea
->setHeight(320);
element_textarea
->setTop(100);
element_textarea
->setCharHeight(19);
element_textarea
->setSpaceWidth(8);
//
//cout<<"=========================="<<endl;
//cout<<element_textarea->getName()<<endl;
//cout<<element_textarea->getWidth() <<endl;
//cout<<element_textarea->getHeight()<<endl;
//cout<<element_textarea->getTop() <<endl;
//cout<<element_textarea->getTypeName() <<endl;
//cout<<element_textarea->getFontName() <<endl;
//cout<<element_textarea->getZOrder() <<endl;
element_textarea->show();

OverlayContainer
* container_TextBoxCaptionBar = (OverlayContainer*)container_root->getChild(container_root->getName() + "/TextBoxCaptionBar");
container_TextBoxCaptionBar
->setWidth(480);
TextAreaOverlayElement
* element_texbar = (TextAreaOverlayElement*)container_TextBoxCaptionBar->getChild(container_TextBoxCaptionBar->getName() + "/TextBoxCaption");
element_texbar
->setCaption(DisplayString("oh, my god"));

//Overlay* pOverlay = OverlayManager::getSingletonPtr()->create("overlay");
//pOverlay->add2D(container_root);
//pOverlay->show();
//////////////////////////////////////////////////////////////////////////

OverlayManager
& overlayManager = OverlayManager::getSingleton();

// Create a panel
OverlayContainer* panel = static_cast<OverlayContainer*>(
overlayManager.createOverlayElement(
"Panel", "PanelTest"));
panel
->setMetricsMode(Ogre::GMM_PIXELS);
panel
->setPosition(10, 10);
panel
->setDimensions(100, 100);
//panel->setMaterialName("MaterialName"); // Optional background material

// Create a text area
TextAreaOverlayElement* textArea = static_cast<TextAreaOverlayElement*>(
overlayManager.createOverlayElement(
"TextArea", "TextAreaTest"));
textArea
->setMetricsMode(Ogre::GMM_PIXELS);
textArea
->setPosition(0, 0);
textArea
->setDimensions(100, 100);
textArea
->setCaption("Hello, World!");
textArea
->setCharHeight(16);
textArea
->setFontName("SdkTrays/Caption");
/*textArea->setFontName("StarWars");*/
textArea
->setColourBottom(ColourValue(0.3, 0.5, 0.3));
textArea
->setColourTop(ColourValue(0.5, 0.7, 0.5));

panel
->addChild(textArea);

TextAreaOverlayElement
* textArea1 = static_cast<TextAreaOverlayElement*>(
overlayManager.createOverlayElement(
"TextArea", "TextAreaTest1"));
textArea1
->setMetricsMode(Ogre::GMM_PIXELS);
textArea1
->setPosition(50, 50);
textArea1
->setDimensions(100, 100);
textArea1
->setCaption("hi, god!");
textArea1
->setCharHeight(16);
textArea1
->setFontName("StarWars");
textArea1
->setColourBottom(ColourValue(0.3, 0.5, 0.3));
textArea1
->setColourTop(ColourValue(0.5, 0.7, 0.5));

panel
->addChild(textArea1);

// Create an overlay, and add the panel
m_overlay = overlayManager.create("OverlayTest");

/*-----------------------------------------------
更换这2行的顺序
-----------------------------------------------
*/
m_overlay
->add2D(container_root);
m_overlay
->add2D(panel);



// Add the text area to the panel

// Show the overlay
//m_overlay->show();
//m_preViewportRenderListener.addOverlay(m_overlay);
m_overlay->show();
m_viewport
->getTarget()->addListener(&m_preViewportRenderListener);
}

};



#endif