Page 1 of 1

Remove frame number magic

Posted: Sat Nov 21, 2009 11:30 am
by yeahRIGHT
Hi everyone,

I recently had some problems getting animations working, using the latest release 1.6.4. After several days, I found out that the OGRE entities perform an internal optimization:

Code: Select all

    void Entity::cacheBoneMatrices(void)
    {
        Root& root = Root::getSingleton();
        unsigned long currentFrameNumber = root.getNextFrameNumber();
        if (*mFrameBonesLastUpdated  != currentFrameNumber) {        // this nice little check here

            mSkeletonInstance->setAnimationState(*mAnimationState);
            mSkeletonInstance->_getBoneMatrices(mBoneMatrices);
            *mFrameBonesLastUpdated  = currentFrameNumber;
        }
    }
The cause of my problem was that the frame number was never increased, because it is only increased in Root::_fireFrameRenderingQueued(FrameEvent& evt). This event is only automatically raised when one chooses to update all render targets at once (Root::_updateAllRenderTargets(void)).


I'm using deferred shading and I think I have valid reasons to update my render targets one at a time. I disable some stuff (for example GUI update callbacks) while updating some render targets. There are certainly other valid reasons, for example, one might not want to update all render targets during a frame at all (a minimap, for example).

After I looked specifically for this problem, I noticed that once can fire the frame events manually. So there is a way to deal with this, but is it really a necessary burden? IMHO, this optimization is non-obvious, nearly non-documented and the benefit is unclear to me (why would OGRE update the animation too often anyway?). I suggest to remove it and to check for other such things as well, outside of the animation code.

Of couse, it is possible that I'm overlooking something. I just wonder whether OGRE could be made easier to use here...

Re: Remove frame number magic

Posted: Sat Nov 21, 2009 11:35 am
by yeahRIGHT
I just saw that the documentation is actually lying. :)

Code: Select all

        /** Method for raising frame rendering queued events. 
        @remarks
            This method is only for internal use when you use OGRE's inbuilt rendering
            loop (Root::startRendering). However, if you run your own rendering loop then
            you you may want to call this method too, although nothing in OGRE relies on this
			particular event. Really if you're running your own rendering loop at
			this level of detail then you can get the same effect as doing your
			updates in a frameRenderingQueued callback by just calling 
			RenderWindow::update with the 'swapBuffers' option set to false. 
        */
        bool _fireFrameRenderingQueued();
The animation system definitely relies on this event, because it relies on the frame number being increased.

Re: Remove frame number magic

Posted: Sat Nov 21, 2009 6:44 pm
by sinbad
yeahRIGHT wrote: The cause of my problem was that the frame number was never increased, because it is only increased in Root::_fireFrameRenderingQueued(FrameEvent& evt). This event is only automatically raised when one chooses to update all render targets at once (Root::_updateAllRenderTargets(void)).
We always tell people that if you run your own update loop that you must call all the Root::_fireFrame* methods, we even included _fireFrameRenderingQueued specifically in the upgrade notes for 1.6.

The API entry there is wrong though, that must have been missed.

Re: Remove frame number magic

Posted: Sat Nov 21, 2009 6:46 pm
by sinbad
Nope, you must just have a very old version. API says in my version:
This method is only for internal use when you use OGRE's inbuilt rendering
loop (Root::startRendering). However, if you run your own rendering loop then
you should call this method too, to ensure that all state is updated
correctly
. You should call it after the windows have been updated
but before the buffers are swapped, or if you are not separating the
update and buffer swap, then after the update just before _fireFrameEnded.
I haven't altered that in a while so I suspect your version is pretty darned old.

Re: Remove frame number magic

Posted: Sat Nov 21, 2009 9:16 pm
by yeahRIGHT
I see it's different for _fireFrameRenderingQueued() and _fireFrameRenderingQueued(FrameEvent& evt). The former has the wrong description.

Re: Remove frame number magic

Posted: Tue Dec 22, 2009 12:16 pm
by mondeva2008
Thanks for this post yeahRIGHT! I have been 3 days fighting with this problem and now I've been able to solve it by simply calling the _fireFrameRenderingQueued() request. Thank you very much!