I'm trying to call wglMakeCurrent using C# native call [DllImport] attribute. The function works and set my opengl context as current.
The thing is sometimes it throws error. It has no pattern, it just fails to make the context current.
I reproduced the same code in c++ and it doesnt have that problem.
My first idea is that it's something related to being HDC or HGLRC handle is not properly disposed or something still keeps alive the handles but I have implemented a cleanup procedure when window is closing I both release HDC and delete HGLRC. In the and it does not work. Here its the code
public enum PixelFormatDescriptorFlags : uint
{
PFD_MAIN_PLANE = 0,
PFD_OVERLAY_PLANE = 1,
PFD_TYPE_RGBA = 0,
PFD_TYPE_COLORINDEX = 1,
PFD_DOUBLEBUFFER = 0x00000001,
PFD_DRAW_TO_WINDOW = 0x00000004,
PFD_DRAW_TO_BITMAP = 0x00000008,
PFD_SUPPORT_GDI = 0x00000010,
PFD_SUPPORT_OPENGL = 0x00000020,
PFD_GENERIC_FORMAT = 0x00000040,
PFD_NEED_PALETTE = 0x00000080,
PFD_NEED_SYSTEM_PALETTE = 0x00000100,
PFD_SWAP_EXCHANGE = 0x00000200,
PFD_SWAP_COPY = 0x00000400,
PFD_SWAP_LAYER_BUFFERS = 0x00000800,
PFD_GENERIC_ACCELERATED = 0x00001000,
PFD_SUPPORT_DIRECTDRAW = 0x00002000,
PFD_DIRECT3D_ACCELERATED = 0x00004000,
PFD_SUPPORT_COMPOSITION = 0x00008000,
PFD_DEPTH_DONTCARE = 0x20000000,
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000,
PFD_STEREO_DONTCARE = 0x80000000
}
public struct HGLRC
{
public int Hglrc;
}
public struct PIXELFORMATDESCRIPTOR
{
public ushort nSize;
public ushort nVersion;
public UInt32 dwFlags;
public byte iPixelType;
public byte cColorBits;
public byte cRedBits;
public byte cRedShift;
public byte cGreenBits;
public byte cGreenShift;
public byte cBlueBits;
public byte cBlueShift;
public byte cAlphaBits;
public byte cAlphaShift;
public byte cAccumBits;
public byte cAccumRedBits;
public byte cAccumGreenBits;
public byte cAccumBlueBits;
public byte cAccumAlphaBits;
public byte cDepthBits;
public byte cStencilBits;
public byte cAuxBuffers;
public byte iLayerType;
public byte bReserved;
public UInt32 dwLayerMask;
public UInt32 dwVisibleMask;
public UInt32 dwDamageMask;
}
public static class Win32GL
{
[System.Runtime.InteropServices.DllImport("ZeroGDIInterface.dll", SetLastError = true)]
public static extern int ChoosePixelFormatGDI(Win32HDC hdc,ref PIXELFORMATDESCRIPTOR desc);
[System.Runtime.InteropServices.DllImport("ZeroGDIInterface.dll", SetLastError = true)]
public static extern int SetPixelFormatGDI(Win32HDC hdc,int format, ref PIXELFORMATDESCRIPTOR desc);
[System.Runtime.InteropServices.DllImport("ZeroGDIInterface.dll", SetLastError = true)]
public static extern HGLRC wglCreateContextGDI(Win32HDC hdc);
[System.Runtime.InteropServices.DllImport("ZeroGDIInterface.dll", SetLastError = true)]
public static extern int wglMakeCurrentGDI(Win32HDC hdc,HGLRC hglrc);
[System.Runtime.InteropServices.DllImport("ZeroGDIInterface.dll", SetLastError = true)]
public static extern int wglDeleteContextGDI(HGLRC hglrc);
}
WindowsWindow win32Window = ownerWindow as WindowsWindow;
PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
pfd.nSize = (short)Marshal.SizeOf<PIXELFORMATDESCRIPTOR>();
pfd.dwFlags = (uint)(PixelFormatDescriptorFlags.PFD_DRAW_TO_WINDOW | PixelFormatDescriptorFlags.PFD_SUPPORT_OPENGL | PixelFormatDescriptorFlags.PFD_DOUBLEBUFFER);
pfd.iPixelType = (byte)PixelFormatDescriptorFlags.PFD_TYPE_RGBA;
pfd.nVersion = 1;
pfd.cColorBits = 32;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = (byte)PixelFormatDescriptorFlags.PFD_MAIN_PLANE;
int pixelFormat = Win32GL.ChoosePixelFormatGDI(win32Window.Hdc, ref pfd);
if(pixelFormat == 0)
{
throw new Exception("Choose pixel format failed!");
}
if (Win32GL.SetPixelFormatGDI(win32Window.Hdc, pixelFormat, ref pfd) == 0)
{
throw new Exception("Set pixel format failed!");
}
HGLRC dummyContext = Win32GL.wglCreateContextGDI(win32Window.Hdc);
if(dummyContext.Hglrc == 0)
{
throw new Exception("Failed to create wgl context");
}
if (Win32GL.wglMakeCurrentGDI(win32Window.Hdc, dummyContext) == 0)
{
throw new Exception("Failed to make the dummy context current! = ");
}
Edit: When it does not throw error, I can simply use the context for clear color and swapping the swapchain buffers. So native bindings and the code works as intended
Edit: Added the [DllImport] and used structures