Renamed ColorDepth to ColorFormat, to avoid class with System.Drawing.ColorDepth.

Update X11 stack to use System.Windows.Forms.XPlatUI for its Display, Screen and RootWindow.
Fixed mode setting for X11GLControl.
Fixed X11 shutdown (was generating X11 errors).
Added DeviceContext getter to WinWindowInfo.
Made IWindowInfo disposable.
Added documentation to many public methods.
Worked around a Mono 1.2.4 bug with Handle creation on Windows.Forms.Control.
Updated GL.BuildExtensionList to correctly parse GL_VERSION when in indirect rendering mode.
Fixed crash errors in X11GLContext.CreateContext and X11GraphicsMode.
Added a ref overload to Glx.ChooseVisual()
IGraphicsContext.MakeCurrent now takes an IWindowInfo parameter. This allows the user to change to window is context is bound to (untested).
Renamed XyzWindowInfo.Handle to XyzWindowInfo.WindowHandle.
This commit is contained in:
the_fiddler 2008-03-03 12:44:56 +00:00
parent 624ca0d9c5
commit 37c40f16eb
26 changed files with 709 additions and 634 deletions

View file

@ -14,7 +14,7 @@ namespace OpenTK
/// <para>A ColorMode contains Red, Green, Blue and Alpha components that descibe
/// the allocated bits per pixel for the corresponding color.</para>
/// </remarks>
[Obsolete("Use OpenTK.Graphics.ColorDepth instead.")]
[Obsolete("Use OpenTK.Graphics.ColorFormat instead.")]
public sealed class ColorMode
{
byte red, green, blue, alpha;

View file

@ -18,7 +18,7 @@ namespace OpenTK
/// <summary>Contains configuration options for OpenTK.</summary>
internal static class Configuration
{
static bool runningOnWindows, runningOnX11, runningOnOSX;
static bool runningOnWindows, runningOnX11, runningOnOSX, runningOnLinux;
#region --- Constructors ---
@ -71,6 +71,13 @@ namespace OpenTK
#endregion
#region internal static bool RunningOnLinux
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on an X11 platform.</summary>
internal static bool RunningOnLinux { get { return runningOnLinux; } }
#endregion
#region internal static bool RunningOnOSX
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on an OSX platform.</summary>

View file

@ -231,7 +231,7 @@ namespace OpenTK
private set { this.refreshRate = value; }
}
#region public ColorDepth Color
#region public ColorFormat Color
[Obsolete("Use GraphicsMode.Color instead.")]
public ColorMode Color

View file

@ -1,6 +1,8 @@
#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*/
#endregion
@ -15,6 +17,7 @@ using System.Windows.Forms;
using OpenTK.Platform;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Diagnostics;
namespace OpenTK
{
@ -24,8 +27,9 @@ namespace OpenTK
public partial class GLControl : UserControl
{
IGraphicsContext context;
IGLControl implementation;
GraphicsMode format;
IGLControlHelper helper;
IWindowInfo window_info;
#region --- Constructor ---
@ -36,15 +40,17 @@ namespace OpenTK
: this(GraphicsMode.Default)
{ }
/// <summary>
/// Constructs a new GLControl with the specified DisplayMode.
/// </summary>
/// <param name="mode"></param>
/// <summary>This method is obsolete and will be removed in future versions.</summary>
/// <param name="mode">Obsolete.</param>
public GLControl(DisplayMode mode)
: this(mode.ToGraphicsMode())
{ }
public GLControl(GraphicsMode format)
/// <summary>
/// Constructs a new GLControl with the specified GraphicsMode.
/// </summary>
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the control.</param>
public GLControl(GraphicsMode mode)
{
InitializeComponent();
@ -53,7 +59,21 @@ namespace OpenTK
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
DoubleBuffered = false;
this.format = format;
this.format = mode;
// On Windows, you first need to create the window, then set the pixel format.
// On X11, you first need to select the visual, then create the window.
// On OSX, ???
// Right now, pixel formats/visuals are selected during context creation. In the future,
// it would be better to decouple selection from context creation, which will allow us
// to clean up this hacky code. The best option is to do this along with multisampling
// support.
if (Configuration.RunningOnWindows)
implementation = new OpenTK.Platform.Windows.WinGLControl(mode, this);
else if (Configuration.RunningOnX11)
implementation = new OpenTK.Platform.X11.X11GLControl(mode, this);
else if (Configuration.RunningOnOSX)
throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information.");
this.CreateControl();
}
@ -62,23 +82,50 @@ namespace OpenTK
#region --- Protected Methods ---
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
// Workaround Mono 1.2.4 bug where the OnHandleCreated event isn't raised at the correct time.
if (this.Context == null)
{
if (!DesignMode)
this.Context = implementation.CreateContext();
else
this.Context = new DummyGLContext(null);
this.window_info = implementation.WindowInfo;
this.MakeCurrent();
((IGraphicsContextInternal)this.Context).LoadAll();
}
}
/// <summary>Raises the HandleCreated event.</summary>
/// <param name="e">Not used.</param>
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (Configuration.RunningOnWindows)
helper = new Platform.Windows.WinGLControlHelper(this);
else if (Configuration.RunningOnX11)
throw new NotImplementedException();
//helper = new Platform.X11.X11GLControlHelper(this);
else if (Configuration.RunningOnOSX)
throw new NotImplementedException();
this.CreateContext();
// On Mono 1.2.4 the Resize event is raised before this :/
//if (!DesignMode)
// this.Context = implementation.CreateContext();
//else
// this.Context = new DummyGLContext(null);
//this.window_info = implementation.WindowInfo;
//this.MakeCurrent();
//((IGraphicsContextInternal)this.Context).LoadAll();
}
/// <summary>Raises the HandleDestroyed event.</summary>
/// <param name="e">Not used.</param>
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
this.DestroyContext();
if (this.Context != null)
{
this.Context.Dispose();
this.Context = null;
}
this.window_info = null;
}
#endregion
@ -105,7 +152,7 @@ namespace OpenTK
/// </summary>
public void MakeCurrent()
{
Context.MakeCurrent();
this.Context.MakeCurrent(this.window_info);
}
#endregion
@ -117,19 +164,44 @@ namespace OpenTK
/// </summary>
public void CreateContext()
{
if (context != null)
throw new InvalidOperationException("GLControl already contains an OpenGL context.");
if (format == null)
format = GraphicsMode.Default;
if (context != null) throw new InvalidOperationException("GLControl already contains an OpenGL context.");
if (format == null) format = GraphicsMode.Default;
if (!this.DesignMode)
{
// Note: Mono's implementation of Windows.Forms on X11 does not allow the context to
// have a different colordepth from the parent window.
context = new GraphicsContext(format, helper.WindowInfo);
//context = new GraphicsContext(format, helper.WindowInfo);
if (Configuration.RunningOnX11)
{
//OpenTK.Platform.X11.X11WindowInfo info =
// (context as IGraphicsContextInternal).Info as OpenTK.Platform.X11.X11WindowInfo;
//IntPtr visual = info.VisualInfo.visual;
//IntPtr colormap = OpenTK.Platform.X11.API.CreateColormap(info.Display, info.RootWindow, visual, 0);
//IntPtr visual = ((OpenTK.Platform.X11.X11WindowInfo)helper.WindowInfo).VisualInfo.visual;
//IntPtr colormap = OpenTK.Platform.X11.API.CreateColormap(info.Display, info.RootWindow, visual, 0);
//Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
//if (xplatui == null)
// throw new PlatformNotSupportedException(
// "System.Windows.Forms.XplatUIX11 missing. Unsupported platform or Mono runtime version, aborting.");
//xplatui.GetField("CustomVisual",
// System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
// .SetValue(null, visual);
//xplatui.GetField("CustomColormap",
// System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
// .SetValue(null, colormap);
//Debug.Print("Mono/X11 System.Windows.Forms custom visual and colormap installed succesfully.");
}
}
else
context = new DummyGLContext(format);
this.MakeCurrent();
(context as IGraphicsContextInternal).LoadAll();
}
#endregion
@ -156,7 +228,7 @@ namespace OpenTK
[Browsable(false)]
public bool IsIdle
{
get { return helper.IsIdle; }
get { return implementation.IsIdle; }
}
#endregion
@ -233,6 +305,9 @@ namespace OpenTK
/// <summary>Grabs a screenshot of the frontbuffer contents.</summary>
/// <returns>A System.Drawing.Bitmap, containing the contents of the frontbuffer.</returns>
/// <exception cref="GraphicsContextException">
/// Occurs when no OpenTK.Graphics.GraphicsContext is current in the calling thread.
/// </exception>
public Bitmap GrabScreenshot()
{
Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);

View file

@ -81,21 +81,6 @@ namespace OpenTK
#endregion
#region --- Private Methods ---
bool MustResize
{
get { return glWindow.Width != this.Width || glWindow.Height != this.Height; }
}
bool HasMainLoop
{
get { return hasMainLoop; }
set { hasMainLoop = value; }
}
#endregion
#region --- Contructors ---
#region public GameWindow()
@ -183,11 +168,8 @@ namespace OpenTK
try
{
glWindow.CreateWindow(width, height, mode, out glContext);
Debug.Print("1");
glContext.MakeCurrent();
Debug.Print("2");
glContext.MakeCurrent(this.WindowInfo);
(glContext as IGraphicsContextInternal).LoadAll();
Debug.Print("3");
}
//catch (GraphicsContextException e)
catch (Exception e)
@ -201,7 +183,7 @@ namespace OpenTK
if ((options & GameWindowFlags.Fullscreen) != 0)
{
device.ChangeResolution(width, height, mode.ColorDepth.BitsPerPixel, 0);
device.ChangeResolution(width, height, mode.ColorFormat.BitsPerPixel, 0);
this.Fullscreen = true;
}
@ -261,6 +243,25 @@ namespace OpenTK
#endregion
#region bool MustResize
bool MustResize
{
get { return glWindow.Width != this.Width || glWindow.Height != this.Height; }
}
#endregion
#region bool HasMainLoop
bool HasMainLoop
{
get { return hasMainLoop; }
set { hasMainLoop = value; }
}
#endregion
#endregion
#region --- Public Methods ---
@ -607,7 +608,7 @@ namespace OpenTK
}
catch (GameWindowExitException)
{
Trace.WriteLine("GameWindowExitException caught - exiting main loop.");
Debug.WriteLine("GameWindowExitException caught - exiting main loop.");
}
finally
{
@ -616,13 +617,13 @@ namespace OpenTK
OnUnloadInternal(EventArgs.Empty);
if (this.Exists)
if (Exists)
{
if (Exists)
glWindow.DestroyWindow();
while (this.Exists)
this.ProcessEvents();
glContext.Dispose();
glWindow.DestroyWindow();
}
while (this.Exists)
this.ProcessEvents();
}
}
@ -899,7 +900,7 @@ namespace OpenTK
/// <remarks>Calling this function is equivalent to calling Context.SwapBuffers()</remarks>
public void SwapBuffers()
{
Context.SwapBuffers();
this.Context.SwapBuffers();
}
#endregion
@ -1310,7 +1311,8 @@ namespace OpenTK
private void DisposeInternal()
{
Dispose(); // User overridable Dispose method.
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
@ -1318,8 +1320,6 @@ namespace OpenTK
/// </summary>
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool manual)
@ -1328,9 +1328,11 @@ namespace OpenTK
{
if (manual)
{
if (glContext != null)
glContext.Dispose();
if (glWindow != null)
{
glContext.Dispose();
glWindow.Dispose();
glWindow = null;
}
@ -1339,6 +1341,7 @@ namespace OpenTK
}
}
/// <summary>Finalizes unmanaged resources consumed by the GameWindow.</summary>
~GameWindow()
{
Dispose(false);

View file

@ -12,12 +12,12 @@ using System.Text;
namespace OpenTK.Graphics
{
/// <summary>Defines the ColorDepth component of a GraphicsMode.</summary>
/// <summary>Defines the ColorFormat component of a GraphicsMode.</summary>
/// <remarks>
/// <para>A ColorDepth contains Red, Green, Blue and Alpha components that descibe
/// <para>A ColorFormat contains Red, Green, Blue and Alpha components that descibe
/// the allocated bits per pixel for the corresponding color.</para>
/// </remarks>
public struct ColorDepth
public struct ColorFormat
{
byte red, green, blue, alpha;
bool isIndexed;
@ -26,10 +26,10 @@ namespace OpenTK.Graphics
#region --- Constructors ---
/// <summary>
/// Constructs a new ColorDepth with the specified aggregate bits per pixel.
/// Constructs a new ColorFormat with the specified aggregate bits per pixel.
/// </summary>
/// <param name="bpp">The bits per pixel sum for the Red, Green, Blue and Alpha color channels.</param>
public ColorDepth(int bpp)
public ColorFormat(int bpp)
{
if (bpp < 0)
throw new ArgumentOutOfRangeException("bpp", "Must be greater or equal to zero.");
@ -73,14 +73,14 @@ namespace OpenTK.Graphics
}
/// <summary>
/// Constructs a new ColorDepth with the specified bits per pixel for
/// Constructs a new ColorFormat with the specified bits per pixel for
/// the Red, Green, Blue and Alpha color channels.
/// </summary>
/// <param name="red">Bits per pixel for the Red color channel.</param>
/// <param name="green">Bits per pixel for the Green color channel.</param>
/// <param name="blue">Bits per pixel for the Blue color channel.</param>
/// <param name="alpha">Bits per pixel for the Alpha color channel.</param>
public ColorDepth(int red, int green, int blue, int alpha)
public ColorFormat(int red, int green, int blue, int alpha)
{
if (red < 0 || green < 0 || blue < 0 || alpha < 0)
throw new ArgumentOutOfRangeException("Arguments must be greater or equal to zero.");
@ -106,7 +106,7 @@ namespace OpenTK.Graphics
public int Blue { get { return blue; } private set { blue = (byte)value; } }
/// <summary>Gets the bits per pixel for the Alpha channel.</summary>
public int Alpha { get { return alpha; } private set { alpha = (byte)value; } }
/// <summary>Gets a System.Boolean indicating whether this ColorDepth is indexed.</summary>
/// <summary>Gets a System.Boolean indicating whether this ColorFormat is indexed.</summary>
public bool IsIndexed { get { return isIndexed; } private set { isIndexed = value; } }
/// <summary>Gets the sum of Red, Green, Blue and Alpha bits per pixel.</summary>
public int BitsPerPixel { get { return bitsPerPixel; } private set { bitsPerPixel = value; } }
@ -116,16 +116,16 @@ namespace OpenTK.Graphics
#region --- Operator Overloads ---
/// <summary>
/// Converts the specified bpp into a new ColorDepth.
/// Converts the specified bpp into a new ColorFormat.
/// </summary>
/// <param name="bpp">The bits per pixel to convert.</param>
/// <returns>A ColorDepth with the specified bits per pixel.</returns>
public static implicit operator ColorDepth(int bpp)
/// <returns>A ColorFormat with the specified bits per pixel.</returns>
public static implicit operator ColorFormat(int bpp)
{
return new ColorDepth(bpp);
return new ColorFormat(bpp);
}
//public static implicit operator int(ColorDepth mode)
//public static implicit operator int(ColorFormat mode)
//{
// return mode.BitsPerPixel;
//}
@ -136,10 +136,10 @@ namespace OpenTK.Graphics
public override bool Equals(object obj)
{
return (obj is ColorDepth) ? (this == (ColorDepth)obj) : false;
return (obj is ColorFormat) ? (this == (ColorFormat)obj) : false;
}
public static bool operator ==(ColorDepth left, ColorDepth right)
public static bool operator ==(ColorFormat left, ColorFormat right)
{
if ((object)left == (object)null && (object)right != (object)null ||
(object)left != (object)null && (object)right == (object)null)
@ -154,7 +154,7 @@ namespace OpenTK.Graphics
left.Alpha == right.Alpha;
}
public static bool operator !=(ColorDepth left, ColorDepth right)
public static bool operator !=(ColorFormat left, ColorFormat right)
{
return !(left == right);
}

View file

@ -75,6 +75,7 @@ namespace OpenTK.Graphics
Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
available_displays.Count, primary ? "primary" : "secondary", available_resolutions.Count);
Debug.Indent();
foreach (DisplayResolution res in available_resolutions)
Debug.Print(res == current_resolution ? String.Format(">> {0} <<", res.ToString()) : res.ToString());

View file

@ -28,8 +28,7 @@ namespace OpenTK.Graphics
static bool direct_rendering = true;
static object context_lock = new object();
// Maps OS-specific context handles to GraphicsContext weak references.
static Dictionary<ContextHandle, WeakReference> available_contexts =
new Dictionary<ContextHandle, WeakReference>();
static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
#region public GraphicsContext(DisplayMode mode, IWindowInfo window)
@ -44,7 +43,9 @@ namespace OpenTK.Graphics
#region public GraphicsContext(GraphicsMode format, IWindowInfo window)
/// <summary>Constructs a new GraphicsContext with the specified format, and attaches it to the specified window.</summary>
/// <summary>
/// Constructs a new GraphicsContext with the specified format, and attaches it to the specified window.
/// </summary>
/// <param name="format">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
public GraphicsContext(GraphicsMode format, IWindowInfo window)
@ -75,8 +76,7 @@ namespace OpenTK.Graphics
else if (Configuration.RunningOnX11)
implementation = new OpenTK.Platform.X11.X11GLContext(format, window, shareContext, DirectRendering);
else
throw new PlatformNotSupportedException(
"Your platform is not currently supported. Please, check http://www.opentk.com for an updated version.");
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
//(implementation as IGraphicsContextInternal).LoadAll();
@ -94,7 +94,7 @@ namespace OpenTK.Graphics
void ContextDestroyed(IGraphicsContext context, EventArgs e)
{
this.Destroy -= ContextDestroyed;
available_contexts.Remove(((IGraphicsContextInternal)this).Context);
//available_contexts.Remove(((IGraphicsContextInternal)this).Context);
}
#endregion
@ -121,13 +121,13 @@ namespace OpenTK.Graphics
}
return null;
}
set
{
if (value != null)
value.MakeCurrent();
else if (CurrentContext != null)
CurrentContext.IsCurrent = false;
}
//set
//{
// if (value != null)
// value.MakeCurrent();
// else if (CurrentContext != null)
// CurrentContext.IsCurrent = false;
//}
}
#endregion
@ -229,11 +229,15 @@ namespace OpenTK.Graphics
}
/// <summary>
/// Makes this context the current rendering target.
/// Makes the GraphicsContext the current rendering target.
/// </summary>
public void MakeCurrent()
/// <param name="info">A System.Platform.IWindowInfo structure for the window this context is bound to.</param>
/// <remarks>
/// You can use this method to bind the GraphicsContext to a different window than the one it was created from.
/// </remarks>
public void MakeCurrent(IWindowInfo info)
{
implementation.MakeCurrent();
implementation.MakeCurrent(info);
}
/// <summary>
@ -242,7 +246,7 @@ namespace OpenTK.Graphics
public bool IsCurrent
{
get { return implementation.IsCurrent; }
set { implementation.IsCurrent = value; }
//set { implementation.IsCurrent = value; }
}
/// <summary>
@ -283,6 +287,7 @@ namespace OpenTK.Graphics
get { return ((IGraphicsContextInternal)implementation).Context; }
}
/*
/// <summary>
/// Gets the IWindowInfo describing the window associated with this context.
/// </summary>
@ -291,6 +296,7 @@ namespace OpenTK.Graphics
get { return (implementation as IGraphicsContextInternal).Info; }
//internal set { (implementation as IGLContextInternal).Info = value; }
}
*/
/// <summary>
/// Gets the DisplayMode of the context.
@ -385,11 +391,15 @@ namespace OpenTK.Graphics
{
if (!disposed)
{
// TODO: Check if this is safe
//if (manual)
if (manual)
{
Debug.WriteLine("Disposing context.");
available_contexts.Remove((this as IGraphicsContextInternal).Context);
// TODO: Check if this is safe
if (implementation != null)
implementation.Dispose();
}
disposed = true;
}
}
@ -402,10 +412,17 @@ namespace OpenTK.Graphics
#endregion
}
#region public class GraphicsException : Exception
/// <summary>Represents errors related to Graphics operations.</summary>
public class GraphicsException : Exception
{
/// <summary>Constructs a new GraphicsException.</summary>
public GraphicsException() : base() { }
/// <summary>Constructs a new GraphicsException with the specified excpetion message.</summary>
/// <param name="message"></param>
public GraphicsException(string message) : base(message) { }
}
#endregion
}

View file

@ -15,143 +15,190 @@ namespace OpenTK.Graphics
/// <summary>Defines the format for graphics operations.</summary>
public class GraphicsMode
{
ColorDepth color_format, accumulator_format;
ColorFormat color_format, accumulator_format;
int depth, stencil, buffers, samples;
bool stereo;
IntPtr index; // The id of the pixel format or visual.
static IGraphicsMode implementation;
static object mode_selection_lock = new object();
#region --- Constructors ---
#region internal GraphicsFormat(GraphicsFormat mode)
#region static GraphicsMode()
static GraphicsMode()
{
if (Configuration.RunningOnWindows)
implementation = new OpenTK.Platform.Windows.WinGraphicsMode();
else if (Configuration.RunningOnX11)
implementation = new OpenTK.Platform.X11.X11GraphicsMode();
else
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
}
#endregion
#region internal GraphicsMode(GraphicsMode mode)
/// <internal />
/// <summary>Constructs a new GraphicsFormat from the given GraphicsFormat.</summary>
/// <param name="mode"></param>
internal GraphicsMode(GraphicsMode mode)
: this(mode.ColorDepth, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo) { }
: this(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo) { }
#endregion
#region public GraphicsFormat()
#region internal GraphicsMode((IntPtr index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
/// <summary>Constructs a new GraphicsFormat with sensible default parameters.</summary>
public GraphicsMode()
: this(Default)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
public GraphicsMode(ColorDepth color)
: this(color, Default.Depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
public GraphicsMode(ColorDepth color, int depth)
: this(color, depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth, int stencil)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
public GraphicsMode(ColorDepth color, int depth, int stencil)
: this(color, depth, stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth, int stencil, int samples)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
public GraphicsMode(ColorDepth color, int depth, int stencil, int samples)
: this(color, depth, stencil, samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorDepth of the accumilliary buffer.</param>
public GraphicsMode(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum)
: this(color, depth, stencil, samples, accum, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum, int buffers)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorDepth of the accumilliary buffer.</param>
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
public GraphicsMode(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum, int buffers)
: this(color, depth, stencil, samples, accum, buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsFormat(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum, int buffers, bool stereo)
/// <summary>Constructs a new GraphicsFormat with the specified parameters.</summary>
/// <param name="color">The ColorDepth of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorDepth of the accumilliary buffer.</param>
/// <param name="stereo">Set to true for a GraphicsFormat with stereographic capabilities.</param>
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
public GraphicsMode(ColorDepth color, int depth, int stencil, int samples, ColorDepth accum, int buffers, bool stereo)
internal GraphicsMode(IntPtr index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo)
{
if (depth < 0) throw new ArgumentOutOfRangeException("depth", "Must be greater than, or equal to zero.");
if (stencil < 0) throw new ArgumentOutOfRangeException("stencil", "Must be greater than, or equal to zero.");
if (buffers <= 0) throw new ArgumentOutOfRangeException("buffers", "Must be greater than zero.");
if (samples < 0) throw new ArgumentOutOfRangeException("samples", "Must be greater than, or equal to zero.");
this.ColorDepth = color;
this.Depth = depth;
this.Stencil = stencil;
this.AccumulatorFormat = accum;
this.Buffers = buffers;
this.Stereo = stereo;
// This method will search for the closest
if (index == IntPtr.Zero)
{
GraphicsMode mode;
lock (mode_selection_lock)
{
mode = implementation.SelectGraphicsMode(color, depth, stencil, samples, accum, buffers, stereo);
}
this.Index = mode.Index;
this.ColorFormat = mode.ColorFormat;
this.Depth = mode.Depth;
this.Stencil = mode.Stencil;
this.Samples = mode.Samples;
this.AccumulatorFormat = mode.AccumulatorFormat;
this.Buffers = mode.Buffers;
this.Stereo = mode.Stereo;
}
else
{
this.Index = index;
this.ColorFormat = color;
this.Depth = depth;
this.Stencil = stencil;
this.Samples = samples;
this.AccumulatorFormat = accum;
this.Buffers = buffers;
this.Stereo = stereo;
}
}
#endregion
#region public GraphicsMode()
/// <summary>Constructs a new GraphicsMode with sensible default parameters.</summary>
public GraphicsMode()
: this(Default)
{ }
#endregion
#region public GraphicsMode(ColorFormat color)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
public GraphicsMode(ColorFormat color)
: this(color, Default.Depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
public GraphicsMode(ColorFormat color, int depth)
: this(color, depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth, int stencil)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
public GraphicsMode(ColorFormat color, int depth, int stencil)
: this(color, depth, stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth, int stencil, int samples)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples)
: this(color, depth, stencil, samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum)
: this(color, depth, stencil, samples, accum, Default.Buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers)
: this(color, depth, stencil, samples, accum, buffers, Default.Stereo)
{ }
#endregion
#region public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
/// <param name="color">The ColorFormat of the color buffer.</param>
/// <param name="depth">The number of bits in the depth buffer.</param>
/// <param name="stencil">The number of bits in the stencil buffer.</param>
/// <param name="samples">The number of samples for FSAA.</param>
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
/// <param name="stereo">Set to true for a GraphicsMode with stereographic capabilities.</param>
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
: this(IntPtr.Zero, color, depth, stencil, samples, accum, buffers, stereo) { }
#endregion
#endregion
#region --- Public Methods ---
#region public int ColorDepth
#region public int ColorFormat
/// <summary>
/// Gets an OpenTK.Graphics.ColorDepth that describes the color format for this GraphicsFormat.
/// Gets an OpenTK.Graphics.ColorFormat that describes the color format for this GraphicsFormat.
/// </summary>
public ColorDepth ColorDepth
public ColorFormat ColorFormat
{
get { return color_format; }
private set { color_format = value; }
@ -162,9 +209,9 @@ namespace OpenTK.Graphics
#region public int AccumulatorFormat
/// <summary>
/// Gets an OpenTK.Graphics.ColorDepth that describes the accumulator format for this GraphicsFormat.
/// Gets an OpenTK.Graphics.ColorFormat that describes the accumulator format for this GraphicsFormat.
/// </summary>
public ColorDepth AccumulatorFormat
public ColorFormat AccumulatorFormat
{
get { return accumulator_format; }
private set { accumulator_format = value; }
@ -200,6 +247,8 @@ namespace OpenTK.Graphics
#endregion
#region public int Samples
/// <summary>
/// Gets a System.Int32 that contains the number of FSAA samples per pixel for this GraphicsFormat.
/// </summary>
@ -209,6 +258,8 @@ namespace OpenTK.Graphics
private set { samples = value; }
}
#endregion
#region public bool Stereo
/// <summary>
@ -248,14 +299,28 @@ namespace OpenTK.Graphics
#endregion
#region --- Internal Methods ---
#region internal IntPtr Index
internal IntPtr Index
{
get { return index; }
set { index = value; }
}
#endregion
#endregion
#region --- Overrides ---
/// <summary>Returns a System.String describing the current GraphicsFormat.</summary>
/// <returns>! System.String describing the current GraphicsFormat.</returns>
public override string ToString()
{
return String.Format("Color: {0}, Depth: {1}, Stencil: {2}, Samples: {3}, Accum: {4}, Buffers: {5}, Stereo: {6}",
ColorDepth, Depth, Stereo, Samples, AccumulatorFormat, Buffers, Stereo);
return String.Format("Index: {0}, Color: {1}, Depth: {2}, Stencil: {3}, Samples: {4}, Accum: {5}, Buffers: {6}, Stereo: {7}",
Index, ColorFormat, Depth, Stereo, Samples, AccumulatorFormat, Buffers, Stereo);
}
#endregion

View file

@ -23,16 +23,17 @@ namespace OpenTK.Graphics
void SwapBuffers();
/// <summary>Makes the GraphicsContext current in the calling thread.</summary>
/// <param name="window">An OpenTK.Platform.IWindowInfo structure that points to a valid window.</param>
/// <remarks>
/// <para>OpenGL commands in one thread, affect the GraphicsContext which is current in that thread.</para>
/// <para>It is an error to issue an OpenGL command in a thread without a current GraphicsContext.</para>
/// </remarks>
void MakeCurrent();
void MakeCurrent(IWindowInfo window);
/// <summary>
/// Gets or sets a System.Boolean indicating whether the GraphicsContext is current in the calling thread.
/// </summary>
bool IsCurrent { get; set; }
bool IsCurrent { get; /*set;*/ }
/// <summary>
/// Raised when a Context is destroyed.
@ -82,7 +83,7 @@ namespace OpenTK.Graphics
/// <summary>
/// Gets the IWindowInfo describing the window associated with this context.
/// </summary>
IWindowInfo Info { get; }
//IWindowInfo Info { get; }
/// <summary>Gets the GraphicsMode of the context.</summary>
GraphicsMode GraphicsMode { get; }

View file

@ -389,9 +389,10 @@ namespace OpenTK.Graphics.OpenGL
// Most drivers return the version in the 3 first characters of the version string,
// (e.g. on Ati X1950 with Catalyst 7.10 -> "2.0.6956 Release"). However, Mesa seems
// to do something strange: "1.4 (2.1 Mesa 7.0.1).".
// Update: this seems to occur with indirect rendering. E.g. Ati 8.2: 1.4 (2.1.7281 ...)
// We'll do some trickery to get the second number (2.1), but this may break on
// some implementations...
if (version_string.ToLower().Contains("mesa"))
//if (version_string.ToLower().Contains("mesa"))
{
int index = version_string.IndexOf('(');
if (index != -1)
@ -399,8 +400,8 @@ namespace OpenTK.Graphics.OpenGL
else
version = version_string.TrimStart(' ');
}
else
version = version_string.TrimStart(' ');
//else
// version = version_string.TrimStart(' ');
Debug.Print(version);

View file

@ -31,12 +31,12 @@ namespace OpenTK.Platform
public IntPtr Context { get { return IntPtr.Zero; } }
public GraphicsMode GraphicsMode { get { return format; } }
public void CreateContext() { }
public void CreateContext(bool direct) { }
//public void CreateContext() { }
//public void CreateContext(bool direct) { }
public void CreateContext(bool direct, IGraphicsContext source) { }
public void SwapBuffers() { }
public void MakeCurrent() { }
public void MakeCurrent(IWindowInfo info) { }
public bool IsCurrent { get { return true; } set { } }
public IntPtr GetCurrentContext() { return IntPtr.Zero; }

View file

@ -12,7 +12,10 @@ using System.Text;
namespace OpenTK.Platform
{
public interface IWindowInfo
/// <summary>Descibes an OS window.</summary>
public interface IWindowInfo : IDisposable
{
// /// <summary>Gets a System.IntPtr which contains the handle of the window.</summary>
//IntPtr WindowHandle { get; }
}
}

View file

@ -33,7 +33,7 @@ namespace OpenTK.Platform.Windows
Debug.WriteLine("Initalizing WMInput driver.");
Debug.Indent();
AssignHandle(parent.Handle);
AssignHandle(parent.WindowHandle);
Debug.Print("Input window attached to parent {0}", parent);
Debug.Unindent();

View file

@ -143,7 +143,7 @@ namespace OpenTK.Platform.Windows
{
if (extensions == null || rebuildExtensionList)
{
extensions = Wgl.Arb.GetExtensionsString(context.Device).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
extensions = Wgl.Arb.GetExtensionsString(context.DeviceContext).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
Array.Sort(extensions);
rebuildExtensionList = false;
}

View file

@ -24,13 +24,14 @@ namespace OpenTK.Platform.Windows
/// 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 : IGraphicsContext, IGraphicsContextInternal, IGLContextCreationHack
internal sealed class WinGLContext : IGraphicsContext, IGraphicsContextInternal//, IGLContextCreationHack
{
IntPtr deviceContext;
//IntPtr deviceContext;
WinWindowInfo currentWindow;
ContextHandle renderContext;
static IntPtr opengl32Handle;
const string opengl32Name = "OPENGL32.DLL";
WinWindowInfo windowInfo = new WinWindowInfo();
//WinWindowInfo windowInfo = new WinWindowInfo();
GraphicsMode format;
//DisplayMode mode = null;
@ -58,32 +59,24 @@ namespace OpenTK.Platform.Windows
}
}
GraphicsMode SelectFormat(GraphicsMode format)
{
using (WinGLNative native = new WinGLNative())
//using (WinGLContext context = new WinGLContext(format, native.WindowInfo, null))
{
// Find the best multisampling mode.
return format;
}
}
public WinGLContext(GraphicsMode format, IWindowInfo window, IGraphicsContext sharedContext)
{
//format = this.SelectFormat(format);
if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
this.windowInfo = (WinWindowInfo)window;
Debug.Print("OpenGL will be bound to handle: {0}", this.windowInfo.Handle);
if (this.windowInfo.Handle == IntPtr.Zero)
throw new ArgumentException("window", "Must be a valid window.");
currentWindow = (WinWindowInfo)window;
if (currentWindow.WindowHandle == IntPtr.Zero) throw new ArgumentException("window", "Must be a valid window.");
Debug.Print("Setting pixel format...");
this.format = this.SetGraphicsModePFD(format);
Debug.Print("OpenGL will be bound to handle: {0}", currentWindow.WindowHandle);
Debug.Print("Setting pixel format... ");
this.SetGraphicsModePFD(format, (WinWindowInfo)window);
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.
renderContext = new ContextHandle(Wgl.Imports.CreateContext(deviceContext));
Debug.Write("Creating render context... ");
renderContext = new ContextHandle(Wgl.Imports.CreateContext(currentWindow.DeviceContext));
if (renderContext == IntPtr.Zero)
renderContext = new ContextHandle(Wgl.Imports.CreateContext(currentWindow.DeviceContext));
if (renderContext == IntPtr.Zero)
throw new GraphicsContextException(String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
Marshal.GetLastWin32Error()));
@ -134,19 +127,33 @@ namespace OpenTK.Platform.Windows
public void SwapBuffers()
{
Functions.SwapBuffers(deviceContext);
Functions.SwapBuffers(currentWindow.DeviceContext);
}
#endregion
#region public void MakeCurrent()
public void MakeCurrent()
#region public void MakeCurrent(IWindowInfo window)
public void MakeCurrent(IWindowInfo window)
{
if (!Wgl.Imports.MakeCurrent(deviceContext, renderContext))
bool success;
if (window != null)
{
Debug.Print("WinGLContext.MakeCurrent() call failed. Error: {0}", Marshal.GetLastWin32Error());
if (((WinWindowInfo)window).WindowHandle == IntPtr.Zero)
throw new ArgumentException("window", "Must point to a valid window.");
currentWindow = (WinWindowInfo)window;
success = Wgl.Imports.MakeCurrent(((WinWindowInfo)window).DeviceContext, this.renderContext);
}
else
success = Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
if (!success)
throw new GraphicsContextException(String.Format(
"Failed to make context {0} current. Error: {1}", this, Marshal.GetLastWin32Error()));
}
#endregion
@ -156,6 +163,7 @@ namespace OpenTK.Platform.Windows
public bool IsCurrent
{
get { return Wgl.GetCurrentContext() == this.renderContext; }
/*
set
{
if (value)
@ -163,6 +171,7 @@ namespace OpenTK.Platform.Windows
else
Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
}
*/
}
@ -218,12 +227,12 @@ namespace OpenTK.Platform.Windows
#endregion
#region IWindowInfo IGLContextInternal.Info
/*
IWindowInfo IGraphicsContextInternal.Info
{
get { return (IWindowInfo)windowInfo; }
}
*/
#endregion
#region GraphicsMode IGLContextInternal.GraphicsMode
@ -275,205 +284,49 @@ namespace OpenTK.Platform.Windows
#region --- Private Methods ---
#region GraphicsMode SetGraphicsModePFD(GraphicsMode format)
#region void SetGraphicsModePFD(GraphicsMode format, WinWindowInfo window)
GraphicsMode SetGraphicsModePFD(GraphicsMode format)
void SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window)
{
deviceContext = Functions.GetDC(this.windowInfo.Handle);
Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
if (mode.Index == IntPtr.Zero) throw new ArgumentException(
"mode", "The Index (pixel format) of the GraphicsMode is not set.");
if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
Debug.Write("Setting pixel format... ");
PixelFormatDescriptor pixelFormat = new PixelFormatDescriptor();
pixelFormat.Size = API.PixelFormatDescriptorSize;
pixelFormat.Version = API.PixelFormatDescriptorVersion;
pixelFormat.Flags =
PixelFormatDescriptorFlags.SUPPORT_OPENGL |
PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
pixelFormat.ColorBits = (byte)(format.ColorDepth.Red + format.ColorDepth.Green + format.ColorDepth.Blue);
pixelFormat.PixelType = format.ColorDepth.IsIndexed ? PixelType.INDEXED : PixelType.RGBA;
pixelFormat.PixelType = PixelType.RGBA;
pixelFormat.RedBits = (byte)format.ColorDepth.Red;
pixelFormat.GreenBits = (byte)format.ColorDepth.Green;
pixelFormat.BlueBits = (byte)format.ColorDepth.Blue;
pixelFormat.AlphaBits = (byte)format.ColorDepth.Alpha;
if (format.AccumulatorFormat.BitsPerPixel > 0)
{
pixelFormat.AccumBits = (byte)(format.AccumulatorFormat.Red + format.AccumulatorFormat.Green + format.AccumulatorFormat.Blue);
pixelFormat.AccumRedBits = (byte)format.AccumulatorFormat.Red;
pixelFormat.AccumGreenBits = (byte)format.AccumulatorFormat.Green;
pixelFormat.AccumBlueBits = (byte)format.AccumulatorFormat.Blue;
pixelFormat.AccumAlphaBits = (byte)format.AccumulatorFormat.Alpha;
}
pixelFormat.DepthBits = (byte)format.Depth;
pixelFormat.StencilBits = (byte)format.Stencil;
if (format.Depth <= 0) pixelFormat.Flags |= PixelFormatDescriptorFlags.DEPTH_DONTCARE;
if (format.Stereo) pixelFormat.Flags |= PixelFormatDescriptorFlags.STEREO;
if (format.Buffers > 1) pixelFormat.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
int pixel = Functions.ChoosePixelFormat(deviceContext, ref pixelFormat);
if (pixel == 0)
throw new GraphicsModeException(String.Format("The requested format is not available: {0}.", format));
// Find out what we really got as a format:
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
pixelFormat.Size = API.PixelFormatDescriptorSize;
pixelFormat.Version = API.PixelFormatDescriptorVersion;
Functions.DescribePixelFormat(deviceContext, pixel, API.PixelFormatDescriptorSize, ref pfd);
GraphicsMode fmt = new GraphicsMode(
new ColorDepth(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
pfd.DepthBits,
pfd.StencilBits,
0,
new ColorDepth(pfd.AccumBits),
(pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
(pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
if (!Functions.SetPixelFormat(deviceContext, pixel, ref pixelFormat))
throw new GraphicsContextException(String.Format("Requested GraphicsMode not available. SetPixelFormat error: {0}",
Marshal.GetLastWin32Error()));
Debug.Print("done! (format: {0})", pixel);
return fmt;
Functions.DescribePixelFormat(window.DeviceContext, (int)mode.Index,
API.PixelFormatDescriptorSize, ref pfd);
Debug.WriteLine(mode.Index.ToString());
if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index, ref pfd))
throw new GraphicsContextException(String.Format(
"Requested GraphicsMode not available. SetPixelFormat error: {0}", Marshal.GetLastWin32Error()));
}
#endregion
#region GraphicsMode SetGraphicsModeARB(GraphicsMode format)
#region void SetGraphicsModeARB(GraphicsMode format, IWindowInfo window)
GraphicsMode SetGraphicsModeARB(GraphicsMode format)
void SetGraphicsModeARB(GraphicsMode format, IWindowInfo window)
{
return null;
throw new NotImplementedException();
}
#endregion
#endregion
#region --- IGLContextCreationHack Members ---
#region bool IGLContextCreationHack.SelectDisplayMode(DisplayMode mode, IWindowInfo info)
/// <summary>
/// HACK! This function will be removed in 0.3.15
/// Checks if the specified OpenTK.Platform.DisplayMode is available, and selects it if it is.
/// </summary>
/// <param name="mode">The OpenTK.Platform.DisplayMode to select.</param>
/// <param name="info">The OpenTK.Platform.IWindowInfo that describes the display to use. Note: a window handle is not necessary for this function!</param>
/// <returns>True if the DisplayMode is available, false otherwise.</returns>
bool IGLContextCreationHack.SelectDisplayMode(DisplayMode mode, IWindowInfo info)
{
// Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl.
if (opengl32Handle == IntPtr.Zero)
{
opengl32Handle = Functions.LoadLibrary(opengl32Name);
if (opengl32Handle == IntPtr.Zero)
{
//System.Diagnostics.Debug.WriteLine("LoadLibrary({0}) set error code: {1}. Will not load extensions.", _dll_name, error_code);
throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}",
opengl32Name, Marshal.GetLastWin32Error()));
}
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle));
}
deviceContext = Functions.GetDC(this.windowInfo.Handle);
Debug.WriteLine(String.Format("Device context: {0}", deviceContext));
Debug.Write("Setting pixel format... ");
PixelFormatDescriptor pixelFormat = new PixelFormatDescriptor();
pixelFormat.Size = API.PixelFormatDescriptorSize;
pixelFormat.Version = API.PixelFormatDescriptorVersion;
pixelFormat.Flags =
PixelFormatDescriptorFlags.SUPPORT_OPENGL |
PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
pixelFormat.ColorBits = (byte)(mode.Color.Red + mode.Color.Green + mode.Color.Blue);
if (mode.Color.IsIndexed)
{
pixelFormat.PixelType = PixelType.INDEXED;
}
else
{
pixelFormat.PixelType = PixelType.RGBA;
pixelFormat.RedBits = (byte)mode.Color.Red;
pixelFormat.GreenBits = (byte)mode.Color.Green;
pixelFormat.BlueBits = (byte)mode.Color.Blue;
pixelFormat.AlphaBits = (byte)mode.Color.Alpha;
}
/*
if (accum != null)
{
pixelFormat.AccumBits = (byte)(accum.Red + accum.Green + accum.Blue);
pixelFormat.AccumRedBits = (byte)accum.Red;
pixelFormat.AccumGreenBits = (byte)accum.Green;
pixelFormat.AccumBlueBits = (byte)accum.Blue;
pixelFormat.AccumAlphaBits = (byte)accum.Alpha;
}
*/
pixelFormat.DepthBits = (byte)mode.DepthBits;
pixelFormat.StencilBits = (byte)mode.StencilBits;
if (mode.DepthBits <= 0)
{
pixelFormat.Flags |= PixelFormatDescriptorFlags.DEPTH_DONTCARE;
}
if (mode.Stereo)
{
pixelFormat.Flags |= PixelFormatDescriptorFlags.STEREO;
}
if (mode.Buffers > 1)
{
pixelFormat.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
}
// TODO: More elaborate mode setting, using DescribePixelFormat.
/*
unsafe
{
int pixel = Wgl.Imports.ChoosePixelFormat(deviceContext, &pixelFormat);
if (pixel == 0)
{
throw new ApplicationException("The requested pixel format is not supported by the hardware configuration.");
}
Wgl.Imports.SetPixelFormat(deviceContext, pixel, &pixelFormat);
Debug.WriteLine(String.Format("done! (format: {0})", pixel));
}
*/
int pixel = Functions.ChoosePixelFormat(deviceContext, ref pixelFormat);
if (pixel == 0)
{
Debug.Print("format not available...");
return false;
}
Functions.SetPixelFormat(deviceContext, pixel, ref pixelFormat);
Debug.Print("done! (format: {0})", pixel);
return true;
}
#endregion
void IGLContextCreationHack.SetWindowHandle(IntPtr handle)
{
this.windowInfo.Handle = handle;
}
#endregion
#region --- Internal Methods ---
#region internal IntPtr Device
#region internal IntPtr DeviceContext
internal IntPtr DeviceContext
{
get
{
if (currentWindow != null)
return currentWindow.DeviceContext;
return IntPtr.Zero;
}
}
internal IntPtr Device { get { return deviceContext; } }
#endregion
@ -544,14 +397,14 @@ namespace OpenTK.Platform.Windows
renderContext = null;
}
if (deviceContext != IntPtr.Zero)
{
if (!Functions.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());
}
}
//if (deviceContext != IntPtr.Zero)
//{
// if (!Functions.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());
// }
//}
/*
if (opengl32Handle != IntPtr.Zero)

View file

@ -14,17 +14,17 @@ using System.Windows.Forms;
namespace OpenTK.Platform.Windows
{
/// <internal />
/// <summary>OpenGL capable Windows.Forms control implementation on win32.</summary>
/// <summary>Utility to obtain IWindowInfo from a System.Windows.Forms.Control on win32.</summary>
internal sealed class WinGLControlHelper : IGLControlHelper
{
MSG msg = new MSG();
WinWindowInfo windowInfo;
Control control;
#region --- Constructors ---
internal WinGLControlHelper(Control c)
public WinGLControlHelper(Control c)
{
windowInfo = new WinWindowInfo(c.Handle, null);
control = c;
}
#endregion
@ -32,7 +32,7 @@ namespace OpenTK.Platform.Windows
#region --- IGLControlHelper Members ---
/// <summary>Returns an OpenTK.Platform.IWindowInfo describing this control.</summary>
public IWindowInfo WindowInfo { get { return windowInfo; } }
public IWindowInfo WindowInfo { get { return new WinWindowInfo(control.Handle, null); } }
/// <summary>Returns true if no messages are pending in the event loop.</summary>
public bool IsIdle

View file

@ -254,19 +254,19 @@ namespace OpenTK.Platform.Windows
get
{
StringBuilder title = new StringBuilder(256);
Functions.GetWindowText(window.Handle, title, title.Capacity);
Functions.GetWindowText(window.WindowHandle, title, title.Capacity);
return title.ToString();
}
set
{
#if DEBUG
bool ret = Functions.SetWindowText(window.Handle, value);
bool ret = Functions.SetWindowText(window.WindowHandle, value);
if (ret)
Debug.Print("Window {0} title changed to {1}.", window.Handle, value);
Debug.Print("Window {0} title changed to {1}.", window.WindowHandle, value);
else
Debug.Print("Window {0} title failed to change to {1}.", window.Handle, value);
Debug.Print("Window {0} title failed to change to {1}.", window.WindowHandle, value);
#else
Functions.SetWindowText(window.Handle, value);
Functions.SetWindowText(window.WindowHandle, value);
#endif
}
}

View file

@ -40,7 +40,7 @@ namespace OpenTK.Platform.Windows
Debug.WriteLine("Initalizing windows raw input driver.");
Debug.Indent();
AssignHandle(parent.Handle);
AssignHandle(parent.WindowHandle);
Debug.Print("Input window attached to parent {0}", parent);
keyboardDriver = new WinRawKeyboard(this.Handle);
mouseDriver = new WinRawMouse(this.Handle);

View file

@ -8,8 +8,9 @@ namespace OpenTK.Platform.Windows
/// <summary>Describes a win32 window.</summary>
internal sealed class WinWindowInfo : IWindowInfo
{
IntPtr handle;
IntPtr handle, dc;
WinWindowInfo parent;
bool disposed;
#region --- Constructors ---
@ -25,10 +26,20 @@ namespace OpenTK.Platform.Windows
#endregion
#region --- Methods ---
#region --- Public Methods ---
internal IntPtr Handle { get { return handle; } set { handle = value; } }
internal WinWindowInfo Parent { get { return parent; } set { parent = value; } }
public IntPtr WindowHandle { get { return handle; } set { handle = value; } }
public WinWindowInfo Parent { get { return parent; } set { parent = value; } }
public IntPtr DeviceContext
{
get
{
if (dc == IntPtr.Zero)
dc = Functions.GetDC(this.WindowHandle);
return dc;
}
//set { dc = value; }
}
#region public override string ToString()
@ -37,7 +48,7 @@ namespace OpenTK.Platform.Windows
public override string ToString()
{
return String.Format("Windows.WindowInfo: Handle {0}, Parent ({1})",
this.Handle, this.Parent != null ? this.Parent.ToString() : "null");
this.WindowHandle, this.Parent != null ? this.Parent.ToString() : "null");
}
/// <summary>Checks if <c>this</c> and <c>obj</c> reference the same win32 window.</summary>
@ -64,5 +75,50 @@ namespace OpenTK.Platform.Windows
#endregion
#endregion
#region --- IDisposable ---
#region public void Dispose()
/// <summary>Releases the unmanaged resources consumed by this instance.</summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region void Dispose(bool manual)
void Dispose(bool manual)
{
if (!disposed)
{
if (this.dc != IntPtr.Zero)
Functions.ReleaseDC(this.handle, this.dc);
if (manual)
{
if (parent != null)
parent.Dispose();
}
disposed = true;
}
}
#endregion
#region ~WinWindowInfo()
~WinWindowInfo()
{
this.Dispose(false);
}
#endregion
#endregion
}
}

View file

@ -1189,19 +1189,20 @@ XF86VidModeGetGammaRampSize(
DirectColor = 5,
}
[Flags]
public enum XVisualInfoMask
{
VisualNoMask = 0x0,
VisualIDMask = 0x1,
VisualScreenMask = 0x2,
VisualDepthMask = 0x4,
VisualClassMask = 0x8,
VisualRedMaskMask = 0x10,
VisualGreenMaskMask = 0x20,
VisualBlueMaskMask = 0x40,
VisualColormapSizeMask = 0x80,
VisualBitsPerRGBMask = 0x100,
VisualAllMask = 0x1FF,
No = 0x0,
ID = 0x1,
Screen = 0x2,
Depth = 0x4,
Class = 0x8,
Red = 0x10,
Green = 0x20,
Blue = 0x40,
ColormapSize = 0x80,
BitsPerRGB = 0x100,
All = 0x1FF,
}
#region public enum MouseMask

View file

@ -1,4 +1,12 @@
using System;
#region --- License ---
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
@ -7,6 +15,8 @@ namespace OpenTK.Platform.X11
{
internal static partial class Functions
{
public static readonly object Lock = new object();
[DllImport("libX11", EntryPoint = "XOpenDisplay")]
public extern static IntPtr XOpenDisplay(IntPtr display);
[DllImport("libX11", EntryPoint = "XCloseDisplay")]
@ -326,8 +336,14 @@ namespace OpenTK.Platform.X11
[DllImport("libX11")]
public extern static void XPeekEvent(IntPtr display, ref XEvent xevent);
[DllImport("libX11")]
public static extern IntPtr XGetVisualInfo(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo vinfo_template,
out int nitems_return);
[DllImport("libX11", EntryPoint = "XGetVisualInfo")]
static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template,
out int nitems);
public static IntPtr XGetVisualInfo(IntPtr display, XVisualInfoMask vinfo_mask, ref XVisualInfo template, out int nitems)
{
return XGetVisualInfoInternal(display, (IntPtr)(int)vinfo_mask, ref template, out nitems);
}
}
}

View file

@ -295,24 +295,27 @@ namespace OpenTK.Platform.X11
[DllImport(Library, EntryPoint = "glXGetProcAddress")]
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
[DllImport(Library, EntryPoint = "glXGetConfig")]
public static extern int GetConfig(IntPtr dpy, ref XVisualInfo vis, GLXAttribute attrib, out int value);
#region glXChooseVisual
[DllImport(Library, EntryPoint = "glXChooseVisual")]
public extern static IntPtr ChooseVisual(IntPtr dpy, int screen, IntPtr attriblist);
[DllImport(Library, EntryPoint = "glXChooseVisual")]
public extern static IntPtr ChooseVisual(IntPtr dpy, int screen, int[] attriblist);
public extern static IntPtr ChooseVisual(IntPtr dpy, int screen, ref int attriblist);
//public static IntPtr ChooseVisual(IntPtr dpy, int screen, int[] attriblist)
//{
// unsafe
// {
// fixed (int* attriblist_ptr = attriblist)
// {
// return ChooseVisual(dpy, screen, (IntPtr)attriblist_ptr);
// }
// }
//}
public static IntPtr ChooseVisual(IntPtr dpy, int screen, int[] attriblist)
{
unsafe
{
fixed (int* attriblist_ptr = attriblist)
{
return ChooseVisual(dpy, screen, (IntPtr)attriblist_ptr);
}
}
}
#endregion

View file

@ -22,8 +22,9 @@ namespace OpenTK.Platform.X11
internal sealed class X11GLContext : IGraphicsContext, IGraphicsContextInternal
{
IntPtr context;
X11WindowInfo window;
IntPtr visual;
//X11WindowInfo window;
X11WindowInfo currentWindow;
//IntPtr visual;
bool vsync_supported;
int vsync_interval;
@ -43,122 +44,68 @@ namespace OpenTK.Platform.X11
//if (mode == null) mode = GraphicsMode.Default;
if (info == null) throw new ArgumentNullException("info", "Should point to a valid window.");
window = (X11WindowInfo)info;
window.VisualInfo = SelectVisual(mode);
currentWindow = (X11WindowInfo)info;
currentWindow.VisualInfo = SelectVisual(mode, currentWindow);
Debug.Print("Chose visual: {0}", window.VisualInfo);
CreateContext(shared, directRendering);
Debug.Print("Chose visual: {0}", currentWindow.VisualInfo);
CreateContext(shared, directRendering, currentWindow);
}
#endregion
#region --- Private Methods ---
#region XVisualInfo SelectVisual(GraphicsMode mode)
#region XVisualInfo SelectVisual(GraphicsMode mode, X11WindowInfo currentWindow)
XVisualInfo SelectVisual(GraphicsMode mode)
XVisualInfo SelectVisual(GraphicsMode mode, X11WindowInfo currentWindow)
{
List<int> visualAttributes = new List<int>();
XVisualInfo info = new XVisualInfo();
info.visualid = (IntPtr)mode.Index;
info.screen = currentWindow.Screen;
int items;
IntPtr vs = Functions.XGetVisualInfo(currentWindow.Display, XVisualInfoMask.ID | XVisualInfoMask.Screen, ref info, out items);
if (items == 0)
throw new GraphicsModeException(String.Format("Invalid GraphicsMode specified ({0}).", mode));
// TODO: Improve modesetting code.
if (mode == null || mode.ColorDepth.BitsPerPixel == 0)
{
// Define the bare essentials - needed for compatibility with Mono's System.Windows.Forms
Debug.Print("Mono/X11 compatibility mode.");
visualAttributes.Add((int)GLXAttribute.RGBA);
//visualAttributes.Add((int)GLXAttribute.RED_SIZE);
//visualAttributes.Add((int)1);
//visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
//visualAttributes.Add((int)1);
//visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
//visualAttributes.Add((int)1);
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
visualAttributes.Add((int)1);
}
else
{
visualAttributes.Add((int)GLXAttribute.RGBA);
visualAttributes.Add((int)GLXAttribute.RED_SIZE);
visualAttributes.Add((int)mode.ColorDepth.Red);
visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
visualAttributes.Add((int)mode.ColorDepth.Green);
visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
visualAttributes.Add((int)mode.ColorDepth.Blue);
visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
visualAttributes.Add((int)mode.ColorDepth.Alpha);
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
visualAttributes.Add((int)mode.Depth);
}
if (mode.Buffers > 1)
visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
if (mode.Stencil > 1)
{
visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
visualAttributes.Add(mode.Stencil);
}
if (mode.AccumulatorFormat.BitsPerPixel > 0)
{
visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
visualAttributes.Add(mode.AccumulatorFormat.Alpha);
visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
visualAttributes.Add(mode.AccumulatorFormat.Blue);
visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
visualAttributes.Add(mode.AccumulatorFormat.Green);
visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
visualAttributes.Add(mode.AccumulatorFormat.Red);
}
if (mode.Stereo)
visualAttributes.Add((int)GLXAttribute.STEREO);
visualAttributes.Add((int)0);
visual = Glx.ChooseVisual(window.Display, window.Screen, visualAttributes.ToArray());
if (visual == IntPtr.Zero)
throw new GraphicsContextException(String.Format("Failed to set requested mode: {0}.", mode.ToString()));
return (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
info = (XVisualInfo)Marshal.PtrToStructure(vs, typeof(XVisualInfo));
Functions.XFree(vs);
return info;
}
#endregion
#region void CreateContext(IGraphicsContext shareContext, bool direct)
void CreateContext(IGraphicsContext shareContext, bool direct)
void CreateContext(IGraphicsContext shareContext, bool direct, X11WindowInfo window)
{
try
{
ContextHandle shareHandle = shareContext != null ? (shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
ContextHandle shareHandle = shareContext != null ? (shareContext as IGraphicsContextInternal).Context :
(ContextHandle)IntPtr.Zero;
Debug.Write("Creating OpenGL context: ");
Debug.Write(direct ? "direct, " : "indirect, ");
Debug.Write(shareHandle.Handle == IntPtr.Zero ? "not shared... " :
String.Format("shared with ({0})... ", shareHandle));
// Try to call Glx.CreateContext with the specified parameters.
context = Glx.CreateContext(window.Display, visual, shareHandle.Handle, direct);
XVisualInfo info = window.VisualInfo; // Cannot pass a Property by reference.
context = Glx.CreateContext(window.Display, ref info, shareHandle.Handle, direct);
// Context creation succeeded, return.
if (context != IntPtr.Zero)
{
Debug.Print("done! (id: {0})", context);
//this.MakeCurrent();
return;
}
// Context creation failed. Retry with a non-shared context with the
// direct/indirect rendering mode flipped.
// Context creation failed. Retry with a non-shared context with the direct/indirect bit flipped.
Debug.Print("failed.");
Debug.Write(String.Format("Creating OpenGL context: {0}, not shared... ", !direct ? "direct" : "indirect"));
context = Glx.CreateContext(window.Display, visual, IntPtr.Zero, !direct);
context = Glx.CreateContext(window.Display, ref info, IntPtr.Zero, !direct);
if (context != IntPtr.Zero)
{
Debug.Print("done! (id: {0})", context);
//this.MakeCurrent();
return;
}
@ -173,7 +120,7 @@ namespace OpenTK.Platform.X11
#endregion
bool SupportsExtension(string e)
bool SupportsExtension(X11WindowInfo window, string e)
{
string extensions = Glx.QueryExtensionsString(window.Display, window.Screen);
return !String.IsNullOrEmpty(extensions) && extensions.Contains(e);
@ -187,35 +134,35 @@ namespace OpenTK.Platform.X11
public void SwapBuffers()
{
Glx.SwapBuffers(window.Display, window.Handle);
//if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
//X11WindowInfo w = (X11WindowInfo)window;
if (currentWindow.Display == IntPtr.Zero || currentWindow.WindowHandle == IntPtr.Zero)
throw new InvalidOperationException(
String.Format("Window is invalid. Display ({0}), Handle ({1}).", currentWindow.Display, currentWindow.WindowHandle));
Glx.SwapBuffers(currentWindow.Display, currentWindow.WindowHandle);
}
#endregion
#region public void MakeCurrent()
#region public void MakeCurrent(IWindowInfo window)
bool result;
public void MakeCurrent()
public void MakeCurrent(IWindowInfo window)
{
Debug.Write(String.Format("Making context {0} current on thread {1} (Display: {2}, Screen: {3}, Window: {4})... ",
context, System.Threading.Thread.CurrentThread.ManagedThreadId, window.Display, window.Screen, window.Handle));
X11WindowInfo w = (X11WindowInfo)window;
bool result;
if (window.Display != IntPtr.Zero && window.Handle != IntPtr.Zero && context != IntPtr.Zero)
{
result = Glx.MakeCurrent(window.Display, window.Handle, context);
if (!result)
{
Debug.WriteLine("failed.");
// probably need to recreate context here.
//throw new ApplicationException(String.Format("Failed to make context {0} current on thread {1}.",
// context, System.Threading.Thread.CurrentThread.ManagedThreadId));
}
else
{
Debug.WriteLine("done!");
}
}
Debug.Write(String.Format("Making context {0} current on thread {1} (Display: {2}, Screen: {3}, Window: {4})... ",
context, System.Threading.Thread.CurrentThread.ManagedThreadId, w.Display, w.Screen, w.WindowHandle));
if (w.Display == IntPtr.Zero || w.WindowHandle == IntPtr.Zero || context == IntPtr.Zero)
throw new InvalidOperationException("Invalid display, window or context.");
result = Glx.MakeCurrent(w.Display, w.WindowHandle, context);
if (!result)
throw new GraphicsContextException("Failed to make context current.");
else
Debug.WriteLine("done!");
}
#endregion
@ -225,13 +172,13 @@ namespace OpenTK.Platform.X11
public bool IsCurrent
{
get { return Glx.GetCurrentContext() == this.context; }
set
{
if (value)
Glx.MakeCurrent(window.Display, window.Handle, context);
else
Glx.MakeCurrent(window.Handle, IntPtr.Zero, IntPtr.Zero);
}
//set
//{
// if (value)
// Glx.MakeCurrent(window.Display, window.Handle, context);
// else
// Glx.MakeCurrent(window.Handle, IntPtr.Zero, IntPtr.Zero);
//}
}
#endregion
@ -295,7 +242,8 @@ namespace OpenTK.Platform.X11
GL.LoadAll();
Glu.LoadAll();
Glx.LoadAll();
vsync_supported = this.SupportsExtension("SGI_swap_control") && this.GetAddress("glXSwapControlSGI") != IntPtr.Zero;
vsync_supported = this.SupportsExtension(currentWindow, "SGI_swap_control") &&
this.GetAddress("glXSwapControlSGI") != IntPtr.Zero;
}
#endregion
@ -321,7 +269,7 @@ namespace OpenTK.Platform.X11
#region IWindowInfo IGLContextInternal.Info
IWindowInfo IGraphicsContextInternal.Info { get { return window; } }
//IWindowInfo IGraphicsContextInternal.Info { get { return window; } }
#endregion
@ -359,9 +307,10 @@ namespace OpenTK.Platform.X11
if (!disposed)
{
// Clean unmanaged resources:
Glx.MakeCurrent(window.Display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(window.Display, context);
API.Free(visual);
Glx.MakeCurrent(currentWindow.Display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(currentWindow.Display, context);
//API.Free(visual);
if (manuallyCalled)
{

View file

@ -82,13 +82,23 @@ namespace OpenTK.Platform.X11
//Utilities.ThrowOnX11Error = true; // Not very reliable
// Open the display to the X server, and obtain the screen and root window.
window.Display = API.OpenDisplay(null); // null == default display //window.Display = API.DefaultDisplay;
if (window.Display == IntPtr.Zero)
throw new Exception("Could not open connection to X");
// We reuse the display connection of System.Windows.Forms.
// TODO: Multiple screens.
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
window.Display = (IntPtr)xplatui.GetField("DisplayHandle",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
window.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
window.Screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
// Open the display to the X server, and obtain the screen and root window.
//window.Display = API.OpenDisplay(null); // null == default display //window.Display = API.DefaultDisplay;
//if (window.Display == IntPtr.Zero)
// throw new Exception("Could not open connection to X");
//window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
//window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen, window.RootWindow);
RegisterAtoms(window);
@ -136,8 +146,11 @@ namespace OpenTK.Platform.X11
Debug.Indent();
// Create the context. This call also creates an XVisualInfo structure for us.
context = new GraphicsContext(mode, window);
XVisualInfo info = new XVisualInfo();
info.visualid = mode.Index;
int dummy;
window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));
// Create a window on this display using the visual above
Debug.Write("Opening render window... ");
@ -157,15 +170,17 @@ namespace OpenTK.Platform.X11
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
(uint)SetWindowValuemask.BackPixel | (uint)SetWindowValuemask.BorderPixel;
window.Handle = Functions.XCreateWindow(window.Display, window.RootWindow,
window.WindowHandle = Functions.XCreateWindow(window.Display, window.RootWindow,
0, 0, width, height, 0, window.VisualInfo.depth/*(int)CreateWindowArgs.CopyFromParent*/,
(int)CreateWindowArgs.InputOutput, window.VisualInfo.visual, (UIntPtr)mask, ref attributes);
if (window.Handle == IntPtr.Zero)
if (window.WindowHandle == IntPtr.Zero)
throw new ApplicationException("XCreateWindow call failed (returned 0).");
XVisualInfo vis = window.VisualInfo;
Glx.CreateContext(window.Display, ref vis, IntPtr.Zero, true);
//XVisualInfo vis = window.VisualInfo;
//Glx.CreateContext(window.Display, ref vis, IntPtr.Zero, true);
context = new GraphicsContext(mode, window);
// Set the window hints
XSizeHints hints = new XSizeHints();
@ -174,12 +189,12 @@ namespace OpenTK.Platform.X11
hints.width = width;
hints.height = height;
hints.flags = (IntPtr)(XSizeHintsFlags.USSize | XSizeHintsFlags.USPosition);
Functions.XSetWMNormalHints(window.Display, window.Handle, ref hints);
Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
// Register for window destroy notification
IntPtr wm_destroy_atom = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
//XWMHints hint = new XWMHints();
Functions.XSetWMProtocols(window.Display, window.Handle, new IntPtr[] { wm_destroy_atom }, 1);
Functions.XSetWMProtocols(window.Display, window.WindowHandle, new IntPtr[] { wm_destroy_atom }, 1);
Top = Left = 0;
Right = Width;
@ -191,11 +206,11 @@ namespace OpenTK.Platform.X11
//Functions.XSetWMName(window.Display, window.Handle, ref text);
//Functions.XSetWMProperties(display, window, name, name, 0, /*None*/ null, 0, hints);
Debug.Print("done! (id: {0})", window.Handle);
Debug.Print("done! (id: {0})", window.WindowHandle);
//(glContext as IGLContextCreationHack).SetWindowHandle(window.Handle);
API.MapRaised(window.Display, window.Handle);
API.MapRaised(window.Display, window.WindowHandle);
mapped = true;
//context.CreateContext(true, null);
@ -245,6 +260,7 @@ namespace OpenTK.Platform.X11
exists = false;
isExiting = true;
Debug.Print("X11 window {0} destroyed.", e.DestroyWindowEvent.window);
window.WindowHandle = IntPtr.Zero;
return;
case XEventName.ConfigureNotify:
@ -384,7 +400,7 @@ namespace OpenTK.Platform.X11
/// </summary>
public IntPtr Handle
{
get { return this.window.Handle; }
get { return this.window.WindowHandle; }
}
#endregion
@ -400,7 +416,7 @@ namespace OpenTK.Platform.X11
get
{
IntPtr name = IntPtr.Zero;
Functions.XFetchName(window.Display, window.Handle, ref name);
Functions.XFetchName(window.Display, window.WindowHandle, ref name);
if (name != IntPtr.Zero)
return Marshal.PtrToStringAnsi(name);
@ -419,7 +435,7 @@ namespace OpenTK.Platform.X11
Functions.XSetWMName(window.Display, window.Handle, ref name);
*/
if (value != null)
Functions.XStoreName(window.Display, window.Handle, value);
Functions.XStoreName(window.Display, window.WindowHandle, value);
}
}
@ -439,12 +455,12 @@ namespace OpenTK.Platform.X11
{
if (value && !mapped)
{
Functions.XMapWindow(window.Display, window.Handle);
Functions.XMapWindow(window.Display, window.WindowHandle);
mapped = true;
}
else if (!value && mapped)
{
Functions.XUnmapWindow(window.Display, window.Handle);
Functions.XUnmapWindow(window.Display, window.WindowHandle);
mapped = false;
}
}
@ -490,7 +506,7 @@ namespace OpenTK.Platform.X11
public void DestroyWindow()
{
Debug.WriteLine("X11GLNative shutdown sequence initiated.");
Functions.XDestroyWindow(window.Display, window.Handle);
Functions.XDestroyWindow(window.Display, window.WindowHandle);
}
#endregion
@ -647,19 +663,13 @@ namespace OpenTK.Platform.X11
{
if (!disposed)
{
//Functions.XUnmapWindow(window.Display, window.WindowHandle);
if (window.WindowHandle != IntPtr.Zero)
Functions.XDestroyWindow(window.Display, window.WindowHandle);
if (manuallyCalled)
{
//if (glContext != null)
// glContext.Dispose();
// Kills connection to the X-Server. We don't want that,
// 'cause it kills the ExampleLauncher too.
//Functions.XCloseDisplay(window.Display);
}
Functions.XUnmapWindow(window.Display, window.Handle);
Functions.XDestroyWindow(window.Display, window.Handle);
disposed = true;
}
}

View file

@ -46,10 +46,10 @@ namespace OpenTK.Platform.X11
#endregion
#region --- Methods ---
#region --- Public Methods ---
/// <summary>Gets or sets the handle of the window.</summary>
public IntPtr Handle { get { return handle; } set { handle = value; } }
public IntPtr WindowHandle { get { return handle; } set { handle = value; } }
/// <summary>Gets or sets the parent of the window.</summary>
public X11WindowInfo Parent { get { return parent; } set { parent = value; } }
/// <summary>Gets or sets the X11 root window.</summary>
@ -64,14 +64,29 @@ namespace OpenTK.Platform.X11
public EventMask EventMask { get { return eventMask; } set { eventMask = value; } }
//public IntPtr TopLevelWindow { get { return topLevelWindow; } set { topLevelWindow = value; } }
#endregion
#region --- IDisposable Members ---
public void Dispose()
{
}
#endregion
#region --- Overrides ---
#region public override string ToString()
/// <summary>Returns a System.String that represents the current window.</summary>
/// <returns>A System.String that represents the current window.</returns>
public override string ToString()
{
return String.Format("X11.WindowInfo: Display {0}, Screen {1}, Handle {2}, Parent: ({3})",
this.Display, this.Screen, this.Handle, this.Parent != null ? this.Parent.ToString() : "null");
this.Display, this.Screen, this.WindowHandle, this.Parent != null ? this.Parent.ToString() : "null");
}
#region public override string ToString()
#endregion
/// <summary>Checks if <c>this</c> and <c>obj</c> reference the same win32 window.</summary>
/// <param name="obj">The object to check against.</param>
@ -97,6 +112,5 @@ namespace OpenTK.Platform.X11
#endregion
#endregion
}
}