luca-piccioni / OpenGL.Net

Modern OpenGL bindings for C#.
MIT License
566 stars 107 forks source link

Question about DeviceContext and Windows WM_PAINT #112

Open toptensoftware opened 5 years ago

toptensoftware commented 5 years ago

Hi,

This is more a question more than an issue, but wasn't sure where else to post it. I'm looking to integrate OpenGL.NET into my custom Windows UI library which draws using traditional Windows WM_PAINT messages rather than running a regularly updating game/animation loop.

I noticed that DeviceContext creates it's own internal hDC with Windows' GetDC(hWnd) function and releases it when the DeviceContext is disposed. How does one get it to paint to the hDC returned from BeginPaint()?

Currently I'm handling it something like this:

case Win32.WM_PAINT:
    // Render using OpenGL.NET's DeviceContext (_dc)
    _dc.MakeCurrent(_ctx);
    OnRender();
    _dc.SwapBuffers();
    _dc.MakeCurrent(IntPtr.Zero);

    // Validate the window
    Win32.ValidateRect(_handle, IntPtr.Zero);
    break;

ie: No BeginPaint/EndPaint calls.

This seems to work, but I'm wondering if this is the correct way to handle it or is there a better way to do it?

Any advice appreciated. Brad

luca-piccioni commented 5 years ago

I don't see any major issue in the code you posted; I would avoid repeated _dc.MakeCurrent(_ctx); and _dc.MakeCurrent(IntPtr.Zero); since they would reload all GL context function pointers at each WM_PAINT message (and this is an expensive task). Ideally, you set a current GL context at window creation, and keep it current as long the window exists. (Hint: see here)

BeginPaint returns an HDC that should be used within the WM_PAINT handler. From what I understand, it is not guaranteed that the returned HDC is always the same, and I think that creating a GL context on it is not a good model to implement (if the HDC is destroyed, even the GL context would be invalid).

For what it worths, this is a partial Win32 window implementation integrated with OpenGL.Net.

toptensoftware commented 5 years ago

Hi Luca,

Thanks for the reply. Unfortunately I can't keep the context current for the entire lifetime of the window. My app loads third party VST plugins - some of which also use OpenGL for rendering so my app and the loaded plugins all need to keep their contexts separate. Is there some way to keep the context and it's associated function pointers cached and just re-activate them with the context?

Brad