2d sprite manager, for Ogre
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
2d sprite manager, for Ogre
edit 10/16: removed code from here, now only in the wiki to avoid code duplication in forums and wiki
This is a small code snippet, a small solution to an old issue in Ogre: lack of a simple way of drawing 2d objects to the screen, the old way. Maybe for programming a hud, maybe for doing a small mini game inside a bigger 3d game, maybe just for using Ogre for 2d programming.
Overlays are nice, and Cegui is nice, but they aren't versatile enough if you want to program, say, a Tetris, or a Mario game. Not that Ogre doesn't allow you to program in 2d using 3d primitives: but you have to use the hardware buffers, and that's a lot of hard work.
The code snippet I present here allows you to blit sprites to screen, just as you did in the old times of DirectDraw, o even before, in the days of memory copying for Dos games.
First, the code, and then some extra information about its use (in the next post):
(CODE REMOVED to avoid code duplication in forums and wiki: go to the code snippet here: http://www.ogre3d.org/wiki/index.php?ti ... eManager2d for the last version)
Hope you like it.
Best regards!
This is a small code snippet, a small solution to an old issue in Ogre: lack of a simple way of drawing 2d objects to the screen, the old way. Maybe for programming a hud, maybe for doing a small mini game inside a bigger 3d game, maybe just for using Ogre for 2d programming.
Overlays are nice, and Cegui is nice, but they aren't versatile enough if you want to program, say, a Tetris, or a Mario game. Not that Ogre doesn't allow you to program in 2d using 3d primitives: but you have to use the hardware buffers, and that's a lot of hard work.
The code snippet I present here allows you to blit sprites to screen, just as you did in the old times of DirectDraw, o even before, in the days of memory copying for Dos games.
First, the code, and then some extra information about its use (in the next post):
(CODE REMOVED to avoid code duplication in forums and wiki: go to the code snippet here: http://www.ogre3d.org/wiki/index.php?ti ... eManager2d for the last version)
Hope you like it.
Best regards!
Last edited by hmoraldo on Mon Oct 16, 2006 3:37 pm, edited 4 times in total.
H. Hernan Moraldo
Personal website
Personal website
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
Some important stuff about this code:
- Initialize the wrapper in your setup code
- End the wrapper when you are not going to use it anymore
- Once per frame, at frame start, you can use sprite blits to draw 2d figures on the screen... actually those are buffered and, at render time, they are sent to the hardware buffers and rendered. Of course, the buffer is cleared as soon as it's rendered to the screen... don't expect sprites to be persistent as meshes are in Ogre, sprites are not! you decide what to blit to the screen every frame, and each time it can be a different amount of sprites.
- The textures you use for your sprites have to be already loaded in the ogre system to work. This is important! otherwise you'll be warned with an exception.
I think with this should be enough to start coding with the wrapper.
Best regards,
- Initialize the wrapper in your setup code
- End the wrapper when you are not going to use it anymore
- Once per frame, at frame start, you can use sprite blits to draw 2d figures on the screen... actually those are buffered and, at render time, they are sent to the hardware buffers and rendered. Of course, the buffer is cleared as soon as it's rendered to the screen... don't expect sprites to be persistent as meshes are in Ogre, sprites are not! you decide what to blit to the screen every frame, and each time it can be a different amount of sprites.
- The textures you use for your sprites have to be already loaded in the ogre system to work. This is important! otherwise you'll be warned with an exception.
I think with this should be enough to start coding with the wrapper.
Best regards,
H. Hernan Moraldo
Personal website
Personal website
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
Ok, I posted it here: http://www.ogre3d.org/wiki/index.php/SpriteManager2d
And also put some extra info there.
Thank you!
And also put some extra info there.
Thank you!
H. Hernan Moraldo
Personal website
Personal website
-
- Greenskin
- Posts: 128
- Joined: Tue Mar 22, 2005 8:18 pm
Sounds really cool!
Is there any way to modify it so that the images don't have to be previously loaded, and can come out of memory instead?
As an example, I want to render my GUI using a web framework so that the whole gui is CSS/javascript/html. I'll be rendering the gui to a bitmap in memory, and then I'd like to blit this to the screen in Ogre.
Would this be possible with your sprite manager?
Is there any way to modify it so that the images don't have to be previously loaded, and can come out of memory instead?
As an example, I want to render my GUI using a web framework so that the whole gui is CSS/javascript/html. I'll be rendering the gui to a bitmap in memory, and then I'd like to blit this to the screen in Ogre.
Would this be possible with your sprite manager?
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
Sure you can use the manager with dynamic textures. Check this: http://www.ogre3d.org/wiki/index.php/Cr ... c_textures
But are you sure you need that? why not draw your layouts directly with 2d sprites, as you would usually do when programming a 2d gui in any 2d api?
Best regards!
But are you sure you need that? why not draw your layouts directly with 2d sprites, as you would usually do when programming a 2d gui in any 2d api?
Best regards!
H. Hernan Moraldo
Personal website
Personal website
-
- Greenskin
- Posts: 128
- Joined: Tue Mar 22, 2005 8:18 pm
Thanks, I'll look into the dynamic textures.
I want to use CSS/javascript/DHTMl so that I don't have to remake the GUI. I can use a whole bunch of javascript libraries that are already out there for use in web pages.
And now, making the GUI for the game is as simple as making a webpage! In addition, flash, etc would all work right away.
Thanks!
I want to use CSS/javascript/DHTMl so that I don't have to remake the GUI. I can use a whole bunch of javascript libraries that are already out there for use in web pages.
And now, making the GUI for the game is as simple as making a webpage! In addition, flash, etc would all work right away.
Thanks!
-
- Gnoblar
- Posts: 14
- Joined: Thu Jan 12, 2006 4:42 pm
- Location: Cluj, Romania
Hi, i don't know if this is a general issue but was in my case. When displaying 2 sprites from the same texture there was a problem due to the operation type so i changed it from Ogre::RenderOperation::OT_TRIANGLE_STRIP in Ogre::RenderOperation::OT_TRIANGLE_LIST in Ogre2dManager::createHardwareBuffer method and worked ok.
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
You are right... I had corrected it in my code but forgot to do it here. Now I corrected both the code here and in the wikis.
Thank you!
Thank you!
H. Hernan Moraldo
Personal website
Personal website
-
- Halfling
- Posts: 72
- Joined: Wed Dec 06, 2006 7:35 am
When I use this to draw, it draw above the CEGUI's window. That's not what I want, can I control the render sort?
And can the Sprite render before the scene?
I know there is a param about that.
void init(Ogre::SceneManager* sceneMan, Ogre::uint8 targetQueue, bool afterQueue);
But when I change targetQueue's value to a smaller value than RENDER_QUEUE_OVERLAY, it dosn't show any thing
And can the Sprite render before the scene?
I know there is a param about that.
void init(Ogre::SceneManager* sceneMan, Ogre::uint8 targetQueue, bool afterQueue);
But when I change targetQueue's value to a smaller value than RENDER_QUEUE_OVERLAY, it dosn't show any thing
-
- Gnoblar
- Posts: 14
- Joined: Thu Jan 12, 2006 4:42 pm
- Location: Cluj, Romania
Hi, to fully control your drawing order you'll need to add a depth component to the sprite structure, pass it through the spriteBlt method and sort your sprite accordingly. That will allow you to specify the draw order for each of your sprites.
As for the overall draw order try initializing Ogre2d after CeGUI (or vice-versa, depending on your choice ) .
Hope that helps
As for the overall draw order try initializing Ogre2d after CeGUI (or vice-versa, depending on your choice ) .
Hope that helps
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
Both for cegui and for the 2d sprite manager you can decide what queue to use. If you are not using overlays, you can set both to RENDER_QUEUE_OVERLAY, and start cegui telling it to go after queue (I think it's the default behaviour), and the 2d manager with afterQueue=false.
In that case, the 2d manager will render first, then overlays, then Cegui.
If you use values different than RENDER_QUEUE_OVERLAY for the queue, I think you have first to tell ogre to create it.
Varying the initialization order wouldn't solve your problem, as it wouldn't affect the rendering order for cegui and the 2d sprite man.
Hope it helps,
In that case, the 2d manager will render first, then overlays, then Cegui.
If you use values different than RENDER_QUEUE_OVERLAY for the queue, I think you have first to tell ogre to create it.
Varying the initialization order wouldn't solve your problem, as it wouldn't affect the rendering order for cegui and the 2d sprite man.
Hope it helps,
H. Hernan Moraldo
Personal website
Personal website
-
- Halfling
- Posts: 72
- Joined: Wed Dec 06, 2006 7:35 am
-
- Halfling
- Posts: 72
- Joined: Wed Dec 06, 2006 7:35 am
I was going on my work and met new problem.
When I use Sprite2DManager to draw, I can't draw with clear pixel.
All the pixels looks unclearly. And when I use openGL RendererSystem, what is strange, it shows more clearly than D3D, but not clearly enough.
I wrote this for test:
m_ogre2dManager->spriteBltFull("test.png", -1.0, 1.0, 1.0, -1.0);
test.png is a 1024 * 768 png file, and my OgreApp start with 1024 * 768 *32bit video mode.
Could it be showed clearly just like DDraw did ?
When I use Sprite2DManager to draw, I can't draw with clear pixel.
All the pixels looks unclearly. And when I use openGL RendererSystem, what is strange, it shows more clearly than D3D, but not clearly enough.
I wrote this for test:
m_ogre2dManager->spriteBltFull("test.png", -1.0, 1.0, 1.0, -1.0);
test.png is a 1024 * 768 png file, and my OgreApp start with 1024 * 768 *32bit video mode.
Could it be showed clearly just like DDraw did ?
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
H. Hernan Moraldo
Personal website
Personal website
-
- Halfling
- Posts: 72
- Joined: Wed Dec 06, 2006 7:35 am
Thank you very much.
It helps, but it is not clear enough.
This is the source picture.
This is the OgreD3DMode screen capture.
This is my code.
RenderSystem* rs = Root::getSingleton().getRenderSystem();
Viewport* vp = rs->_getViewport();
Real hOffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
Real vOffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
m_ogre2dManager->spriteBltFull("test.png", -1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset);
It helps, but it is not clear enough.
This is the source picture.
This is the OgreD3DMode screen capture.
This is my code.
RenderSystem* rs = Root::getSingleton().getRenderSystem();
Viewport* vp = rs->_getViewport();
Real hOffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
Real vOffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
m_ogre2dManager->spriteBltFull("test.png", -1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset);
-
- Halfling
- Posts: 72
- Joined: Wed Dec 06, 2006 7:35 am
I found that when I set all TextureUnitFilter to FO_NONE, it looked clearly.
But it still isn't as clear as the source picture.
And I found that the vertical line looked good, but the horizontal line looked bad. So it must be something wrong with y axis.
Then I tried OpenGL mode, which has no TexelOffset, the result is same. So I think the problem is nothing about the texelOffset.
This is all my relative code.
void Ogre2dManager::prepareForRender()
{
...
rs->_setTextureUnitFiltering(0, Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);
...
}
Ogre::RenderSystem * rs = Root::getSingleton().getRenderSystem();
Viewport* vp = rs->_getViewport();
Real hoffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
Real voffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
m_ogre2dManager->spriteBltFull("test3.png", -1 + hoffset, 1 - voffset, 1 + hoffset, -1 - voffset);
But it still isn't as clear as the source picture.
And I found that the vertical line looked good, but the horizontal line looked bad. So it must be something wrong with y axis.
Then I tried OpenGL mode, which has no TexelOffset, the result is same. So I think the problem is nothing about the texelOffset.
This is all my relative code.
void Ogre2dManager::prepareForRender()
{
...
rs->_setTextureUnitFiltering(0, Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);
...
}
Ogre::RenderSystem * rs = Root::getSingleton().getRenderSystem();
Viewport* vp = rs->_getViewport();
Real hoffset = rs->getHorizontalTexelOffset() / (0.5 * vp->getActualWidth());
Real voffset = rs->getVerticalTexelOffset() / (0.5 * vp->getActualHeight());
m_ogre2dManager->spriteBltFull("test3.png", -1 + hoffset, 1 - voffset, 1 + hoffset, -1 - voffset);
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
It seems you found the solution here already: http://www.ogre3d.org/phpBB2/viewtopic. ... highlight= (am I right?)
H. Hernan Moraldo
Personal website
Personal website
-
- Kobold
- Posts: 37
- Joined: Tue Jun 27, 2006 8:18 pm
- Location: Canada
SpriteManager2D
is there a way to work with the sprite textures in memory? for example, set a colour in the texture to be transparent or perform enhancements to the texture such as a colour invert?
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
What you need to do if you need that, is to lock your textures and write to them. Check http://www.ogre3d.org/docs/manual/manual_57.html and check in the code snippets as there are explanations and code of how to modify your textures in real time.
H. Hernan Moraldo
Personal website
Personal website
-
- Gnoblar
- Posts: 15
- Joined: Fri Aug 11, 2006 9:43 am
Hiya,
This looks to be exactly what I need, however I am having trouble putting it to use because I am very much a newbie with Ogre. Any chance an a sample project demonstrating use?
I also have two questions regarding this. Firstly, the textures are referenced by filename when drawing. Is it not slow to pass a string as an argument to the (potentially heavily used) blit function? Could I replace it by some sort of numeric handle? Secondly I saw complaints about loss of pixel-perfect quality at non power of 2 textures. How would I automate the creation of a larger texture to fit these? I read somwhere that Ogre does this automatically and this is somehow the cause of the quality loss. This makes no sense to me; I have in a previously used engine loaded any size images onto larger power of 2 textures and drawn them at pixel perfect quality with no problems.
Thanks in advance!
This looks to be exactly what I need, however I am having trouble putting it to use because I am very much a newbie with Ogre. Any chance an a sample project demonstrating use?
I also have two questions regarding this. Firstly, the textures are referenced by filename when drawing. Is it not slow to pass a string as an argument to the (potentially heavily used) blit function? Could I replace it by some sort of numeric handle? Secondly I saw complaints about loss of pixel-perfect quality at non power of 2 textures. How would I automate the creation of a larger texture to fit these? I read somwhere that Ogre does this automatically and this is somehow the cause of the quality loss. This makes no sense to me; I have in a previously used engine loaded any size images onto larger power of 2 textures and drawn them at pixel perfect quality with no problems.
Thanks in advance!
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
Sorry I haven't a sample project for this.Eternius wrote:Any chance an a sample project demonstrating use?
I could have used references to strings (I guess I forgot to), but anyway the code later does some string copies, and other stuff like that. Anyway, it won't make a difference unless you do a real huge amount of blits per frame. I think these would be very special needs, not the case for this simple sprite manager.Eternius wrote:Firstly, the textures are referenced by filename when drawing. Is it not slow to pass a string as an argument to the (potentially heavily used) blit function?
Yes, you can use a numeric handle if you want.
First, this is only a problem if your video card (or your user's) doesn't support non-power of two textures. Second, to do this I guess you'd have to create a texture by yourself, with power of two dimensions, and do a manual initialization of its contents. But it is a lot of work for something that, otherwise, Ogre handles by itself.Eternius wrote:How would I automate the creation of a larger texture to fit these? I read somwhere that Ogre does this automatically and this is somehow the cause of the quality loss. This makes no sense to me; I have in a previously used engine loaded any size images onto larger power of 2 textures and drawn them at pixel perfect quality with no problems.
H. Hernan Moraldo
Personal website
Personal website
-
- Gnoblar
- Posts: 15
- Joined: Fri Aug 11, 2006 9:43 am
Thank you for the answers.
I'm still having no luck whatsoever putting this to use...
Edit: here's what I'm doing..
I took the framework of basic tutorial 4 on the wiki, and added the code for 2d sprite manager to the header file and cpp file, followed by original tutorial code.
Load a texture on createScene
Attempt to blit a sprite on frameStarted
Call sprite manager init code on TutorialFrameListener creation
When running it crashes. After prodding around I found that I get the same crash if I completely comment out the sprite manager init code, so I'm guessing I didn't place it where it should be?
I'm still having no luck whatsoever putting this to use...
Edit: here's what I'm doing..
I took the framework of basic tutorial 4 on the wiki, and added the code for 2d sprite manager to the header file and cpp file, followed by original tutorial code.
Load a texture on createScene
Attempt to blit a sprite on frameStarted
Call sprite manager init code on TutorialFrameListener creation
When running it crashes. After prodding around I found that I get the same crash if I completely comment out the sprite manager init code, so I'm guessing I didn't place it where it should be?
-
- OGRE Expert User
- Posts: 517
- Joined: Tue Mar 07, 2006 11:22 pm
- Location: Buenos Aires, Argentina
- x 1
-
- Gnoblar
- Posts: 15
- Joined: Fri Aug 11, 2006 9:43 am
I edited my previous post with a description of the problem.
The problematic code is here
When it runs, it crashes and breaks in list.h at
The problematic code is here
When it runs, it crashes and breaks in list.h at
Code: Select all
iterator end()
{ // return iterator for end of mutable sequence
return (iterator(_Myhead, this));
}