Ogre Version: :13.2.4:
Operating System: :Windows 10:
Render System: :DX9 DX11:
Hi.
I try to (re)write my gui system, what is based on manualobject. I noticed is the update time is too long even though I "only" want to update a thousand of triangles(text) at once.
I measured the vertex pushing time, and I got this result( the time is in microseconds/μs):
Code: Select all
22:55:44: Sender:consolewindow Entry count: 2 Elapsed time: 87.000000
22:55:44: Sender:headercaption Entry count: 7 Elapsed time: 157.000000
22:55:44: Sender:headerbuttona Entry count: 1 Elapsed time: 58.000000
22:55:44: Sender:headerbuttonb Entry count: 1 Elapsed time: 65.000000
22:55:44: Sender:headerbuttonc Entry count: 1 Elapsed time: 55.000000
22:55:44: Sender:functiontabs Entry count: 2 Elapsed time: 69.000000
22:55:44: Sender:logtabbutton Entry count: 1 Elapsed time: 52.000000
22:55:44: Sender:logtabbuttoncaption Entry count: 3 Elapsed time: 98.000000
22:55:44: Sender:logtab Entry count: 1 Elapsed time: 57.000000
22:55:44: Sender:logtextbox Entry count: 2 Elapsed time: 74.000000
22:55:44: Sender:logtextbox_line_0 Entry count: 59 Elapsed time: 1008.000000
22:55:44: Sender:logtextbox_line_1 Entry count: 74 Elapsed time: 1414.000000
22:55:44: Sender:logtextbox_line_2 Entry count: 37 Elapsed time: 734.000000
22:55:44: Sender:logtextbox_line_3 Entry count: 72 Elapsed time: 1395.000000
22:55:44: Sender:logtextbox_line_4 Entry count: 67 Elapsed time: 1254.000000
22:55:44: Sender:logtextbox_line_5 Entry count: 38 Elapsed time: 723.000000
22:55:44: Sender:logtextbox_line_6 Entry count: 75 Elapsed time: 1373.000000
22:55:44: Sender:logtextbox_line_7 Entry count: 78 Elapsed time: 1636.000000
22:55:44: Sender:logtextbox_line_8 Entry count: 74 Elapsed time: 1362.000000
22:55:44: Sender:logtextbox_line_9 Entry count: 104 Elapsed time: 1704.000000
22:55:44: Sender:logtextbox_line_10 Entry count: 79 Elapsed time: 1471.000000
22:55:44: Sender:logtextbox_line_11 Entry count: 64 Elapsed time: 1300.000000
22:55:44: Sender:logtextbox_line_12 Entry count: 50 Elapsed time: 859.000000
22:55:44: Sender:logtextbox_line_13 Entry count: 68 Elapsed time: 1352.000000
22:55:44: Sender:logtextbox_line_14 Entry count: 72 Elapsed time: 1362.000000
22:55:44: Sender:logtextbox_line_15 Entry count: 41 Elapsed time: 1144.000000
22:55:44: Sender:logtextbox_line_16 Entry count: 0 Elapsed time: 36.000000
22:55:44: Sender:logtextbox_line_17 Entry count: 0 Elapsed time: 29.000000
Here is how I define the manualobject
Code: Select all
void Layer::initmanual()
{
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite();
Ogre::SceneManager* scenemanager = Ogre::Root::getSingletonPtr()->getSceneManager("MainScene");
manual = scenemanager->createManualObject(widgetname +"_Guimanual");
manual->setUseIdentityProjection(true);
manual->setUseIdentityView(true);
manual->setKeepDeclarationOrder(true);
manual->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY);
manual->setBoundingBox(aabInf);
setqueueindex(getqueueindex() + 1);
manual->setRenderQueueGroup(queueindex);
manual->setCastShadows(false);
manual->setDebugDisplayEnabled(false);
manual->setDynamic(true);
Layoutnode = scenemanager->getRootSceneNode()->createChildSceneNode();
Layoutnode->attachObject(manual);
Layoutnode->setPosition(0, 0, 0);
}
Here is the code I use for updating the manualobject:
Code: Select all
#define PUSH_VERTEX(MANUALOBJECT, X, Y, UV, COLOUR)\
MANUALOBJECT->position(X, Y, -1);\
MANUALOBJECT->textureCoord(UV.x, UV.y);\
MANUALOBJECT->colour(COLOUR);
.
.
.
void LayoutManager::redraw(Widget* dirtywidget)
{
if (dirtywidget->isdirty())
{
//more widget share the same manual, the child can get the parent's manual
Ogre::ManualObject* Layoutmanual = dirtywidget->getmanual();
if (dirtywidget->isdrawed()) Layoutmanual->beginUpdate(dirtywidget->getmanualindex());
else
{
int manualindex = Layoutmanual->getNumSections();
dirtywidget->setmanualindex(manualindex);
dirtywidget->markasdrawed();
std::string materialname = dirtywidget->getmaterialname();
Layoutmanual->begin(materialname, Ogre::RenderOperation::OT_TRIANGLE_LIST);
}
int trianglecounter = 0;
std::vector<data::Widgetdrawdata> widgetdrawdata = dirtywidget->getwidgetdrawdata();
Layoutmanual->estimateVertexCount((widgetdrawdata.size() * 4) + 4);
Layoutmanual->estimateIndexCount((widgetdrawdata.size() * 6) + 12);
functions.debugtimestart();//time measuring point start
for (auto widget = widgetdrawdata.begin(); widget != widgetdrawdata.end(); ++widget)
{
PUSH_VERTEX(Layoutmanual, widget->position.left, widget->position.top, widget->mUV[0], widget->colour);
PUSH_VERTEX(Layoutmanual, widget->position.left, widget->position.bottom, widget->mUV[1], widget->colour);
PUSH_VERTEX(Layoutmanual, widget->position.right, widget->position.top, widget->mUV[2], widget->colour);
PUSH_VERTEX(Layoutmanual, widget->position.right, widget->position.bottom, widget->mUV[3], widget->colour);
Layoutmanual->triangle(0 + trianglecounter, 1 + trianglecounter, 2 + trianglecounter);
Layoutmanual->triangle(2 + trianglecounter, 1 + trianglecounter, 3 + trianglecounter);
trianglecounter += 4;
}
functions.debugtimeend(dirtywidget->getname() + " Entry count: " + functions.converttostring(widgetdrawdata.size()));//time measuring point end
Layoutmanual->end();
dirtywidget->markasclean();
}
std::vector<Widget*> childwidgets = dirtywidget->getchildwidgets();
for (int i = 0; i < childwidgets.size(); i++) redraw(childwidgets[i]);
}
I drawing every elements(buttons/captions/ textboxes, etc) on a different section. So I only need to redraw only that section.
The slowness won't be the problem most of the time, but for example, if I want to scroll the text, I have no other option, just to redraw the whole text again.
I knew it's not the fastest,but Is updating manualobject really is this slow? one millisecond for 70-ish triangles feels way off.
Do I miss something, or declared something wrong? Is there any way to speed up omhow?
Or is there any other options to draw 2d elements more efficiently?
I looked around to find a gui for ogre, but I didn't found any good so far. Either missing something I want or over complicated, or simply not working.