private static void InitializeMonitors() { // Register monitor callback, invoked when the monitor configuration changes. Glfw.SetMonitorCallback(OnMonitorCallback); // Scan currently connected monitors foreach (var monitor in Glfw.GetMonitors()) { OnMonitorCallback(monitor, ConnectState.Connected); } }
private static void PerformMainWindowLoop() { // While any window is open while (Windows.Count > 0) { // Poll window events Glfw.WaitEventsTimeout(WaitEventsTimeout); // Process invoke queue _invokeQueue.ProcessJobs(); // Sleep thread, prevent tight spinning // NOTE: Removed because WaitEventsTimeout above should block... // Thread.Sleep(1); } }
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); }); }
protected override void SwapBuffers() { // Swap buffers (on the gl thread) Invoke(() => Glfw.SwapBuffers(_window.Handle), false); }