[solved] Expansive, dense forests

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Lord LoriK
Goblin
Posts: 254
Joined: Tue Feb 13, 2007 5:33 am

Post by Lord LoriK »

I don't see how case one can take place, because Root::_fireFrameStarted() always removes the listeners before calling frameStarted() events, and the same thing goes for Root::_fireFrameEnded(). Putting breakpoints in the frameStarted() showed nothing after I removed the listeners. I tested three different cases with equal results: one with the example framework, and the others with custom initialization. All of them had leaks with your code, and none had them without it, but I always updated everything before _fireFrameStarted(), so that could be the difference.

Maybe you are updating your paged geometry between _fireFrameStarted() and _fireFrameEnded(), and thats why you get errors? I'm not trying to be offensive, but have you checked that the "delete this" lines run? I did and I never got them to run even once.
User avatar
syedhs
Silver Sponsor
Silver Sponsor
Posts: 2703
Joined: Mon Aug 29, 2005 3:24 pm
Location: Kuala Lumpur, Malaysia
x 51

Post by syedhs »

Root::_fireFrameStarted is the code block where it really removes the framelistener, and then iterate thru each of the framelistener. So you can see, there are two processes here:-
1) remove the framelistener which has been requested to be removed
2) and then iterating thru each of the framelistener, run frameStarted.

So when you ask a framelistener to be removed, this is going to be run within another framelistener which is usually the main framelistener. So here, the code already executes the process (1), and in the midst of process (2). I can verify this from a copy-paste code from OgreRoot.cpp ( I remove some lines make it a bit shorter)

Code: Select all

    bool Root::_fireFrameStarted(FrameEvent& evt)
    {
        // Remove all marked listeners (MY COMMENT: PROCESS 1)
        std::set<FrameListener*>::iterator i;
        for (i = mRemovedFrameListeners.begin();
            i != mRemovedFrameListeners.end(); i++)
        {
            mFrameListeners.erase(*i);
        }
        mRemovedFrameListeners.clear();

        // Tell all listeners (MY COMMENT: PROCESS 2)
        for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
        {
            if (!(*i)->frameStarted(evt))
                return false;
        }
    }
So when a framelistener is removed from another framelistener and then deleted from memory, it may or may not trigger crash because by that time it has already in process (2). The crash will happen if the deleted framelistener is already deleted and not executed yet. But in some other cases where you get lucky (due to the non-guarantee framelistener execution execution order), the main listener is executed after the supposedly deleted frame listener.. so there is no crash and the framelistener is deleted succesfully.

So the line 'delete this' may or may not executed depending on your luck (you are either in case 1 or case 2)
Lord LoriK wrote:I'm not trying to be offensive, but have you checked that the "delete this" lines run? I did and I never got them to run even once.
Maybe yours never get executed, but from the logic here it may/may not get executed.

Edit: You know what, both of the 'delete this' got executed when I exit the scene.
Lord LoriK
Goblin
Posts: 254
Joined: Tue Feb 13, 2007 5:33 am

Post by Lord LoriK »

syedhs wrote:You know what, both of the 'delete this' got executed when I exit the scene.
Ok, fine. I never delete a frame listener from within another listener. I think the right way to solve it might be a "finalize()" method for the paged geometry to clean up before deleting it.
Lshink
Halfling
Posts: 69
Joined: Sun Mar 05, 2006 6:08 pm

Post by Lshink »

Sorry to de-rail the current topic at hand here but does anyone know how to use just one page loader to load two different settings such as batchpage and imposterpage?

For example, I use paged geometry for both grass and trees. However I always want the grass to be a billboard and tree to go from billboard/mesh. Currently I have to use two page loaders, each with their proper settings. One for the grass and one for the trees. Is there any easy way to use to one page loader for both of these?
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

For example, I use paged geometry for both grass and trees. However I always want the grass to be a billboard and tree to go from billboard/mesh. Currently I have to use two page loaders, each with their proper settings. One for the grass and one for the trees. Is there any easy way to use to one page loader for both of these?
For this purpose, it's best to use two PagedGeometry objects with a PageLoader each.

One PagedGeometry object loads the trees, and another loads the grass. This way you can even specify different viewing ranges. For example, you might want trees visible up to 1000 units, and grass up to 200 units.

I could allow PagedGeometry to accept multiple PageLoaders and viewing ranges, but that would only make things more confusing. And even if I did, it wouldn't be any faster.

P.S. Although the impostor system will work for grass, it would work best (most efficient) if you used BatchPage with your own grass mesh generated like in the Ogre grass demo. Then you can apply a vertex shader of your own to the geometry and make the grass wave in the breeze, or whatever you want.
Lshink
Halfling
Posts: 69
Joined: Sun Mar 05, 2006 6:08 pm

Post by Lshink »

JohnJ:

Thanks for the information. Thats how I have it setup at the moment, with two pageloaders. I thought having one would increase my performance, but as you stated it wouldn't. I'll just stick with what I have :)
User avatar
syedhs
Silver Sponsor
Silver Sponsor
Posts: 2703
Joined: Mon Aug 29, 2005 3:24 pm
Location: Kuala Lumpur, Malaysia
x 51

Post by syedhs »

Hmm it is a bit strange but good news anyway. Updating to the latest forest source code does solve the problem of me using shader-based Billboard. No more crash after a few seconds of running.
Dale_ee
Gnoblar
Posts: 5
Joined: Wed Mar 21, 2007 6:59 pm

Post by Dale_ee »

This thing is really awesome, I like it very much.
There are some problems I experience with it. Main is - all entities that are rendered to imposters do not have lighting on them. It looks like that:

Image

Closer ones are rendered correctly, and those far away are overbrightened, because lighting doesn't affect them.
What can I do to fix this problem?[/img]
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

PagedGeometry doesn't specifically disable lighting when rendering, so it's probably to do with when your lights are set up. Impostors are rendered when you first add the object, and if you're lights aren't set up by then, Ogre may have to default to full-bright lighting. To fix this, try setting up all your lights before you set-up the PagedGeometry.

P.S. And remember that the impostor prerenders won't be updated unless you go into your executable folder and delete the "Impostor.___.___.mesh.png" files.
Dale_ee
Gnoblar
Posts: 5
Joined: Wed Mar 21, 2007 6:59 pm

Post by Dale_ee »

I tried to start PagedGeometry on hotkey after scene loading, but got the same result... Lights were definetely present by the time I pressed that button.
User avatar
sjcomp
Gnome
Posts: 315
Joined: Sat Apr 23, 2005 2:35 pm
Location: Dover, NH

Post by sjcomp »

Can you check the actual textures generated for imposters and see how they look like. They are located at the same directory with the executable after you run the program. If these textures have very bright trees, than it's a problem with generation of the trees. If they look normal, than it is most probably the problem is more on your side of the code.
Regards, Alexander. http://sjcomp.com
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

I don't know, the impostor system should render the billboards exactly as your objects appear (so it's not the "user's" fault). The only thing I can think of that would cause an inconsistency is the problem I mentioned above (changing lighting) - otherwise it may be a bug.

Dale_ee:
Are you still getting the problem after deleting the textures also? Also maybe try using the included example as a template and insert your tree model to make sure it's not a problem with your code. This may be a bug in PagedGeometry, although I can't figure why. Hopefully we can track this down quickly.
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3

Post by Praetor »

Is there a way to provide a mechanism to manually force an update to the imposters? That way if it is absolutely necessary a programmer can force an update.
User avatar
syedhs
Silver Sponsor
Silver Sponsor
Posts: 2703
Joined: Mon Aug 29, 2005 3:24 pm
Location: Kuala Lumpur, Malaysia
x 51

Post by syedhs »

I think it is not a bug. Try turning the lighting off in the trees' materials and they will end up rendered with the same tint of green (instead of darker trees). It is definitely lighting.
Dale_ee
Gnoblar
Posts: 5
Joined: Wed Mar 21, 2007 6:59 pm

Post by Dale_ee »

Ok, that was my bad.
When I performed second test, I forgot to delete old impostor textures, so technically I couldn't see any effect of creating PagedGeometry "later in scene". Problem was I had something like this:

loadScene();
generateTrees();

Which is unacceptable somehow. I think lighting is not yet properly set until the end of the frame.

Now it works perfectly, thanks for rapid advices.
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

Dale_ee: It's good to hear you got it working :)

Praetor: Not currently, but I'll try to add this in the next release.
Rowan
Gnoblar
Posts: 14
Joined: Tue Apr 18, 2006 5:39 am
Location: Australia

Post by Rowan »

Hi, firstly great job with this engine, thanks.

My question concerns setting queryFlags for the different objects created by the engine. I didn't notice any previous posts regarding this ( unless I missed them), so maybe I am missing something obvious.

Being more or less an Ogre beginner, I eventually managed to locate the object creation routines for each of the pagetypes you supplied and add the required 'setQueryFlags( )' for the entities & regions. This works fine for me, but I am wondering if there is a proper mechanism for this, or is it something intentionally left for the user ( as in user-created pagetypes )?
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

setQueryFlags() is currently not a built-in feature of PagedGeometry, so you're correct that you should add it yourself. I could add an interface through GeometryPage and GeometryPageManager to manage query flags, but I'm not sure it's appropriate, since the GeometryPage is abstracted beyond the entity/queryflag level (for example, trees could possibly be represented by a single large volumetric texture for all you know, so camera picking isn't guaranteed).


BTW, I've been thinking about detail level transitions, and it seems that there are two major methods I can use to do it:

One method is to implement the fading in a vertex shader which is applied to the impostors/entities/staticgeometry. Unfortunately, this technique means that to automate the process, you must replace any vertex shaders the user is using (like a grass/leaf breeze effect) with your own, or "tell" the user to implement the fade themselves. Another drawback is that this technique is not compatible with pure fixed function video cards, so a fall-back technique needs to be implemented as well. Probably the only advantage to this method is that it can look the best.

The other technique is to use the CPU to manage fade transitions of geometry pages. This is much more flexible and compatible, but I'm afraid it will slow things down. Since Ogre's rendering engine is based around materials, you can't change a material value (like alpha) on a per-entity basis; you have to tediously clone and manage materials to simulate per-entity alpha. However, this technique allows finer control over the fading, so the double-drawing (drawing both detail levels at the same time during a transition) can be reduced.

So far I'm planning on implementing method #2. It's the most compatible, easy to use (no shader conflicts), flexible, and possibly the most efficient for the GPU (though I haven't tested this). The only difficulty so far is that it seems you need to create a special material manager in order to achieve per-entity alpha, unfortunately. If anyone knows a way around this that I haven't read about (besides the current method ;) ), please let me know :) Otherwise, I'll try to get transitions working soon.
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

Unfortunately, it looks like smooth alpha transitions between static geometry and other detail levels will be impossible in the current implementation, since Ogre doesn't seem to allow material control on StaticGeometry objects (unless you re-build the entire batch). There may be another way to do this that I'm missing, but so far it looks like I'll have to write my own version of StaticGeometry to properly support fading transitions.
User avatar
SpannerMan
Gold Sponsor
Gold Sponsor
Posts: 446
Joined: Fri May 02, 2003 10:05 am
Location: UK

Post by SpannerMan »

JohnJ wrote:...but so far it looks like I'll have to write my own version of StaticGeometry to properly support fading transitions.
That seems a shame - wouldnt it be possible to instead mod Ogre's version (if possible) and just submit a patch?
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

That seems a shame - wouldnt it be possible to instead mod Ogre's version (if possible) and just submit a patch?
Modifying Ogre to allow per-renderable alpha would definitely be the best solution, but unfortunately this would make PagedGeometry impossible for most people to use unless the modifications get accepted into Ogre officially (since most users probably just download the SDK, like me).
User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
x 4

Post by Falagard »

Writing your own version of static geometry isn't much trouble since static geometry is a simple renderable and not tied deeply into Ogre. I've created my own version of static geometry to support loading building the static geometry over multiple frames to avoid hiccuping in the frame rate and it wasn't hard - just copied Ogre's implementation into new .h and .cpp files and modified where I needed.
User avatar
JohnJ
OGRE Expert User
OGRE Expert User
Posts: 975
Joined: Thu Aug 04, 2005 4:14 am
Location: Santa Clara, California
x 4

Post by JohnJ »

I know that I can write my own static geometry, but optimally I would add a per-entity alpha feature to Ogre (but then it wouldn't work with other people).
I've created my own version of static geometry to support loading building the static geometry over multiple frames to avoid hiccuping in the frame rate
Are you building a single mesh over multiple frames? If so, I didn't even know that was possible :) PagedGeometry could really benefit from something like this, because you could use much larger page sizes without stuttering frame rates (better batching).
Shadow007
Gremlin
Posts: 185
Joined: Sat May 07, 2005 3:27 pm

Why don't U submit the patch ?

Post by Shadow007 »

I know it would be more work, but would'nt it be possible to both submit a patch, and, in case it is not merged / waiting for it to be merged, writing your own implementation... so that when the patch is integrated, you delete your AlphaTransitionedSTaticGemoetry and switch to the then official StaticGeometry (with Alpha enabled)
User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
x 4

Post by Falagard »

I know that I can write my own static geometry, but optimally I would add a per-entity alpha feature to Ogre (but then it wouldn't work with other people).
Not sure exactly what you're trying to do here.

You're trying to use alpha to transition between two different states, like StaticGeometry to Impostors or something?

You probably don't need to set per entity alpha. You can use a vertex shader to modify the alpha based on distance, for example I know this doesn't work in fixed function, but nowadays who cares? Even if you did care, your StaticGeometry is a merged set of entities, you'd need to break it back up into separate entities to be able to modify alpha per entity.

If you wanted to change the material on Ogre's built in StaticGeometry you could by iterating through Regions, LODBuckets, MaterialBuckets, until you get to GeometryBuckets, and then call setMaterial, so if you wanted to for example, you could clone the existing material and then set the material to the clone and modify it's alpha. Doesn't make sense because it modifies the alpha in the entire StaticGeometry, but it's possible.

Also, there is already some code in the wiki for per renderable alpha here:
http://www.ogre3d.org/wiki/index.php/Pe ... ansparency
I don't believe Ogre needs to be modified at all.
Are you building a single mesh over multiple frames? If so, I didn't even know that was possible Smile PagedGeometry could really benefit from something like this, because you could use much larger page sizes without stuttering frame rates (better batching).
Yeah, I lock the vertex and index buffers once, then over multiple frames fill them, then unlock them once finished. To be honest, I don't know if this will cause problems sometimes but so far I haven't had any issues. With Ogre's new support for loading resources in a background thread I've been pondering how to do the whole thing in a background thread instead. For example, I could create a new resource called StaticGeometryResource and find a way to pass the resource the list of meshes and their locations and have it build the geometry on a background thread while loading. As far as I know Ogre supports creating SceneNodes and everything in the background thread now, so it should work.