Ubinator's picture

How to use the debug version of OpenTK

I'm not sure if I'm using it correctly, I compiled from the source code in debug mode. Then I removed the reference to the current OpenTK and added it. Now when I debug I get a heap of stuff printed out to the Immediate Window which ends with Main loop started. After that nothing. I am getting silent crashes and not being told anything about them.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

That's the way to use the debug version - the messages in the output window confirm that you are running a debug build.

Which version of OpenTK are you using? Silent crashes should never happen, you should be getting an exception whenever something goes wrong (e.g. an OpenGL error occurs.)

Ubinator's picture

Should be the latest 1.1.0-2013-11-22 Downloaded fresh off the release page. I do have a bit of multithreading going on, for example I have a normal form which then opens a gamewindow in a background worker thread, the information that the gamewindow uses comes from another thread. Could it be that SyncLocks are causing the silent crashes? As I have a number of them in the render loop.

the Fiddler's picture

You are combining two different GUI toolkits in the same process, as well as creating windows on a non-GUI (background) thread. This is not a supported scenario.

If you need to work with WinForms, you should switch to GLControl instead. As with all WinForms Controls, you *must* create the GLControl on the GUI thread. If you wish, you can then move OpenGL rendering to a background thread by calling glControl.Context.MakeCurrent(null) on the GUI thread and glControl.MakeCurrent() on the background thread.

I would suggest avoiding BackgroundWorker for OpenGL, as that does not give you any control over the lifetime of threads (for all you know, it may terminate threads unexpectedly or launch your code on different threads every time, leading to unexpected crashes.) Create and use a regular System.Threading.Thread instead.

Ubinator's picture

Using the GL Control caused me lots of problems so I abandoned it ages ago. I only use the form as a menu/sidebar type thing because building menus with GL is crazy difficult. I thought it would be fine, as it has been until I started adding sync locks and splitting my data building into a separate thread that problems started and I only did that because my data building is slow and as such slowed down the GL window.

The background worker should not be a problem, the lifetime of the thread is as long as there is work to do which there always is because its all just 1 big loop isn'it it? I dont understand what you mean "launch your code on different threads every time" I just run the entire openTK example (with my code) in 1 backgroundworker, which has never caused a problem. Anyway I see where you're coming from, I will change it over to a normal thread since that could be some of the problem, I'm just not sure what happens exactly when a SyncLock is hit, I believe it pauses execution of the code block if another synclock is in use, which makes me think it could be exiting the thread, I will see.

Ill just write up some really hacky debug method to try and find my problems haha. Thanks anyway.

the Fiddler's picture

It might be worth giving GLControl another look, there are several fixes in the latest version to make it work better with the Visual Studio designer.

In any case, this piece of advice may be useful when combining WinForms and GameWindow in the same process:

Two UI threads in C# windows application wrote:

You need to call Thread.SetApartmentState() to switch the thread to STA before starting it. And pump a message loop to keep any windows created on that thread alive, Application.Run(). Application.ExitThread() will terminate the message loop and cause the thread to exit. Using Run(Form) makes that automatic, just as it does on the main thread.

GameWindow.Run() pumps the message loop, so that's taken care of. TryThread.SetAparmentState() to see if it helps with the crashes you are seeing.

If you manage to capture the exact exception or MDA you are receiving, please file a bug report here. It might be possible to add a workaround inside OpenTK.

Edit: make sure that you don't call any GameWindow methods from multiple threads! This is the same as with WinForms: you can only access a window on the thread it was created on.

Ubinator's picture

Yeah I learnt, accidentally, early on about not using any gamewindow/opentk methods in other threads. Thanks for that info that should be handy, I'll go through now and implement it and report back.

EDIT: I think this has fixed it, I am no longer getting silent crashes and actually got a out of memory exception just before, which I now know where my problem is.

Thanks for the help its much appreciated and your doing a great job looking after all this.

laztrezort's picture

Hi.

I'm using the latest (1.1-b3), debug version the library, and exceptions are not getting thrown automatically on GL errors. It's my understanding that the debug build should throw an error any time GL.GetError() would return an error condition - is this correct?

Just to make sure I wasn't missing something, I made a minimal test project:

using OpenTK;
using System;
using OpenTK.Graphics.OpenGL;
 
namespace OTKTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Mygame game = new Mygame();
 
            game.Run();
        }
    }
 
    class Mygame : GameWindow
    {
        public Mygame()
        {
            var err = GL.GetError();
            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0,
                TextureTarget.Texture2D, 0, 0);
            err = GL.GetError();
        }
    }
}

The FrameBufferTexture2D call causes an INAVLID_OPERATION error, but no exception is thrown.

Am I missing a setting somewhere, or perhaps I misunderstood how OptenTK handles errors?

Thanks!

the Fiddler's picture

1.1-b3 implements a new interop method that performs better. The automatic calls to GL.GetError are not yet implemented there, I will re-add them in 1.1-b4 (ETA tomorrow.)

laztrezort's picture

Thanks Fiddler for the info, much appreciated.