pabloiw's picture

Multiple Monitors - 2 GameWindows Problem

Hello, I'm running 2 GameWndow's on 2 monitors, and when I click on the primary monitor - rendered scenes starts to blink. I was trying to replace GameWindow by Form + GLControl, but it didn't help me either;

Test.cs

namespace OpenGL.Test
{
	using OpenGL;
	using System;
	using System.Windows.Forms;
 
	static class Test
	{			
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			GraphicsEngine ge = new GraphicsEngine();
			Application.Run();
		}
	}
}

GraphicsEngine.cs

namespace OpenGL
{
	using Microsoft.Win32;
	using OpenTK;
	using OpenTK.Graphics;
	using OpenTK.Graphics.OpenGL;
	using OpenTK.Input;
	using System;
	using System.Collections.Generic;
	using System.Drawing;
	using System.Threading;
 
	public class GraphicsEngine
	{
		#region Fields
		private object locker = new object();
		private List<GameWindow> gameWindows = new List<GameWindow>();
		private Thread renderThread;
		private Rectangle[] screens;
		private bool altIsDown = false;
		#region Render Animations
		private float x = 0, y = 0, angle = 0;
		private int xdir = 1, ydir = 1;
		private int quadSize = 200;
		Random rand = new Random();
		#endregion
		#endregion
 
		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="GraphicsEngine" /> class.
		/// </summary>
		public GraphicsEngine()
		{
			UpdateMonitorsList();
			x = FullBounds.X;
			y = FullBounds.Y;
 
			GraphicsContext.CurrentContext.MakeCurrent(null);
			renderThread = new Thread(() => RenderThread());
			renderThread.IsBackground = true;
			renderThread.Start();
		}
		#endregion
 
		#region Properties
		public Rectangle FullBounds { get; set; }
		#endregion
 
		#region Methods
		#region Public
		#endregion
 
		#region Private
		private void RenderThread()
		{
			while (true)
			{
				lock (gameWindows)
				{
					foreach (GameWindow gw in gameWindows)
					{
						OnRender(gw);
					}
				}
				Thread.Sleep(10);
			}
		}
 
		private void OnRender(GameWindow gameWindow)
		{
			gameWindow.MakeCurrent();
 
			GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.ClearColor(Color.SteelBlue);
 
 
			GL.MatrixMode(MatrixMode.Modelview);
			GL.LoadIdentity();
 
			Matrix4 m = Matrix4.CreateRotationZ(angle) * Matrix4.CreateTranslation(x, y, 0);
			GL.PushMatrix();
			GL.LoadMatrix(ref m);
 
			if (x == FullBounds.Left + quadSize / 2f && y == FullBounds.Top + quadSize / 2f)
			{
				xdir = rand.Next(2);
				ydir = rand.Next(2);
			}
			else if (x == FullBounds.Right - quadSize / 2f && y == FullBounds.Top + quadSize / 2f)
			{
				xdir = rand.Next(2) - 1;
				ydir = rand.Next(2);
			}
			else if (x == FullBounds.Right - quadSize / 2f && y == FullBounds.Bottom - quadSize / 2f)
			{
				xdir = rand.Next(2) - 1;
				ydir = rand.Next(2) - 1;
			}
			else if (x == FullBounds.Left + quadSize / 2f && y == FullBounds.Bottom - quadSize / 2f)
			{
				xdir = rand.Next(2);
				ydir = rand.Next(2) - 1;
			}
 
			x += xdir * 14;
			y += ydir * 14 * (FullBounds.Height - quadSize) / (float)(FullBounds.Width - quadSize);
			x = x < FullBounds.Left + quadSize / 2f ? FullBounds.Left + quadSize / 2f : (x > FullBounds.Right - quadSize / 2f ? FullBounds.Right - quadSize / 2f : x);
			y = y < FullBounds.Top + quadSize / 2f ? FullBounds.Top + quadSize / 2f : (y > FullBounds.Bottom - quadSize / 2f ? FullBounds.Bottom - quadSize / 2f : y);
 
			angle += 0.05f;
 
			GL.Begin(BeginMode.Quads);
			GL.Color3(Color.OrangeRed);
			GL.Vertex3(-quadSize / 2f, -quadSize / 2f, 0.0f);
			GL.Vertex3(quadSize / 2f, -quadSize / 2f, 0.0f);
			GL.Vertex3(quadSize / 2f, quadSize / 2f, 0.0f);
			GL.Vertex3(-quadSize / 2f, quadSize / 2f, 0.0f);
			GL.End();
 
			GL.PopMatrix();
 
			gameWindow.SwapBuffers();
		}
 
		private void OnKeyDown(object sender, KeyboardKeyEventArgs e)
		{
			if (e.Key == Key.AltLeft)
			{
				altIsDown = true;
			}
			if (altIsDown && e.Key == Key.F4)
			{
				lock (gameWindows)
				{
					foreach (GameWindow window in gameWindows)
					{
						window.Close();
					}
				}
				renderThread.Abort();
				Environment.Exit(0);
			}
		}
 
		private void OnKeyUp(object sender, KeyboardKeyEventArgs e)
		{
			if (e.Key == Key.AltLeft)
			{
				altIsDown = false;
			}
		}
 
		private void InitializateView(Rectangle fullBounds)
		{
			if (FullBounds != fullBounds)
			{
				FullBounds = fullBounds;
				lock (gameWindows)
				{
					foreach (GameWindow window in gameWindows)
					{
						window.MakeCurrent();
 
						GL.Viewport(window.Size);
 
						GL.MatrixMode(MatrixMode.Projection);
						GL.LoadIdentity();
 
						GL.Ortho(window.Bounds.Left, window.Bounds.Right, window.Bounds.Bottom, window.Bounds.Top, 1, -1);
					}
				}
 
			}
		}
 
		private void Initialize(GameWindow gameWindow)
		{
			gameWindow.Keyboard.KeyDown += OnKeyDown;
			gameWindow.Keyboard.KeyUp += OnKeyUp;
			gameWindow.Closing += OnClosing;
		}
 
		private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			Deinitialize(sender as GameWindow);
		}
 
		private void Deinitialize(GameWindow gameWindow)
		{
			gameWindow.Keyboard.KeyDown -= OnKeyDown;
			gameWindow.Keyboard.KeyUp -= OnKeyUp;
		}
 
		private void UpdateMonitorsList()
		{
			List<Rectangle> screensTemp = new List<Rectangle>();
			foreach (DisplayDevice displayDevice in OpenTK.DisplayDevice.AvailableDisplays)
			{
				screensTemp.Add(displayDevice.Bounds);
			}
 
			screens = new Rectangle[screensTemp.Count];
			int i = 0;
			Rectangle fullScreenRect = screensTemp[0];
			foreach (Rectangle r in screensTemp)
			{
				if (r.X < fullScreenRect.X)
				{
					fullScreenRect.X = r.X;
				}
				if (r.Y < fullScreenRect.Y)
				{
					fullScreenRect.Y = r.Y;
				}
				screens[i] = r;
 
				lock (gameWindows)
				{
					if (i > gameWindows.Count - 1)
					{
						GameWindow gameWindow = new GameWindow() { Bounds = r, WindowBorder = WindowBorder.Hidden, WindowState = WindowState.Fullscreen };
						Initialize(gameWindow);
						gameWindows.Add(gameWindow);
						gameWindow.Visible = true;
					}
					else
					{
						gameWindows[i].Bounds = r;
					}
				}
 
				i++;
			}
			foreach (Rectangle r in screensTemp)
			{
				if (r.X + r.Width - fullScreenRect.X > fullScreenRect.Width)
				{
					fullScreenRect.Width = r.X + r.Width - fullScreenRect.X;
				}
				if (r.Y + r.Height - fullScreenRect.Y > fullScreenRect.Height)
				{
					fullScreenRect.Height = r.Y + r.Height - fullScreenRect.Y;
				}
			}
			InitializateView(fullScreenRect);
 
			foreach (Rectangle s in screens)
			{
				Console.WriteLine(s.ToString());
			}
		}
		#endregion
 
		#endregion
	}
}

I would be very grateful, if you will help me with this issue.