protected override void MakeCurrent()
            {
                // Waits until window reference is known
                SpinWait.SpinUntil(() => _window != null);

                // Makes context current on calling thread
                Glfw.MakeContextCurrent(_window.Handle);

                // Configure swap interval
                Glfw.SetSwapInterval(_vsync ? 1 : 0);

                // Enable quality MSAA
                if (Screen.Surface.Multisample > MultisampleQuality.None)
                {
                    // Load glMinSampleShading, this could be cached... but this way makes it pretty
                    // seamless to include.
                    var glMinSampleShader = LoadFunction <MinSampleShading>("glMinSampleShading");

                    // Enable multisampling explicity. From what I've read this is
                    // should already be enabled but I thought it good to enable it myself.
                    GL.Enable((EnableCap)0x809D);  // GL_MULTISAMPLE

                    // If we are running a version that can support sample shading
                    // enable it and set the rate to 100%. This allows multisampling
                    // to affect every pixel instead of just the geometry edges.
                    if (glMinSampleShader != null)
                    {
                        GL.Enable((EnableCap)0x8C36);  // GL_SAMPLE_SHADING
                        glMinSampleShader(1F);
                    }
                }
            }
Exemple #2
0
        private static void InitializeGraphicsAdapter()
        {
            // Set GLFW hints to use OpenGL 3.2 core (forward compatible)
            // We are assuming OpenGL is the only implementation relevant here. Sorry Vulkan!
            // In the future if a Vulkan implementation is introduced to Heirloom, we will have to rewrite this
            // initialization procedure.
            Glfw.SetWindowCreationHint(WindowAttribute.ClientApi, (int)ClientApi.OpenGL);
            Glfw.SetWindowCreationHint(WindowAttribute.OpenGLProfile, (int)OpenGLProfile.Core);
            Glfw.SetWindowCreationHint(WindowAttribute.OpenGLForwardCompatibility, true);
            Glfw.SetWindowCreationHint(WindowAttribute.ContextVersionMajor, 3);
            Glfw.SetWindowCreationHint(WindowAttribute.ContextVersionMinor, 2);

            // Creates the "sharing window" that is permanently hidden to the user.
            // It is used to query window capabilities and assist with sharing OpenGL resources.
            // It is also used when shaders or other OpenGL resources that need to be created
            // on an OGL bound thread but do not have a clear context available to them.
            Glfw.SetWindowCreationHint(WindowAttribute.TransparentFramebuffer, true);
            Glfw.SetWindowCreationHint(WindowAttribute.Visible, false);
            ShareContext = Glfw.CreateWindow(256, 256, "GLFW Background Window");

            // Use share context temporarily to load the GL functions and construct the graphics adapter object...
            Glfw.MakeContextCurrent(ShareContext);
            {
                // Loads the GL functions via GLFW lookup
                GL.LoadFunctions(Glfw.GetProcAddress);

                // On the desktop we actually use GL 3.2, but the implementation is limited to GLES 3.0 features.
                // This is to help make a uniform implementation for supportd on mobile platforms. This however,
                // does allow the user to create incompatible shaders between platforms. As mobile is currently not
                // a supported project, this is not yet a concern.
                GraphicsAdapter = new OpenGLWindowGraphicsAdapter();
                GraphicsFactory = GraphicsAdapter as IWindowGraphicsFactory;
                GraphicsAdapter.Initialize();
            }
            Glfw.MakeContextCurrent(WindowHandle.None);

            // Reset default window creation hints
            Glfw.SetWindowCreationHint(WindowAttribute.FocusOnShow, true);
            Glfw.SetWindowCreationHint(WindowAttribute.Visible, true);
        }
        protected internal override void Invoke(Action function)
        {
            if (Adapter?.IsDisposed ?? false)
            {
                Log.Error("Unable to schedule action on GL thread. Adapter has been disposed.");
            }

            lock (_graphics)
            {
                // Try to invoke on an existing graphics thread
                foreach (var gfx in _graphics)
                {
                    // If graphics context is still initialized...
                    if (gfx.IsInitialized)
                    {
                        // Invoke action on that thread and exit
                        gfx.Invoke(function);
                        return;
                    }
                }
            }

            // Was unable to invoke on a graphics thread, so we will temporarily make the window
            // events thread a graphics thread to invoke the function.
            Application.Invoke(() =>
            {
                // Make the share context current here
                Glfw.MakeContextCurrent(Application.ShareContext);

                // Execute function and keep return value
                function();

                // Release context from thread. We want it not associated with any thread.
                Glfw.MakeContextCurrent(WindowHandle.None);
            });
        }