Page 1 of 1

How to draw CEGUI on Ogre Billboard?

Posted: Tue Jan 17, 2012 08:38
by wilsonwing
Hi, I am using CEGUI and Ogre.
CEGUI works really good and helps me a lot.
But I need some help on the following issue, can't find similar topic on forum or google. :(

1. Is it possible to draw single CEGUI::Window to Ogre billboard?
I find this post http://www.cegui.org.uk/phpBB2/viewtopic.php?=10&t=4767&p=22514&hilit=RENDER_QUEUE_MAIN#p22514 similar to my question, but drawing all the windows on the current RenderTarget to one texture.
My goal is to draw single CEGUI::Window to single texture, and set the texture to Ogre billboard.
I read the CEGUI API, but no luck.

2. If (1.) is not possible. Is it possible to use the font texture generate by CEGUI and render these font to Ogre billboard?
I am using Chinese Font, has 20,000 more code points. Ogre loads font file(and generate to texture) takes too long time.
CEGUI has good ability to read font and draw to texture by code points.
Using CEGUI font system and draw to Ogre billboard might be a good solution to me.


Thanks for any help in advance. :)

Re: How to draw CEGUI on Ogre Billboard?

Posted: Tue Jan 17, 2012 11:49
by evilrat
not sure why you want draw each window separately...

i'm don't use ogre, but generally speaking cegui provide fbo(preferable way) id, bind that fbo when draw ogre billboard texture, in case of 2 different render context you need to share lists(if opengl/windows) or mem copy between contexts. going that way you can draw ui sheet only with required text and get what you asking, if i'm not mistaken on what you want to do

p.s. sorry, my english isn't so good

Re: How to draw CEGUI on Ogre Billboard?

Posted: Tue Jan 17, 2012 13:49
by wilsonwing
evilrat wrote:not sure why you want draw each window separately...

i'm don't use ogre, but generally speaking cegui provide fbo(preferable way) id, bind that fbo when draw ogre billboard texture, in case of 2 different render context you need to share lists(if opengl/windows) or mem copy between contexts. going that way you can draw ui sheet only with required text and get what you asking, if i'm not mistaken on what you want to do

p.s. sorry, my english isn't so good


Hi,
Thanks for the quick reply.

I think to use Ogre billboard, I must have a Ogre material.
To use Ogre material, I have to create a CEGUI::TextureTarget and convert it to Ogre texture.
I see CEGUI::OgreTexture and CEGUI::Window have:

Code: Select all

CEGUI::OgreTexture:
void    loadFromMemory (const void *buffer, const Size &buffer_size, PixelFormat pixel_format)
 Loads (copies) an image in memory into the texture. The texture is resized as required to hold the image.

CEGUI::Window:
GeometryBuffer&    getGeometryBuffer ()
Return the GeometryBuffer object for this Window.



Does it helps?

ps. The questions are not solved :wink:

Re: How to draw CEGUI on Ogre Billboard?

Posted: Tue Jan 17, 2012 14:39
by evilrat
well, some kind of.

geometry buffer has method GeometryBuffer::getActiveTexture() which return Texture (struct?) ptr, this ptr, i think, you could feed to loadFromMemory method of OgreTexture which perform some data copying related to ogre.

Re: How to draw CEGUI on Ogre Billboard?

Posted: Wed Jan 18, 2012 03:37
by wilsonwing
evilrat wrote:well, some kind of.

geometry buffer has method GeometryBuffer::getActiveTexture() which return Texture (struct?) ptr, this ptr, i think, you could feed to loadFromMemory method of OgreTexture which perform some data copying related to ogre.

I look into the API GeometryBuffer::getActiveTexture(), and is confused by

Code: Select all

Return a pointer to the currently active Texture object. This may return 0 if no texture is set

What is "the currently active Texture object" means ? Is it the texture of the window I am using to draw on screen?
Is it like:
I have a imageset -> a image from the imageset -> create a window using the image -> the window is a texture, and saved to buffer -> so if I call getActiveTexture(), I get the texture with a window draw on it, and the texture is called ActiveTexture?
Am I thinking it right?

And for the code, I was original thinking of:

Code: Select all

//create a texture, cast to OgreTexture
CEGUI::Texture &guiTex = CEGUI::OgreRenderer->createTexture();
CEGUI::OgreTexture &ogreTex = static_cast<CEGUI::OgreTexture&>(guiTex);

//a CEGUI::Window
Cegui::Window* pWnd = somewhereCreateACeguiWindow();
//get the buffer
GeometryBuffer &buf = pWnd->getGeometryBuffer();
//write the buffer to ogreTexture, so I have a ogreTexture with a window draw on it?
ogreTex->loadFromMemory(&buf , sizeof(buf), CEGUI::Texture::PF_RGBA);


But after your advice:

Code: Select all

//a CEGUI::Window
Cegui::Window* pWnd = somewhereCreateACeguiWindow();
//get the buffer
CEGUI::Texture* pGuiTex = pWnd->getGeometryBuffer().getActiveTexture();
//And just cast it to OgreTexture?
CEGUI::OgreTexture* pOgreTex = static_cast<CEGUI::OgreTexture*>(pGuiTex );



not sure why you want draw each window separately...

In game, character has name and health bar show on top of their head, using billboard(s).
I am trying to make it.
And because different character has different name text and health bar, using one cegui window is not enough.
So I need one CEGUI window to show on one Ogre billboard, as a name or health bar.

Thanks for help, very appreciate.

ps. My English is not good, either :wink: Hope you can understand.

Re: How to draw CEGUI on Ogre Billboard?

Posted: Wed Jan 18, 2012 07:59
by evilrat
current active texture is a opengl/directx texture id, that id 'has' binded texture data


you should do that on root window if you want a complete window drawed, or on text window if you want only text:

Code: Select all

//a CEGUI::Window
Cegui::Window* pWnd = somewhereCreateACeguiWindow();
//get the buffer
CEGUI::Texture* pGuiTex = pWnd->getGeometryBuffer().getActiveTexture();
//And just cast it to OgreTexture?
CEGUI::OgreTexture* pOgreTex = static_cast<CEGUI::OgreTexture*>(pGuiTex );


static cast here is just fooling a compiler, it doesn't work that way

Code: Select all

pOgreTex->loadFromMemory(pGuiTex,...)


so now it should copy real image data from geometry buffer, i.e. the current window
as i said before, i don't know ogre but this seems to be window texture usable by ogre.

i'm look at ogre rendermodule Texture.h , there is Ogre::TexturePtr getOgreTexture() inside.
possibly you may use this texture directly to draw on billboard.

Code: Select all

Cegui::Window* pWnd = somewhereCreateACeguiWindow();
CEGUI::OgreTexture* pOgreTex = pWnd->getGeometryBuffer().getActiveTexture()->getOgreTexture();


also you may think to just change window text and re-render window instead of having lots of windows for each player, or also you may think about keeping all that health bars on ui side, but that involves some advanced math to trace camera to player relative position and adjust ui elements position on screen.

Re: How to draw CEGUI on Ogre Billboard?

Posted: Wed Jan 18, 2012 14:09
by wilsonwing
Thanks for the explain.
It is quite clear now.

also you may think to just change window text and re-render window instead of having lots of windows for each player

Good idea!

or also you may think about keeping all that health bars on ui side

I've considered this method. But CEGUI on Ogre always render after Ogre, so the Z order will be a problem.

Anyway, I will try it this weekend and post the result.
Thanks again!

Re: How to draw CEGUI on Ogre Billboard?

Posted: Sat Jan 21, 2012 03:22
by wilsonwing
I try these code, and failed.
I got a NULL pointer here ==> CEGUI::Texture* pCETex = buf.getActiveTexture();
pCETex is NULL.
Not even reach the OgreTexture part yet.

Code: Select all

   CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
   CEGUI::Window *wnd;
   wnd = wmgr->getWindow((CEGUI::utf8*)"MenuWnd");
   wnd->setUsingAutoRenderingSurface(true);
   wnd->invalidate(true);
   CEGUI::GeometryBuffer& buf = wnd->getGeometryBuffer();
   CEGUI::Texture* pCETex = buf.getActiveTexture();
   if(pCETex) // <== NULL here, not entering 'if'
   {
      CEGUI::OgreTexture* pOgreTex = static_cast<CEGUI::OgreTexture*>(pCETex);
   }


I search for getGeometryBuffer and getActiveTexture, but no help...very little disscusion here.
Maybe I need to do something before getActiveTexture? But I am not sure what to do... :?

Thank you for any idea :D

Re: How to draw CEGUI on Ogre Billboard?

Posted: Sat Jan 21, 2012 04:15
by evilrat
well that getActiveTexture method has description it CAN return 0 if no active textures, and there is also setActiveTexture method described as texture setter for drawing on that texture. may be you should try to set your own texture here first?


oops, nevermind this looks like texture for window :?

try another way, set for your render target or window target, however i can't say you how to do it since i'm never used it before

Re: How to draw CEGUI on Ogre Billboard?

Posted: Sun Jan 22, 2012 03:22
by wilsonwing
I tried these, no help :?

Got all black (or alpha = 0) on this one:

Code: Select all

   wnd = wmgr->getWindow((CEGUI::utf8*)"RoomWnd_btnStart");
   wnd->setUsingAutoRenderingSurface(true);
   wnd->invalidate(false);

   unsigned int s = 64;
   CEGUI::Size size(s,s);
   CEGUI::Texture* d_texture = &CEGUI::System::getSingleton().getRenderer()->createTexture(size);
   CEGUI::GeometryBuffer& buf = wnd->getGeometryBuffer();
   buf.setActiveTexture(d_texture);
   CEGUI::Texture* pCETex = buf.getActiveTexture();


Got noisy pixel on this one:

Code: Select all

   wnd = wmgr->getWindow((CEGUI::utf8*)"RoomWnd_btnStart");
   wnd->setUsingAutoRenderingSurface(true);
   wnd->invalidate(false);

   CEGUI::Size size(wnd->getPixelSize());
   CEGUI::Texture* d_texture = &CEGUI::System::getSingleton().getRenderer()->createTexture();
   CEGUI::GeometryBuffer& buf = wnd->getGeometryBuffer();
   d_texture->loadFromMemory(&buf, size, CEGUI::Texture::PF_RGBA);
   buf.setActiveTexture(d_texture);
   CEGUI::Texture* pCETex = buf.getActiveTexture();


Feel frustrating.
Anyway, Thanks you, evilrat , help me many . :wink:

I'll contiune on searching, and hoping somone can help me on this.

Re: How to draw CEGUI on Ogre Billboard?

Posted: Sun Jan 22, 2012 13:04
by Kulik
You can simply enable the root CEGUI GUI sheet's AutoRenderingSurface, that way it will render to a render texture. You can then get that surface (one of the methods of CEGUI::Window) and static cast it and get the underlying Ogre Texture. To use that with Ogre should be easy then...

Re: How to draw CEGUI on Ogre Billboard?

Posted: Sun Jan 22, 2012 15:17
by wilsonwing
Kulik wrote:You can simply enable the root CEGUI GUI sheet's AutoRenderingSurface, that way it will render to a render texture. You can then get that surface (one of the methods of CEGUI::Window) and static cast it and get the underlying Ogre Texture. To use that with Ogre should be easy then...


Hi.
Thanks for your reply first :)

I think you are talking the way described in this link http://www.cegui.org.uk/phpBB2/viewtopic.php?=10&t=4767&p=22514&hilit=RENDER_QUEUE_MAIN#p22514
Just like this:

Code: Select all

        wnd->setUsingAutoRenderingSurface( true ) ;
        CEGUI::OgreTextureTarget &aTarget = dynamic_cast<CEGUI::OgreTextureTarget&>( wnd->getRenderingSurface()->getRenderTarget() ) ;
        CEGUI::Texture& ceTex = aTarget.getTexture() ;
        CEGUI::OgreTexture& ogreTex = static_cast<CEGUI::OgreTexture&>(ceTex);


But I want a single CEGUI window render to a texture, to be used on a Ogre billboard.
More than 1 CEGUI window will be used.
(I want to use them to draw character's name, show on top of character using a billboard. And there are many characters)
At the same time, there must be other CEGUI use for my game's main GUI.(showing skill, map, character info...etc)
And the billboard GUI and main GUI are not on the same root CEGUI GUI sheet.

I think this way(setting AutoRenderingSurface) doesn't work. :(
It will show all the main GUI of the root sheet.
Or do I understand you wrong?

Thanks.

ps. I also got a black rendered texture using AutoRenderingSurface method...

Re: How to draw CEGUI on Ogre Billboard?

Posted: Mon Jan 23, 2012 07:31
by CrazyEddie
Important note: I have not read every post in this topic ;)

The AutoRenderingSurface is a per-window setting. If you enable it on some window that has no child content, then only that windows rendering will appear on the underlying texture. However, the windows are still part of the overall hierarchy and as such will be drawn when you render CEGUI (and you must do that in order that the ARS texture be rendered to - this could be the cause of the black texture you have). When you really need in this scenario is the fabled 'multiple GUI roots' - which would basically allow rendering of separate window hierarchies (including single windows) individually.

One thing I would add to is to question whether using CEGUI to render text to a texture for character labels is a good decision - I'm not saying it is, or it isn't, but without having looked into anything in any detail, I would suspect there are better ways than using CEGUI Windows for this (you could likely still use CEGUI's font support if you wanted).

With regards to the broader topic of Ogre and Ogre billboards - I am not an expert in the former, and have no knowledge at all of the latter.

CE.