Decoupled GLContext from GLControl/GameWindow even more, by using IWindowInfo to pass data between them.

Implemented the IWindowInfo.GetInfoFrom methods.
Removed said methods from OpenTK/Platform/Utilities.
This commit is contained in:
the_fiddler 2007-09-09 11:52:09 +00:00
parent e0c514f96e
commit c1fa34087c
10 changed files with 291 additions and 103 deletions

View file

@ -11,11 +11,16 @@ using System.Text;
namespace OpenTK.Platform
{
/// <summary>
/// This interface supports OpenTK, and is not intended for use by OpenTK programs.
/// Provides a platform independent mechanism to interact with System.Windows.Forms.Control,
/// System.Windows.Forms.NativeWindow and OpenTK.GameWindow low-level implementation data.
/// </summary>
public interface IWindowInfo
{
IntPtr Handle { get; }
IWindowInfo Parent { get; }
void GetInfoFrom(System.Windows.Forms.Control control);
void GetInfoFrom(System.Windows.Forms.NativeWindow window);
void GetInfoFrom(OpenTK.GameWindow window);
void GetInfoFrom(IWindowInfo info);
}
}

View file

@ -82,11 +82,6 @@ namespace OpenTK.Platform
private static Platform platform = Platform.Unknown;
public static IWindowInfo GetWindowInfo(Form form)
{
throw new NotImplementedException();
}
#region public static IntPtr GetAddress(string function)
/// <summary>

View file

@ -13,16 +13,19 @@ using System.Runtime.InteropServices;
using OpenTK.OpenGL;
using System.Diagnostics;
namespace OpenTK.Platform.Windows
{
public sealed class WinGLContext : OpenTK.Platform.IGLContext, IDisposable
/// <summary>
/// Provides methods to create and control an opengl context on the Windows platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary>
internal sealed class WinGLContext : OpenTK.Platform.IGLContext, IDisposable
{
private IntPtr deviceContext;
private IntPtr renderContext;
static private IntPtr opengl32Handle;
static private readonly string opengl32Name = "OPENGL32.DLL";
private IntPtr windowHandle;
private WindowInfo windowInfo = new WindowInfo();
private DisplayMode mode;
@ -30,25 +33,33 @@ namespace OpenTK.Platform.Windows
#region --- Contructors ---
public WinGLContext()
: this(new DisplayMode(640, 480, new ColorMode(32), 16, 0, 0, 2, false, false, false, 0.0f))
internal WinGLContext()
: this(new DisplayMode(640, 480))
{
}
public WinGLContext(DisplayMode mode)
internal WinGLContext(DisplayMode mode)
{
Trace.WriteLine(String.Format("Creating opengl context (driver: {0})", this.ToString()));
//Trace.WriteLine(String.Format("Creating opengl context (driver: {0})", this.ToString()));
this.mode = mode;
}
public WinGLContext(DisplayMode mode, IWindowInfo info)
{
this.windowInfo = info as WindowInfo;
this.mode = mode;
}
#endregion
#region public void PrepareContext(IntPtr handle)
#region private void PrepareContext()
public void PrepareContext(IntPtr handle)
private void PrepareContext()
{
this.windowHandle = handle;
Debug.WriteLine(String.Format("OpenGL context is bound to handle: {0}", windowHandle));
if (this.windowInfo.Handle == IntPtr.Zero)
throw new ApplicationException("No Window Handle specified for opengl context.");
Debug.WriteLine(String.Format("OpenGL context is bound to handle: {0}", this.windowInfo.Handle));
// Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl.
if (opengl32Handle == IntPtr.Zero)
@ -68,7 +79,7 @@ namespace OpenTK.Platform.Windows
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle));
}
deviceContext = API.GetDC(windowHandle);
deviceContext = API.GetDC(this.windowInfo.Handle);
Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
Debug.Write("Setting pixel format... ");
@ -152,6 +163,8 @@ namespace OpenTK.Platform.Windows
public void CreateContext()
{
this.PrepareContext();
Debug.Write("Creating render context... ");
// Do not rely on OpenTK.Platform.Windows.Wgl - the context is not ready yet,
// and Wgl extensions will fail to load.
@ -302,7 +315,7 @@ namespace OpenTK.Platform.Windows
if (deviceContext != IntPtr.Zero)
{
if (!API.ReleaseDC(windowHandle, deviceContext))
if (!API.ReleaseDC(this.windowInfo.Handle, deviceContext))
{
//throw new ApplicationException("Could not release device context. Error: " + Marshal.GetLastWin32Error());
//Debug.Print("Could not destroy the device context. Error: {0}", Marshal.GetLastWin32Error());

View file

@ -35,8 +35,6 @@ namespace OpenTK.Platform.Windows
c.HandleCreated += new EventHandler(c_HandleCreated);
c.HandleDestroyed += new EventHandler(c_HandleDestroyed);
glContext = new WinGLContext(mode);
}
#endregion
@ -48,7 +46,10 @@ namespace OpenTK.Platform.Windows
try
{
glContext.PrepareContext((sender as Control).Handle);
if (glContext != null)
glContext.Dispose();
glContext = new WinGLContext(mode, new WindowInfo(sender as Control));
glContext.CreateContext();
glContext.MakeCurrent();
}

View file

@ -215,6 +215,7 @@ namespace OpenTK.Platform.Windows
public IWindowInfo WindowInfo
{
get { return window; }
private set { window = value as WindowInfo; }
}
#endregion
@ -287,16 +288,14 @@ namespace OpenTK.Platform.Windows
public void OnCreate(EventArgs e)
{
window = new WindowInfo();
window.Handle = this.Handle;
window.Parent = null;
this.WindowInfo = new WindowInfo(this);
Debug.Print("Window created: {0}", window);
try
{
glContext = new WinGLContext(this.mode);
glContext.PrepareContext(this.Handle);
glContext = new WinGLContext(this.mode, this.WindowInfo);
//glContext.PrepareContext(this.Handle);
glContext.CreateContext();
//glContext.MakeCurrent();
GL.LoadAll();

View file

@ -7,18 +7,59 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace OpenTK.Platform.Windows
{
/// <summary>
/// Describes a Windows window.
/// Describes a Windows.Form.Control, Windows.Forms.NativeWindow or OpenTK.GameWindow on the Windows platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary>
internal class WindowInfo : IWindowInfo
internal sealed class WindowInfo : IWindowInfo
{
private IntPtr handle;
private WindowInfo parent;
public WindowInfo()
{
}
public WindowInfo(IWindowInfo info)
{
if (info == null)
throw new ArgumentException("WindowInfo cannot be null.");
this.Handle = info.Handle;
this.Parent = info.Parent;
}
public WindowInfo(Control control)
{
if (control == null)
throw new ArgumentException("Control cannot be null.");
this.Handle = control.Handle;
this.Parent = control.Parent != null ? new WindowInfo(control.Parent) : this.Parent;
}
public WindowInfo(NativeWindow window)
{
if (window == null)
throw new ArgumentException("NativeWindow cannot be null.");
this.Handle = window.Handle;
this.Parent = null;
}
public WindowInfo(GameWindow window)
{
if (window == null)
throw new ArgumentException("GameWindow cannot be null.");
this.Handle = window.WindowInfo.Handle;
this.Parent = window.WindowInfo.Parent;
}
#region --- IWindowInfo Members ---
public IntPtr Handle
@ -30,7 +71,57 @@ namespace OpenTK.Platform.Windows
public IWindowInfo Parent
{
get { return parent; }
internal set { parent = value as WindowInfo; }
internal set
{
parent = value as WindowInfo;
}
}
public void GetInfoFrom(Control control)
{
if (control == null)
throw new ArgumentException("Control cannot be null.");
this.Handle = control.Handle;
if (control.Parent == null)
{
this.Parent = null;
}
else
{
if (this.Parent == null)
this.Parent = new WindowInfo(control.Parent);
else
this.Parent.GetInfoFrom(control.Parent);
}
}
public void GetInfoFrom(NativeWindow window)
{
if (window == null)
throw new ArgumentException("NativeWindow cannot be null.");
this.Handle = window.Handle;
this.Parent = null;
}
public void GetInfoFrom(GameWindow window)
{
if (window == null)
throw new ArgumentException("GameWindow cannot be null.");
WindowInfo info = (window.WindowInfo as Windows.WindowInfo);
this.Handle = info.Handle;
this.Parent = info.Parent;
}
public void GetInfoFrom(IWindowInfo info)
{
if (info == null)
throw new ArgumentException("IWindowInfo cannot be null.");
this.Handle = info.Handle;
this.Parent = info.Parent;
}
#endregion
@ -40,6 +131,5 @@ namespace OpenTK.Platform.Windows
return String.Format("Windows.WindowInfo: Handle {0}, Parent ({1})",
this.Handle, this.Parent != null ? this.Parent.ToString() : "null");
}
}
}

View file

@ -7,44 +7,99 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace OpenTK.Platform.X11
{
/// <summary>
/// Describes an X11 window.
/// Describes a Windows.Form.Control, Windows.Forms.NativeWindow or OpenTK.GameWindow on the X11 platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary>
public class WindowInfo : IWindowInfo
internal sealed class WindowInfo : IWindowInfo
{
public WindowInfo()
{
visinfo = new XVisualInfo();
}
public WindowInfo(WindowInfo parent)
{
this.Handle = parent.Handle;
this.TopLevelWindow = parent.TopLevelWindow;
this.Screen = parent.Screen;
this.Display = parent.Display;
this.RootWindow = parent.RootWindow;
this.VisualInfo = parent.VisualInfo;
this.Parent = parent;
}
private IntPtr rootWindow, handle, topLevelWindow, display;
private int screen;
private WindowInfo parent;
private XVisualInfo visinfo;
public IntPtr RootWindow { get { return rootWindow; } set { rootWindow = value; } }
public IntPtr TopLevelWindow { get { return topLevelWindow; } set { topLevelWindow = value; } }
public IntPtr Display { get { return display; } set { display = value; } }
public int Screen { get { return screen; } set { screen = value; } }
public XVisualInfo VisualInfo { get { return visinfo; } set { visinfo = value; } }
public WindowInfo()
{
visinfo = new XVisualInfo();
}
public IntPtr Handle { get { return handle; } set { handle = value; } }
public IWindowInfo Parent { get { return parent; } set { parent = value as WindowInfo; } }
public WindowInfo(Control control)
{
throw new NotImplementedException();
}
public WindowInfo(NativeWindow window)
{
throw new NotImplementedException();
}
public WindowInfo(GameWindow window)
{
throw new NotImplementedException();
}
public WindowInfo(WindowInfo info)
{
this.GetInfoFrom(info);
}
#region --- IWindowInfo Members ---
public void GetInfoFrom(Control control)
{
if (control == null)
throw new ArgumentException("GameWindow cannot be null.");
throw new NotImplementedException();
}
public void GetInfoFrom(NativeWindow window)
{
if (window == null)
throw new ArgumentException("GameWindow cannot be null.");
throw new NotImplementedException();
}
public void GetInfoFrom(GameWindow window)
{
if (window == null)
throw new ArgumentException("GameWindow cannot be null.");
this.GetInfoFrom(window.WindowInfo as X11.WindowInfo);
}
public void GetInfoFrom(IWindowInfo info)
{
if (info == null)
throw new ArgumentException("WindowInfo cannot be null");
WindowInfo winfo = info as WindowInfo;
this.Handle = info.Handle;
this.Parent = info.Parent;
this.RootWindow = winfo.RootWindow;
this.TopLevelWindow = winfo.TopLevelWindow;
this.Display = winfo.Display;
this.Screen = winfo.Screen;
this.VisualInfo = winfo.VisualInfo;
}
public IntPtr Handle { get { return handle; } internal set { handle = value; } }
public IWindowInfo Parent { get { return parent; } internal set { parent = value as WindowInfo; } }
#endregion
public IntPtr RootWindow { get { return rootWindow; } internal set { rootWindow = value; } }
public IntPtr TopLevelWindow { get { return topLevelWindow; } internal set { topLevelWindow = value; } }
public IntPtr Display { get { return display; } internal set { display = value; } }
public int Screen { get { return screen; } internal set { screen = value; } }
public XVisualInfo VisualInfo { get { return visinfo; } internal set { visinfo = value; } }
public override string ToString()
{

View file

@ -15,29 +15,55 @@ using OpenTK.OpenGL;
namespace OpenTK.Platform.X11
{
/// <summary>
/// Provides methods to create and control an opengl context on X11.
/// Provides methods to create and control an opengl context on the X11 platform.
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary>
public sealed class X11GLContext : OpenTK.Platform.IGLContext
internal sealed class X11GLContext : OpenTK.Platform.IGLContext
{
private IntPtr context;
private DisplayMode mode;
internal WindowInfo windowInfo;
internal IntPtr visual;
private WindowInfo windowInfo;
private IntPtr visual;
private bool disposed;
#region --- Public Constructor ---
#region --- Constructors ---
internal X11GLContext()
: this(new DisplayMode())
internal X11GLContext() : this(new DisplayMode(), new WindowInfo())
{
}
internal X11GLContext(DisplayMode mode)
internal X11GLContext(DisplayMode mode) : this(mode, new WindowInfo())
{
this.windowInfo = new WindowInfo();
}
internal X11GLContext(DisplayMode mode, IWindowInfo info)
{
if (info == null)
throw new ArgumentException("IWindowInfo cannot be null.");
this.windowInfo = info as WindowInfo;
this.mode = mode;
this.ChooseContext();
}
#endregion
#region internal XVisualInfo VisualInfo
internal XVisualInfo VisualInfo
{
get { return windowInfo.VisualInfo; }
}
#endregion
#region internal IntPtr Handle
internal IntPtr Handle
{
get { return windowInfo.Handle; }
set { windowInfo.Handle = value; }
}
#endregion
@ -62,12 +88,10 @@ namespace OpenTK.Platform.X11
#endregion
#region internal void PrepareContext(X11.WindowInfo info)
#region private void PrepareContext()
internal void PrepareContext(X11.WindowInfo info)
private void ChooseContext()
{
this.windowInfo = new WindowInfo(info);
List<int> visualAttributes = new List<int>();
if (mode == null)

View file

@ -25,6 +25,8 @@ namespace OpenTK.Platform.X11
#region --- Contructors ---
#region public X11GLControl(UserControl c)
public X11GLControl(UserControl c)
{
Debug.WriteLine("Creating opengl control (X11GLControl driver)");
@ -37,44 +39,42 @@ namespace OpenTK.Platform.X11
throw new ArgumentException("UserControl c may not be null.");
}
//this.mode = mode;
glContext = new X11GLContext(null);
c.HandleCreated += new EventHandler(c_HandleCreated);
c.HandleDestroyed += new EventHandler(c_HandleDestroyed);
xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
Debug.Write("System.Windows.Forms.XplatUIX11: ");
if (xplatui == null)
throw new ApplicationException("Could not get System.Windows.Forms.XplatUIX11 through reflection. Unsupported platform or Mono runtime version, aborting.");
if (xplatui != null)
{
info.Display = (IntPtr)xplatui.GetField("DisplayHandle",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.Display = (IntPtr)xplatui.GetField("DisplayHandle",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.Screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
Debug.Print("Data read from System.Windows.Forms.XplatUIX11: {0}", info.ToString());
info.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
//this.mode = mode;
glContext = new X11GLContext(null, info);
//glContext.PrepareContext(info);
info.Screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.VisualInfo = glContext.VisualInfo;
Debug.Print("Display: {0}, Screen: {1}, Root Window: {2}, GLControl: {3}",
info.Display, info.Screen, info.RootWindow, info.Handle);
Debug.Print("Setting XplatUIX11.CustomVisual");
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, info.VisualInfo.visual);
glContext.PrepareContext(info);
info.VisualInfo = glContext.windowInfo.VisualInfo;
Debug.Print("Setting XplatUIX11.CustomVisual");
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, info.VisualInfo.visual);
Debug.Print("Setting XplatUIX11.CustomColormap");
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(info.Display, info.RootWindow, info.VisualInfo.visual, 0));
}
Debug.Print("Setting XplatUIX11.CustomColormap");
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(info.Display, info.RootWindow, info.VisualInfo.visual, 0));
Debug.Unindent();
}
#endregion
#region void c_HandleCreated(object sender, EventArgs e)
void c_HandleCreated(object sender, EventArgs e)
{
UserControl c = (sender as UserControl);
@ -83,7 +83,7 @@ namespace OpenTK.Platform.X11
try
{
glContext.windowInfo.Handle = info.Handle = (sender as UserControl).Handle;
glContext.Handle = info.Handle = (sender as UserControl).Handle;
glContext.CreateContext(null, true);
glContext.MakeCurrent();
}
@ -98,12 +98,18 @@ namespace OpenTK.Platform.X11
}
}
#endregion
#region void c_HandleDestroyed(object sender, EventArgs e)
void c_HandleDestroyed(object sender, EventArgs e)
{
Debug.Print("X11GLControl handle destroyed, disposing X11GLContext.");
glContext.Dispose();
}
#endregion
#region private IntPtr FindColormap()
/// <summary>
@ -122,7 +128,7 @@ namespace OpenTK.Platform.X11
return Functions.XDefaultColormap(info.Display, info.Screen);
}
return API.CreateColormap(info.Display, info.RootWindow, glContext.windowInfo.VisualInfo.visual, 0/*AllocNone*/);
return API.CreateColormap(info.Display, info.RootWindow, glContext.VisualInfo.visual, 0/*AllocNone*/);
}
#endregion

View file

@ -255,9 +255,9 @@ namespace OpenTK.Platform.X11
Debug.Print("Display: {0}, Screen {1}, Root window: {2}",
window.Display, window.Screen, window.RootWindow);
glContext = new X11GLContext(mode);
glContext.PrepareContext(window);
window.VisualInfo = glContext.windowInfo.VisualInfo;
glContext = new X11GLContext(mode, window);
//glContext.PrepareContext(window);
window.VisualInfo = glContext.VisualInfo;
// Create a window on this display using the visual above
Debug.Write("Opening render window... ");
@ -303,7 +303,7 @@ namespace OpenTK.Platform.X11
Debug.Print("done! (id: {0})", window.Handle);
glContext.windowInfo.Handle = window.Handle;
glContext.Handle = window.Handle;
glContext.CreateContext(null, true);
glContext.MakeCurrent();