2d sprite manager, for Ogre

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
khamill
Gnoblar
Posts: 4
Joined: Wed May 02, 2007 2:49 am

Post by khamill »

Does anyone know why I'm getting an "Assertion Failed"
File: ogresharedptr.h
Line: 158

I have loaded all my resources. Could it be because I'm using the latest version of Ogre?
I'm getting the identical error using the sprite2d class... I'm using Ogre downloaded in Mid April 2007. A black screen comes up and this exception appears.

I've ran the example application where robot.mesh is loaded. I've tried to display droplet.png in the media/materials/textures directory and I get this error. My resource.cfg file is pointing to that directory.

My ogre log does not say loading droplet.png. Should it?

Code: Select all

Ogre2dManager* ogre2dManager=new Ogre2dManager;
	 ogre2dManager->init(mSceneManager, Ogre::RENDER_QUEUE_OVERLAY, true);

     ogre2dManager->spriteBltFull("droplet.png", 0,0,128,128);
User avatar
odyeiop
Halfling
Posts: 97
Joined: Fri Dec 22, 2006 4:56 am
Location: stoney creek

Post by odyeiop »

Try manually loading the images. Just make sure to manually unload them when the sprite manager closes.
I'm Immortal as you are Divine.
khamill
Gnoblar
Posts: 4
Joined: Wed May 02, 2007 2:49 am

Post by khamill »

I tried loading the image manually and still no luck.

At first I was having trouble doing that. I was getting filenotfound errors.
Then when I got that to work, I got the Assertion failed exception again.

When I comment out this line:

Code: Select all

ogre2dManager->spriteBltFull("droplet.png", 0,0,128,128); 
The program runs fine.

I realize that's pretty obvious, but it sort of leads to beleive it's either my video card or there is a problem with the Sprite2d class under eihort??
khamill
Gnoblar
Posts: 4
Joined: Wed May 02, 2007 2:49 am

Post by khamill »

Here is my code: Many lines are commented out, but this version gives me the exception.

Code: Select all


NT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT) 
#else 
int main(int argc, char **argv) 
#endif 
{

try 
   { 
     ////////////////////////////////////////////////////////////// 
     // Initialization of Root and RenderWindow 
     ////////////////////////////////////////////////////////////// 
     Root* mRoot = new Root("../plugins.cfg","ogre.cfg","ogre.log"); 
     if (!mRoot->restoreConfig()) 
     { 
       if (!mRoot->showConfigDialog()) 
       { 
         return 1; 
       } 
     } 
     RenderWindow* mWindow = mRoot->initialise(true,"Application"); 

     ////////////////////////////////////////////////////////////// 
     // Initialization of Scene 
     ////////////////////////////////////////////////////////////// 
     SceneManager* mSceneManager = mRoot->createSceneManager(ST_GENERIC,"sceneManager"); 
     Camera* mCamera = mSceneManager->createCamera("Camera"); 
     mCamera->setPosition(Vector3(0.0f,0.0f,500.0f)); 
     mCamera->lookAt(Vector3(0.0f,0.0f,0.0f)); 
     mCamera->setNearClipDistance(5.0f); 
     mCamera->setFarClipDistance(5000.0f); 
     //////////////////////////////////////////////////////////// 
     // Binding of Scene and RenderWindow 
     //////////////////////////////////////////////////////////// 
     Viewport* mViewport = mWindow->addViewport(mCamera); 
     mViewport->setBackgroundColour(ColourValue(100.0f,100.0f,100.0f)); 
   
     mCamera->setAspectRatio(Real(mViewport->getActualWidth()) / 
                             Real(mViewport->getActualHeight())); 

	 //ResourceGroupManager::getSingleton().addResourceLocation("FileSystem","/../media/materials/textures","General");
	 //Ogre::ResourceGroupManager::getSingleton().addResourceLocation("c:/", "FileSystem", "General"); 
	 //ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	 //Ogre::Image *img = new Ogre::Image; 

	 //img->load( "c:/droplet.png", "General" );  

	 Ogre2dManager* ogre2dManager=new Ogre2dManager;
	 ogre2dManager->init(mSceneManager, Ogre::RENDER_QUEUE_OVERLAY, true);

     ogre2dManager->spriteBltFull("droplet.png", -0.5, 0.5, 0.5, -0.5);
     ////////////////////////////////////////////////////////////// 
     // Running the main loop 
     ////////////////////////////////////////////////////////////// 
     mRoot->startRendering(); 
   
	 ogre2dManager->end();
	 delete ogre2dManager;
     delete mRoot; 
   } 
   catch (Exception& e) 
   { 
	 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif

   } 

return 0;
}
Help Needed...
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

You didn't load the image you are using. To load, you have to use a code similar to this one:

Code: Select all

Ogre::TextureManager::getSingleton().load("Image.jpg",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Please read the older posts in this thread, as many questions on how to use this code snippet have already been explained (and there is some sample code too).

Also remember you have to call the blit functions once per frame, so you'd have to put the blit code in your frame listener.

Hope that helps...

Best regards,
H. Hernan Moraldo
Personal website
khamill
Gnoblar
Posts: 4
Joined: Wed May 02, 2007 2:49 am

Post by khamill »

hmoraldo

Thankyou very much. I got it to work.

I was loading the image in previous attempts using this code:

Code: Select all


Ogre::Image *img = new Ogre::Image;
img->load( "droplet.png", "General" );  

That didn't seem to work. In the code I had above , these lines were commented out as I didn't beleive they were the cause of my problem. I used the code you added to load the image and it worked fine. I also moved the Blit call to my Framelistener.

Thank again.
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

I'm glad it worked!!

Best regards,
H. Hernan Moraldo
Personal website
dewyatt
Gnoblar
Posts: 10
Joined: Tue Feb 13, 2007 1:46 pm

Post by dewyatt »

Stupid question, sorry :oops: ...how could I use spriteBltFull like a 'normal' 2D function?
I mean passing in 2 pixel coordinates as parameters, like this:

Code: Select all

spriteBltFull("Image.png", 400, 300)
My guess is that i'd have to convert pixel coords to rel coords, flip the Y,
and maybe change the coords so it's drawn down-right from the specified coords (instead of centered or something).
Is that right at all?
And is it possible to retain the correct aspect ratio of the image?
Could somebody provide an example maybe? All my attempts have failed :(
DragonXVI
Gnoblar
Posts: 10
Joined: Fri Jun 08, 2007 3:33 pm

Post by DragonXVI »

Hi, firstly this thing sounds ideal for the project I'm working on, since CEGUI and what not seemed more based on creating windowed gui, what I need are 2D Sprites that can be moved around the screen space.

However, I'm having a similar problem in that when running with the code, in that Ogre'll run, but as soon as it starts rendering it'll crash.

I'm using Ogre 1.4 and currently the project's loosely based on the tutorial projects (What with the robots and ninjas and such like)

I've got Ogre2d-main.h and Ogre2d-main.cpp, but when the lines

Code: Select all

Ogre2dManager *ogre2dManager=new Ogre2dManager;
ogre2dManager->init(mSceneMgr, Ogre::RENDER_QUEUE_OVERLAY, true);
are added to the framelistener constructor, that causes the crash. When they're commented out, it'll run...

Code: Select all

Ogre2dManager *ogre2dManager;
is also in the framelistener as a public member[/code]
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

dewyatt wrote:Stupid question, sorry :oops: ...how could I use spriteBltFull like a 'normal' 2D function?
I mean passing in 2 pixel coordinates as parameters, like this:

Code: Select all

spriteBltFull("Image.png", 400, 300)
My guess is that i'd have to convert pixel coords to rel coords, flip the Y,
and maybe change the coords so it's drawn down-right from the specified coords (instead of centered or something).
Is that right at all?
And is it possible to retain the correct aspect ratio of the image?
Could somebody provide an example maybe? All my attempts have failed :(
You can use getActualWidth() and getActualHeight() in the viewport to get the screen size. To get the texture size, you use getWidth() and getHeight() on the texture. And that's it.

Sorry for the late reply, and didn't have the time to write sample code for this now... check this related thread (http://www.ogre3d.org/phpBB2/viewtopic. ... sc&start=0) of another code snippet I coded, where solving a similar problem is needed (look at posts asking for how to make the video run full screen).
H. Hernan Moraldo
Personal website
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

DragonXVI wrote:However, I'm having a similar problem in that when running with the code, in that Ogre'll run, but as soon as it starts rendering it'll crash.is also in the framelistener as a public member
Could you give me more details of how it crashes? Could you debug, step line by line and tell me which line in the class makes the program crash?

That would make diagnose a lot easier...

Sorry for the late reply...
H. Hernan Moraldo
Personal website
DragonXVI
Gnoblar
Posts: 10
Joined: Fri Jun 08, 2007 3:33 pm

Post by DragonXVI »

Fixed the problem, think it was something to do with the project structure. Used the blank ogre example (Tutorial 0) files and everything's working. Thus far it's working excellently :D
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

murderv wrote:moraldo, i have just noticed you can feed texture coordinates to the method parameters.. so i should just make a animatedSprite class around this and based on some speed draw different parts of the texture.. would that be the correct way to do it?
Yes, you can just make animated sprites by feeding the sprite manager with different textures or different parts of a texture so that to the user, a different image is shown at every instant. Also you can displace the sprites by changing their destination coordinates.

All you see in sprite based games, you can do by using this kind of methods. It basically depends on your ingenuity.
murderv wrote:another question i have is what about raycasting.. how could i pick any sprite and drag it around the screen?
Well, the sprite manager isn't prepared for that directly. You can program that by checking what sprite is below the cursor, always checking the cursor isn't pointing to a transparent pixel of course.
murderv wrote:ive noticed you use relative coordinate system (0,0) is center of the screen.. shouldnt be hard to chagne that to put (0,0) as top-left corner.
Not at all, that would be easy, as that kind of change of coordinates only requires using an addition over the coordinate components (x+somevalue, y+somevalue). Sorry I have no time now to send you a patch, but it would be actually easy to implement.
murderv wrote:one other question moraldo, what about using materials instead of textures? or even use manualobjects? any advantages over this one ?
It's just using textures for simplicity and efficiency.
murderv wrote:what about colorkey masking or transparency? whats the best way to handle it for sprites?
Use pngs with transparency channel, Ogre will take care by itself (they will be loaded as sprites with transparency automatically)

I'll copy this to the sprite manager thread...

Best regards!
H. Hernan Moraldo
Personal website
lmas19820607
Halfling
Posts: 72
Joined: Wed Dec 06, 2006 7:35 am

Post by lmas19820607 »

could I use this spriteManager to draw 2D object with depth test?
I need draw some 2D object in same scene together with 3D mesh.

I modified the code, use rs->_setDepthBufferParams(true, true); to open depth test.
But when I change the z value of sprite, it only show sprites when z value between -1.0f and 0.0f. If z value goes outside the range, the sprite can't be showen.

Can I use this spriteManager instead of Billboard or something, it mean's a lot to me!
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hmoraldo,

i have been using the spritemanager code for an application and i have noticed that it eats alot of memory when i implemented the WindowsEventListener to be able to ALT-TAB between windows..

once it loses focus, the memory usage starts increasing depending on the number of sprites i am rendering.. it went up to 600MB..

most of the time i just cant get back to the application..

ive checked the creating of vertexbuffer and its usage methods.. but still no luck..

even if modified code, the core of the render is the same as yours..

do you have any idea why this could be ?

thanks in advance
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

lmas19820607: you should be able to do that; sadly these days I'm not having much time as to program and post a patch here, but it shouldn't be hard to program.

murderv: could you test that in your computer, with a program consisting only of the 2d sprite manager? can you test that with the latest version in the wiki?
H. Hernan Moraldo
Personal website
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hmoraldo,

yes it happens the same with the sprite manager i just took from wiki.
if that latest version? looks to me its the same..

i just loaded one texture, but still it increments memory usage, by a small amount but thats because i only loaded that one texture..

you have any idea what it could be ?
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

lmas, check this piece of the code:

rs->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
rs->_setViewMatrix(Ogre::Matrix4::IDENTITY);
rs->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);
rs->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY);


you should use same projection/view/world matrix from your world..
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

Yes, there were some previous versions to this one, that also were posted in the same page (check the history), for bug fixes and other stuff.

Please do another test: try compiling an Ogre project with only the sprite manager to be sure that's where the leak is coming from.

If the problem is still there, we could be having two different problems:

1) with the hardware buffer. If that was the case, we could test by checking whether the problem happens when there are increases in the number in sprites in use, but never when there are no increases (as those increases are the only ones that make the system create new hardware buffers).

Ie, check if the problem appears when you make the program consistently render on screen only 1000 sprites, but no more or less than that.

(Also it could be the case that you are initializing and ending more than once the entire system in the entire life of the program, but I suspect it's not the case. Am I right?)

2) with the sprites buffer. If the 1st test fails, we should check there isn't a leak with the sprites buffer. We are using clear() for the sprites buffer, and if that is producing a leak, I would infer that's a problem in the stl library you are using to compile. Or maybe we are doing something wrong when managing the list, we should check.

By the way... if there was a leak of objects created within the program (but not in the libraries), the debug version of your program should tell you by the leaks file. Please check that too.

Best regards,
H. Hernan Moraldo
Personal website
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hmoraldo,

i have tested with celShading sample and the memory increase still happens. with only one spriteblt call. the memory increase was small but it happened..

im my application i render tens of sprites so the leak is alot bigger and faster, and i do render a fixed number of sprites all times.. i did not increase the number of sprites to render and still the leak is there.

i am initializing/deleting the sprite manager once in the life of the application. its not the case, yes.

i also thought it could be the clear() but i do not suspect thats is the case.. i use STL vector and list alot in the program and it only happens when i enable the sprite render calls ?

i will try the memory leak code and see what i can get, still its pretty weird it only happens when we change window focus, no ?

ill keep in touch.. so far no luck here..
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hi again,

i have used the visual studio debug but it gives me alot of crap. i think he thinks its ogre's leaks...

on the other hand i used Paul Nettle's memory manager and it tells me i have no memory leaks at all!

im not sure what to think could be causing the mem usage increase and why it only happens when i use the sprite manager..


[EDIT]

here is some information of the renderBuffer method i logged.


17:37:02: inrender=18 <----- number of verts per frame
17:37:02: windowFocusChange <----- i pressed ALT-TAB
<----- while out of focus
17:37:03: windowFocusChange <----- back on the app window
17:37:03: inrender=9576 <------ ????? this might be the reason it takes ages to get back on track and eats lot of memory


this is logged here:

currChunk = chunks.begin();
endChunk = chunks.end();
renderOp.vertexData->vertexStart = 0;
vertexCount = 0;
for( ; currChunk!=endChunk; currChunk++ )
{
(...)
// render!
renderSystem->_render( renderOp );

vertexCount += currChunk->vertexCount;
}
Ogre::LogManager::getSingleton().logMessage( "inrender=" + Ogre::StringConverter::toString(vertexCount) );
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

It would seem as if "std::list<VertexChunk> chunks;" wasn't being a new list in every method call... but why, if it's local to the method? Or maybe it's being filled with wrong data at some time... or maybe it's a problem with the "sprites" variable.

Can you check the contents of chunks? How many chunks are there? Which chunks have many more vertex than desired? (or there are just too much chunks?)

And also, does the amount of chunks increase with every alt tab? Do the amount of sprites in "sprites" increase too, or does it keep constant?

Sorry I'm not in a production machine these days and have no time to do the debug myself, but if I can help...
H. Hernan Moraldo
Personal website
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hmoraldo,

its not the chunks list problem.. since its a local it works just fine..
the problem comes from the sprites list.. that is the one that grows infinetely when out of focus..

i solved the problem by doing a clear in frameStarted()

just added a new method to the manager

void Begin()
{
sprites.clear();
}


and in your mainloop call it before any sprite render call..
it worked.. but there might be a better solution for this..
ill see what i can do.. meanwhile if you have any better idea, let me know..
User avatar
hmoraldo
OGRE Expert User
OGRE Expert User
Posts: 517
Joined: Tue Mar 07, 2006 11:22 pm
Location: Buenos Aires, Argentina
x 1

Post by hmoraldo »

murderv wrote:its not the chunks list problem.. since its a local it works just fine..
Sure, but since the code was looking fine, I was starting to check at some out of the box ideas. Maybe for some reason STL was creating a new object with old data? or there was corrupted data of some kind in the memory, etc...

Can you test putting the sprites.clear(); in other places in the code? renderQueueStarted would be a good place to test.

Did anybody else find this kind of results in their use of the manager?

I'll be traveling next week, when I'm back I'll try to compile this again and see if it's happening in my builds too, and in such a case, I'll debug it too.
H. Hernan Moraldo
Personal website
murderv
Greenskin
Posts: 105
Joined: Tue Jun 26, 2007 12:20 pm

Post by murderv »

hi,

i have another question about spritemanager which i could solve so far..

im having troubles in alpha blending when i use directx rendersystem..

this is the result picture:

http://img137.imageshack.us/my.php?imag ... ingmu3.jpg

i am just using the same blend modes spritemanager uses, passing the alpha value for each chunk..


blend/alpha mode im using before rendering the primitives

colorBlendMode.blendType = Ogre::LBT_COLOUR;
colorBlendMode.source1 = Ogre::LBS_TEXTURE;
colorBlendMode.source2 = Ogre::LBS_DIFFUSE;
colorBlendMode.operation = Ogre::LBX_SOURCE1;

for( all sprites )
{
alphaBlendMode.blendType = Ogre::LBT_ALPHA;
alphaBlendMode.source1 = Ogre::LBS_TEXTURE;
alphaBlendMode.operation = Ogre::LBX_BLEND_MANUAL;
alphaBlendMode.factor = chunk->alpha;
renderSystem->_setTextureBlendMode( 0, alphaBlendMode );
}

any ideas here?
thanks in advance