Modified GraphicsMode.Index to be a nullable property. Modified consuming classes to check Index.HasValue prior to first use.

This commit is contained in:
the_fiddler 2009-08-15 16:44:43 +00:00
parent b503c41bf1
commit 9a6a539d26
6 changed files with 408 additions and 333 deletions

View file

@ -19,7 +19,7 @@ namespace OpenTK.Graphics
ColorFormat color_format, accumulator_format; ColorFormat color_format, accumulator_format;
int depth, stencil, buffers, samples; int depth, stencil, buffers, samples;
bool stereo; bool stereo;
IntPtr? index; // The id of the pixel format or visual. IntPtr? index = null; // The id of the pixel format or visual.
static GraphicsMode defaultMode; static GraphicsMode defaultMode;
static IGraphicsMode implementation; static IGraphicsMode implementation;
@ -43,9 +43,9 @@ namespace OpenTK.Graphics
#endregion #endregion
#region internal GraphicsMode((IntPtr index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo) #region internal GraphicsMode(IntPtr? index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
internal GraphicsMode(IntPtr index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, internal GraphicsMode(IntPtr? index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo) int buffers, bool stereo)
{ {
if (depth < 0) throw new ArgumentOutOfRangeException("depth", "Must be greater than, or equal to zero."); if (depth < 0) throw new ArgumentOutOfRangeException("depth", "Must be greater than, or equal to zero.");
@ -160,7 +160,7 @@ namespace OpenTK.Graphics
/// <param name="stereo">Set to true for a GraphicsMode with stereographic capabilities.</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> /// <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) 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) { } : this(null, color, depth, stencil, samples, accum, buffers, stereo) { }
#endregion #endregion
@ -287,7 +287,7 @@ namespace OpenTK.Graphics
#region internal IntPtr Index #region internal IntPtr Index
internal IntPtr Index internal IntPtr? Index
{ {
get get
{ {
@ -309,7 +309,7 @@ namespace OpenTK.Graphics
Stereo = mode.Stereo; Stereo = mode.Stereo;
} }
return index.Value; return index;
} }
set { index = value; } set { index = value; }
} }

View file

@ -29,14 +29,15 @@ using System;
using OpenTK.Graphics; using OpenTK.Graphics;
using System.Diagnostics; using System.Diagnostics;
using OpenTK.Platform.Windows;
namespace OpenTK.Platform.Egl namespace OpenTK.Platform.Egl
{ {
class EglContext : IGraphicsContext class EglContext : IGraphicsContext, IGraphicsContextInternal
{ {
#region Fields #region Fields
EglWindowInfo window; EglWindowInfo WindowInfo;
EGLContext context; EGLContext context;
GraphicsMode mode; GraphicsMode mode;
bool vsync = true; // Default vsync value is defined as 1 (true) in EGL. bool vsync = true; // Default vsync value is defined as 1 (true) in EGL.
@ -56,14 +57,23 @@ namespace OpenTK.Platform.Egl
EglContext shared = (EglContext)sharedContext; EglContext shared = (EglContext)sharedContext;
Egl.Initialize(window.Display, out major, out minor); int dummy_major, dummy_minor;
if (!Egl.Initialize(window.Display, out dummy_major, out dummy_minor))
throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError()));
EGLConfig config = new EGLConfig(mode.Index); WindowInfo = window;
mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
if (!mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
EGLConfig config = new EGLConfig(mode.Index.Value);
if (window.Surface.Handle == EGLSurface.None.Handle) if (window.Surface.Handle == EGLSurface.None.Handle)
window.CreateWindowSurface(config); window.CreateWindowSurface(config);
context = Egl.CreateContext(window.Display, config, shared.context, null); int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
context = Egl.CreateContext(window.Display, config, shared != null ? shared.context : EGLContext.None, attrib_list);
MakeCurrent(window); MakeCurrent(window);
} }
@ -73,14 +83,18 @@ namespace OpenTK.Platform.Egl
public void SwapBuffers() public void SwapBuffers()
{ {
Egl.SwapBuffers(window.Display, window.Surface); Egl.SwapBuffers(WindowInfo.Display, WindowInfo.Surface);
} }
public void MakeCurrent(IWindowInfo window) public void MakeCurrent(IWindowInfo window)
{ {
EglWindowInfo egl = (EglWindowInfo)window; // Ignore 'window', unless it actually is an EGL window. In other words,
Egl.MakeCurrent(egl.Display, egl.Surface, egl.Surface, context); // trying to make the EglContext current on a non-EGL window will do,
this.window = egl; // nothing (the EglContext will remain current on the previous EGL window
// or the window it was constructed on (which may not be EGL)).
if (window is EglWindowInfo)
WindowInfo = (EglWindowInfo)window;
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, context);
} }
public bool IsCurrent public bool IsCurrent
@ -100,10 +114,10 @@ namespace OpenTK.Platform.Egl
} }
set set
{ {
if (Egl.SwapInterval(window.Display, value ? 1 : 0)) if (Egl.SwapInterval(WindowInfo.Display, value ? 1 : 0))
vsync = value; vsync = value;
else else
Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", window.Display, value); Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value);
} }
} }
@ -147,8 +161,8 @@ namespace OpenTK.Platform.Egl
{ {
if (manual) if (manual)
{ {
Egl.MakeCurrent(window.Display, window.Surface, window.Surface, EGLContext.None); Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None);
Egl.DestroyContext(window.Display, context); Egl.DestroyContext(WindowInfo.Display, context);
} }
else else
{ {
@ -164,5 +178,42 @@ namespace OpenTK.Platform.Egl
} }
#endregion #endregion
#region IGraphicsContextInternal Members
public IGraphicsContext Implementation
{
get { return this; }
}
public void LoadAll()
{
// Todo: enable those
//OpenTK.Graphics.ES10.ES.LoadAll();
OpenTK.Graphics.ES11.GL.LoadAll();
//OpenTK.Graphics.ES20.ES.LoadAll();
}
public ContextHandle Context
{
get { return new ContextHandle(context.Handle.Value); }
}
public void RegisterForDisposal(IDisposable resource)
{
throw new NotImplementedException();
}
public void DisposeResources()
{
throw new NotImplementedException();
}
public IntPtr GetAddress(string function)
{
return Egl.GetProcAddress(function);
}
#endregion
} }
} }

View file

@ -429,9 +429,26 @@ namespace OpenTK.Platform.MacOS
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
private const string Library = "libdl.dylib";
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
private static extern bool NSIsSymbolNameDefined(string s);
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
private static extern IntPtr NSLookupAndBindSymbol(string s);
[DllImport(Library, EntryPoint = "NSAddressOfSymbol")]
private static extern IntPtr NSAddressOfSymbol(IntPtr symbol);
IntPtr IGraphicsContextInternal.GetAddress(string function) IntPtr IGraphicsContextInternal.GetAddress(string function)
{ {
throw new Exception("The method or operation is not implemented."); string fname = "_" + function;
if (!NSIsSymbolNameDefined(fname))
return IntPtr.Zero;
IntPtr symbol = NSLookupAndBindSymbol(fname);
if (symbol != IntPtr.Zero)
symbol = NSAddressOfSymbol(symbol);
return symbol;
} }
#endregion #endregion

View file

@ -314,15 +314,16 @@ namespace OpenTK.Platform.Windows
void SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window) void SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window)
{ {
if (mode.Index == IntPtr.Zero) throw new ArgumentException( if (!mode.Index.HasValue)
"mode", "The Index (pixel format) of the GraphicsMode is not set."); throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
if (window == null) throw new ArgumentNullException("window", "Must point to a valid window."); if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
PixelFormatDescriptor pfd = new PixelFormatDescriptor(); PixelFormatDescriptor pfd = new PixelFormatDescriptor();
Functions.DescribePixelFormat(window.DeviceContext, (int)mode.Index, Functions.DescribePixelFormat(window.DeviceContext, (int)mode.Index.Value,
API.PixelFormatDescriptorSize, ref pfd); API.PixelFormatDescriptorSize, ref pfd);
Debug.WriteLine(mode.Index.ToString()); Debug.WriteLine(mode.Index.ToString());
if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index, ref pfd)) if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd))
throw new GraphicsContextException(String.Format( throw new GraphicsContextException(String.Format(
"Requested GraphicsMode not available. SetPixelFormat error: {0}", Marshal.GetLastWin32Error())); "Requested GraphicsMode not available. SetPixelFormat error: {0}", Marshal.GetLastWin32Error()));
} }

View file

@ -24,13 +24,16 @@ namespace OpenTK.Platform.X11
internal X11GLControl(GraphicsMode mode, Control control) internal X11GLControl(GraphicsMode mode, Control control)
{ {
if (!mode.Index.HasValue)
throw new GraphicsModeException("Invalid GraphicsMode.");
this.mode = mode; this.mode = mode;
this.control = control; this.control = control;
X11WindowInfo window = (X11WindowInfo)this.WindowInfo; X11WindowInfo window = (X11WindowInfo)this.WindowInfo;
XVisualInfo info = new XVisualInfo(); XVisualInfo info = new XVisualInfo();
info.VisualID = mode.Index;
info.VisualID = mode.Index.Value;
int dummy; int dummy;
window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure( window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo)); Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));

View file

@ -124,7 +124,10 @@ namespace OpenTK.Platform.X11
lock (API.Lock) lock (API.Lock)
{ {
info.VisualID = mode.Index; if (!mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
info.VisualID = mode.Index.Value;
int dummy; int dummy;
window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure( window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo)); Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));