Beispiel #1
0
        public WglContext()
        {
            var wc = new WNDCLASS
            {
                cbClsExtra    = 0,
                cbWndExtra    = 0,
                hbrBackground = IntPtr.Zero,
                hCursor       = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW),
                hIcon         = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_APPLICATION),
                hInstance     = Kernel32.CurrentModuleHandle,
                lpfnWndProc   = (WNDPROC)User32.DefWindowProc,
                lpszClassName = "Griffin",
                lpszMenuName  = null,
                style         = User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC
            };

            gWC = User32.RegisterClass(ref wc);
            if (gWC == 0)
            {
                throw new Exception("Could not register window class.");
            }

            fWindow = User32.CreateWindow(
                "Griffin",
                "The Invisible Man",
                WindowStyles.WS_OVERLAPPEDWINDOW,
                0, 0,
                1, 1,
                IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero);
            if (fWindow == IntPtr.Zero)
            {
                throw new Exception($"Could not create window.");
            }

            fDeviceContext = User32.GetDC(fWindow);
            if (fDeviceContext == IntPtr.Zero)
            {
                Destroy();
                throw new Exception("Could not get device context.");
            }

            if (!Wgl.HasExtension(fDeviceContext, "WGL_ARB_pixel_format") ||
                !Wgl.HasExtension(fDeviceContext, "WGL_ARB_pbuffer"))
            {
                Destroy();
                throw new Exception("DC does not have extensions.");
            }

            var iAttrs = new int[]
            {
                Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB,
                Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE,
                //Wgl.WGL_DOUBLE_BUFFER_ARB, (doubleBuffered ? TRUE : FALSE),
                Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE,
                Wgl.WGL_RED_BITS_ARB, 8,
                Wgl.WGL_GREEN_BITS_ARB, 8,
                Wgl.WGL_BLUE_BITS_ARB, 8,
                Wgl.WGL_ALPHA_BITS_ARB, 8,
                Wgl.WGL_STENCIL_BITS_ARB, 8,
                Wgl.NONE, Wgl.NONE
            };
            var  piFormats = new int[1];
            uint nFormats;

            Wgl.wglChoosePixelFormatARB(fDeviceContext, iAttrs, null, (uint)piFormats.Length, piFormats, out nFormats);
            if (nFormats == 0)
            {
                Destroy();
                throw new Exception("Could not get pixel formats.");
            }

            fPbuffer = Wgl.wglCreatePbufferARB(fDeviceContext, piFormats[0], 1, 1, null);
            if (fPbuffer == IntPtr.Zero)
            {
                Destroy();
                throw new Exception("Could not create Pbuffer.");
            }

            fPbufferDC = Wgl.wglGetPbufferDCARB(fPbuffer);
            if (fPbufferDC == IntPtr.Zero)
            {
                Destroy();
                throw new Exception("Could not get Pbuffer DC.");
            }

            var prevDC   = Wgl.wglGetCurrentDC();
            var prevGLRC = Wgl.wglGetCurrentContext();

            fPbufferGlContext = Wgl.wglCreateContext(fPbufferDC);

            Wgl.wglMakeCurrent(prevDC, prevGLRC);

            if (fPbufferGlContext == IntPtr.Zero)
            {
                Destroy();
                throw new Exception("Could not creeate Pbuffer GL context.");
            }
        }
Beispiel #2
0
 public static extern ushort RegisterClass(ref WNDCLASS lpWndClass);
Beispiel #3
0
        static Wgl()
        {
            // save the current GL context
            var prevDC   = Wgl.wglGetCurrentDC();
            var prevGLRC = Wgl.wglGetCurrentContext();

            // register the dummy window class
            var wc = new WNDCLASS
            {
                style         = (User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC),
                lpfnWndProc   = (WNDPROC)User32.DefWindowProc,
                cbClsExtra    = 0,
                cbWndExtra    = 0,
                hInstance     = Kernel32.CurrentModuleHandle,
                hCursor       = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW),
                hIcon         = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_WINLOGO),
                hbrBackground = IntPtr.Zero,
                lpszMenuName  = null,
                lpszClassName = "DummyClass"
            };

            if (User32.RegisterClass(ref wc) == 0)
            {
                throw new Exception("Could not register dummy class.");
            }

            // get the the dummy window bounds
            var windowRect = new RECT {
                left = 0, right = 8, top = 0, bottom = 8
            };

            User32.AdjustWindowRectEx(ref windowRect, WindowStyles.WS_SYSMENU, false, User32.WS_EX_CLIENTEDGE);

            // create the dummy window
            var dummyWND = User32.CreateWindowEx(
                User32.WS_EX_CLIENTEDGE,
                "DummyClass",
                "DummyWindow",
                WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_SYSMENU,
                0, 0,
                windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
                IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero);

            if (dummyWND == IntPtr.Zero)
            {
                User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle);
                throw new Exception("Could not create dummy window.");
            }

            // get the dummy DC
            var dummyDC = User32.GetDC(dummyWND);

            // get the dummy pixel format
            var dummyPFD = new PIXELFORMATDESCRIPTOR();

            dummyPFD.nSize        = (ushort)Marshal.SizeOf(dummyPFD);
            dummyPFD.nVersion     = 1;
            dummyPFD.dwFlags      = Gdi32.PFD_DRAW_TO_WINDOW | Gdi32.PFD_SUPPORT_OPENGL;
            dummyPFD.iPixelType   = Gdi32.PFD_TYPE_RGBA;
            dummyPFD.cColorBits   = 32;
            dummyPFD.cDepthBits   = 24;
            dummyPFD.cStencilBits = 8;
            dummyPFD.iLayerType   = Gdi32.PFD_MAIN_PLANE;
            var dummyFormat = Gdi32.ChoosePixelFormat(dummyDC, ref dummyPFD);

            Gdi32.SetPixelFormat(dummyDC, dummyFormat, ref dummyPFD);

            // get the dummy GL context
            var dummyGLRC = Wgl.wglCreateContext(dummyDC);

            if (dummyGLRC == IntPtr.Zero)
            {
                throw new Exception("Could not create dummy GL context.");
            }
            Wgl.wglMakeCurrent(dummyDC, dummyGLRC);

            // get the extension methods using the dummy context
            wglGetExtensionsStringARB = Wgl.wglGetProcAddress <wglGetExtensionsStringARBDelegate>("wglGetExtensionsStringARB");
            wglChoosePixelFormatARB   = Wgl.wglGetProcAddress <wglChoosePixelFormatARBDelegate>("wglChoosePixelFormatARB");
            wglCreatePbufferARB       = Wgl.wglGetProcAddress <wglCreatePbufferARBDelegate>("wglCreatePbufferARB");
            wglDestroyPbufferARB      = Wgl.wglGetProcAddress <wglDestroyPbufferARBDelegate>("wglDestroyPbufferARB");
            wglGetPbufferDCARB        = Wgl.wglGetProcAddress <wglGetPbufferDCARBDelegate>("wglGetPbufferDCARB");
            wglReleasePbufferDCARB    = Wgl.wglGetProcAddress <wglReleasePbufferDCARBDelegate>("wglReleasePbufferDCARB");
            wglSwapIntervalEXT        = Wgl.wglGetProcAddress <wglSwapIntervalEXTDelegate>("wglSwapIntervalEXT");
            // GET_PROC(ChoosePixelFormat, ARB);
            // GET_PROC(GetPixelFormatAttribiv, ARB);
            // GET_PROC(GetPixelFormatAttribfv, ARB);
            // GET_PROC(CreateContextAttribs, ARB);

            // destroy the dummy GL context
            Wgl.wglMakeCurrent(dummyDC, IntPtr.Zero);
            Wgl.wglDeleteContext(dummyGLRC);

            // destroy the dummy window
            User32.DestroyWindow(dummyWND);
            User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle);

            // reset the initial GL context
            Wgl.wglMakeCurrent(prevDC, prevGLRC);
        }