Backported bugfixes from 1.0 branch.

This commit is contained in:
the_fiddler 2010-02-03 19:04:42 +00:00
parent 411f4bcc98
commit 53b84d18d4
39 changed files with 513 additions and 550 deletions

View file

@ -7582,6 +7582,10 @@ ActiveUniformBlockParameter enum:
use ARB_uniform_buffer_object UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES use ARB_uniform_buffer_object UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER
use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER use ARB_uniform_buffer_object UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
# Used in primitive restart
EnableCap enum:
PRIMITIVE_RESTART = 0x8F9D # 3.1 (different from NV_primitive_restart)
# Non-core # Non-core

View file

@ -116,8 +116,7 @@ namespace Examples.Tutorial
return; return;
} }
// Alt+Enter toggles fullscreen mode. if (Keyboard[Key.F11])
if ((Keyboard[Key.AltLeft] || Keyboard[Key.AltRight]) && Keyboard[Key.Enter])
if (WindowState != WindowState.Fullscreen) if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen; WindowState = WindowState.Fullscreen;
else else

View file

@ -108,8 +108,7 @@ namespace Examples.Tutorial
return; return;
} }
if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) && if (Keyboard[OpenTK.Input.Key.F11])
Keyboard[OpenTK.Input.Key.Enter])
if (WindowState != WindowState.Fullscreen) if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen; WindowState = WindowState.Fullscreen;
else else

View file

@ -221,8 +221,7 @@ namespace Examples.Tutorial
if (Keyboard[OpenTK.Input.Key.Escape]) if (Keyboard[OpenTK.Input.Key.Escape])
this.Exit(); this.Exit();
if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) && if (Keyboard[OpenTK.Input.Key.F11])
Keyboard[OpenTK.Input.Key.Enter])
if (WindowState != WindowState.Fullscreen) if (WindowState != WindowState.Fullscreen)
WindowState = WindowState.Fullscreen; WindowState = WindowState.Fullscreen;
else else

View file

@ -66,14 +66,14 @@ namespace Examples.Tutorial
{ {
base.OnLoad(e); base.OnLoad(e);
Color color = Color.MidnightBlue; Color4 color = Color4.MidnightBlue;
GL.ClearColor(color.R, color.G, color.B, color.A); GL.ClearColor(color.R, color.G, color.B, color.A);
GL.Enable((All)EnableCap.DepthTest); GL.Enable((All)EnableCap.DepthTest);
} }
#endregion #endregion
#region OnResize #region OnResize
/// <summary> /// <summary>
/// Called when the user resizes the window. /// Called when the user resizes the window.
@ -95,7 +95,7 @@ namespace Examples.Tutorial
#endregion #endregion
#region OnUpdateFrame #region OnUpdateFrame
/// <summary> /// <summary>
/// Prepares the next frame for rendering. /// Prepares the next frame for rendering.
@ -115,7 +115,7 @@ namespace Examples.Tutorial
#endregion #endregion
#region OnRenderFrame #region OnRenderFrame
/// <summary> /// <summary>
/// Place your rendering code here. /// Place your rendering code here.
@ -138,7 +138,7 @@ namespace Examples.Tutorial
#endregion #endregion
#region private void DrawCube() #region private void DrawCube()
private void DrawCube() private void DrawCube()
{ {
@ -188,7 +188,7 @@ namespace Examples.Tutorial
#endregion #endregion
#region public static void Main() #region public static void Main()
/// <summary> /// <summary>
/// Entry point of this example. /// Entry point of this example.

View file

@ -41,7 +41,7 @@ using OpenTK.Graphics.ES20;
namespace Examples.Tutorial namespace Examples.Tutorial
{ {
[Example("Immediate mode", ExampleCategory.OpenGLES, "2.0", Documentation = "SimpleES20Window")] [Example("Simple ES 2.0", ExampleCategory.OpenGLES, "2.0", Documentation = "SimpleES20Window")]
public class SimpleES20Window : GameWindow public class SimpleES20Window : GameWindow
{ {
#region Constructor #region Constructor
@ -58,7 +58,7 @@ namespace Examples.Tutorial
{ {
base.OnLoad(e); base.OnLoad(e);
Color color = Color.MidnightBlue; Color4 color = Color4.MidnightBlue;
GL.ClearColor(color.R, color.G, color.B, color.A); GL.ClearColor(color.R, color.G, color.B, color.A);
GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.DepthTest);
} }
@ -119,48 +119,6 @@ namespace Examples.Tutorial
private void DrawCube() private void DrawCube()
{ {
#if false
GL.Begin(BeginMode.Quads);
GL.Color3(Color.Silver);
GL.Vertex3(-1.0f, -1.0f, -1.0f);
GL.Vertex3(-1.0f, 1.0f, -1.0f);
GL.Vertex3(1.0f, 1.0f, -1.0f);
GL.Vertex3(1.0f, -1.0f, -1.0f);
GL.Color3(Color.Honeydew);
GL.Vertex3(-1.0f, -1.0f, -1.0f);
GL.Vertex3(1.0f, -1.0f, -1.0f);
GL.Vertex3(1.0f, -1.0f, 1.0f);
GL.Vertex3(-1.0f, -1.0f, 1.0f);
GL.Color3(Color.Moccasin);
GL.Vertex3(-1.0f, -1.0f, -1.0f);
GL.Vertex3(-1.0f, -1.0f, 1.0f);
GL.Vertex3(-1.0f, 1.0f, 1.0f);
GL.Vertex3(-1.0f, 1.0f, -1.0f);
GL.Color3(Color.IndianRed);
GL.Vertex3(-1.0f, -1.0f, 1.0f);
GL.Vertex3(1.0f, -1.0f, 1.0f);
GL.Vertex3(1.0f, 1.0f, 1.0f);
GL.Vertex3(-1.0f, 1.0f, 1.0f);
GL.Color3(Color.PaleVioletRed);
GL.Vertex3(-1.0f, 1.0f, -1.0f);
GL.Vertex3(-1.0f, 1.0f, 1.0f);
GL.Vertex3(1.0f, 1.0f, 1.0f);
GL.Vertex3(1.0f, 1.0f, -1.0f);
GL.Color3(Color.ForestGreen);
GL.Vertex3(1.0f, -1.0f, -1.0f);
GL.Vertex3(1.0f, 1.0f, -1.0f);
GL.Vertex3(1.0f, 1.0f, 1.0f);
GL.Vertex3(1.0f, -1.0f, 1.0f);
GL.End();
#endif
} }
#endregion #endregion

View file

@ -43,17 +43,7 @@ namespace Examples
public FullscreenAntialias() public FullscreenAntialias()
: base(800, 600, new GraphicsMode(32, 0, 0, 4)) : base(800, 600, new GraphicsMode(32, 0, 0, 4))
{ {
Keyboard.KeyDown += delegate(object sender, KeyboardKeyEventArgs e) Keyboard.KeyDown += Keyboard_KeyDown;
{
if (e.Key == Key.Escape)
this.Exit();
if ((e.Key == Key.AltLeft || e.Key == Key.AltRight) && (e.Key == Key.Enter || e.Key == Key.KeypadEnter))
if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Fullscreen;
};
} }
#region Keyboard_KeyDown #region Keyboard_KeyDown
@ -63,12 +53,12 @@ namespace Examples
/// </summary> /// </summary>
/// <param name="sender">The KeyboardDevice which generated this event.</param> /// <param name="sender">The KeyboardDevice which generated this event.</param>
/// <param name="key">The key that was pressed.</param> /// <param name="key">The key that was pressed.</param>
void Keyboard_KeyDown(KeyboardDevice sender, Key key) void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
{ {
if (sender[Key.Escape]) if (e.Key == Key.Escape)
this.Exit(); this.Exit();
if ((sender[Key.AltLeft] || sender[Key.AltRight]) && (sender[Key.Enter] || sender[Key.KeypadEnter])) if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen) if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal; this.WindowState = WindowState.Normal;
else else

View file

@ -39,7 +39,7 @@ namespace Examples.Tutorial
if (e.Key == Key.Escape) if (e.Key == Key.Escape)
this.Exit(); this.Exit();
if ((e.Key == Key.AltLeft || e.Key == Key.AltRight) && (e.Key == Key.Enter || e.Key == Key.KeypadEnter)) if (e.Key == Key.F11)
if (this.WindowState == WindowState.Fullscreen) if (this.WindowState == WindowState.Fullscreen)
this.WindowState = WindowState.Normal; this.WindowState = WindowState.Normal;
else else

View file

@ -64,7 +64,7 @@ namespace Examples.Tests
Utilities.SetWindowTitle(game); Utilities.SetWindowTitle(game);
game.Keyboard.KeyUp += delegate(object sender, OpenTK.Input.KeyboardKeyEventArgs e) game.Keyboard.KeyUp += delegate(object sender, OpenTK.Input.KeyboardKeyEventArgs e)
{ {
if (e.Key == OpenTK.Input.Key.Space) if (e.Key == OpenTK.Input.Key.F11)
{ {
if (game.WindowState == OpenTK.WindowState.Fullscreen) if (game.WindowState == OpenTK.WindowState.Fullscreen)
game.WindowState = OpenTK.WindowState.Normal; game.WindowState = OpenTK.WindowState.Normal;

View file

@ -29,6 +29,10 @@ namespace Examples
return (int)((c.A << 24) | (c.B << 16) | (c.G << 8) | c.R); return (int)((c.A << 24) | (c.B << 16) | (c.G << 8) | c.R);
} }
/// <summary>
/// Sets the window title to the name of the sample.
/// </summary>
/// <param name="window"></param>
public static void SetWindowTitle(GameWindow window) public static void SetWindowTitle(GameWindow window)
{ {
ExampleAttribute info = GetExampleAttribute(window.GetType()); ExampleAttribute info = GetExampleAttribute(window.GetType());
@ -36,6 +40,10 @@ namespace Examples
window.Icon = OpenTK.Examples.Properties.Resources.App; window.Icon = OpenTK.Examples.Properties.Resources.App;
} }
/// <summary>
/// Sets the window title to the name of the sample.
/// </summary>
/// <param name="window"></param>
public static void SetWindowTitle(System.Windows.Forms.Form window) public static void SetWindowTitle(System.Windows.Forms.Form window)
{ {
ExampleAttribute info = GetExampleAttribute(window.GetType()); ExampleAttribute info = GetExampleAttribute(window.GetType());

View file

@ -59,8 +59,7 @@ namespace OpenTK.Audio
#region static AudioContext() #region static AudioContext()
/// <private /> /// \internal
/// <static />
/// <summary> /// <summary>
/// Runs before the actual class constructor, to load available devices. /// Runs before the actual class constructor, to load available devices.
/// </summary> /// </summary>
@ -224,7 +223,7 @@ namespace OpenTK.Audio
Four = 4, Four = 4,
} }
/// <private /> /// \internal
/// <summary>Creates the audio context using the specified device.</summary> /// <summary>Creates the audio context using the specified device.</summary>
/// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device.</param> /// <param name="device">The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device.</param>
/// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param> /// <param name="freq">Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default.</param>
@ -358,7 +357,7 @@ namespace OpenTK.Audio
#region static void MakeCurrent(AudioContext context) #region static void MakeCurrent(AudioContext context)
/// <private /> /// \internal
/// <summary>Makes the specified AudioContext current in the calling thread.</summary> /// <summary>Makes the specified AudioContext current in the calling thread.</summary>
/// <param name="context">The OpenTK.Audio.AudioContext to make current, or null.</param> /// <param name="context">The OpenTK.Audio.AudioContext to make current, or null.</param>
/// <exception cref="ObjectDisposedException"> /// <exception cref="ObjectDisposedException">

View file

@ -294,9 +294,9 @@ namespace OpenTK.Audio.OpenAL
/// <summary>This function retrieves a set of three floating-point values from a property of the listener.</summary> /// <summary>This function retrieves a set of three floating-point values from a property of the listener.</summary>
/// <param name="param">The name of the attribute to be retrieved: ALListener3f.Position, ALListener3f.Velocity</param> /// <param name="param">The name of the attribute to be retrieved: ALListener3f.Position, ALListener3f.Velocity</param>
/// <param name="value1">Pointers to the three floating-point being retrieved.</param> /// <param name="value1">The first floating-point value being retrieved.</param>
/// <param name="value2">Pointers to the three floating-point being retrieved.</param> /// <param name="value2">The second floating-point value being retrieved.</param>
/// <param name="value3">Pointers to the three floating-point being retrieved.</param> /// <param name="value3">The third floating-point value being retrieved.</param>
[DllImport(AL.Lib, EntryPoint = "alGetListener3f", ExactSpelling = true, CallingConvention = AL.Style), SuppressUnmanagedCodeSecurity()] [DllImport(AL.Lib, EntryPoint = "alGetListener3f", ExactSpelling = true, CallingConvention = AL.Style), SuppressUnmanagedCodeSecurity()]
public static extern void GetListener(ALListener3f param, [Out] out float value1, [Out] out float value2, [Out] out float value3); public static extern void GetListener(ALListener3f param, [Out] out float value1, [Out] out float value2, [Out] out float value3);
// AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); // AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );

View file

@ -285,6 +285,27 @@ namespace OpenTK
Context.MakeCurrent(WindowInfo); Context.MakeCurrent(WindowInfo);
} }
#endregion
#region OnClose
/// <summary>
/// Called when the NativeWindow is about to close.
/// </summary>
/// <param name="e">
/// The <see cref="System.ComponentModel.CancelEventArgs" /> for this event.
/// Set e.Cancel to true in order to stop the GameWindow from closing.</param>
protected override void OnClosing (System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
if (!e.Cancel)
{
isExiting = true;
OnUnloadInternal(EventArgs.Empty);
}
}
#endregion #endregion
#region OnLoad #region OnLoad
@ -381,20 +402,25 @@ namespace OpenTK
Debug.Print("Entering main loop."); Debug.Print("Entering main loop.");
update_watch.Start(); update_watch.Start();
render_watch.Start(); render_watch.Start();
while (!IsExiting && Exists) while (true)
{ {
ProcessEvents(); ProcessEvents();
DispatchUpdateAndRenderFrame(this, EventArgs.Empty); if (Exists && !IsExiting)
DispatchUpdateAndRenderFrame(this, EventArgs.Empty);
else
return;
} }
} }
finally finally
{ {
OnUnloadInternal(EventArgs.Empty); Move -= DispatchUpdateAndRenderFrame;
Resize -= DispatchUpdateAndRenderFrame;
if (Exists) if (Exists)
{ {
Dispose(); // TODO: Should similar behaviour be retained, possibly on native window level?
//while (this.Exists) ProcessEvents(); // TODO: Should similar behaviour be retained, possibly on native window level? //while (this.Exists)
// ProcessEvents(false);
} }
} }
} }
@ -464,16 +490,6 @@ namespace OpenTK
return; return;
double time_left = next_render - time; double time_left = next_render - time;
// Todo: remove this?
if (VSync == VSyncMode.Adaptive)
{
// Check if we have enough time for a vsync
if (TargetRenderPeriod != 0 && RenderTime > 2.0 * TargetRenderPeriod)
Context.VSync = false;
else
Context.VSync = true;
}
if (time_left <= 0.0) if (time_left <= 0.0)
{ {
// Schedule next render event. The 1 second cap ensures // Schedule next render event. The 1 second cap ensures
@ -487,6 +503,22 @@ namespace OpenTK
if (time > 0) if (time > 0)
{ {
// Todo: revisit this code. Maybe check average framerate instead?
// Note: VSyncMode.Adaptive enables vsync by default. The code below
// is supposed to disable vsync if framerate becomes too low (half of target
// framerate in the current approach) and reenable once the framerate
// rises again.
// Note 2: calling Context.VSync = true repeatedly seems to cause jitter on
// some configurations. If possible, we should avoid repeated calls.
if (VSync == VSyncMode.Adaptive && TargetRenderPeriod != 0)
{
// Check if we have enough time for a vsync
if (RenderTime > 2.0 * TargetRenderPeriod)
Context.VSync = false;
else
Context.VSync = true;
}
render_period = render_args.Time = time; render_period = render_args.Time = time;
OnRenderFrameInternal(render_args); OnRenderFrameInternal(render_args);
render_time = render_watch.Elapsed.TotalSeconds; render_time = render_watch.Elapsed.TotalSeconds;
@ -864,11 +896,33 @@ namespace OpenTK
#endregion #endregion
#endregion #region WindowState
#region Events /// <summary>
/// Gets or states the state of the NativeWindow.
/// </summary>
public override WindowState WindowState
{
get
{
return base.WindowState;
}
set
{
base.WindowState = value;
Debug.Print("Updating Context after setting WindowState to {0}", value);
/// <summary> if (Context != null)
Context.Update(WindowInfo);
}
}
#endregion
#endregion
#region Events
/// <summary>
/// Occurs before the window is displayed for the first time. /// Occurs before the window is displayed for the first time.
/// </summary> /// </summary>
public event EventHandler<EventArgs> Load; public event EventHandler<EventArgs> Load;
@ -1018,7 +1072,8 @@ namespace OpenTK
/// </summary> /// </summary>
On, On,
/// <summary> /// <summary>
/// VSync enabled, but automatically disabled if framerate falls below a specified limit. /// VSync enabled, unless framerate falls below one half of target framerate.
/// If no target framerate is specified, this behaves exactly like <see cref="VSyncMode.On"/>.
/// </summary> /// </summary>
Adaptive, Adaptive,
} }

View file

@ -115,10 +115,10 @@ namespace OpenTK.Graphics
public int ToArgb() public int ToArgb()
{ {
uint value = uint value =
(uint)(A / Byte.MaxValue) << 24 | (uint)(A * Byte.MaxValue) << 24 |
(uint)(R / Byte.MaxValue) << 16 | (uint)(R * Byte.MaxValue) << 16 |
(uint)(G / Byte.MaxValue) << 8 | (uint)(G * Byte.MaxValue) << 8 |
(uint)(B / Byte.MaxValue); (uint)(B * Byte.MaxValue);
return unchecked((int)value); return unchecked((int)value);
} }

View file

@ -40,11 +40,6 @@ namespace OpenTK.Graphics
#region --- Constructors --- #region --- Constructors ---
static GraphicsContext()
{
GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext();
}
// Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method).
GraphicsContext(ContextHandle handle) GraphicsContext(ContextHandle handle)
{ {
@ -105,14 +100,25 @@ namespace OpenTK.Graphics
// Todo: Add a DummyFactory implementing IPlatformFactory. // Todo: Add a DummyFactory implementing IPlatformFactory.
if (designMode) if (designMode)
{
implementation = new Platform.Dummy.DummyGLContext(); implementation = new Platform.Dummy.DummyGLContext();
}
else else
{
IPlatformFactory factory = null;
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
{ {
case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; case false: factory = Factory.Default; break;
case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; case true: factory = Factory.Embedded; break;
} }
implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags);
// Note: this approach does not allow us to mix native and EGL contexts in the same process.
// This should not be a problem, as this use-case is not interesting for regular applications.
if (GetCurrentContext == null)
GetCurrentContext = factory.CreateGetCurrentGraphicsContext();
}
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
} }
finally finally
@ -252,6 +258,10 @@ namespace OpenTK.Graphics
/// <summary> /// <summary>
/// Gets the GraphicsContext that is current in the calling thread. /// Gets the GraphicsContext that is current in the calling thread.
/// </summary> /// </summary>
/// <remarks>
/// Note: this property will not function correctly when both desktop and EGL contexts are
/// available in the same process. This scenario is very unlikely to appear in practice.
/// </remarks>
public static IGraphicsContext CurrentContext public static IGraphicsContext CurrentContext
{ {
get get

View file

@ -5756,6 +5756,7 @@ namespace OpenTK.Graphics.OpenGL
RasterizerDiscard = ((int)0x8C89), RasterizerDiscard = ((int)0x8C89),
FramebufferSrgb = ((int)0x8DB9), FramebufferSrgb = ((int)0x8DB9),
SampleMask = ((int)0x8E51), SampleMask = ((int)0x8E51),
PrimitiveRestart = ((int)0x8F9D),
} }
public enum ErrorCode : int public enum ErrorCode : int

View file

@ -729,7 +729,7 @@ namespace OpenTK.Graphics.OpenGL
public static void TexCoordPointer(int size, TexCoordPointerType type, int stride, int offset) public static void TexCoordPointer(int size, TexCoordPointerType type, int stride, int offset)
{ {
TexCoordPointer(size, type, stride, offset); TexCoordPointer(size, type, stride, (IntPtr)offset);
} }
public static void VertexAttribPointer(int index, int size, VertexAttribPointerType type, bool normalized, int stride, int offset) public static void VertexAttribPointer(int index, int size, VertexAttribPointerType type, bool normalized, int stride, int offset)

View file

@ -136,7 +136,7 @@ namespace OpenTK.Input
/// </summary> /// </summary>
public int Wheel public int Wheel
{ {
get { return (int)(wheel + 0.5f); } get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
internal set { WheelPrecise = value; } internal set { WheelPrecise = value; }
} }
@ -306,7 +306,7 @@ namespace OpenTK.Input
{ {
get get
{ {
int result = (int)(wheel - wheel_last_accessed + 0.5f); int result = (int)Math.Round(wheel - wheel_last_accessed, MidpointRounding.AwayFromZero);
wheel_last_accessed = (int)wheel; wheel_last_accessed = (int)wheel;
return result; return result;
} }
@ -614,13 +614,13 @@ namespace OpenTK.Input
/// Gets the value of the wheel in integer units. /// Gets the value of the wheel in integer units.
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead. /// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
/// </summary> /// </summary>
public int Value { get { return (int)(value + 0.5f); } } public int Value { get { return (int)Math.Round(value, MidpointRounding.AwayFromZero); } }
/// <summary> /// <summary>
/// Gets the change in value of the wheel for this event in integer units. /// Gets the change in value of the wheel for this event in integer units.
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead. /// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
/// </summary> /// </summary>
public int Delta { get { return (int)(delta + 0.5f); } } public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
/// <summary> /// <summary>
/// Gets the precise value of the wheel in floating-point units. /// Gets the precise value of the wheel in floating-point units.

View file

@ -167,7 +167,7 @@ namespace OpenTK
{ {
get get
{ {
return (float)System.Math.Sqrt(X * X + Y * Y); return System.Math.Sqrt(X * X + Y * Y);
} }
} }
@ -230,7 +230,7 @@ namespace OpenTK
/// </summary> /// </summary>
public void Normalize() public void Normalize()
{ {
double scale = 1.0f / Length; double scale = 1.0 / Length;
X *= scale; X *= scale;
Y *= scale; Y *= scale;
} }
@ -627,7 +627,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns> /// <returns>The normalized vector</returns>
public static Vector2d Normalize(Vector2d vec) public static Vector2d Normalize(Vector2d vec)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
vec.X *= scale; vec.X *= scale;
vec.Y *= scale; vec.Y *= scale;
return vec; return vec;
@ -640,7 +640,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param> /// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector2d vec, out Vector2d result) public static void Normalize(ref Vector2d vec, out Vector2d result)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
result.X = vec.X * scale; result.X = vec.X * scale;
result.Y = vec.Y * scale; result.Y = vec.Y * scale;
} }
@ -882,7 +882,7 @@ namespace OpenTK
/// <returns>The result of the operation.</returns> /// <returns>The result of the operation.</returns>
public static Vector2d operator /(Vector2d vec, double f) public static Vector2d operator /(Vector2d vec, double f)
{ {
double mult = 1.0f / f; double mult = 1.0 / f;
vec.X *= mult; vec.X *= mult;
vec.Y *= mult; vec.Y *= mult;
return vec; return vec;

View file

@ -199,7 +199,7 @@ namespace OpenTK
{ {
get get
{ {
return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z); return System.Math.Sqrt(X * X + Y * Y + Z * Z);
} }
} }
@ -220,7 +220,7 @@ namespace OpenTK
{ {
get get
{ {
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z); return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z);
} }
} }
@ -254,7 +254,7 @@ namespace OpenTK
/// </summary> /// </summary>
public void Normalize() public void Normalize()
{ {
double scale = 1.0f / this.Length; double scale = 1.0 / this.Length;
X *= scale; X *= scale;
Y *= scale; Y *= scale;
Z *= scale; Z *= scale;
@ -433,7 +433,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")] [Obsolete("Use static Divide() method instead.")]
public static Vector3d Div(Vector3d a, double f) public static Vector3d Div(Vector3d a, double f)
{ {
double mult = 1.0f / f; double mult = 1.0 / f;
a.X *= mult; a.X *= mult;
a.Y *= mult; a.Y *= mult;
a.Z *= mult; a.Z *= mult;
@ -449,7 +449,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")] [Obsolete("Use static Divide() method instead.")]
public static void Div(ref Vector3d a, double f, out Vector3d result) public static void Div(ref Vector3d a, double f, out Vector3d result)
{ {
double mult = 1.0f / f; double mult = 1.0 / f;
result.X = a.X * mult; result.X = a.X * mult;
result.Y = a.Y * mult; result.Y = a.Y * mult;
result.Z = a.Z * mult; result.Z = a.Z * mult;
@ -747,7 +747,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns> /// <returns>The normalized vector</returns>
public static Vector3d Normalize(Vector3d vec) public static Vector3d Normalize(Vector3d vec)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
vec.X *= scale; vec.X *= scale;
vec.Y *= scale; vec.Y *= scale;
vec.Z *= scale; vec.Z *= scale;
@ -761,7 +761,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param> /// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector3d vec, out Vector3d result) public static void Normalize(ref Vector3d vec, out Vector3d result)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
result.X = vec.X * scale; result.X = vec.X * scale;
result.Y = vec.Y * scale; result.Y = vec.Y * scale;
result.Z = vec.Z * scale; result.Z = vec.Z * scale;
@ -1085,7 +1085,7 @@ namespace OpenTK
/// <param name="result">The transformed vector</param> /// <param name="result">The transformed vector</param>
public static void Transform(ref Vector3d vec, ref Matrix4d mat, out Vector3d result) public static void Transform(ref Vector3d vec, ref Matrix4d mat, out Vector3d result)
{ {
Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0f); Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0);
Vector4d.Transform(ref v4, ref mat, out v4); Vector4d.Transform(ref v4, ref mat, out v4);
result = v4.Xyz; result = v4.Xyz;
} }

View file

@ -260,7 +260,7 @@ namespace OpenTK
{ {
get get
{ {
return (double)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W); return System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
} }
} }
@ -281,7 +281,7 @@ namespace OpenTK
{ {
get get
{ {
return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W);
} }
} }
@ -314,7 +314,7 @@ namespace OpenTK
/// </summary> /// </summary>
public void Normalize() public void Normalize()
{ {
double scale = 1.0f / this.Length; double scale = 1.0 / this.Length;
X *= scale; X *= scale;
Y *= scale; Y *= scale;
Z *= scale; Z *= scale;
@ -469,7 +469,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")] [Obsolete("Use static Divide() method instead.")]
public static Vector4d Div(Vector4d a, double f) public static Vector4d Div(Vector4d a, double f)
{ {
double mult = 1.0f / f; double mult = 1.0 / f;
a.X *= mult; a.X *= mult;
a.Y *= mult; a.Y *= mult;
a.Z *= mult; a.Z *= mult;
@ -486,7 +486,7 @@ namespace OpenTK
[Obsolete("Use static Divide() method instead.")] [Obsolete("Use static Divide() method instead.")]
public static void Div(ref Vector4d a, double f, out Vector4d result) public static void Div(ref Vector4d a, double f, out Vector4d result)
{ {
double mult = 1.0f / f; double mult = 1.0 / f;
result.X = a.X * mult; result.X = a.X * mult;
result.Y = a.Y * mult; result.Y = a.Y * mult;
result.Z = a.Z * mult; result.Z = a.Z * mult;
@ -761,7 +761,7 @@ namespace OpenTK
/// <returns>The normalized vector</returns> /// <returns>The normalized vector</returns>
public static Vector4d Normalize(Vector4d vec) public static Vector4d Normalize(Vector4d vec)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
vec.X *= scale; vec.X *= scale;
vec.Y *= scale; vec.Y *= scale;
vec.Z *= scale; vec.Z *= scale;
@ -776,7 +776,7 @@ namespace OpenTK
/// <param name="result">The normalized vector</param> /// <param name="result">The normalized vector</param>
public static void Normalize(ref Vector4d vec, out Vector4d result) public static void Normalize(ref Vector4d vec, out Vector4d result)
{ {
double scale = 1.0f / vec.Length; double scale = 1.0 / vec.Length;
result.X = vec.X * scale; result.X = vec.X * scale;
result.Y = vec.Y * scale; result.Y = vec.Y * scale;
result.Z = vec.Z * scale; result.Z = vec.Z * scale;

View file

@ -485,7 +485,7 @@ namespace OpenTK
/// <summary> /// <summary>
/// Gets or states the state of the NativeWindow. /// Gets or states the state of the NativeWindow.
/// </summary> /// </summary>
public WindowState WindowState public virtual WindowState WindowState
{ {
get get
{ {

View file

@ -7,5 +7,6 @@
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" /> <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" /> <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
</configuration> </configuration>

View file

@ -33,108 +33,13 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.Egl namespace OpenTK.Platform.Egl
{ {
// Note: the Workaround structs declared in each type below work around using EGLNativeDisplayType = IntPtr;
// gmcs 2.4.2 bug #530270 (https://bugzilla.novell.com/show_bug.cgi?id=530270). using EGLNativePixmapType = IntPtr;
// They don't cause any change in functionality other than make the compiler happy. using EGLConfig = IntPtr;
using EGLContext = IntPtr;
struct EGLNativeDisplayType using EGLDisplay = IntPtr;
{ using EGLSurface = IntPtr;
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] using EGLClientBuffer = IntPtr;
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLNativeDisplayType(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLNativeDisplayType Default = new EGLNativeDisplayType();
}
struct EGLNativePixmapType
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLNativePixmapType(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
struct EGLConfig
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLConfig(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
struct EGLContext
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLContext(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLContext None;
}
struct EGLDisplay
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLDisplay(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLDisplay Null = default(EGLDisplay);
}
struct EGLSurface
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLSurface(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
public static readonly EGLSurface None = default(EGLSurface);
}
struct EGLClientBuffer
{
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public struct Workaround { }
public readonly Compute.Handle<Workaround> Handle;
public EGLClientBuffer(IntPtr handle)
{
Handle = new Compute.Handle<Workaround>(handle);
}
}
static partial class Egl static partial class Egl
{ {
@ -267,21 +172,14 @@ namespace OpenTK.Platform.Egl
public static extern int GetError(); public static extern int GetError();
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")]
static extern IntPtr eglGetDisplay(EGLNativeDisplayType display_id); public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
public static EGLDisplay GetDisplay(EGLNativeDisplayType display_id)
{
IntPtr ptr = eglGetDisplay(display_id);
EGLDisplay ret = new EGLDisplay(ptr);
return ret;
}
[DllImportAttribute("libEGL.dll", EntryPoint = "eglInitialize")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglInitialize")]
[return: MarshalAsAttribute(UnmanagedType.I1)] //[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor); public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")]
[return: MarshalAsAttribute(UnmanagedType.I1)] //[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool Terminate(EGLDisplay dpy); public static extern bool Terminate(EGLDisplay dpy);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")]
@ -300,14 +198,7 @@ namespace OpenTK.Platform.Egl
public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value); public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")]
static extern IntPtr eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list); public static extern EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list);
public static EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list)
{
IntPtr ptr = eglCreateWindowSurface(dpy, config, win, attrib_list);
EGLSurface ret = new EGLSurface(ptr);
return ret;
}
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")]
public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list); public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
@ -363,9 +254,9 @@ namespace OpenTK.Platform.Egl
public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list) public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list)
{ {
IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list); IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list);
if (ptr == EGLContext.None.Handle.Value) if (ptr == IntPtr.Zero)
throw new GraphicsContextException(String.Format("Failed to create EGL context, error: {0}.", Egl.GetError())); throw new GraphicsContextException(String.Format("Failed to create EGL context, error: {0}.", Egl.GetError()));
return new EGLContext(ptr); return ptr;
} }
[DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")]

View file

@ -38,7 +38,7 @@ namespace OpenTK.Platform.Egl
#region Fields #region Fields
EglWindowInfo WindowInfo; EglWindowInfo WindowInfo;
EGLContext HandleAsEGLContext { get { return new EGLContext(Handle.Handle); } set { Handle = new ContextHandle(value.Handle.Value); } } IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
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.
#endregion #endregion
@ -64,13 +64,13 @@ namespace OpenTK.Platform.Egl
Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo); Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
if (!Mode.Index.HasValue) if (!Mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
EGLConfig config = new EGLConfig(mode.Index.Value); IntPtr config = Mode.Index.Value;
if (window.Surface.Handle == EGLSurface.None.Handle) if (window.Surface == IntPtr.Zero)
window.CreateWindowSurface(config); window.CreateWindowSurface(config);
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE }; int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : EGLContext.None, attrib_list); HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : IntPtr.Zero, attrib_list);
MakeCurrent(window); MakeCurrent(window);
} }
@ -108,7 +108,7 @@ namespace OpenTK.Platform.Egl
public override bool IsCurrent public override bool IsCurrent
{ {
get { return Egl.GetCurrentContext().Handle == HandleAsEGLContext.Handle; } get { return Egl.GetCurrentContext() == HandleAsEGLContext; }
} }
public override bool VSync public override bool VSync
@ -155,12 +155,12 @@ namespace OpenTK.Platform.Egl
{ {
if (manual) if (manual)
{ {
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None); Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, IntPtr.Zero);
Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext); Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext);
} }
else else
{ {
Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext.Handle); Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext);
} }
IsDisposed = true; IsDisposed = true;
} }

View file

@ -38,7 +38,7 @@ namespace OpenTK.Platform.Egl
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo) public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
{ {
EGLConfig[] configs = new EGLConfig[1]; IntPtr[] configs = new IntPtr[1];
int[] attribList = new int[] int[] attribList = new int[]
{ {
//Egl.SURFACE_TYPE, Egl.WINDOW_BIT, //Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
@ -58,7 +58,7 @@ namespace OpenTK.Platform.Egl
}; };
// Todo: what if we don't wish to use the default display? // Todo: what if we don't wish to use the default display?
EGLDisplay display = Egl.GetDisplay(EGLNativeDisplayType.Default); IntPtr display = Egl.GetDisplay(IntPtr.Zero);
int major, minor; int major, minor;
if (!Egl.Initialize(display, out major, out minor)) if (!Egl.Initialize(display, out major, out minor))
throw new GraphicsModeException(String.Format("Failed to initialize display connection, error {0}", Egl.GetError())); throw new GraphicsModeException(String.Format("Failed to initialize display connection, error {0}", Egl.GetError()));
@ -75,7 +75,7 @@ namespace OpenTK.Platform.Egl
} }
// See what we really got // See what we really got
EGLConfig active_config = configs[0]; IntPtr active_config = configs[0];
int r, g, b, a; int r, g, b, a;
Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r); Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r);
Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g); Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g);
@ -88,7 +88,7 @@ namespace OpenTK.Platform.Egl
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers); Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers);
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples); Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples);
return new GraphicsMode(active_config.Handle.Value, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false); return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false);
} }
#endregion #endregion

View file

@ -37,10 +37,12 @@ namespace OpenTK.Platform.Egl
// EGL factory for the Windows platform. // EGL factory for the Windows platform.
class EglWinPlatformFactory : WinFactory class EglWinPlatformFactory : WinFactory
{ {
#region Public Members
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
WinWindowInfo win_win = (WinWindowInfo)window; WinWindowInfo win_win = (WinWindowInfo)window;
EGLDisplay egl_display = Egl.GetDisplay(EGLNativeDisplayType.Default); // Egl.GetDisplay(new EGLNativeDisplayType(win_win.DeviceContext)); IntPtr egl_display = GetDisplay(win_win.DeviceContext);
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display); EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display);
return new EglContext(mode, egl_win, shareContext, major, minor, flags); return new EglContext(mode, egl_win, shareContext, major, minor, flags);
} }
@ -48,14 +50,37 @@ namespace OpenTK.Platform.Egl
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
WinWindowInfo win_win = (WinWindowInfo)window; WinWindowInfo win_win = (WinWindowInfo)window;
EGLDisplay egl_display = Egl.GetDisplay(EGLNativeDisplayType.Default); // Egl.GetDisplay(new EGLNativeDisplayType(win_win.DeviceContext)); IntPtr egl_display = GetDisplay(win_win.DeviceContext);
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display); EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.WindowHandle, egl_display);
return new EglContext(handle, egl_win, shareContext, major, minor, flags); return new EglContext(handle, egl_win, shareContext, major, minor, flags);
} }
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{
return (GraphicsContext.GetCurrentContextDelegate)delegate
{
return new ContextHandle(Egl.GetCurrentContext());
};
}
public override IGraphicsMode CreateGraphicsMode() public override IGraphicsMode CreateGraphicsMode()
{ {
return new EglGraphicsMode(); return new EglGraphicsMode();
} }
#endregion
#region Private Members
IntPtr GetDisplay(IntPtr dc)
{
IntPtr display = Egl.GetDisplay(dc);
if (display == IntPtr.Zero)
display = Egl.GetDisplay(IntPtr.Zero);
return display;
}
#endregion
} }
} }

View file

@ -39,21 +39,21 @@ namespace OpenTK.Platform.Egl
#region Fields #region Fields
IntPtr handle; IntPtr handle;
EGLDisplay display; IntPtr display;
EGLSurface surface; IntPtr surface;
bool disposed; bool disposed;
#endregion #endregion
#region Constructiors #region Constructiors
public EglWindowInfo(IntPtr handle, EGLDisplay display) public EglWindowInfo(IntPtr handle, IntPtr display)
{ {
Handle = handle; Handle = handle;
Display = display; Display = display;
} }
public EglWindowInfo(IntPtr handle, EGLDisplay display, EGLSurface surface) public EglWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
{ {
Handle = handle; Handle = handle;
Display = display; Display = display;
@ -66,11 +66,11 @@ namespace OpenTK.Platform.Egl
public IntPtr Handle { get { return handle; } private set { handle = value; } } public IntPtr Handle { get { return handle; } private set { handle = value; } }
public EGLDisplay Display { get { return display; } private set { display = value; } } public IntPtr Display { get { return display; } private set { display = value; } }
public EGLSurface Surface { get { return surface; } private set { surface = value; } } public IntPtr Surface { get { return surface; } private set { surface = value; } }
public void CreateWindowSurface(EGLConfig config) public void CreateWindowSurface(IntPtr config)
{ {
Surface = Egl.CreateWindowSurface(Display, config, Handle, null); Surface = Egl.CreateWindowSurface(Display, config, Handle, null);
int error = Egl.GetError(); int error = Egl.GetError();
@ -90,7 +90,7 @@ namespace OpenTK.Platform.Egl
public void DestroySurface() public void DestroySurface()
{ {
if (Surface.Handle != EGLSurface.None.Handle) if (Surface != IntPtr.Zero)
if (!Egl.DestroySurface(Display, Surface)) if (!Egl.DestroySurface(Display, Surface))
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface); Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
} }

View file

@ -38,15 +38,23 @@ namespace OpenTK.Platform.Egl
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
X11WindowInfo x11_win = (X11WindowInfo)window; X11WindowInfo x11_win = (X11WindowInfo)window;
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(new EGLNativeDisplayType(x11_win.Display))); EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(x11_win.Display));
return new EglContext(mode, egl_win, shareContext, major, minor, flags); return new EglContext(mode, egl_win, shareContext, major, minor, flags);
} }
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
X11WindowInfo x11_win = (X11WindowInfo)window; X11WindowInfo x11_win = (X11WindowInfo)window;
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(new EGLNativeDisplayType(x11_win.Display))); EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.WindowHandle, Egl.GetDisplay(x11_win.Display));
return new EglContext(handle, egl_win, shareContext, major, minor, flags); return new EglContext(handle, egl_win, shareContext, major, minor, flags);
} }
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{
return (GraphicsContext.GetCurrentContextDelegate)delegate
{
return new ContextHandle(Egl.GetCurrentContext());
};
}
} }
} }

View file

@ -32,6 +32,8 @@ namespace OpenTK.Platform.MacOS
GraphicsMode graphics_mode; GraphicsMode graphics_mode;
CarbonWindowInfo carbonWindow; CarbonWindowInfo carbonWindow;
IntPtr shareContextRef; IntPtr shareContextRef;
DisplayDevice device;
bool mIsFullscreen = false;
public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext)
{ {
@ -43,7 +45,19 @@ namespace OpenTK.Platform.MacOS
if (shareContext is AglContext) if (shareContext is AglContext)
shareContextRef = ((AglContext)shareContext).Handle.Handle; shareContextRef = ((AglContext)shareContext).Handle.Handle;
if (shareContext is GraphicsContext)
{
ContextHandle shareHandle = shareContext != null ?
(shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
shareContextRef = shareHandle.Handle;
}
if (shareContextRef == IntPtr.Zero)
{
Debug.Print("No context sharing will take place.");
}
CreateContext(mode, carbonWindow, shareContextRef, true); CreateContext(mode, carbonWindow, shareContextRef, true);
} }
@ -76,7 +90,7 @@ namespace OpenTK.Platform.MacOS
IntPtr shareContextRef, bool fullscreen) IntPtr shareContextRef, bool fullscreen)
{ {
List<int> aglAttributes = new List<int>(); List<int> aglAttributes = new List<int>();
Debug.Print("AGL pixel format attributes:"); Debug.Print("AGL pixel format attributes:");
Debug.Indent(); Debug.Indent();
@ -101,7 +115,7 @@ namespace OpenTK.Platform.MacOS
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_ALPHA_SIZE, mode.AccumulatorFormat.Alpha); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_ALPHA_SIZE, mode.AccumulatorFormat.Alpha);
} }
if (mode.Samples > 0) if (mode.Samples > 1)
{ {
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples);
@ -160,8 +174,10 @@ namespace OpenTK.Platform.MacOS
MyAGLReportError("aglChoosePixelFormat"); MyAGLReportError("aglChoosePixelFormat");
} }
Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef);
// create the context and share it with the share reference. // create the context and share it with the share reference.
Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef));
MyAGLReportError("aglCreateContext"); MyAGLReportError("aglCreateContext");
@ -243,6 +259,7 @@ namespace OpenTK.Platform.MacOS
void SetDrawable(CarbonWindowInfo carbonWindow) void SetDrawable(CarbonWindowInfo carbonWindow)
{ {
IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow);
//Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort);
Agl.aglSetDrawable(Handle.Handle, windowPort); Agl.aglSetDrawable(Handle.Handle, windowPort);
@ -261,18 +278,58 @@ namespace OpenTK.Platform.MacOS
} }
else else
windowPort = API.GetWindowPort(carbonWindow.WindowRef); windowPort = API.GetWindowPort(carbonWindow.WindowRef);
return windowPort; return windowPort;
} }
public override void Update(IWindowInfo window) public override void Update(IWindowInfo window)
{ {
CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window; CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window;
if (carbonWindow.GoFullScreenHack)
{
carbonWindow.GoFullScreenHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.SetFullscreen(this);
else
Debug.Print("Could not find window!");
return;
}
else if (carbonWindow.GoWindowedHack)
{
carbonWindow.GoWindowedHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.UnsetFullscreen(this);
else
Debug.Print("Could not find window!");
}
if (mIsFullscreen)
return;
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
SetBufferRect(carbonWindow); SetBufferRect(carbonWindow);
Agl.aglUpdateContext(Handle.Handle); Agl.aglUpdateContext(Handle.Handle);
} }
private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow)
{
WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.WindowRef];
if (r.IsAlive)
{
return (CarbonGLNative) r.Target;
}
else
return null;
}
void MyAGLReportError(string function) void MyAGLReportError(string function)
{ {
Agl.AglError err = Agl.GetError(); Agl.AglError err = Agl.GetError();
@ -285,24 +342,43 @@ namespace OpenTK.Platform.MacOS
bool firstFullScreen = false; bool firstFullScreen = false;
internal void SetFullScreen(CarbonWindowInfo info) internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height)
{ {
Agl.aglSetFullScreen(Handle.Handle, 0, 0, 0, 0); CarbonGLNative wind = GetCarbonWindow(info);
Debug.Print("Switching to full screen {0}x{1} on context {2}",
wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, Handle.Handle);
CG.DisplayCapture(GetQuartzDevice(info));
Agl.aglSetFullScreen(Handle.Handle, wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, 0, 0);
MakeCurrent(info);
width = wind.TargetDisplayDevice.Width;
height = wind.TargetDisplayDevice.Height;
// This is a weird hack to workaround a bug where the first time a context // This is a weird hack to workaround a bug where the first time a context
// is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen // is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen
// and redo it as fullscreen. // and redo it as fullscreen.
if (firstFullScreen == false) if (firstFullScreen == false)
{ {
firstFullScreen = true; firstFullScreen = true;
UnsetFullScreen(info); UnsetFullScreen(info);
SetFullScreen(info); SetFullScreen(info, out width, out height);
} }
mIsFullscreen = true;
} }
internal void UnsetFullScreen(CarbonWindowInfo windowInfo) internal void UnsetFullScreen(CarbonWindowInfo windowInfo)
{ {
Debug.Print("Unsetting AGL fullscreen.");
Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero);
SetDrawable(windowInfo); Agl.aglUpdateContext(Handle.Handle);
CG.DisplayRelease(GetQuartzDevice(windowInfo));
Debug.Print("Resetting drawable.");
SetDrawable(windowInfo);
mIsFullscreen = false;
} }

View file

@ -44,9 +44,6 @@ namespace OpenTK.Platform.MacOS
CarbonWindowInfo window; CarbonWindowInfo window;
CarbonInput mInputDriver; CarbonInput mInputDriver;
[Obsolete]
GraphicsContext context;
static MacOSKeyMap Keymap = new MacOSKeyMap(); static MacOSKeyMap Keymap = new MacOSKeyMap();
IntPtr uppHandler; IntPtr uppHandler;
@ -107,11 +104,11 @@ namespace OpenTK.Platform.MacOS
public CarbonGLNative(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device) public CarbonGLNative(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{ {
CreateNativeWindow(WindowClass.Document, CreateNativeWindow(WindowClass.Document,
WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.StandardDocument | WindowAttributes.StandardHandler |
WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, WindowAttributes.InWindowMenu | WindowAttributes.LiveResize,
new Rect((short)x, (short)y, (short)width, (short)height)); new Rect((short)x, (short)y, (short)width, (short)height));
mDisplayDevice = device; mDisplayDevice = device;
} }
@ -252,23 +249,32 @@ namespace OpenTK.Platform.MacOS
API.HideWindow(window.WindowRef); API.HideWindow(window.WindowRef);
} }
void SetFullscreen() internal void SetFullscreen(AglContext context)
{ {
windowedBounds = bounds; windowedBounds = bounds;
((AglContext)(context as IGraphicsContextInternal).Implementation).SetFullScreen(window); int width, height;
context.SetFullScreen(window, out width, out height);
Debug.Print("Prev Size: {0}, {1}", Width, Height); Debug.Print("Prev Size: {0}, {1}", Width, Height);
clientRectangle.Size = new Size(width, height);
Debug.Print("New Size: {0}, {1}", Width, Height);
// TODO: if we go full screen we need to make this use the device specified. // TODO: if we go full screen we need to make this use the device specified.
bounds = DisplayDevice.Default.Bounds; bounds = mDisplayDevice.Bounds;
Debug.Print("New Size: {0}, {1}", Width, Height);
windowState = WindowState.Fullscreen;
} }
void UnsetFullscreen() internal void UnsetFullscreen(AglContext context)
{ {
((AglContext)(context as IGraphicsContextInternal).Implementation).UnsetFullScreen(window); context.UnsetFullScreen(window);
Debug.Print("Telling Carbon to reset window state to " + windowState.ToString());
SetCarbonWindowState();
SetSize((short)windowedBounds.Width, (short)windowedBounds.Height); SetSize((short)windowedBounds.Width, (short)windowedBounds.Height);
} }
@ -371,16 +377,16 @@ namespace OpenTK.Platform.MacOS
case KeyboardEventKind.RawKeyDown: case KeyboardEventKind.RawKeyDown:
OnKeyPress(mKeyPressArgs); OnKeyPress(mKeyPressArgs);
InputDriver.Keyboard[0][Keymap[code]] = true; InputDriver.Keyboard[0][Keymap[code]] = true;
return OSStatus.EventNotHandled; return OSStatus.NoError;
case KeyboardEventKind.RawKeyUp: case KeyboardEventKind.RawKeyUp:
InputDriver.Keyboard[0][Keymap[code]] = false; InputDriver.Keyboard[0][Keymap[code]] = false;
return OSStatus.EventNotHandled; return OSStatus.NoError;
case KeyboardEventKind.RawKeyModifiersChanged: case KeyboardEventKind.RawKeyModifiersChanged:
ProcessModifierKey(inEvent); ProcessModifierKey(inEvent);
return OSStatus.EventNotHandled; return OSStatus.NoError;
default: default:
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
@ -679,26 +685,9 @@ namespace OpenTK.Platform.MacOS
#endregion #endregion
#region INativeGLWindow Members #region INativeWindow Members
public void CreateWindow(int width, int height, GraphicsMode mode, int major, int minor, GraphicsContextFlags flags, out IGraphicsContext context) public void ProcessEvents()
{
Rect r = new Rect(0, 0, (short)width, (short)height);
CreateNativeWindow(mWindowClass, mWindowAttrib, r);
Show();
this.context = new GraphicsContext(mode, window, major, minor, flags);
this.context.MakeCurrent(window);
context = this.context;
}
public void DestroyWindow()
{
Dispose();
}
public void ProcessEvents()
{ {
Application.ProcessEvents(); Application.ProcessEvents();
} }
@ -708,13 +697,18 @@ namespace OpenTK.Platform.MacOS
IntPtr handle = window.WindowRef; IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Console.WriteLine("Rect: {0}", r); Debug.Print("Rect: {0}", r);
return new Point(point.X - r.X, point.Y - r.Y); return new Point(point.X - r.X, point.Y - r.Y);
} }
public Point PointToScreen(Point point) public Point PointToScreen(Point point)
{ {
throw new NotImplementedException(); IntPtr handle = window.WindowRef;
Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion);
Debug.Print("Rect: {0}", r);
return new Point(point.X + r.X, point.Y + r.Y);
} }
public bool Exists public bool Exists
@ -740,21 +734,6 @@ namespace OpenTK.Platform.MacOS
} }
} }
public bool Fullscreen
{
get
{
return false;
}
set
{
throw new NotImplementedException();
}
}
#endregion
#region INativeWindow Members
public Icon Icon public Icon Icon
{ {
@ -969,7 +948,6 @@ namespace OpenTK.Platform.MacOS
if (Carbon.API.IsWindowCollapsed(window.WindowRef)) if (Carbon.API.IsWindowCollapsed(window.WindowRef))
return WindowState.Minimized; return WindowState.Minimized;
if (Carbon.API.IsWindowInStandardState(window.WindowRef)) if (Carbon.API.IsWindowInStandardState(window.WindowRef))
{ {
return WindowState.Maximized; return WindowState.Maximized;
@ -983,81 +961,94 @@ namespace OpenTK.Platform.MacOS
return; return;
Debug.Print("Switching window state from {0} to {1}", WindowState, value); Debug.Print("Switching window state from {0} to {1}", WindowState, value);
WindowState oldState = WindowState;
if (WindowState == WindowState.Fullscreen) windowState = value;
if (oldState == WindowState.Fullscreen)
{ {
UnsetFullscreen(); window.GoWindowedHack = true;
// when returning from full screen, wait until the context is updated
// to actually do the work.
return;
} }
if (WindowState == WindowState.Minimized)
if (oldState == WindowState.Minimized)
{ {
API.CollapseWindow(window.WindowRef, false); API.CollapseWindow(window.WindowRef, false);
} }
CarbonPoint idealSize;
switch (value) SetCarbonWindowState();
{
case WindowState.Fullscreen:
SetFullscreen();
break;
case WindowState.Maximized:
// hack because mac os has no concept of maximized. Instead windows are "zoomed"
// meaning they are maximized up to their reported ideal size. So we report a
// large ideal size.
idealSize = new CarbonPoint(9000, 9000);
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomOut, ref idealSize);
break;
case WindowState.Normal:
if (WindowState == WindowState.Maximized)
{
idealSize = new CarbonPoint();
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize);
}
break;
case WindowState.Minimized:
API.CollapseWindow(window.WindowRef, true);
break;
}
windowState = value;
OnWindowStateChanged();
OnResize();
} }
} }
public WindowBorder WindowBorder private void SetCarbonWindowState()
{ {
get CarbonPoint idealSize;
{
return windowBorder;
}
set
{
if (windowBorder != value)
{
windowBorder = value;
if (windowBorder == WindowBorder.Resizable) switch (windowState)
{ {
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom, case WindowState.Fullscreen:
WindowAttributes.NoAttributes); window.GoFullScreenHack = true;
}
else if (windowBorder == WindowBorder.Fixed)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes,
WindowAttributes.Resizable | WindowAttributes.FullZoom);
}
if (WindowBorderChanged != null) break;
WindowBorderChanged(this, EventArgs.Empty);
} case WindowState.Maximized:
} // hack because mac os has no concept of maximized. Instead windows are "zoomed"
// meaning they are maximized up to their reported ideal size. So we report a
// large ideal size.
idealSize = new CarbonPoint(9000, 9000);
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomOut, ref idealSize);
break;
case WindowState.Normal:
if (WindowState == WindowState.Maximized)
{
idealSize = new CarbonPoint();
API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize);
}
break;
case WindowState.Minimized:
API.CollapseWindow(window.WindowRef, true);
break;
}
OnWindowStateChanged();
OnResize();
}
public WindowBorder WindowBorder
{
get
{
return windowBorder;
}
set
{
if (windowBorder == value)
return;
windowBorder = value;
if (windowBorder == WindowBorder.Resizable)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom,
WindowAttributes.NoAttributes);
}
else if (windowBorder == WindowBorder.Fixed)
{
API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes,
WindowAttributes.Resizable | WindowAttributes.FullZoom);
}
if (WindowBorderChanged != null)
WindowBorderChanged(this, EventArgs.Empty);
}
} }
#region --- Event wrappers --- #region --- Event wrappers ---

View file

@ -41,6 +41,8 @@ namespace OpenTK.Platform.MacOS
bool ownHandle = false; bool ownHandle = false;
bool disposed = false; bool disposed = false;
bool isControl = false; bool isControl = false;
bool goFullScreenHack = false;
bool goWindowedHack = false;
#region Constructors #region Constructors
@ -69,6 +71,18 @@ namespace OpenTK.Platform.MacOS
get { return this.windowRef; } get { return this.windowRef; }
} }
internal bool GoFullScreenHack
{
get { return goFullScreenHack; }
set { goFullScreenHack = value; }
}
internal bool GoWindowedHack
{
get { return goWindowedHack; }
set { goWindowedHack = value; }
}
/// <summary> /// <summary>
/// Gets a value indicating whether this instance refers to a System.Windows.Forms.Control. /// Gets a value indicating whether this instance refers to a System.Windows.Forms.Control.
/// </summary> /// </summary>

View file

@ -844,6 +844,9 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
[DllImport("user32.dll", SetLastError=true)]
public static extern BOOL SetForegroundWindow(HWND hWnd);
#endregion #endregion
#region Display settings #region Display settings

View file

@ -68,6 +68,7 @@ namespace OpenTK.Platform.Windows
WindowState windowState = WindowState.Normal; WindowState windowState = WindowState.Normal;
bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible). bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible).
bool focused; bool focused;
bool mouse_outside_window = true;
Rectangle Rectangle
bounds = new Rectangle(), bounds = new Rectangle(),
@ -75,8 +76,7 @@ namespace OpenTK.Platform.Windows
previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode. previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode.
Icon icon; Icon icon;
const ClassStyle DefaultClassStyle = const ClassStyle DefaultClassStyle = ClassStyle.OwnDC;
ClassStyle.OwnDC | ClassStyle.VRedraw | ClassStyle.HRedraw | ClassStyle.Ime;
readonly IntPtr DefaultWindowProcedure = readonly IntPtr DefaultWindowProcedure =
Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc)); Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc));
@ -140,8 +140,6 @@ namespace OpenTK.Platform.Windows
keyboards.Add(keyboard); keyboards.Add(keyboard);
mice.Add(mouse); mice.Add(mouse);
EnableMouseLeaveNotifications();
} }
#endregion #endregion
@ -184,22 +182,6 @@ namespace OpenTK.Platform.Windows
StopTimer(handle); StopTimer(handle);
break; break;
case WindowMessage.NCCALCSIZE:
// Need to update the client rectangle, because it has the wrong size on Vista with Aero enabled.
//if (m.WParam == new IntPtr(1))
//{
// unsafe
// {
// NcCalculateSize* nc_calc_size = (NcCalculateSize*)m.LParam;
// //nc_calc_size->NewBounds = nc_calc_size->OldBounds;
// //nc_calc_size->OldBounds = nc_calc_size->NewBounds;
// //client_rectangle = rect.OldClientRectangle;
// }
// m.Result = new IntPtr((int)(NcCalcSizeOptions.ALIGNTOP | NcCalcSizeOptions.ALIGNLEFT/* | NcCalcSizeOptions.REDRAW*/));
//}
break;
case WindowMessage.ERASEBKGND: case WindowMessage.ERASEBKGND:
return new IntPtr(1); return new IntPtr(1);
@ -296,23 +278,27 @@ namespace OpenTK.Platform.Windows
(short)((uint)lParam.ToInt32() & 0x0000FFFF), (short)((uint)lParam.ToInt32() & 0x0000FFFF),
(short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16)); (short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16));
mouse.Position = point; mouse.Position = point;
if (mouse_outside_window)
{ {
if (!ClientRectangle.Contains(point)) // Once we receive a mouse move event, it means that the mouse has
{ // re-entered the window.
Functions.ReleaseCapture(); mouse_outside_window = false;
if (MouseLeave != null) EnableMouseTracking();
MouseLeave(this, EventArgs.Empty);
} if (MouseEnter != null)
else if (Functions.GetCapture() != window.WindowHandle) MouseEnter(this, EventArgs.Empty);
{
Functions.SetFocus(window.WindowHandle);
Functions.SetCapture(window.WindowHandle);
if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty);
}
} }
break; break;
case WindowMessage.MOUSELEAVE:
mouse_outside_window = true;
// Mouse tracking is disabled automatically by the OS
if (MouseLeave != null)
MouseLeave(this, EventArgs.Empty);
break;
case WindowMessage.MOUSEWHEEL: case WindowMessage.MOUSEWHEEL:
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese // This is due to inconsistent behavior of the WParam value on 64bit arch, whese
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000 // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
@ -454,6 +440,8 @@ namespace OpenTK.Platform.Windows
Win32Rectangle rect; Win32Rectangle rect;
Functions.GetClientRect(handle, out rect); Functions.GetClientRect(handle, out rect);
client_rectangle = rect.ToRectangle(); client_rectangle = rect.ToRectangle();
Functions.SetForegroundWindow(handle);
} }
break; break;
@ -478,7 +466,6 @@ namespace OpenTK.Platform.Windows
exists = false; exists = false;
Functions.UnregisterClass(ClassName, Instance); Functions.UnregisterClass(ClassName, Instance);
//Marshal.FreeHGlobal(ClassName);
window.Dispose(); window.Dispose();
child_window.Dispose(); child_window.Dispose();
@ -493,6 +480,18 @@ namespace OpenTK.Platform.Windows
return Functions.DefWindowProc(handle, message, wParam, lParam); return Functions.DefWindowProc(handle, message, wParam, lParam);
} }
private void EnableMouseTracking()
{
TrackMouseEventStructure me = new TrackMouseEventStructure();
me.Size = TrackMouseEventStructure.SizeInBytes;
me.TrackWindowHandle = child_window.WindowHandle;
me.Flags = TrackMouseEventFlags.LEAVE;
if (!Functions.TrackMouseEvent(ref me))
Debug.Print("[Warning] Failed to enable mouse tracking, error: {0}.",
Marshal.GetLastWin32Error());
}
private void StartTimer(IntPtr handle) private void StartTimer(IntPtr handle)
{ {
if (timer_handle == UIntPtr.Zero) if (timer_handle == UIntPtr.Zero)
@ -610,18 +609,6 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
void EnableMouseLeaveNotifications()
{
TrackMouseEventStructure tme = new TrackMouseEventStructure();
tme.Size = TrackMouseEventStructure.SizeInBytes;
tme.Flags |= TrackMouseEventFlags.LEAVE;
tme.TrackWindowHandle = child_window.WindowHandle;
tme.HoverTime = -1; // HOVER_DEFAULT
if (!Functions.TrackMouseEvent(ref tme))
Debug.Print("[Error] Failed to enable mouse event tracking. Error: {0}",
Marshal.GetLastWin32Error());
}
#endregion #endregion
#region INativeWindow Members #region INativeWindow Members
@ -682,7 +669,7 @@ namespace OpenTK.Platform.Windows
} }
set set
{ {
Size = value.Size; ClientSize = value.Size;
} }
} }
@ -905,6 +892,8 @@ namespace OpenTK.Platform.Windows
WindowBorder = WindowBorder.Hidden; WindowBorder = WindowBorder.Hidden;
command = ShowWindowCommand.MAXIMIZE; command = ShowWindowCommand.MAXIMIZE;
Functions.SetForegroundWindow(window.WindowHandle);
break; break;
} }
@ -953,6 +942,11 @@ namespace OpenTK.Platform.Windows
if (windowBorder == value) if (windowBorder == value)
return; return;
// We wish to avoid making an invisible window visible just to change the border.
// However, it's a good idea to make a visible window invisible temporarily, to
// avoid garbage caused by the border change.
bool was_visible = Visible;
// To ensure maximized/minimized windows work correctly, reset state to normal, // To ensure maximized/minimized windows work correctly, reset state to normal,
// change the border, then go back to maximized/minimized. // change the border, then go back to maximized/minimized.
WindowState state = WindowState; WindowState state = WindowState;
@ -982,7 +976,8 @@ namespace OpenTK.Platform.Windows
Functions.AdjustWindowRectEx(ref rect, style, false, ParentStyleEx); Functions.AdjustWindowRectEx(ref rect, style, false, ParentStyleEx);
// This avoids leaving garbage on the background window. // This avoids leaving garbage on the background window.
Visible = false; if (was_visible)
Visible = false;
Functions.SetWindowLong(window.WindowHandle, GetWindowLongOffsets.STYLE, (IntPtr)(int)style); Functions.SetWindowLong(window.WindowHandle, GetWindowLongOffsets.STYLE, (IntPtr)(int)style);
Functions.SetWindowPos(window.WindowHandle, IntPtr.Zero, 0, 0, rect.Width, rect.Height, Functions.SetWindowPos(window.WindowHandle, IntPtr.Zero, 0, 0, rect.Width, rect.Height,
@ -992,7 +987,7 @@ namespace OpenTK.Platform.Windows
// Force window to redraw update its borders, but only if it's // Force window to redraw update its borders, but only if it's
// already visible (invisible windows will change borders when // already visible (invisible windows will change borders when
// they become visible, so no need to make them visiable prematurely). // they become visible, so no need to make them visiable prematurely).
if (Visible) if (was_visible)
Visible = true; Visible = true;
WindowState = state; WindowState = state;

View file

@ -252,6 +252,7 @@ namespace OpenTK.Platform.X11
#endregion #endregion
/// \internal
/// <summary> /// <summary>
/// Provides access to GLX functions. /// Provides access to GLX functions.
/// </summary> /// </summary>

View file

@ -14,6 +14,7 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
/// \internal
/// <summary> /// <summary>
/// Provides methods to create and control an opengl context on the X11 platform. /// 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. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -370,7 +371,7 @@ namespace OpenTK.Platform.X11
{ {
IntPtr display = Display; IntPtr display = Display;
if (IsCurrent) if (IsCurrent)
MakeCurrent(null); Glx.MakeCurrent(display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(display, Handle); Glx.DestroyContext(display, Handle);
} }

View file

@ -38,6 +38,7 @@ using System.Drawing;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
/// \internal
/// <summary> /// <summary>
/// Drives GameWindow on X11. /// Drives GameWindow on X11.
/// This class supports OpenTK, and is not intended for use by OpenTK programs. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
@ -148,7 +149,8 @@ namespace OpenTK.Platform.X11
EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask | EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask |
EventMask.PointerMotionMask | EventMask.FocusChangeMask | EventMask.PointerMotionMask | EventMask.FocusChangeMask |
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
EventMask.EnterWindowMask | EventMask.LeaveWindowMask; EventMask.EnterWindowMask | EventMask.LeaveWindowMask |
EventMask.PropertyChangeMask;
attributes.event_mask = (IntPtr)window.EventMask; attributes.event_mask = (IntPtr)window.EventMask;
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask | uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
@ -237,25 +239,25 @@ namespace OpenTK.Platform.X11
Debug.WriteLine("Registering atoms."); Debug.WriteLine("Registering atoms.");
_atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true); _atom_wm_destroy = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
_atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false); _atom_net_wm_state = Functions.XInternAtom(window.Display, "_NET_WM_STATE", false);
_atom_net_wm_state_minimized = Functions.XInternAtom(window.Display, "_NET_WM_STATE_MINIMIZED", false); _atom_net_wm_state_minimized = Functions.XInternAtom(window.Display, "_NET_WM_STATE_MINIMIZED", false);
_atom_net_wm_state_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false); _atom_net_wm_state_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false);
_atom_net_wm_state_maximized_horizontal = _atom_net_wm_state_maximized_horizontal =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false); Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_HORZ", false);
_atom_net_wm_state_maximized_vertical = _atom_net_wm_state_maximized_vertical =
Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false); Functions.XInternAtom(window.Display, "_NET_WM_STATE_MAXIMIZED_VERT", false);
_atom_net_wm_allowed_actions = _atom_net_wm_allowed_actions =
Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false); Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false);
_atom_net_wm_action_resize = _atom_net_wm_action_resize =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_RESIZE", false);
_atom_net_wm_action_maximize_horizontally = _atom_net_wm_action_maximize_horizontally =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_HORZ", false);
_atom_net_wm_action_maximize_vertically = _atom_net_wm_action_maximize_vertically =
Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false); Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false);
_atom_net_wm_icon = _atom_net_wm_icon =
Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false); Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false);
// string[] atom_names = new string[] // string[] atom_names = new string[]
// { // {
@ -624,9 +626,6 @@ namespace OpenTK.Platform.X11
{ {
isExiting = true; isExiting = true;
if (Unload != null)
Unload(this, EventArgs.Empty);
Debug.WriteLine("Destroying window."); Debug.WriteLine("Destroying window.");
Functions.XDestroyWindow(window.Display, window.WindowHandle); Functions.XDestroyWindow(window.Display, window.WindowHandle);
break; break;
@ -740,6 +739,12 @@ namespace OpenTK.Platform.X11
Functions.XRefreshKeyboardMapping(ref e.MappingEvent); Functions.XRefreshKeyboardMapping(ref e.MappingEvent);
} }
break; break;
case XEventName.PropertyNotify:
if (e.PropertyEvent.atom == _atom_net_wm_state)
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
break;
default: default:
//Debug.WriteLine(String.Format("{0} event was not handled", e.type)); //Debug.WriteLine(String.Format("{0} event was not handled", e.type));
@ -980,7 +985,8 @@ namespace OpenTK.Platform.X11
{ {
Functions.XGetWindowProperty(window.Display, window.WindowHandle, Functions.XGetWindowProperty(window.Display, window.WindowHandle,
_atom_net_wm_state, IntPtr.Zero, new IntPtr(256), false, _atom_net_wm_state, IntPtr.Zero, new IntPtr(256), false,
IntPtr.Zero, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop); new IntPtr(4) /*XA_ATOM*/, out actual_atom, out actual_format,
out nitems, out bytes_after, ref prop);
} }
if ((long)nitems > 0 && prop != IntPtr.Zero) if ((long)nitems > 0 && prop != IntPtr.Zero)
@ -1029,6 +1035,7 @@ namespace OpenTK.Platform.X11
using (new XLock(window.Display)) using (new XLock(window.Display))
{ {
// Reset the current window state
if (current_state == OpenTK.WindowState.Minimized) if (current_state == OpenTK.WindowState.Minimized)
Functions.XMapWindow(window.Display, window.WindowHandle); Functions.XMapWindow(window.Display, window.WindowHandle);
else if (current_state == OpenTK.WindowState.Fullscreen) else if (current_state == OpenTK.WindowState.Fullscreen)
@ -1087,9 +1094,6 @@ namespace OpenTK.Platform.X11
if (temporary_resizable) if (temporary_resizable)
WindowBorder = previous_state; WindowBorder = previous_state;
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
} }
} }
@ -1209,15 +1213,6 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region public bool IsExiting
public bool IsExiting
{
get { return isExiting; }
}
#endregion
#region public bool IsIdle #region public bool IsIdle
public bool IsIdle public bool IsIdle
@ -1227,65 +1222,6 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region public bool Fullscreen
public bool Fullscreen
{
get
{
return false;
//return fullscreen;
}
set
{
// if (value && !fullscreen)
// {
// Debug.Print("Going fullscreen");
// Debug.Indent();
// DisableWindowDecorations();
// pre_fullscreen_height = this.Height;
// pre_fullscreen_width = this.Width;
// //Functions.XRaiseWindow(this.window.Display, this.Handle);
// Functions.XMoveResizeWindow(this.window.Display, this.Handle, 0, 0,
// DisplayDevice.Default.Width, DisplayDevice.Default.Height);
// Debug.Unindent();
// fullscreen = true;
// }
// else if (!value && fullscreen)
// {
// Debug.Print("Going windowed");
// Debug.Indent();
// Functions.XMoveResizeWindow(this.window.Display, this.Handle, 0, 0,
// pre_fullscreen_width, pre_fullscreen_height);
// pre_fullscreen_height = pre_fullscreen_width = 0;
// EnableWindowDecorations();
// Debug.Unindent();
// fullscreen = false;
// }
/*
Debug.Print(value ? "Going fullscreen" : "Going windowed");
IntPtr state_atom = Functions.XInternAtom(this.window.Display, "_NET_WM_STATE", false);
IntPtr fullscreen_atom = Functions.XInternAtom(this.window.Display, "_NET_WM_STATE_FULLSCREEN", false);
XEvent xev = new XEvent();
xev.ClientMessageEvent.type = XEventName.ClientMessage;
xev.ClientMessageEvent.serial = IntPtr.Zero;
xev.ClientMessageEvent.send_event = true;
xev.ClientMessageEvent.window = this.Handle;
xev.ClientMessageEvent.message_type = state_atom;
xev.ClientMessageEvent.format = 32;
xev.ClientMessageEvent.ptr1 = (IntPtr)(value ? NetWindowManagerState.Add : NetWindowManagerState.Remove);
xev.ClientMessageEvent.ptr2 = (IntPtr)(value ? 1 : 0);
xev.ClientMessageEvent.ptr3 = IntPtr.Zero;
Functions.XSendEvent(this.window.Display, API.RootWindow, false,
(IntPtr)(EventMask.SubstructureRedirectMask | EventMask.SubstructureNotifyMask), ref xev);
fullscreen = !fullscreen;
*/
}
}
#endregion
#region public IntPtr Handle #region public IntPtr Handle
/// <summary> /// <summary>
@ -1455,10 +1391,7 @@ namespace OpenTK.Platform.X11
while (Exists) while (Exists)
ProcessEvents(); ProcessEvents();
} }
if (GraphicsContext.CurrentContext != null)
GraphicsContext.CurrentContext.MakeCurrent(null);
window.Dispose(); window.Dispose();
window = null; window = null;
} }

View file

@ -15,6 +15,7 @@ using System.Drawing;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
/// \internal
/// <summary> /// <summary>
/// Drives the InputDriver on X11. /// Drives the InputDriver on X11.
/// This class supports OpenTK, and is not intended for users of OpenTK. /// This class supports OpenTK, and is not intended for users of OpenTK.

View file

@ -31,6 +31,7 @@ using System.Text;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
/// \internal
/// <summary>Describes an X11 window.</summary> /// <summary>Describes an X11 window.</summary>
sealed class X11WindowInfo : IWindowInfo sealed class X11WindowInfo : IWindowInfo
{ {