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
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.
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?
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,
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 :)
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