
Drawing without GameWindow or GLControl
Posted Friday, 12 March, 2010 - 19:13 by codingthewheel inHi,
Is there a way to use the GL.XXXXXX calls without a GameWindow or GLControl?
Failing that, is it possible to attach a GameWindow to an existing window (rather than creating a new window)?
Scenario: I'm writing a C# plugin that's handed a window by the host application (this is on Windows XP/Vista). This window is already prepared for OpenGL use, by the host application: pixel format, GL context, all set up and ready to go. C++ OpenGL calls work. C# calls to glXxxxx functions through P/Invoke work. But when I go through the TK bindings, I'm getting a crash.
What am I missing?
Many thanks,
James


Comments
Re: Drawing without GameWindow or GLControl
Edit: I just realized this is already covered in the documentation: http://www.opentk.com/doc/graphics/graphicscontext. Leaving the code here for posterity.
You just need to inform OpenTK that an external context exists:
Then store the IGraphicsContext somewhere so it isn't collected by the GC. This is a "dummy" context, which means it is not actually functional (i.e. calling
IGraphicsContext.MakeCurrent(...)will do nothing). The real context belongs to the host application.In some specific cases, you might wish to control the context through C#, too. In that case, you can create a fully functional context with:
You can now use any IGraphicsContext method, for example
context.VSync = true. While this can be useful, it is also dangerous: it is your job to ensure the context remains valid (i.e. don't callMakeCurrent(null, null)orDispose()while the host is using OpenGL!)Unless you need to direct control through C#, I'd suggest following the first approach.
Edit 2: fixed the second code snipped to pass
winfocorrectly.Re: Drawing without GameWindow or GLControl
Hi. Thanks for the quick response. :)
What I'm not understanding from the docs is the relationship between OpenGL's internal notion of "current context" and OpenTK's notion of the same thing. I have studied that page and tried various combinations; can't seem to get it to gel.
So to simplify things, I'm now trying to create the OpenGL context entirely on the plugin side. It (the plugin) is handed an existing window which hasn't been prepped for OpenGL (SetPixelFormat/wglMakeCurrent/etc haven't been called). I want to "OpenGL-itize this window" in the usual manner: create a context, make it current, etc. Here's the C# code I'm using to init the window:
So apparently, this would require me to actually know what I'm doing. Unfortunately I can't debug into the TK delegates type stuff right now. Also, when I try it the other way: initializing the OpenGL window on the host, and using:
It blows up on the call to CreateDummyContext. And yet the external context is current and on the same thread so, not sure what I'm doing wrong. One way or another, no matter where I create the context or what I do with it, it blows up in the GL.XXXX calls.
Re: Drawing without GameWindow or GLControl
Am I right to assume that the C# plugin is running in the same process as the host? (OpenGL contexts cannot function across processes.)
Assuming the above is true, creating a new context like you do should allow you to use GL methods right away. Can you please post the complete error message?
CreateDummyContext()will try to retrieve the current context using wglGetCurrentContext (or the relevant glx/agl methods). Apparently, this is failing for some reason. Again, the complete error message could give a clue about the cause.Two other suggestions:
int handleValis not valid for 64bit applications. Something to keep in mind if 64bit support is a concern.Re: Drawing without GameWindow or GLControl
Yep, they're in the same (32-bit) process. The error message was an "Object reference not set to an instance of an object" at the point of the GL.XXXXX call with an empty InnerException. Ie, no stack trace, and no indication of where inside the code the error may have happened. It was weird.
So I figured it was some funky entry point thing, and called
GL.LoadAllbefore the firstGL.Xxxxand everything works per your original answer. I notice thatLoadAllis marked deprecated, though, so maybe this isn't the best way?At any rate, it's working. Thanks!
Re: Drawing without GameWindow or GLControl
GL.LoadAll() is deprecated because entry points are actually loaded by the context, not the GL class. The non-deprecated method is called
_context.LoadAll()(in SVN) or(_context as IGraphicsContextInternal).LoadAll()(in 1.0 beta-3).Now, the strange thing is that entry points are loaded automatically when you create a new context (GraphicsContext.cs, line 177), so you shouldn't have to do that manually. Will have to investigate what is going on here.
In any case, glad it's working.
Re: Drawing without GameWindow or GLControl
(I'm not good at English, sorry.)
I had tried to initialize GraphicsContext with external OpenGL context (manually created by wglCreateContext() ) with these codes, and it works. (in 1.0 beta-2, windows7)
It seems to load the entry points automatically.