Axiom -

3 views
Skip to first unread message

andris

unread,
Feb 6, 2006, 1:54:01 PM2/6/06
to RealmForge GDK
Hello there,

I post with a litle hope in mind:
when Axiom (dev. branch) is rendering, the application must stay active
in order to function. Whenever you switch to another app, regardless if
fullscreen or windowed, the engine fails and application terminates.
Does it the same to you?

I posted about this to sourceforge's Axiom bug list already and was not
the only one, but am writing here also with hope something could be
done with this, because I'm unable to debug nearly anything after
rendering has been started!!!

When enter debug mode, I'm able to debug some while until around next
RenderOneFrame() is called (inside Root.StartRendering() method).
Stepping into and tracking a bit deeper I get to:

class: FrameTimeControllerValue

private void RenderSystem_FrameStarted( object source,
FrameEventArgs e )
{
// apply the time factor to the time since last frame and
save it
frameTime = timeFactor * e.TimeSinceLastFrame;

} ***


*** = When I'm here an exception with message 'Error in the
application' is always raised. Yes happens when I'm at the enclosing
bracket...


I'm using Axiom DirectX9 Render System for rendering, didn't try OpenGL
as there isn't such choice in Axiom's video mode setup dialog.


Any ideas what's happening and how to correct it?
Thanks

Terry L. Triplett

unread,
Feb 6, 2006, 2:25:08 PM2/6/06
to realm...@googlegroups.com
Can't address your problem directly (am recovering from Super Bowl
Sunday, and don't have an answer anyway). As to your comment below,
however ...

The OpenGL rendersystem assembly isn't one of the dependencies of the
demos on Windows (though I think I changed that in either the NAnt files
or the DNPB files in a recent commit). That's why it doesn't show up in
the setup dialog. If you place it in the demos runtime directory, it
will show up as an option.

Michael Cummings

unread,
Feb 6, 2006, 2:28:05 PM2/6/06
to realm...@googlegroups.com
I am thinking that the problem is most likely related to a DX9 issue in which the render device is being lost and not recovered properly. I recently saw a commit from the OGRE team that addresses a similar issue.

JW Sullivan

unread,
Feb 6, 2006, 4:08:02 PM2/6/06
to realm...@googlegroups.com
I've been getting this problem as well while testing the CEGUI# code.  When the app dissapears, it was the input device that was getting lost and not restored.  It could also be the rendering device as Michael pointed out, but the exception I was getting was for the lost input device.  I have not attempted to look into this any further as that is not my current focus (although it will need to get fixed to make debugging some code easier).
 
J.W.
 

andris

unread,
Feb 6, 2006, 7:42:45 PM2/6/06
to RealmForge GDK
Oh why didn't I right away:

Stack trace:

at Microsoft.DirectX.DirectInput.Device.get_CurrentMouseState()

** and further **

at Axiom.Platforms.Win32.Win32InputReader.CaptureImmediateMouse() in
E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 541
at Axiom.Platforms.Win32.Win32InputReader.CaptureMouse() in
E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 523
at Axiom.Platforms.Win32.Win32InputReader.Capture() in
E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 242
at WindowsApplication1.AxiomGame.OnFrameStarted(Object source,
FrameEventArgs e) in
E:\Dev\Prj\Jets\A\WindowsApplication1\AxiomGame.cs:line 308
at Axiom.FrameEvent.Invoke(Object source, FrameEventArgs e)
at Axiom.Root.OnFrameStarted(FrameEventArgs e) in
E:\Dev\Prj\Jets\Axiom\Engine\Core\Root.cs:line 885
at Axiom.Root.OnFrameStarted() in
E:\Dev\Prj\Jets\Axiom\Engine\Core\Root.cs:line 827
at Axiom.Root.RenderOneFrame() in
E:\Dev\Prj\Jets\Axiom\Engine\Core\Root.cs:line 534
at Axiom.Root.StartRendering() in
E:\Dev\Prj\Jets\Axiom\Engine\Core\Root.cs:line 569
at WindowsApplication1.AxiomGame.Start(RenderWindow win) in
E:\Dev\Prj\Jets\A\WindowsApplication1\AxiomGame.cs:line 267


But seeing from the side of debugging the source, the exception is
invoked at the enclosing bracket of such primitive function - see first
post.

Why? There must be threading involved..? Actually I don't see where
input capturing would be running separately from the StartRendering
loop.

But rendering itself still runs in separate thread, doesn't it?
Any ideas already what can be conflicting?

JW Sullivan

unread,
Feb 6, 2006, 8:18:00 PM2/6/06
to realm...@googlegroups.com
Axiom isn't inherently multithreaded, so unless you have created a multithreaded application, then this is not a threading issue.  In my case, while debugging, the input device is acquired in exclusive mode.  When a breakpoint is hit, then the input device is lost.  Then when program execution continues the exception gets thrown because the device is not re-acquired.
 
It is probably a similar situation with the alt-tab scenario.  When I get a chance I'll try and debug the situation I run into to see if there I can find a solution, which might be able to help you.
 
J.W.
 
On 2/6/06, andris <and...@seznam.cz> wrote:

Oh why didn't I right away:

Stack trace:

  at Microsoft.DirectX.DirectInput.Device.get_CurrentMouseState ()

** and further **

  at Axiom.Platforms.Win32.Win32InputReader.CaptureImmediateMouse() in
E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 541
  at Axiom.Platforms.Win32.Win32InputReader.CaptureMouse () in

E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 523
  at Axiom.Platforms.Win32.Win32InputReader.Capture() in
E:\Dev\Prj\Jets\Axiom\Platforms\Win32\Win32InputReader.cs:line 242
  at WindowsApplication1.AxiomGame.OnFrameStarted (Object source,

JW Sullivan

unread,
Feb 7, 2006, 2:02:31 AM2/7/06
to realm...@googlegroups.com
Well, I believe that I have a solution.  You are recieving the error in the Axiom.Platforms.Win32.Win32InputReader.CaptureImmediateMouse() funcion on the following line:

mouseState = mouseDevice.CurrentMouseState;

The exception that is getting thrown is an InputLostException, which is due to the mouse device getting lost when alt-tabbing.  If you replace this line of code with the following code, then your application will no longer generate this exception and terminate abruptly:

            try
            {
                // capture the current mouse state
                mouseState = mouseDevice.CurrentMouseState;
            }
            catch (Exception)
            {
                try
                {
                    mouseDevice.Acquire ();
                    mouseState = mouseDevice.CurrentMouseState;
                }
                catch (Exception)
                {
                }
            }

I have verified that this works on my machine.  This will restore the lost device when it is detected.  I'm not sure that this is the best solution as it will generate an exception every time it is called until the application regains focus, and this will not update mouseState.  It will however, stop generating the exception, and will properly reacquire the device.

J.W.

JW Sullivan

unread,
Feb 7, 2006, 2:10:09 AM2/7/06
to realm...@googlegroups.com
I should say that it will fail every time it is called until the application regains focus.  The exception will be trapped and not propogated through.

J.W.

andris

unread,
Feb 7, 2006, 10:45:59 AM2/7/06
to RealmForge GDK
Thanks J.W.
Your solution worked for me. I can activate/deactivate the application
as expected even minimize it to taskbar.

I looked at the Win32InputReader class a bit more


There is actually a

if ( VerifyInputAcquired() )

condition in the main Capture() method, which should care for those
cases when the window is not active or is recovering from inactive
state, calling Device.Acquire() when necessary. Also disables DirectX
exceptions for a while.
So when returns false, nothing should be captured and cause an
exception.

It looks like it should work, but the check if window is active isn't
probably sufficient, although I'm not sure why. Originally looks like
this:


protected bool VerifyInputAcquired()
{
// if the window is coming back from being deactivated,
lets grab input again
if ( window.IsActive && !lastWindowActive )
{
// no exceptions right now, thanks anyway
DirectXException.IgnoreExceptions();

// acquire and capture keyboard input
if ( useKeyboard )
{
keyboardDevice.Acquire();
CaptureKeyboard();
}

// acquire and capture mouse input
if ( useMouse )
{
mouseDevice.Acquire();
CaptureMouse();
}

// wait...i like exceptions!
DirectXException.EnableExceptions();
}

// store the current window state
lastWindowActive = window.IsActive;

return lastWindowActive;
}


Even using try-catch blocks in this functions instead of disabling
exceptions didn't help.


My solution was to omit the nice VerifyInputAcquired() function (+
"protected bool lastWindowActive;" variable)

...and modify Capture() method as follows (hope this will be readable
after posted..:)


/// <summary>
/// Captures the state of all active input controllers.
/// </summary>
public override void Capture()
{
this.control.BringToFront();
this.control.Select();
this.control.Show();

if (window.IsActive)
try {
CaptureInput();
}
catch ( Exception ) {
try {
// try to acquire device and try again
if ( useKeyboard ) {
keyboardDevice.Acquire();
}
if ( useMouse ) {
mouseDevice.Acquire();
}
CaptureInput();
}
catch ( Exception ) {
ClearInput(); //not to appear as something
would be pressed or whatever.
}
}
}

This introduces 2 new protected methods:

/// <summary>
/// Clear this class input buffers (those accesible to
client through one of the public methods)
/// </summary>
private void ClearInput() {
keyboardState = null;
mouseRelX = mouseRelY = mouseRelZ = 0;
mouseButtons = 0;
}


/// <summary>
/// Capture buffered or unbuffered mouse and/or keyboard
input.
/// </summary>
private void CaptureInput() {

if ( useKeyboard ) {
if ( useKeyboardEvents ) {
ReadBufferedKeyboardData();
}
else {
// TODO Grab keyboard modifiers
CaptureKeyboard();
}
}

if ( useMouse ) {
if ( useMouseEvents ) {
//TODO: implement
}
else {
CaptureMouse();
}
}
}

I personally feel this makes the code more robust and also gives good
chance to extend the CaptureInput() with future functionality (buffered
mouse, gamepad...), also is more consistent when it comes to "buffered
or unbuffered" handling.

What do you think, is that a solution? (works at least :)

andris

unread,
Feb 8, 2006, 6:40:13 AM2/8/06
to RealmForge GDK
Hi, I kindly hope you gonna use this patch unless there is a better
solution :)

You know, as soon SVN gets updated this bug shouldn't appear anymore as
the cause is fairly isolated...

I just wonder why from the side of the C#2005Express debugger, the
exception seems to be raised at the very end of such a simple function
which also resides in another class.

Anybody knows? Just that I would better understand the debugger
maybe...

Thanks for help, however.
Andris

andris

unread,
Feb 8, 2006, 6:44:18 AM2/8/06
to RealmForge GDK
I ment that RenderSystem_FrameStarted() function mentioned in first
post...

Michael Cummings

unread,
Feb 8, 2006, 6:56:12 AM2/8/06
to realm...@googlegroups.com
I am reviewing it today. Before I apply the patch I need to take a look at the implementation of the input reader in RAGE. It may solve this problem as well.
 
Borrillis

 

andris

unread,
Feb 8, 2006, 7:29:22 AM2/8/06
to RealmForge GDK
It doesn't ;)
RAGE's input reader still only calls Capture().

Reply all
Reply to author
Forward
0 new messages