diff --git a/Source/Bind/Specifications/GL2/enumext.spec b/Source/Bind/Specifications/GL2/enumext.spec index 0e7ca858e..35c550185 100644 --- a/Source/Bind/Specifications/GL2/enumext.spec +++ b/Source/Bind/Specifications/GL2/enumext.spec @@ -7582,6 +7582,10 @@ ActiveUniformBlockParameter enum: 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_FRAGMENT_SHADER + +# Used in primitive restart +EnableCap enum: + PRIMITIVE_RESTART = 0x8F9D # 3.1 (different from NV_primitive_restart) # Non-core diff --git a/Source/Examples/OpenGL/1.1/VertexArrays.cs b/Source/Examples/OpenGL/1.1/VertexArrays.cs index 15783af95..edcd6e96f 100644 --- a/Source/Examples/OpenGL/1.1/VertexArrays.cs +++ b/Source/Examples/OpenGL/1.1/VertexArrays.cs @@ -116,8 +116,7 @@ protected override void OnUpdateFrame(FrameEventArgs e) return; } - // Alt+Enter toggles fullscreen mode. - if ((Keyboard[Key.AltLeft] || Keyboard[Key.AltRight]) && Keyboard[Key.Enter]) + if (Keyboard[Key.F11]) if (WindowState != WindowState.Fullscreen) WindowState = WindowState.Fullscreen; else diff --git a/Source/Examples/OpenGL/1.1/VertexLighting.cs b/Source/Examples/OpenGL/1.1/VertexLighting.cs index 47709c9b3..47a20f19f 100644 --- a/Source/Examples/OpenGL/1.1/VertexLighting.cs +++ b/Source/Examples/OpenGL/1.1/VertexLighting.cs @@ -108,8 +108,7 @@ protected override void OnUpdateFrame(FrameEventArgs e) return; } - if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) && - Keyboard[OpenTK.Input.Key.Enter]) + if (Keyboard[OpenTK.Input.Key.F11]) if (WindowState != WindowState.Fullscreen) WindowState = WindowState.Fullscreen; else diff --git a/Source/Examples/OpenGL/GLSL/SimpleGLSL.cs b/Source/Examples/OpenGL/GLSL/SimpleGLSL.cs index 596630e56..d1b3d02d9 100644 --- a/Source/Examples/OpenGL/GLSL/SimpleGLSL.cs +++ b/Source/Examples/OpenGL/GLSL/SimpleGLSL.cs @@ -221,8 +221,7 @@ protected override void OnUpdateFrame(FrameEventArgs e) if (Keyboard[OpenTK.Input.Key.Escape]) this.Exit(); - if ((Keyboard[OpenTK.Input.Key.AltLeft] || Keyboard[OpenTK.Input.Key.AltRight]) && - Keyboard[OpenTK.Input.Key.Enter]) + if (Keyboard[OpenTK.Input.Key.F11]) if (WindowState != WindowState.Fullscreen) WindowState = WindowState.Fullscreen; else diff --git a/Source/Examples/OpenGLES/1.1/SimpleWindow.cs b/Source/Examples/OpenGLES/1.1/SimpleWindow.cs index f54faae82..843604f71 100644 --- a/Source/Examples/OpenGLES/1.1/SimpleWindow.cs +++ b/Source/Examples/OpenGLES/1.1/SimpleWindow.cs @@ -66,14 +66,14 @@ protected override void OnLoad(EventArgs e) { base.OnLoad(e); - Color color = Color.MidnightBlue; + Color4 color = Color4.MidnightBlue; GL.ClearColor(color.R, color.G, color.B, color.A); GL.Enable((All)EnableCap.DepthTest); } #endregion - #region OnResize + #region OnResize /// /// Called when the user resizes the window. @@ -95,7 +95,7 @@ protected override void OnResize(EventArgs e) #endregion - #region OnUpdateFrame + #region OnUpdateFrame /// /// Prepares the next frame for rendering. @@ -115,7 +115,7 @@ protected override void OnUpdateFrame(FrameEventArgs e) #endregion - #region OnRenderFrame + #region OnRenderFrame /// /// Place your rendering code here. @@ -138,7 +138,7 @@ protected override void OnRenderFrame(FrameEventArgs e) #endregion - #region private void DrawCube() + #region private void DrawCube() private void DrawCube() { @@ -188,7 +188,7 @@ private void DrawCube() #endregion - #region public static void Main() + #region public static void Main() /// /// Entry point of this example. diff --git a/Source/Examples/OpenGLES/2.0/SimpleWindow20.cs b/Source/Examples/OpenGLES/2.0/SimpleWindow20.cs index e91b888b2..16aae4174 100644 --- a/Source/Examples/OpenGLES/2.0/SimpleWindow20.cs +++ b/Source/Examples/OpenGLES/2.0/SimpleWindow20.cs @@ -41,7 +41,7 @@ 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 { #region Constructor @@ -58,7 +58,7 @@ protected override void OnLoad(EventArgs e) { base.OnLoad(e); - Color color = Color.MidnightBlue; + Color4 color = Color4.MidnightBlue; GL.ClearColor(color.R, color.G, color.B, color.A); GL.Enable(EnableCap.DepthTest); } @@ -119,48 +119,6 @@ protected override void OnRenderFrame(FrameEventArgs e) 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 diff --git a/Source/Examples/OpenTK/GameWindow/FullscreenAntialias.cs b/Source/Examples/OpenTK/GameWindow/FullscreenAntialias.cs index 01cbb17d5..0f640ffba 100644 --- a/Source/Examples/OpenTK/GameWindow/FullscreenAntialias.cs +++ b/Source/Examples/OpenTK/GameWindow/FullscreenAntialias.cs @@ -43,17 +43,7 @@ public class FullscreenAntialias : GameWindow public FullscreenAntialias() : base(800, 600, new GraphicsMode(32, 0, 0, 4)) { - Keyboard.KeyDown += delegate(object sender, KeyboardKeyEventArgs e) - { - 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; - }; + Keyboard.KeyDown += Keyboard_KeyDown; } #region Keyboard_KeyDown @@ -63,12 +53,12 @@ public FullscreenAntialias() /// /// The KeyboardDevice which generated this event. /// The key that was pressed. - 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(); - if ((sender[Key.AltLeft] || sender[Key.AltRight]) && (sender[Key.Enter] || sender[Key.KeypadEnter])) + if (e.Key == Key.F11) if (this.WindowState == WindowState.Fullscreen) this.WindowState = WindowState.Normal; else diff --git a/Source/Examples/OpenTK/GameWindow/SimpleWindow.cs b/Source/Examples/OpenTK/GameWindow/SimpleWindow.cs index a1c425d66..577ef8fff 100644 --- a/Source/Examples/OpenTK/GameWindow/SimpleWindow.cs +++ b/Source/Examples/OpenTK/GameWindow/SimpleWindow.cs @@ -39,7 +39,7 @@ void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e) 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 (e.Key == Key.F11) if (this.WindowState == WindowState.Fullscreen) this.WindowState = WindowState.Normal; else diff --git a/Source/Examples/OpenTK/Test/Multithreading.cs b/Source/Examples/OpenTK/Test/Multithreading.cs index cf0568310..a411a497b 100644 --- a/Source/Examples/OpenTK/Test/Multithreading.cs +++ b/Source/Examples/OpenTK/Test/Multithreading.cs @@ -64,7 +64,7 @@ static void RunGame() Utilities.SetWindowTitle(game); 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) game.WindowState = OpenTK.WindowState.Normal; diff --git a/Source/Examples/Utilities.cs b/Source/Examples/Utilities.cs index 6e50fdcf8..93eb87abc 100644 --- a/Source/Examples/Utilities.cs +++ b/Source/Examples/Utilities.cs @@ -29,6 +29,10 @@ public static int ColorToRgba32(Color c) return (int)((c.A << 24) | (c.B << 16) | (c.G << 8) | c.R); } + /// + /// Sets the window title to the name of the sample. + /// + /// public static void SetWindowTitle(GameWindow window) { ExampleAttribute info = GetExampleAttribute(window.GetType()); @@ -36,6 +40,10 @@ public static void SetWindowTitle(GameWindow window) window.Icon = OpenTK.Examples.Properties.Resources.App; } + /// + /// Sets the window title to the name of the sample. + /// + /// public static void SetWindowTitle(System.Windows.Forms.Form window) { ExampleAttribute info = GetExampleAttribute(window.GetType()); diff --git a/Source/OpenTK/Audio/AudioContext.cs b/Source/OpenTK/Audio/AudioContext.cs index 9f92160eb..9495d081d 100644 --- a/Source/OpenTK/Audio/AudioContext.cs +++ b/Source/OpenTK/Audio/AudioContext.cs @@ -59,8 +59,7 @@ public sealed class AudioContext : IDisposable #region static AudioContext() - /// - /// + /// \internal /// /// Runs before the actual class constructor, to load available devices. /// @@ -224,7 +223,7 @@ public enum MaxAuxiliarySends:int Four = 4, } - /// + /// \internal /// Creates the audio context using the specified device. /// The device descriptor obtained through AudioContext.AvailableDevices, or null for the default device. /// Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default. @@ -358,7 +357,7 @@ void CreateContext(string device, int freq, int refresh, bool sync, bool enableE #region static void MakeCurrent(AudioContext context) - /// + /// \internal /// Makes the specified AudioContext current in the calling thread. /// The OpenTK.Audio.AudioContext to make current, or null. /// diff --git a/Source/OpenTK/Audio/OpenAL/AL/AL.cs b/Source/OpenTK/Audio/OpenAL/AL/AL.cs index 5191eb578..295756d0d 100644 --- a/Source/OpenTK/Audio/OpenAL/AL/AL.cs +++ b/Source/OpenTK/Audio/OpenAL/AL/AL.cs @@ -294,9 +294,9 @@ public static void Listener(ALListenerfv param, ref Vector3 at, ref Vector3 up) /// This function retrieves a set of three floating-point values from a property of the listener. /// The name of the attribute to be retrieved: ALListener3f.Position, ALListener3f.Velocity - /// Pointers to the three floating-point being retrieved. - /// Pointers to the three floating-point being retrieved. - /// Pointers to the three floating-point being retrieved. + /// The first floating-point value being retrieved. + /// The second floating-point value being retrieved. + /// The third floating-point value being retrieved. [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); // AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index c6e2cd783..ef204b1c1 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -285,6 +285,27 @@ public void MakeCurrent() Context.MakeCurrent(WindowInfo); } + #endregion + + #region OnClose + + /// + /// Called when the NativeWindow is about to close. + /// + /// + /// The for this event. + /// Set e.Cancel to true in order to stop the GameWindow from closing. + protected override void OnClosing (System.ComponentModel.CancelEventArgs e) + { + base.OnClosing(e); + if (!e.Cancel) + { + isExiting = true; + OnUnloadInternal(EventArgs.Empty); + } + } + + #endregion #region OnLoad @@ -381,20 +402,25 @@ public void Run(double updates_per_second, double frames_per_second) Debug.Print("Entering main loop."); update_watch.Start(); render_watch.Start(); - while (!IsExiting && Exists) + while (true) { ProcessEvents(); - DispatchUpdateAndRenderFrame(this, EventArgs.Empty); + if (Exists && !IsExiting) + DispatchUpdateAndRenderFrame(this, EventArgs.Empty); + else + return; } } finally { - OnUnloadInternal(EventArgs.Empty); + Move -= DispatchUpdateAndRenderFrame; + Resize -= DispatchUpdateAndRenderFrame; if (Exists) { - Dispose(); - //while (this.Exists) ProcessEvents(); // TODO: Should similar behaviour be retained, possibly on native window level? + // TODO: Should similar behaviour be retained, possibly on native window level? + //while (this.Exists) + // ProcessEvents(false); } } } @@ -464,16 +490,6 @@ void RaiseRenderFrame(Stopwatch render_watch, ref double next_render, FrameEvent return; 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) { // Schedule next render event. The 1 second cap ensures @@ -487,6 +503,22 @@ void RaiseRenderFrame(Stopwatch render_watch, ref double next_render, FrameEvent 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; OnRenderFrameInternal(render_args); render_time = render_watch.Elapsed.TotalSeconds; @@ -864,11 +896,33 @@ public VSyncMode VSync #endregion - #endregion + #region WindowState - #region Events + /// + /// Gets or states the state of the NativeWindow. + /// + public override WindowState WindowState + { + get + { + return base.WindowState; + } + set + { + base.WindowState = value; + Debug.Print("Updating Context after setting WindowState to {0}", value); + + if (Context != null) + Context.Update(WindowInfo); + } + } + #endregion - /// + #endregion + + #region Events + + /// /// Occurs before the window is displayed for the first time. /// public event EventHandler Load; @@ -1018,7 +1072,8 @@ public enum VSyncMode /// On, /// - /// 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 . /// Adaptive, } diff --git a/Source/OpenTK/Graphics/Color4.cs b/Source/OpenTK/Graphics/Color4.cs index 0a23c57c3..56bc35331 100644 --- a/Source/OpenTK/Graphics/Color4.cs +++ b/Source/OpenTK/Graphics/Color4.cs @@ -115,10 +115,10 @@ public Color4(System.Drawing.Color color) public int ToArgb() { uint value = - (uint)(A / Byte.MaxValue) << 24 | - (uint)(R / Byte.MaxValue) << 16 | - (uint)(G / Byte.MaxValue) << 8 | - (uint)(B / Byte.MaxValue); + (uint)(A * Byte.MaxValue) << 24 | + (uint)(R * Byte.MaxValue) << 16 | + (uint)(G * Byte.MaxValue) << 8 | + (uint)(B * Byte.MaxValue); return unchecked((int)value); } diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index f464fb893..c231b73ae 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -40,11 +40,6 @@ public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal #region --- Constructors --- - static GraphicsContext() - { - GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext(); - } - // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). GraphicsContext(ContextHandle handle) { @@ -105,14 +100,25 @@ public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int min // Todo: Add a DummyFactory implementing IPlatformFactory. if (designMode) + { implementation = new Platform.Dummy.DummyGLContext(); + } else + { + IPlatformFactory factory = null; switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) { - case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; - case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; + case false: factory = Factory.Default; 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)); } finally @@ -252,6 +258,10 @@ public static void Assert() /// /// Gets the GraphicsContext that is current in the calling thread. /// + /// + /// 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. + /// public static IGraphicsContext CurrentContext { get diff --git a/Source/OpenTK/Graphics/OpenGL/GLEnums.cs b/Source/OpenTK/Graphics/OpenGL/GLEnums.cs index 29ea98f3a..66658e4aa 100644 --- a/Source/OpenTK/Graphics/OpenGL/GLEnums.cs +++ b/Source/OpenTK/Graphics/OpenGL/GLEnums.cs @@ -5756,6 +5756,7 @@ public enum EnableCap : int RasterizerDiscard = ((int)0x8C89), FramebufferSrgb = ((int)0x8DB9), SampleMask = ((int)0x8E51), + PrimitiveRestart = ((int)0x8F9D), } public enum ErrorCode : int diff --git a/Source/OpenTK/Graphics/OpenGL/GLHelper.cs b/Source/OpenTK/Graphics/OpenGL/GLHelper.cs index 4b76cc4b4..02e73a0cd 100644 --- a/Source/OpenTK/Graphics/OpenGL/GLHelper.cs +++ b/Source/OpenTK/Graphics/OpenGL/GLHelper.cs @@ -729,7 +729,7 @@ public static void EdgeFlagPointer(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) diff --git a/Source/OpenTK/Input/MouseDevice.cs b/Source/OpenTK/Input/MouseDevice.cs index fc7a26045..d0b92b228 100644 --- a/Source/OpenTK/Input/MouseDevice.cs +++ b/Source/OpenTK/Input/MouseDevice.cs @@ -136,7 +136,7 @@ public IntPtr DeviceID /// public int Wheel { - get { return (int)(wheel + 0.5f); } + get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); } internal set { WheelPrecise = value; } } @@ -306,7 +306,7 @@ public int WheelDelta { 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; return result; } @@ -614,13 +614,13 @@ public MouseWheelEventArgs(MouseWheelEventArgs args) /// Gets the value of the wheel in integer units. /// To support high-precision mice, it is recommended to use instead. /// - public int Value { get { return (int)(value + 0.5f); } } + public int Value { get { return (int)Math.Round(value, MidpointRounding.AwayFromZero); } } /// /// Gets the change in value of the wheel for this event in integer units. /// To support high-precision mice, it is recommended to use instead. /// - public int Delta { get { return (int)(delta + 0.5f); } } + public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } } /// /// Gets the precise value of the wheel in floating-point units. diff --git a/Source/OpenTK/Math/Vector2d.cs b/Source/OpenTK/Math/Vector2d.cs index 70bddeab4..e0aae38e0 100644 --- a/Source/OpenTK/Math/Vector2d.cs +++ b/Source/OpenTK/Math/Vector2d.cs @@ -167,7 +167,7 @@ public double Length { get { - return (float)System.Math.Sqrt(X * X + Y * Y); + return System.Math.Sqrt(X * X + Y * Y); } } @@ -230,7 +230,7 @@ public Vector2d PerpendicularLeft /// public void Normalize() { - double scale = 1.0f / Length; + double scale = 1.0 / Length; X *= scale; Y *= scale; } @@ -627,7 +627,7 @@ public static void Clamp(ref Vector2d vec, ref Vector2d min, ref Vector2d max, o /// The normalized vector public static Vector2d Normalize(Vector2d vec) { - double scale = 1.0f / vec.Length; + double scale = 1.0 / vec.Length; vec.X *= scale; vec.Y *= scale; return vec; @@ -640,7 +640,7 @@ public static Vector2d Normalize(Vector2d vec) /// The normalized vector 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.Y = vec.Y * scale; } @@ -882,7 +882,7 @@ public static void Transform(ref Vector2d vec, ref Quaterniond quat, out Vector2 /// The result of the operation. public static Vector2d operator /(Vector2d vec, double f) { - double mult = 1.0f / f; + double mult = 1.0 / f; vec.X *= mult; vec.Y *= mult; return vec; diff --git a/Source/OpenTK/Math/Vector3d.cs b/Source/OpenTK/Math/Vector3d.cs index d7e4d685e..bf2d60b9e 100644 --- a/Source/OpenTK/Math/Vector3d.cs +++ b/Source/OpenTK/Math/Vector3d.cs @@ -199,7 +199,7 @@ public double Length { 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 @@ public double LengthFast { 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 @@ public double LengthSquared /// public void Normalize() { - double scale = 1.0f / this.Length; + double scale = 1.0 / this.Length; X *= scale; Y *= scale; Z *= scale; @@ -433,7 +433,7 @@ public static void Mult(ref Vector3d a, double f, out Vector3d result) [Obsolete("Use static Divide() method instead.")] public static Vector3d Div(Vector3d a, double f) { - double mult = 1.0f / f; + double mult = 1.0 / f; a.X *= mult; a.Y *= mult; a.Z *= mult; @@ -449,7 +449,7 @@ public static Vector3d Div(Vector3d a, double f) [Obsolete("Use static Divide() method instead.")] 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.Y = a.Y * mult; result.Z = a.Z * mult; @@ -747,7 +747,7 @@ public static void Clamp(ref Vector3d vec, ref Vector3d min, ref Vector3d max, o /// The normalized vector public static Vector3d Normalize(Vector3d vec) { - double scale = 1.0f / vec.Length; + double scale = 1.0 / vec.Length; vec.X *= scale; vec.Y *= scale; vec.Z *= scale; @@ -761,7 +761,7 @@ public static Vector3d Normalize(Vector3d vec) /// The normalized vector 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.Y = vec.Y * scale; result.Z = vec.Z * scale; @@ -1085,7 +1085,7 @@ public static Vector3d Transform(Vector3d vec, Matrix4d mat) /// The transformed vector 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); result = v4.Xyz; } diff --git a/Source/OpenTK/Math/Vector4d.cs b/Source/OpenTK/Math/Vector4d.cs index abe6d1642..f6e046410 100644 --- a/Source/OpenTK/Math/Vector4d.cs +++ b/Source/OpenTK/Math/Vector4d.cs @@ -260,7 +260,7 @@ public double Length { 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 @@ public double LengthFast { 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 @@ public double LengthSquared /// public void Normalize() { - double scale = 1.0f / this.Length; + double scale = 1.0 / this.Length; X *= scale; Y *= scale; Z *= scale; @@ -469,7 +469,7 @@ public static void Mult(ref Vector4d a, double f, out Vector4d result) [Obsolete("Use static Divide() method instead.")] public static Vector4d Div(Vector4d a, double f) { - double mult = 1.0f / f; + double mult = 1.0 / f; a.X *= mult; a.Y *= mult; a.Z *= mult; @@ -486,7 +486,7 @@ public static Vector4d Div(Vector4d a, double f) [Obsolete("Use static Divide() method instead.")] 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.Y = a.Y * mult; result.Z = a.Z * mult; @@ -761,7 +761,7 @@ public static void Clamp(ref Vector4d vec, ref Vector4d min, ref Vector4d max, o /// The normalized vector public static Vector4d Normalize(Vector4d vec) { - double scale = 1.0f / vec.Length; + double scale = 1.0 / vec.Length; vec.X *= scale; vec.Y *= scale; vec.Z *= scale; @@ -776,7 +776,7 @@ public static Vector4d Normalize(Vector4d vec) /// The normalized vector 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.Y = vec.Y * scale; result.Z = vec.Z * scale; diff --git a/Source/OpenTK/NativeWindow.cs b/Source/OpenTK/NativeWindow.cs index c25e4166b..74d123b77 100644 --- a/Source/OpenTK/NativeWindow.cs +++ b/Source/OpenTK/NativeWindow.cs @@ -485,7 +485,7 @@ public IWindowInfo WindowInfo /// /// Gets or states the state of the NativeWindow. /// - public WindowState WindowState + public virtual WindowState WindowState { get { diff --git a/Source/OpenTK/OpenTK.dll.config b/Source/OpenTK/OpenTK.dll.config index 4d4102086..99aef8624 100644 --- a/Source/OpenTK/OpenTK.dll.config +++ b/Source/OpenTK/OpenTK.dll.config @@ -7,5 +7,6 @@ - + + diff --git a/Source/OpenTK/Platform/Egl/Egl.cs b/Source/OpenTK/Platform/Egl/Egl.cs index 0dc84d1c3..84bf38469 100644 --- a/Source/OpenTK/Platform/Egl/Egl.cs +++ b/Source/OpenTK/Platform/Egl/Egl.cs @@ -33,108 +33,13 @@ namespace OpenTK.Platform.Egl { - // Note: the Workaround structs declared in each type below work around - // gmcs 2.4.2 bug #530270 (https://bugzilla.novell.com/show_bug.cgi?id=530270). - // They don't cause any change in functionality other than make the compiler happy. - - struct EGLNativeDisplayType - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLNativeDisplayType(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - - public static readonly EGLNativeDisplayType Default = new EGLNativeDisplayType(); - } - - struct EGLNativePixmapType - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLNativePixmapType(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - } - - struct EGLConfig - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLConfig(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - } - - struct EGLContext - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLContext(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - - public static readonly EGLContext None; - } - - struct EGLDisplay - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLDisplay(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - - public static readonly EGLDisplay Null = default(EGLDisplay); - } - - struct EGLSurface - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLSurface(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - - public static readonly EGLSurface None = default(EGLSurface); - } - - struct EGLClientBuffer - { - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public struct Workaround { } - - public readonly Compute.Handle Handle; - - public EGLClientBuffer(IntPtr handle) - { - Handle = new Compute.Handle(handle); - } - } + using EGLNativeDisplayType = IntPtr; + using EGLNativePixmapType = IntPtr; + using EGLConfig = IntPtr; + using EGLContext = IntPtr; + using EGLDisplay = IntPtr; + using EGLSurface = IntPtr; + using EGLClientBuffer = IntPtr; static partial class Egl { @@ -267,21 +172,14 @@ static partial class Egl public static extern int GetError(); [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")] - static extern IntPtr eglGetDisplay(EGLNativeDisplayType display_id); - - public static EGLDisplay GetDisplay(EGLNativeDisplayType display_id) - { - IntPtr ptr = eglGetDisplay(display_id); - EGLDisplay ret = new EGLDisplay(ptr); - return ret; - } + public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id); [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); [DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")] - [return: MarshalAsAttribute(UnmanagedType.I1)] + //[return: MarshalAsAttribute(UnmanagedType.I1)] public static extern bool Terminate(EGLDisplay dpy); [DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")] @@ -300,14 +198,7 @@ public static EGLDisplay GetDisplay(EGLNativeDisplayType display_id) public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value); [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")] - static extern IntPtr eglCreateWindowSurface(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; - } + public static extern EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, int[] attrib_list); [DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")] public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list); @@ -363,9 +254,9 @@ public static EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, I public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] 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())); - return new EGLContext(ptr); + return ptr; } [DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")] diff --git a/Source/OpenTK/Platform/Egl/EglContext.cs b/Source/OpenTK/Platform/Egl/EglContext.cs index 39ad46a95..2c183cbb9 100644 --- a/Source/OpenTK/Platform/Egl/EglContext.cs +++ b/Source/OpenTK/Platform/Egl/EglContext.cs @@ -38,7 +38,7 @@ class EglContext : EmbeddedGraphicsContext #region Fields 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. #endregion @@ -64,13 +64,13 @@ class EglContext : EmbeddedGraphicsContext 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); + IntPtr config = Mode.Index.Value; - if (window.Surface.Handle == EGLSurface.None.Handle) + if (window.Surface == IntPtr.Zero) window.CreateWindowSurface(config); 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); } @@ -108,7 +108,7 @@ public override void MakeCurrent(IWindowInfo window) public override bool IsCurrent { - get { return Egl.GetCurrentContext().Handle == HandleAsEGLContext.Handle; } + get { return Egl.GetCurrentContext() == HandleAsEGLContext; } } public override bool VSync @@ -155,12 +155,12 @@ void Dispose(bool 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); } 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; } diff --git a/Source/OpenTK/Platform/Egl/EglGraphicsMode.cs b/Source/OpenTK/Platform/Egl/EglGraphicsMode.cs index c8ca453f4..32df2ef35 100644 --- a/Source/OpenTK/Platform/Egl/EglGraphicsMode.cs +++ b/Source/OpenTK/Platform/Egl/EglGraphicsMode.cs @@ -38,7 +38,7 @@ class EglGraphicsMode : IGraphicsMode 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[] { //Egl.SURFACE_TYPE, Egl.WINDOW_BIT, @@ -58,7 +58,7 @@ public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil }; // 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; if (!Egl.Initialize(display, out major, out minor)) throw new GraphicsModeException(String.Format("Failed to initialize display connection, error {0}", Egl.GetError())); @@ -75,7 +75,7 @@ public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil } // See what we really got - EGLConfig active_config = configs[0]; + IntPtr active_config = configs[0]; int r, g, b, a; Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r); Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g); @@ -88,7 +88,7 @@ public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers); 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 diff --git a/Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs b/Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs index 6e518cb6f..8e807b9e4 100644 --- a/Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs +++ b/Source/OpenTK/Platform/Egl/EglWinPlatformFactory.cs @@ -37,10 +37,12 @@ namespace OpenTK.Platform.Egl // EGL factory for the Windows platform. class EglWinPlatformFactory : WinFactory { + #region Public Members + public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) { 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); return new EglContext(mode, egl_win, shareContext, major, minor, flags); } @@ -48,14 +50,37 @@ public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) { 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); 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() { 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 } } diff --git a/Source/OpenTK/Platform/Egl/EglWindowInfo.cs b/Source/OpenTK/Platform/Egl/EglWindowInfo.cs index a81217dec..eb6eab5dd 100644 --- a/Source/OpenTK/Platform/Egl/EglWindowInfo.cs +++ b/Source/OpenTK/Platform/Egl/EglWindowInfo.cs @@ -39,21 +39,21 @@ class EglWindowInfo : IWindowInfo #region Fields IntPtr handle; - EGLDisplay display; - EGLSurface surface; + IntPtr display; + IntPtr surface; bool disposed; #endregion #region Constructiors - public EglWindowInfo(IntPtr handle, EGLDisplay display) + public EglWindowInfo(IntPtr handle, IntPtr display) { Handle = handle; Display = display; } - public EglWindowInfo(IntPtr handle, EGLDisplay display, EGLSurface surface) + public EglWindowInfo(IntPtr handle, IntPtr display, IntPtr surface) { Handle = handle; Display = display; @@ -66,11 +66,11 @@ public EglWindowInfo(IntPtr handle, EGLDisplay display, EGLSurface surface) 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); int error = Egl.GetError(); @@ -90,7 +90,7 @@ public void CreateWindowSurface(EGLConfig config) public void DestroySurface() { - if (Surface.Handle != EGLSurface.None.Handle) + if (Surface != IntPtr.Zero) if (!Egl.DestroySurface(Display, Surface)) Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface); } diff --git a/Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs b/Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs index 40054c3db..2322a2af9 100644 --- a/Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs +++ b/Source/OpenTK/Platform/Egl/EglX11PlatformFactory.cs @@ -38,15 +38,23 @@ class EglX11PlatformFactory : X11Factory public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) { 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); } public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) { 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); } + + public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext() + { + return (GraphicsContext.GetCurrentContextDelegate)delegate + { + return new ContextHandle(Egl.GetCurrentContext()); + }; + } } } diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index f57e8d7c0..0ecae5260 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -32,6 +32,8 @@ class AglContext : DesktopGraphicsContext GraphicsMode graphics_mode; CarbonWindowInfo carbonWindow; IntPtr shareContextRef; + DisplayDevice device; + bool mIsFullscreen = false; public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) { @@ -43,7 +45,19 @@ public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareC if (shareContext is AglContext) 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); } @@ -76,7 +90,7 @@ private void AddPixelAttrib(List aglAttributes, Agl.PixelFormatAttribute pi IntPtr shareContextRef, bool fullscreen) { List aglAttributes = new List(); - + Debug.Print("AGL pixel format attributes:"); Debug.Indent(); @@ -101,7 +115,7 @@ private void AddPixelAttrib(List aglAttributes, Agl.PixelFormatAttribute pi 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_SAMPLES_ARB, mode.Samples); @@ -160,8 +174,10 @@ private void AddPixelAttrib(List aglAttributes, Agl.PixelFormatAttribute pi MyAGLReportError("aglChoosePixelFormat"); } - - + + + Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef); + // create the context and share it with the share reference. Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); MyAGLReportError("aglCreateContext"); @@ -243,6 +259,7 @@ void SetBufferRect(CarbonWindowInfo carbonWindow) void SetDrawable(CarbonWindowInfo carbonWindow) { IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); + //Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort); Agl.aglSetDrawable(Handle.Handle, windowPort); @@ -261,18 +278,58 @@ private static IntPtr GetWindowPortForWindowInfo(CarbonWindowInfo carbonWindow) } else windowPort = API.GetWindowPort(carbonWindow.WindowRef); + return windowPort; } public override void Update(IWindowInfo 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); SetBufferRect(carbonWindow); 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) { Agl.AglError err = Agl.GetError(); @@ -285,24 +342,43 @@ void MyAGLReportError(string function) 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 // is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen // and redo it as fullscreen. - if (firstFullScreen == false) - { - firstFullScreen = true; - UnsetFullScreen(info); - SetFullScreen(info); - } + if (firstFullScreen == false) + { + firstFullScreen = true; + UnsetFullScreen(info); + SetFullScreen(info, out width, out height); + } + + mIsFullscreen = true; } internal void UnsetFullScreen(CarbonWindowInfo windowInfo) { + Debug.Print("Unsetting AGL fullscreen."); Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); - SetDrawable(windowInfo); + Agl.aglUpdateContext(Handle.Handle); + + CG.DisplayRelease(GetQuartzDevice(windowInfo)); + Debug.Print("Resetting drawable."); + SetDrawable(windowInfo); + + mIsFullscreen = false; } diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs index fd11ab04f..aa4833650 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -44,9 +44,6 @@ class CarbonGLNative : INativeWindow CarbonWindowInfo window; CarbonInput mInputDriver; - [Obsolete] - GraphicsContext context; - static MacOSKeyMap Keymap = new MacOSKeyMap(); IntPtr uppHandler; @@ -107,11 +104,11 @@ static CarbonGLNative() 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.InWindowMenu | WindowAttributes.LiveResize, new Rect((short)x, (short)y, (short)width, (short)height)); - + mDisplayDevice = device; } @@ -252,23 +249,32 @@ void Hide() API.HideWindow(window.WindowRef); } - void SetFullscreen() + internal void SetFullscreen(AglContext context) { 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); + 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. - 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); } @@ -371,16 +377,16 @@ private OSStatus ProcessKeyboardEvent(IntPtr inCaller, IntPtr inEvent, EventInfo case KeyboardEventKind.RawKeyDown: OnKeyPress(mKeyPressArgs); InputDriver.Keyboard[0][Keymap[code]] = true; - return OSStatus.EventNotHandled; + return OSStatus.NoError; case KeyboardEventKind.RawKeyUp: InputDriver.Keyboard[0][Keymap[code]] = false; - - return OSStatus.EventNotHandled; + + return OSStatus.NoError; case KeyboardEventKind.RawKeyModifiersChanged: ProcessModifierKey(inEvent); - return OSStatus.EventNotHandled; + return OSStatus.NoError; default: return OSStatus.EventNotHandled; @@ -679,26 +685,9 @@ private void LoadSize() #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) - { - 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() + public void ProcessEvents() { Application.ProcessEvents(); } @@ -708,13 +697,18 @@ public Point PointToClient(Point point) IntPtr handle = window.WindowRef; 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); } 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 @@ -740,21 +734,6 @@ public OpenTK.Input.IInputDriver InputDriver } } - public bool Fullscreen - { - get - { - return false; - } - set - { - throw new NotImplementedException(); - } - } - - #endregion - - #region INativeWindow Members public Icon Icon { @@ -969,7 +948,6 @@ public WindowState WindowState if (Carbon.API.IsWindowCollapsed(window.WindowRef)) return WindowState.Minimized; - if (Carbon.API.IsWindowInStandardState(window.WindowRef)) { return WindowState.Maximized; @@ -983,81 +961,94 @@ public WindowState WindowState return; Debug.Print("Switching window state from {0} to {1}", WindowState, value); + WindowState oldState = WindowState; + + windowState = value; - if (WindowState == WindowState.Fullscreen) + 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); } - CarbonPoint idealSize; - switch (value) - { - 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; - } + SetCarbonWindowState(); + } + } - windowState = value; + private void SetCarbonWindowState() + { + CarbonPoint idealSize; - OnWindowStateChanged(); + switch (windowState) + { + case WindowState.Fullscreen: + window.GoFullScreenHack = true; - OnResize(); - } - } + break; - public WindowBorder WindowBorder - { - get - { - return windowBorder; - } - set - { - if (windowBorder != value) - { - windowBorder = value; + 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; - 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); - } + case WindowState.Normal: + if (WindowState == WindowState.Maximized) + { + idealSize = new CarbonPoint(); + API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize); + } + break; - if (WindowBorderChanged != null) - WindowBorderChanged(this, EventArgs.Empty); - } - } + 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 --- diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs index 0b4377b05..13f2dfe80 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -41,6 +41,8 @@ sealed class CarbonWindowInfo : IWindowInfo bool ownHandle = false; bool disposed = false; bool isControl = false; + bool goFullScreenHack = false; + bool goWindowedHack = false; #region Constructors @@ -69,6 +71,18 @@ internal IntPtr WindowRef get { return this.windowRef; } } + internal bool GoFullScreenHack + { + get { return goFullScreenHack; } + set { goFullScreenHack = value; } + } + internal bool GoWindowedHack + { + get { return goWindowedHack; } + set { goWindowedHack = value; } + } + + /// /// Gets a value indicating whether this instance refers to a System.Windows.Forms.Control. /// diff --git a/Source/OpenTK/Platform/Windows/API.cs b/Source/OpenTK/Platform/Windows/API.cs index 374931800..106b23e54 100644 --- a/Source/OpenTK/Platform/Windows/API.cs +++ b/Source/OpenTK/Platform/Windows/API.cs @@ -844,6 +844,9 @@ public static HCURSOR LoadCursor(CursorName lpCursorName) #endregion + [DllImport("user32.dll", SetLastError=true)] + public static extern BOOL SetForegroundWindow(HWND hWnd); + #endregion #region Display settings diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs index ed0ba0133..4e1ded1a1 100644 --- a/Source/OpenTK/Platform/Windows/WinGLNative.cs +++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs @@ -68,6 +68,7 @@ internal sealed class WinGLNative : INativeWindow, IInputDriver WindowState windowState = WindowState.Normal; bool borderless_maximized_window_state = false; // Hack to get maximized mode with hidden border (not normally possible). bool focused; + bool mouse_outside_window = true; Rectangle bounds = new Rectangle(), @@ -75,8 +76,7 @@ internal sealed class WinGLNative : INativeWindow, IInputDriver previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode. Icon icon; - const ClassStyle DefaultClassStyle = - ClassStyle.OwnDC | ClassStyle.VRedraw | ClassStyle.HRedraw | ClassStyle.Ime; + const ClassStyle DefaultClassStyle = ClassStyle.OwnDC; readonly IntPtr DefaultWindowProcedure = Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc)); @@ -140,8 +140,6 @@ public WinGLNative(int x, int y, int width, int height, string title, GameWindow keyboards.Add(keyboard); mice.Add(mouse); - - EnableMouseLeaveNotifications(); } #endregion @@ -184,22 +182,6 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP StopTimer(handle); 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: return new IntPtr(1); @@ -296,23 +278,27 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP (short)((uint)lParam.ToInt32() & 0x0000FFFF), (short)(((uint)lParam.ToInt32() & 0xFFFF0000) >> 16)); mouse.Position = point; + + if (mouse_outside_window) { - if (!ClientRectangle.Contains(point)) - { - Functions.ReleaseCapture(); - if (MouseLeave != null) - MouseLeave(this, EventArgs.Empty); - } - else if (Functions.GetCapture() != window.WindowHandle) - { - Functions.SetFocus(window.WindowHandle); - Functions.SetCapture(window.WindowHandle); - if (MouseEnter != null) - MouseEnter(this, EventArgs.Empty); - } + // Once we receive a mouse move event, it means that the mouse has + // re-entered the window. + mouse_outside_window = false; + EnableMouseTracking(); + + if (MouseEnter != null) + MouseEnter(this, EventArgs.Empty); } 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: // This is due to inconsistent behavior of the WParam value on 64bit arch, whese // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000 @@ -454,6 +440,8 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP Win32Rectangle rect; Functions.GetClientRect(handle, out rect); client_rectangle = rect.ToRectangle(); + + Functions.SetForegroundWindow(handle); } break; @@ -478,7 +466,6 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP exists = false; Functions.UnregisterClass(ClassName, Instance); - //Marshal.FreeHGlobal(ClassName); window.Dispose(); child_window.Dispose(); @@ -493,6 +480,18 @@ IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntP 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) { if (timer_handle == UIntPtr.Zero) @@ -610,18 +609,6 @@ void DestroyWindow() #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 #region INativeWindow Members @@ -682,7 +669,7 @@ public Rectangle ClientRectangle } set { - Size = value.Size; + ClientSize = value.Size; } } @@ -905,6 +892,8 @@ public WindowState WindowState WindowBorder = WindowBorder.Hidden; command = ShowWindowCommand.MAXIMIZE; + Functions.SetForegroundWindow(window.WindowHandle); + break; } @@ -953,6 +942,11 @@ public WindowBorder WindowBorder if (windowBorder == value) 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, // change the border, then go back to maximized/minimized. WindowState state = WindowState; @@ -982,7 +976,8 @@ public WindowBorder WindowBorder Functions.AdjustWindowRectEx(ref rect, style, false, ParentStyleEx); // 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.SetWindowPos(window.WindowHandle, IntPtr.Zero, 0, 0, rect.Width, rect.Height, @@ -992,7 +987,7 @@ public WindowBorder WindowBorder // Force window to redraw update its borders, but only if it's // already visible (invisible windows will change borders when // they become visible, so no need to make them visiable prematurely). - if (Visible) + if (was_visible) Visible = true; WindowState = state; diff --git a/Source/OpenTK/Platform/X11/Bindings/Glx.cs b/Source/OpenTK/Platform/X11/Bindings/Glx.cs index dec8464a2..805027097 100644 --- a/Source/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/Source/OpenTK/Platform/X11/Bindings/Glx.cs @@ -252,6 +252,7 @@ enum ErrorCode : int #endregion + /// \internal /// /// Provides access to GLX functions. /// diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 5fbd2bf1a..c0acef6b0 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -14,6 +14,7 @@ namespace OpenTK.Platform.X11 { + /// \internal /// /// 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. @@ -370,7 +371,7 @@ private void Dispose(bool manuallyCalled) { IntPtr display = Display; if (IsCurrent) - MakeCurrent(null); + Glx.MakeCurrent(display, IntPtr.Zero, IntPtr.Zero); Glx.DestroyContext(display, Handle); } diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 67ab8fb8f..13f877cb8 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -38,6 +38,7 @@ namespace OpenTK.Platform.X11 { + /// \internal /// /// Drives GameWindow on X11. /// This class supports OpenTK, and is not intended for use by OpenTK programs. @@ -148,7 +149,8 @@ internal sealed class X11GLNative : INativeWindow, IDisposable EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask | EventMask.PointerMotionMask | EventMask.FocusChangeMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | - EventMask.EnterWindowMask | EventMask.LeaveWindowMask; + EventMask.EnterWindowMask | EventMask.LeaveWindowMask | + EventMask.PropertyChangeMask; attributes.event_mask = (IntPtr)window.EventMask; uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask | @@ -237,25 +239,25 @@ private void RegisterAtoms(X11WindowInfo window) Debug.WriteLine("Registering atoms."); _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_fullscreen = Functions.XInternAtom(window.Display, "_NET_WM_STATE_FULLSCREEN", false); _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 = - 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 = - Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false); + _atom_net_wm_allowed_actions = + Functions.XInternAtom(window.Display, "_NET_WM_ALLOWED_ACTIONS", false); _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 = - 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 = - Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false); + Functions.XInternAtom(window.Display, "_NET_WM_ACTION_MAXIMIZE_VERT", false); - _atom_net_wm_icon = - Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false); + _atom_net_wm_icon = + Functions.XInternAtom(window.Display, "_NEW_WM_ICON", false); // string[] atom_names = new string[] // { @@ -624,9 +626,6 @@ public void ProcessEvents() { isExiting = true; - if (Unload != null) - Unload(this, EventArgs.Empty); - Debug.WriteLine("Destroying window."); Functions.XDestroyWindow(window.Display, window.WindowHandle); break; @@ -740,6 +739,12 @@ public void ProcessEvents() Functions.XRefreshKeyboardMapping(ref e.MappingEvent); } break; + + case XEventName.PropertyNotify: + if (e.PropertyEvent.atom == _atom_net_wm_state) + if (WindowStateChanged != null) + WindowStateChanged(this, EventArgs.Empty); + break; default: //Debug.WriteLine(String.Format("{0} event was not handled", e.type)); @@ -980,7 +985,8 @@ public OpenTK.WindowState WindowState { Functions.XGetWindowProperty(window.Display, window.WindowHandle, _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) @@ -1029,6 +1035,7 @@ public OpenTK.WindowState WindowState using (new XLock(window.Display)) { + // Reset the current window state if (current_state == OpenTK.WindowState.Minimized) Functions.XMapWindow(window.Display, window.WindowHandle); else if (current_state == OpenTK.WindowState.Fullscreen) @@ -1087,9 +1094,6 @@ public OpenTK.WindowState WindowState if (temporary_resizable) WindowBorder = previous_state; - - if (WindowStateChanged != null) - WindowStateChanged(this, EventArgs.Empty); } } @@ -1209,15 +1213,6 @@ public bool Exists #endregion - #region public bool IsExiting - - public bool IsExiting - { - get { return isExiting; } - } - - #endregion - #region public bool IsIdle public bool IsIdle @@ -1227,65 +1222,6 @@ public bool IsIdle #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 /// @@ -1455,10 +1391,7 @@ private void Dispose(bool manuallyCalled) while (Exists) ProcessEvents(); } - - if (GraphicsContext.CurrentContext != null) - GraphicsContext.CurrentContext.MakeCurrent(null); - + window.Dispose(); window = null; } diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs index 8f7ecae2d..ae4473b1b 100644 --- a/Source/OpenTK/Platform/X11/X11Input.cs +++ b/Source/OpenTK/Platform/X11/X11Input.cs @@ -15,6 +15,7 @@ namespace OpenTK.Platform.X11 { + /// \internal /// /// Drives the InputDriver on X11. /// This class supports OpenTK, and is not intended for users of OpenTK. diff --git a/Source/OpenTK/Platform/X11/X11WindowInfo.cs b/Source/OpenTK/Platform/X11/X11WindowInfo.cs index 9dcf1f93a..aed904892 100644 --- a/Source/OpenTK/Platform/X11/X11WindowInfo.cs +++ b/Source/OpenTK/Platform/X11/X11WindowInfo.cs @@ -31,6 +31,7 @@ namespace OpenTK.Platform.X11 { + /// \internal /// Describes an X11 window. sealed class X11WindowInfo : IWindowInfo {