logixoul's picture

Using OpenTK without GameWindow/GLControl

I'm using OpenGL with Qt.
I want to use OpenTK as a simple binding to OpenGL, bеcause it's nicer to write GL.Vertex3(...) than Gl.glVertex3f(...).
But apparently OpenTK tries to be more than that... it tries to handle my GL context or something. More precisely: when I create an opengl window from within Qt, then call a function such as GL.Viewport, I get a null reference exception (which I don't know how to debug).

However, when I first create a small dummy OpenTK.GameWindow and run its mainloop in a separate thread, then that makes GL calls in my actual Qt window work. I suppose that during the GameWindow initialization, some internal DC handle gets initialized, which makes my calls work even for the other window.

So, how would I go about a proper solution? I tried looking through the OpenTK source but once I got to the bindings, I got confused by the code-generation going on.


Comment viewing options

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

OpenTK requires a valid context to retrieve OpenGL function pointers. You can instruct OpenTK that you are using an "external" context with:

var context = GraphicsContext.CreateDummyContext();

That's all there is to it. Just make sure you call this *after* creating the context through Qt and store the reference somewhere so it isn't reclaimed by the garbage collector.

You can find more details in the GraphicsContext documentation.

logixoul's picture

Great, but calling CreateDummyContext also produces a NullReferenceException. I'm running Win7, OpenTK is v1.0.0.201.

the Fiddler's picture

Ah yes, the NullReferenceException should be fixed in SVN. Try compiling a fresh checkout from https://opentk.svn.sourceforge.net/svnroot/opentk/branches/1.0

logixoul's picture

Ok, with the svn version I get "No GraphicContext is current on the calling thread."
This happens when I call CreateDummyContext in my implementation of QGLWidget.resizeGL, right before the first OpenTK call. That's surely the right place to do it, because at that point, QGLContext.currentContext() returns a non-null object (which means we do have a context at this point).
If you'd like, we could take this conversation to an irc channel or skype ("monov2").

Edit: I uploaded an example project showing the problem. http://www.speedyshare.com/files/23020805/BugTest.7z
Edit: the above link expired, here's a new one: http://www.sendspace.com/file/o3i16u

the Fiddler's picture

Thanks, I've got the file and will test as soon as I can find some free time.

logixoul's picture

Any update on this?
I think this bug was supposedly fixed in the new OpenTK release (1.0 final) but I tried that release and it still doesn't work.
In case you don't want to deal with Qt, here's a minimal testcase using Tao.SDL:

using OpenTK.Graphics;
using Tao.Sdl;
static class Program
    static void Main()
        Sdl.SDL_SetVideoMode(600, 400, 0, Sdl.SDL_OPENGL);
        var gc = GraphicsContext.CreateDummyContext();
        // The last line throws:
        //     InvalidOperationException occurred
        //     No GraphicsContext is current on the calling thread.
the Fiddler's picture

Hm, the relevant patches may have been forgotten in merge hell. Let me see what is going on here.

the Fiddler's picture

This is *really* fixed in trunk r2782, now. Just make sure your SDL window is created and the OpenGL context is made current before calling CreateDummyContext().

its's picture

I tried to call CreateDummyContext() and it did'nt work, too.
I'm using OpenTK 1.0 release: 6 October 2010, Windows 7, GeForce GTX 460.

CreateDummyContext() throws InvalidOperationException wiht the message "No GraphicsContext is current on the calling thread.".

But, this code, creating dummy context in another way, works well.

IntPtr hRC;//Handle of the context
IntPtr hWnd;//Handle of the window
OpenTK.Platform.IWindowInfo windowInfo
 = OpenTK.Platform.Utilities.CreateWindowsWindowInfo( hWnd );
OpenTK.ContextHandle handle = new OpenTK.ContextHandle( hRC );
GraphicsContext otkContext = GraphicsContext.CreateDummyContext( handle );
otkContext.MaeCurrent( windowInfo );
its's picture

Sorry, I mistook.
The codes I posted above does not work.
Please ignore it.