Problem with Tutorial6 modification

HRB

25-09-2008 07:30:19

Hi there!

I've stumbled upon a AccessViolation when I tried to modify tut6.

I replaced:

public void Go()
{
while (mRoot != null && mRoot.RenderOneFrame())
{
MoveCam();
Application.DoEvents();
Thread.Sleep(INTERFRAMEPAUSE); // fps limit
}
}

with:

bool FrameStarted(FrameEvent evt)
{
deltaT = evt.timeSinceLastFrame; // for fps independend cam

MoveCam();
Application.DoEvents();
Thread.Sleep(INTERFRAMEPAUSE); // limit fps

return mRoot != null;
}

public void Go()
{
mRoot.StartRendering();
}


At first everything seems to be fine. BUT if I close the window -> AccessViolation.

This will also happen if I don't even register the FrameStarted method as a listener to mRoot!

Is there something that needs to be done when I use StartRendering() instead of RenderOneFrame()?
Might there be another way to get the timeSinceLastFrame?

Beauty

25-09-2008 09:13:14

You mean this tutorial?
www.ogre3d.org/wiki/index.php/Mogre_Basic_Tutorial_6

In which line the exception will be thrown?
(if it's an other tutorial: maybe comment an outher try catch instruction to get the place)

HRB

25-09-2008 09:52:53


You mean this tutorial?
www.ogre3d.org/wiki/index.php/Mogre_Basic_Tutorial_6

Exactly.


In which line the exception will be thrown?

I knew i forgot something...

mRoot.StartRendering() will throw the AccessViolationException as soon as the window is closed.

Everything else works perfectly fine. Just closing the application causes trouble!

Beauty

25-09-2008 12:07:57

I looked to the API documentation of StartRendering()

This method begins the automatic rendering of the scene. It will NOT return until the rendering cycle is halted.

I assume the Ogre intermal loop try render, but by closing the application the needed ressources are disposed. So maybe there is a pointer that point to somewhere what doesn't exist anymore.

But I have an idea:
Catch the close application event and stop the rendering there.

Wait. I will look for the code ...
Ok I found it:

// set this line to start of application
// (call it in the Form class when the Form was created)
// (e.g. put the line after call of InitializeComponent())
this.FormClosing += new FormClosingEventHandler(CloseButtonClicked);


private void CloseButtonClicked(object sender, EventArgs e)
{
// if you want to prevent closing (when close button was clicked) enable the next line
// ((FormClosingEventArgs)e).Cancel = true; // prevent closing

// ... do something before the application will be closed ...
mRoot.QueueEndRendering();
}


I suppose QueueEndRendering() is the right call to stop the render loop.

HRB

26-09-2008 09:31:50

Does this work out for you?

I still get the Exception.

It disappears when

((FormClosingEventArgs)e).Cancel = true; // prevent closing

is not commented out.
But shouldn't this stop the window from closing?

Beauty

01-10-2008 12:09:42

I never used mRoot.StartRendering() and mRoot.QueueEndRendering().

In a second window (Form) of my application I use ((FormClosingEventArgs)e).Cancel = true; to prevent closing the window. (I just hide it.)
But you really want to close the window. So you don't set it true.

Maybe make a test:
Add a GUI botton (easy with Windows Forms). When you click it then the function mRoot.QueueEndRendering() should be called.
What happens then?
* Does the rendering stop?
* Do you get an Exeption after button click?
* Do you get an Exeption after closing the application?