David Bakin's picture

GLControl and Windows Forms integration - what can you expect?

I'm new to OpenGL as well as OpenTK - so I may have some misunderstandings that I hope you can clear up.

How integrated is GLControl with Windows Forms? I already understand that DrawToBitmap won't work (and I know how to use GL.ReadPixels to workaround that). But what else related to painting can or can't be expected to work?

For example: I have placed a GLControl and a (Windows Forms) Label (also a PictureBox) inside a GroupBox, with the Label and PictureBox in front (z-order) of the GLControl. I was expecting normal behavior where the controls nearer in z-order appear on top of the GLControl. But that doesn't happen: only the GLControl draws.

Is this because it is a hardware renderer and it essentially owns that screen real estate?

If not, what am I doing wrong?
If so, is there any way to work around it?

Thanks! -- David


Comment viewing options

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

This topic comes up from time to time. There is a MSDN page that describes some limitations, as well as several discussions on the web about mixing GDI with OpenGL.

To the best of my knowledge:

  • You cannot mix GDI with hardware-accelerated OpenGL on the same device context (e.g. you cannot use TextRenderer.DrawText() on a GLControl).
  • You can display sibling/child windows on top of a GLControl (the GLControl intentionally avoids WS_CLIPSIBLINGS | WS_CLIPCHILDREN).

If you have downloaded OpenTK from sourceforge or from github, run OpenTK.Examples and select OpenTK -> GLControl Simple. This sample draws a GLControl with three WinForms Buttons on top and it appears to be working correctly on every system I have tried so far (AMD, Intel, Nvidia, VirtualBox and Parallels.)

If I drag and drop a PictureBox and a Label on top of the GLControl, everything still appears to be working correctly (tested on an Intel GPU.)

Can you try this sample to see if it is working on your system?

David Bakin's picture

Thanks for the clarification on OpenGL vs GDI, and the doc pointer.

W.r.t. the overlay issue: My bad! Last night I was testing on my old desktop, with recent NVidia drivers but a rather old card - a GeForce 8400 GS. This morning, on my laptop with recent NVidia drivers and a Quadro 2000M - works fine!

So I guess its time to upgrade my desktop's graphics card or just abandon it for OpenGL purposes ...

David Bakin's picture

Hi. I'm back with another question about overlaying a window on top of a GLControl. I've read the MSDN "Limitations" page you linked to, as well as your comment.

In my sample, derived from the tutorial here, I put a label with transparent background color, and a PictureBox containing a PNG with transparent areas, on top of an GLControl. I set GLControl.BackColor to the same as the GL.ClearColor method I called. The GLControl is their Parent.

What I see is the label and picture drawn on top of the GLControl and the parts of their background that are transparent show the the GLControl's background color. But when the triangle rotates under these two controls the triangle doesn't show. BUT Spy++ shows that in fact (as I would expect) the label and the picture are their own GDI windows. Based on what you said above and the MSDN page that is not "mixing" GDI + hardware accelerated OpenGL in the same device context, so that limitation doesn't seem to apply.

I have this code in a public bitbucket repository (if I've made it public correctly) at https://bitbucket.org/davidbak_mobi/bakinplaypen/overview - where the project OpenGLTest2 is what I've just described and the project OpenGLTest3 is not opengl at all but a plain Windows Form app where the GLControl is replaced by a PictureBox and the same hierarchical structure of controls shows that in Windows Form transparent behaves properly and what is on the underlying PictureBox does show through, not just the background color. (This is a VS2012 solution.)

So ... am I misunderstanding the limitation? Thanks again!

(My goal, BTW, is to put a graphical markup window on top of the GLControl, so that graphical markups (drawn in the usual GDI+ manner) will appear on top of some kind of OpenGL-generated 2D image.)

the Fiddler's picture

Thanks for the test code. I cannot see a TestOpenGL3 folder in the repository and after spending a few moments I haven't been able to get a transparent Label showing on top of a regular PictureBox. Maybe there is a trick to fix this, but the Label appears to inherit the BackColor of whichever Control is set as its Parent.

In any case, GDI cannot access pixels rendered with OpenGL, unless a software-accelerated context is used. You can draw a transparent *top-level* window over a GLControl (as this involves the DWM, which *can* access these pixels), but I do not know if this is possible with plain Controls (i.e. sibling or child windows.)

A quick search hints that this might indeed be possible, so I guess a motivated person would probably be able to get WinForms to cooperate. I do not know if this would require changes to OpenTK, but I would be willing to merge a github pull-request that would enable this scenario.

The relevant code is in GLControl.cs and WinGLControl.cs.

Edit: one good solution might be to use a layered window to host the controls you wish to overlay: http://code.msdn.microsoft.com/windowsdesktop/CSWinFormLayeredWindow-23c...

David Bakin's picture

Fiddler - thanks! I'll try the layered window suggestion shortly - an item from work has taken priority. I'll let you know.