diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 9b59d52cb..02b47806e 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -1,353 +1,352 @@ - - - - {BEB1C785-5CAD-48FF-A886-876BF0A318D4} - Debug - AnyCPU - WinExe - ClassicalSharp - ClassicalSharp - v2.0 - - - Properties - False - True - False - False - obj\$(Configuration)\ - 4 - OnBuildSuccess - - - AnyCPU - 4194304 - False - Auto - 4096 - - - ..\output\debug\ - true - Full - False - False - DEBUG;TRACE; - Project - obj\ - - - ..\output\release\ - false - None - True - False - TRACE; - obj\ - Project - - - AnyCPU - ..\output\debug\ - true - Full - False - False - DEBUG;TRACE;USE_DX; - Project - obj\ - - - ..\output\release\ - false - None - True - False - TRACE;USE_DX; - obj\ - Project - - - - - SharpWave.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - credits.txt - PreserveNewest - - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {35FEE071-2DE6-48A1-9343-B5C1F202A12B} - OpenTK - - + + + + {BEB1C785-5CAD-48FF-A886-876BF0A318D4} + Debug + AnyCPU + WinExe + ClassicalSharp + ClassicalSharp + v2.0 + + + Properties + False + True + False + False + obj\$(Configuration)\ + 4 + OnBuildSuccess + + + AnyCPU + 4194304 + False + Auto + 4096 + + + ..\output\debug\ + true + Full + False + False + DEBUG;TRACE; + Project + obj\ + + + ..\output\release\ + false + None + True + False + TRACE; + obj\ + Project + + + AnyCPU + ..\output\debug\ + true + Full + False + False + DEBUG;TRACE;USE_DX; + Project + obj\ + + + ..\output\release\ + false + None + True + False + TRACE;USE_DX; + obj\ + Project + + + + + SharpWave.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + credits.txt + PreserveNewest + + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {35FEE071-2DE6-48A1-9343-B5C1F202A12B} + OpenTK + + \ No newline at end of file diff --git a/ClassicalSharp/Game/Game.Init.cs b/ClassicalSharp/Game/Game.Init.cs index 2aeac50ad..d0c1eee38 100644 --- a/ClassicalSharp/Game/Game.Init.cs +++ b/ClassicalSharp/Game/Game.Init.cs @@ -155,7 +155,7 @@ namespace ClassicalSharp { } } - window.LoadIcon(); + LoadIcon(); string connectString = "Connecting to " + IPAddress + ":" + Port + ".."; if (Graphics.WarnIfNecessary(Chat)) { MapBordersRenderer.UseLegacyMode(true); @@ -247,5 +247,19 @@ namespace ClassicalSharp { AddScheduledTask(defTicks, ParticleManager.Tick); AddScheduledTask(defTicks, Animations.Tick); } + + void LoadIcon() { + string launcherFile = "Launcher2.exe"; + if (!Platform.FileExists(launcherFile)) { + launcherFile = "Launcher.exe"; + } + if (!Platform.FileExists(launcherFile)) return; + + try { + window.Icon = Icon.ExtractAssociatedIcon(launcherFile); + } catch (Exception ex) { + ErrorHandler.LogError("Game.LoadIcon()", ex); + } + } } } \ No newline at end of file diff --git a/ClassicalSharp/Game/Game.Properties.cs b/ClassicalSharp/Game/Game.Properties.cs index 69b1deac6..6db7bc37a 100644 --- a/ClassicalSharp/Game/Game.Properties.cs +++ b/ClassicalSharp/Game/Game.Properties.cs @@ -207,7 +207,7 @@ namespace ClassicalSharp { } } - internal DesktopWindow window; + internal INativeWindow window; public int Width, Height; @@ -219,11 +219,6 @@ namespace ClassicalSharp { return window.PointToScreen(coords); } - public bool VSync { - get { return window.VSync; } - set { window.VSync = value; } - } - bool visible = true; internal bool realVisible = true; public bool CursorVisible { diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index fe1e399b6..70cc696c3 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -19,7 +19,9 @@ using ClassicalSharp.Renderers; using ClassicalSharp.Selections; using ClassicalSharp.Textures; using OpenTK; +using OpenTK.Graphics; using OpenTK.Input; +using OpenTK.Platform; #if ANDROID using Android.Graphics; #endif @@ -30,9 +32,9 @@ namespace ClassicalSharp { public partial class Game : IDisposable { - public Game(string username, string mppass, string skinServer, - bool nullContext, int width, int height) { - window = new DesktopWindow(this, username, nullContext, width, height); + public Game(string username, string mppass, string skinServer, int width, int height) { + string title = Program.AppName + " (" + username + ")"; + window = Factory.CreateWindow(width, height, title, GraphicsMode.Default, DisplayDevice.Primary); Username = username; Mppass = mppass; this.skinServer = skinServer; @@ -56,9 +58,39 @@ namespace ClassicalSharp { return true; } - public void Run() { window.Run(); } + Stopwatch render_watch = new Stopwatch(); + FrameEventArgs render_args = new FrameEventArgs(); + public void Run() { + window.Visible = true; + window.Closed += OnClosed; + window.Resize += OnResize; + + OnLoad(); + OnResize(null, null); + Utils.LogDebug("Entering main loop."); + render_watch.Start(); + + while (true) { + window.ProcessEvents(); + if (window.Exists && !isExiting) { + // Cap the maximum time drift to 1 second (e.g. when the process is suspended). + double time = render_watch.Elapsed.TotalSeconds; + if (time > 1.0) time = 1.0; + if (time <= 0) continue; + + render_watch.Reset(); + render_watch.Start(); + RenderFrame(time); + } else { return; } + } + } - public void Exit() { window.Exit(); } + bool isExiting; + public void Exit() { + isExiting = true; + // TODO: is isExiting right + window.Close(); + } public void SetViewDistance(int distance, bool userDist) { if (userDist) { @@ -211,7 +243,7 @@ namespace ClassicalSharp { return -1; } - internal void OnResize() { + void OnResize(object sender, EventArgs e) { Size size = window.ClientSize; Width = size.Width; Height = size.Height; @@ -220,6 +252,10 @@ namespace ClassicalSharp { Gui.OnResize(); } + void OnClosed(object sender, EventArgs e) { + Dispose(); + } + void OnNewMapCore(object sender, EventArgs e) { for (int i = 0; i < Components.Count; i++) Components[i].OnNewMap(this); @@ -408,6 +444,8 @@ namespace ClassicalSharp { Drawer2D.DisposeInstance(); Graphics.Dispose(); + // TODO: is this needed + //window.Dispose(); if (!Options.HasChanged()) return; Options.Load(); diff --git a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs index ba5e3a6b3..6cb10c720 100644 --- a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs +++ b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs @@ -441,7 +441,6 @@ namespace ClassicalSharp.GraphicsAPI { bool vsync = false; public override void SetVSync(Game game, bool value) { - game.VSync = value; if (vsync == value) return; vsync = value; @@ -500,10 +499,10 @@ namespace ClassicalSharp.GraphicsAPI { args.BackBufferHeight = height; args.BackBufferFormat = viewFormat; args.BackBufferCount = 1; - args.EnableAutoDepthStencil = true; + args.EnableAutoDepthStencil = 1; args.PresentationInterval = vsync ? PresentInterval.One : PresentInterval.Immediate; args.SwapEffect = SwapEffect.Discard; - args.Windowed = true; + args.Windowed = 1; return args; } diff --git a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs index 96e06eef1..cd3681d22 100644 --- a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs +++ b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs @@ -6,7 +6,9 @@ using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using OpenTK; +using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; +using OpenTK.Platform; using BmpPixelFormat = System.Drawing.Imaging.PixelFormat; using GlPixelFormat = OpenTK.Graphics.OpenGL.PixelFormat; @@ -21,8 +23,13 @@ namespace ClassicalSharp.GraphicsAPI { const int dynamicListId = 1234567891; IntPtr dynamicListData; #endif + IGraphicsContext glContext; - public OpenGLApi() { + public OpenGLApi(IWindowInfo window) { + glContext = Factory.Default.CreateGLContext(GraphicsMode.Default, window); + glContext.MakeCurrent(window); + glContext.LoadAll(); + MinZNear = 0.1f; InitFields(); int texDims; @@ -529,14 +536,14 @@ namespace ClassicalSharp.GraphicsAPI { } public override void EndFrame(Game game) { - game.window.SwapBuffers(); + glContext.SwapBuffers(); #if GL11 activeList = -1; #endif } public override void SetVSync(Game game, bool value) { - game.VSync = value; + glContext.VSync = value; } bool isIntelRenderer; @@ -587,6 +594,12 @@ namespace ClassicalSharp.GraphicsAPI { public override void OnWindowResize(Game game) { GL.Viewport(0, 0, game.Width, game.Height); + glContext.Update(game.window); + } + + public override void Dispose() { + base.Dispose(); + glContext.Dispose(); } void InitFields() { diff --git a/ClassicalSharp/Platform/DesktopWindow.cs b/ClassicalSharp/Platform/DesktopWindow.cs deleted file mode 100644 index c13e8c09b..000000000 --- a/ClassicalSharp/Platform/DesktopWindow.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 -using System; -using System.Drawing; -using OpenTK; -using OpenTK.Graphics; - -namespace ClassicalSharp { - - /// Implementation of a native window and native input handling mechanism on Windows, OSX, and Linux. - public sealed class DesktopWindow : GameWindow { - - Game game; - public DesktopWindow(Game game, string username, bool nullContext, int width, int height) : - base(width, height, GraphicsMode.Default, Program.AppName + " (" + username + ")", nullContext, 0, DisplayDevice.Primary) { - this.game = game; - } - - protected override void OnLoad(EventArgs e) { - game.OnLoad(); - base.OnLoad(e); - } - - public override void Dispose() { - game.Dispose(); - base.Dispose(); - } - - protected override void OnRenderFrame(FrameEventArgs e) { - game.RenderFrame(e.Time); - base.OnRenderFrame(e); - } - - protected override void OnResize(object sender, EventArgs e) { - game.OnResize(); - base.OnResize(sender, e); - } - - public void LoadIcon() { - string launcherFile = "Launcher2.exe"; - if (!Platform.FileExists(launcherFile)) { - launcherFile = "Launcher.exe"; - } - if (!Platform.FileExists(launcherFile)) return; - - try { - Icon = Icon.ExtractAssociatedIcon(launcherFile); - } catch (Exception ex) { - ErrorHandler.LogError("DesktopWindow.LoadIcon()", ex); - } - } - } -} diff --git a/ClassicalSharp/Program.cs b/ClassicalSharp/Program.cs index 81200e1bd..76df986b8 100644 --- a/ClassicalSharp/Program.cs +++ b/ClassicalSharp/Program.cs @@ -38,11 +38,6 @@ namespace ClassicalSharp { OpenTK.Configuration.SkipPerfCountersHack(); Utils.LogDebug("Starting " + AppName + ".."); - bool nullContext = true; - #if !USE_DX - nullContext = false; - #endif - Options.Load(); DisplayDevice device = DisplayDevice.Primary; int width = Options.GetInt(OptionsKey.WindowWidth, 0, device.Width, 0); @@ -57,17 +52,17 @@ namespace ClassicalSharp { if (args.Length == 0 || args.Length == 1) { const string skinServer = "http://static.classicube.net/skins/"; string user = args.Length > 0 ? args[0] : "Singleplayer"; - using (Game game = new Game(user, null, skinServer, nullContext, width, height)) + using (Game game = new Game(user, null, skinServer, width, height)) game.Run(); } else if (args.Length < 4) { Utils.LogDebug("ClassicalSharp.exe is only the raw client. You must either use the launcher or" + " provide command line arguments to start the client."); } else { - RunMultiplayer(args, nullContext, width, height); + RunMultiplayer(args, width, height); } } - static void RunMultiplayer(string[] args, bool nullContext, int width, int height) { + static void RunMultiplayer(string[] args, int width, int height) { IPAddress ip = null; if (!IPAddress.TryParse(args[2], out ip)) { Utils.LogDebug("Invalid IP \"" + args[2] + '"'); return; @@ -83,7 +78,7 @@ namespace ClassicalSharp { } string skinServer = args.Length >= 5 ? args[4] : "http://static.classicube.net/skins/"; - using (Game game = new Game(args[0], args[1], skinServer, nullContext, width, height)) { + using (Game game = new Game(args[0], args[1], skinServer, width, height)) { game.IPAddress = ip; game.Port = port; game.Run(); diff --git a/Launcher2/LauncherWindow.cs b/Launcher2/LauncherWindow.cs index 9e842e66b..f6c9df2c6 100644 --- a/Launcher2/LauncherWindow.cs +++ b/Launcher2/LauncherWindow.cs @@ -15,13 +15,14 @@ using Launcher.Web; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; +using OpenTK.Platform; namespace Launcher { public sealed partial class LauncherWindow { /// Underlying native window instance. - public NativeWindow Window; + public INativeWindow Window; /// Platform specific class used to draw 2D elements, /// such as text, rounded rectangles and lines. @@ -169,8 +170,8 @@ namespace Launcher { } public void Run() { - Window = new NativeWindow(640, 400, Program.AppName, - GraphicsMode.Default, DisplayDevice.Primary); + Window = Factory.CreateWindow(640, 400, Program.AppName, + GraphicsMode.Default, DisplayDevice.Primary); Window.Visible = true; Drawer = new GdiPlusDrawer2D(); Init(); diff --git a/OpenTK/GameWindow.cs b/OpenTK/GameWindow.cs index 09324137f..d64940684 100644 --- a/OpenTK/GameWindow.cs +++ b/OpenTK/GameWindow.cs @@ -39,227 +39,11 @@ namespace OpenTK { public enum GameWindowFlags { Default = 0 }; - /// - /// The GameWindow class contains cross-platform methods to create and render on an OpenGL - /// window, handle input and load resources. - /// - /// - /// GameWindow contains several events you can hook or override to add your custom logic: - /// - /// - /// OnLoad: Occurs after creating the OpenGL context, but before entering the main loop. - /// Override to load resources. - /// - /// - /// OnUnload: Occurs after exiting the main loop, but before deleting the OpenGL context. - /// Override to unload resources. - /// - /// - /// OnResize: Occurs whenever GameWindow is resized. You should update the OpenGL Viewport - /// and Projection Matrix here. - /// - /// - /// OnUpdateFrame: Occurs at the specified logic update rate. Override to add your game - /// logic. - /// - /// - /// OnRenderFrame: Occurs at the specified frame render rate. Override to add your - /// rendering code. - /// - /// - /// Call the Run() method to start the application's main loop. Run(double, double) takes two - /// parameters that - /// specify the logic update rate, and the render update rate. - /// - public class GameWindow : NativeWindow, IGameWindow, IDisposable { - - IGraphicsContext glContext; - bool isExiting = false; - double render_period; - // TODO: Implement these: - double render_time; - bool vsync; - - Stopwatch render_watch = new Stopwatch(); - double next_render = 0.0; - FrameEventArgs render_args = new FrameEventArgs(); - - /// Constructs a new GameWindow with the specified attributes. - /// The width of the GameWindow in pixels. - /// The height of the GameWindow in pixels. - /// The OpenTK.Graphics.GraphicsMode of the GameWindow. - /// The title of the GameWindow. - /// GameWindow options regarding window appearance and behavior. - /// The OpenTK.Graphics.DisplayDevice to construct the GameWindow in. - public GameWindow(int width, int height, GraphicsMode mode, string title, bool nullContext, - GameWindowFlags options, DisplayDevice device) : base(width, height, title, mode, device) { - try { - glContext = nullContext ? new NullContext() : - Factory.Default.CreateGLContext(mode, WindowInfo); - glContext.MakeCurrent(WindowInfo); - glContext.LoadAll(); - VSync = true; - } catch (Exception e) { - Debug.Print(e.ToString()); - base.Dispose(); - throw; - } - } - - /// Disposes of the GameWindow, releasing all resources consumed by it. - public override void Dispose() { - try { - Dispose(true); - } finally { - try { - if (glContext != null) { - glContext.Dispose(); - glContext = null; - } - } finally { - base.Dispose(); - } - } - GC.SuppressFinalize(this); - } - - /// Closes the GameWindow. Equivalent to method. - /// Override if you are not using . - /// If you override this method, place a call to base.Exit(), to ensure proper OpenTK shutdown. - public virtual void Exit() { - Close(); - } - - /// 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(object sender, System.ComponentModel.CancelEventArgs e) { - base.OnClosing(sender, e); - if (!e.Cancel) { - isExiting = true; - OnUnload(EventArgs.Empty); - } - } - - /// Called after an OpenGL context has been established, but before entering the main loop. - /// Not used. - protected virtual void OnLoad(EventArgs e) { - if (Load != null) Load(this, e); - } - - /// Called after GameWindow.Exit was called, but before destroying the OpenGL context. - /// Not used. - protected virtual void OnUnload(EventArgs e) { - if (Unload != null) Unload(this, e); - } - - /// Enters the game loop of the GameWindow updating and rendering at maximum frequency. - /// When overriding the default game loop you should call ProcessEvents() - /// to ensure that your GameWindow responds to operating system events. - /// Once ProcessEvents() returns, it is time to call update and render the next frame. - /// The frequency of RenderFrame events. - public void Run() { - EnsureUndisposed(); - try { - Visible = true; // Make sure the GameWindow is visible. - OnLoad(EventArgs.Empty); - OnResize(null, EventArgs.Empty); - Debug.Print("Entering main loop."); - render_watch.Start(); - - while (true) { - ProcessEvents(); - if (Exists && !IsExiting) - RaiseRenderFrame(render_watch, ref next_render, render_args); - else - return; - } - } finally { - if (Exists) { - // TODO: Should similar behaviour be retained, possibly on native window level? - //while (this.Exists) - // ProcessEvents(false); - } - } - } - - void RaiseRenderFrame(Stopwatch render_watch, ref double next_render, FrameEventArgs render_args) { - // Cap the maximum time drift to 1 second (e.g. when the process is suspended). - double time = render_watch.Elapsed.TotalSeconds; - if (time > 1.0) - time = 1.0; - if (time <= 0) - return; - double time_left = next_render - time; - - if (time_left <= 0.0) { - // Schedule next render event. The 1 second cap ensures the process does not appear to hang. - next_render = time_left; - if (next_render < -1.0) - next_render = -1.0; - - render_watch.Reset(); - render_watch.Start(); - - if (time > 0) { - render_period = render_args.Time = time; - OnRenderFrameInternal(render_args); - render_time = render_watch.Elapsed.TotalSeconds; - } - } - } - - /// Swaps the front and back buffer, presenting the rendered scene to the user. - public void SwapBuffers() { - EnsureUndisposed(); - this.Context.SwapBuffers(); - } - - /// Returns the opengl IGraphicsContext associated with the current GameWindow. - public IGraphicsContext Context { - get { EnsureUndisposed(); return glContext; } - } - - /// - /// Gets a value indicating whether the shutdown sequence has been initiated - /// for this window, by calling GameWindow.Exit() or hitting the 'close' button. - /// If this property is true, it is no longer safe to use any OpenTK.Input or - /// OpenTK.Graphics.OpenGL functions or properties. - /// - public bool IsExiting { - get { EnsureUndisposed(); return isExiting; } - } - - /// Gets a double representing the actual frequency of RenderFrame events, in hertz (i.e. fps or frames per second). - public double RenderFrequency { - get { - EnsureUndisposed(); - if (render_period == 0.0) - return 1.0; - return 1.0 / render_period; - } - } - - /// Gets a double representing the period of RenderFrame events, in seconds. - public double RenderPeriod { - get { EnsureUndisposed(); return render_period; } - } - - /// Gets a double representing the time spent in the RenderFrame function, in seconds. - public double RenderTime { - get { EnsureUndisposed(); return render_time; } - protected set { EnsureUndisposed(); render_time = value; } - } - - /// Gets or sets the VSyncMode. - public bool VSync { - get { EnsureUndisposed(); return vsync; } - set { EnsureUndisposed(); Context.VSync = (vsync = value); } - } + public class GameWindow { + // TODO: /// Gets or states the state of the NativeWindow. - public override WindowState WindowState { + /*public override WindowState WindowState { get { return base.WindowState; } set { base.WindowState = value; @@ -268,33 +52,6 @@ namespace OpenTK if (Context != null) Context.Update(WindowInfo); } - } - - /// Occurs before the window is displayed for the first time. - public event EventHandler Load; - - /// Occurs when it is time to render a frame. - public event EventHandler RenderFrame; - - /// Occurs before the window is destroyed. - public event EventHandler Unload; - - /// Override to add custom cleanup logic. - /// True, if this method was called by the application; false if this was called by the finalizer thread. - protected virtual void Dispose(bool manual) { } - - /// Called when the frame is rendered. - /// Contains information necessary for frame rendering. - /// Subscribe to the event instead of overriding this method. - protected virtual void OnRenderFrame(FrameEventArgs e) { - if (RenderFrame != null) RenderFrame(this, e); - } - - protected override void OnResize(object sender, EventArgs e) { - base.OnResize(sender, e); - glContext.Update(base.WindowInfo); - } - - private void OnRenderFrameInternal(FrameEventArgs e) { if (Exists && !isExiting) OnRenderFrame(e); } + }*/ } } \ No newline at end of file diff --git a/OpenTK/Graphics/GraphicsContextBase.cs b/OpenTK/Graphics/GraphicsContextBase.cs deleted file mode 100644 index a3b2267aa..000000000 --- a/OpenTK/Graphics/GraphicsContextBase.cs +++ /dev/null @@ -1,73 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; -using OpenTK.Platform; - -namespace OpenTK.Graphics { - - // Provides the foundation for all IGraphicsContext implementations. - abstract class GraphicsContextBase : IGraphicsContext { - - bool disposed; - - protected IntPtr ContextHandle; - protected GraphicsMode Mode; - - public abstract void SwapBuffers(); - - public abstract void MakeCurrent(IWindowInfo window); - - public abstract bool IsCurrent { get; } - - public bool IsDisposed { - get { return disposed; } - protected set { disposed = value; } - } - - public abstract bool VSync { get; set; } - - public virtual void Update(IWindowInfo window) { } - - public GraphicsMode GraphicsMode { get { return Mode; } } - - public abstract void LoadAll(); - - public IntPtr Context { get { return ContextHandle; } } - - public abstract IntPtr GetAddress(string function); - - public void Dispose() { - Dispose(true); - GC.SuppressFinalize( this ); - } - - protected abstract void Dispose(bool calledManually); - - ~GraphicsContextBase() { Dispose(false); } - } -} diff --git a/OpenTK/Graphics/GraphicsContextException.cs b/OpenTK/Graphics/GraphicsContextException.cs deleted file mode 100644 index c44d5cf9a..000000000 --- a/OpenTK/Graphics/GraphicsContextException.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK.Graphics -{ - /// - /// Represents errors related to a GraphicsContext. - /// - public class GraphicsContextException : Exception - { - /// - /// Constructs a new GraphicsContextException. - /// - public GraphicsContextException() : base() { } - /// - /// Constructs a new GraphicsContextException with the given error message. - /// - public GraphicsContextException(string message) : base(message) { } - } -} diff --git a/OpenTK/Graphics/GraphicsMode.cs b/OpenTK/Graphics/GraphicsMode.cs index cf467246c..83b7a7f92 100644 --- a/OpenTK/Graphics/GraphicsMode.cs +++ b/OpenTK/Graphics/GraphicsMode.cs @@ -55,4 +55,9 @@ namespace OpenTK.Graphics { } } } + + public class GraphicsModeException : Exception { + public GraphicsModeException() : base() { } + public GraphicsModeException(string message) : base(message) { } + } } diff --git a/OpenTK/Graphics/GraphicsModeException.cs b/OpenTK/Graphics/GraphicsModeException.cs deleted file mode 100644 index 21b669c90..000000000 --- a/OpenTK/Graphics/GraphicsModeException.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace OpenTK.Graphics { - - /// Represents errors related to unavailable graphics parameters. - public class GraphicsModeException : Exception { - - /// Constructs a new GraphicsModeException. - public GraphicsModeException() : base() { } - - /// Constructs a new GraphicsModeException with the given error message. - public GraphicsModeException(string message) : base(message) { } - } -} diff --git a/OpenTK/Graphics/IGraphicsContext.cs b/OpenTK/Graphics/IGraphicsContext.cs index 861728088..163e5e725 100644 --- a/OpenTK/Graphics/IGraphicsContext.cs +++ b/OpenTK/Graphics/IGraphicsContext.cs @@ -12,10 +12,10 @@ using OpenTK.Platform; namespace OpenTK.Graphics { /// Provides methods for creating and interacting with an OpenGL context. - public interface IGraphicsContext : IDisposable { + public abstract class IGraphicsContext : IDisposable { /// Swaps buffers, presenting the rendered scene to the user. - void SwapBuffers(); + public abstract void SwapBuffers(); /// Makes the GraphicsContext current in the calling thread. /// An OpenTK.Platform.IWindowInfo structure that points to a valid window. @@ -23,36 +23,45 @@ namespace OpenTK.Graphics { /// OpenGL commands in one thread, affect the GraphicsContext which is current in that thread. /// It is an error to issue an OpenGL command in a thread without a current GraphicsContext. /// - void MakeCurrent(IWindowInfo window); + public abstract void MakeCurrent(IWindowInfo window); /// Gets a indicating whether this instance is current in the calling thread. - bool IsCurrent { get; } - - /// Gets a indicating whether this instance has been disposed. - /// It is an error to access any instance methods if this property returns true. - bool IsDisposed { get; } + public abstract bool IsCurrent { get; } /// Gets or sets a value indicating whether VSyncing is enabled. - bool VSync { get; set; } + public abstract bool VSync { get; set; } /// Updates the graphics context. This must be called when the region the graphics context /// is drawn to is resized. - /// - void Update(IWindowInfo window); + public virtual void Update(IWindowInfo window) { } /// Gets the GraphicsMode of this instance. - GraphicsMode GraphicsMode { get; } + public GraphicsMode Mode; /// Loads all OpenGL entry points. Requires this instance to be current on the calling thread. - void LoadAll(); + public abstract void LoadAll(); - /// Gets a handle to the OpenGL rendering context. - IntPtr Context { get; } + /// Handle to the OpenGL rendering context. + public IntPtr ContextHandle; /// Gets the address of an OpenGL extension function. /// The name of the OpenGL function (e.g. "glGetString") /// A pointer to the specified function or IntPtr.Zero if the function isn't /// available in the current opengl context. - IntPtr GetAddress(string function); + public abstract IntPtr GetAddress(string function); + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize( this ); + } + + protected abstract void Dispose(bool calledManually); + + ~IGraphicsContext() { Dispose(false); } + } + + public class GraphicsContextException : Exception { + public GraphicsContextException() : base() { } + public GraphicsContextException(string message) : base(message) { } } } diff --git a/OpenTK/Graphics/OpenGL/GLHelper.cs b/OpenTK/Graphics/OpenGL/GLHelper.cs index 3489bb37a..a21f3b0b7 100644 --- a/OpenTK/Graphics/OpenGL/GLHelper.cs +++ b/OpenTK/Graphics/OpenGL/GLHelper.cs @@ -15,12 +15,12 @@ namespace OpenTK.Graphics.OpenGL { static GL() { } - GraphicsContextBase context; + IGraphicsContext context; protected override IntPtr GetAddress( string funcname ) { return context.GetAddress( funcname ); } - internal void LoadEntryPoints( GraphicsContextBase context ) { + internal void LoadEntryPoints( IGraphicsContext context ) { this.context = context; Debug.Print("Loading OpenGL function pointers... "); AlphaFuncAddress = GetAddress( "glAlphaFunc" ); diff --git a/OpenTK/IGameWindow.cs b/OpenTK/IGameWindow.cs deleted file mode 100644 index bb0496459..000000000 --- a/OpenTK/IGameWindow.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; - -namespace OpenTK.Platform { - - /// Defines the interface for a GameWindow. - public interface IGameWindow : INativeWindow { - - /// Enters the game loop of the GameWindow using the maximum update rate. - void Run(); - - /// Swaps the front and back buffers of the current GraphicsContext, presenting the rendered scene to the user. - void SwapBuffers(); - - /// Occurs before the window is displayed for the first time. - event EventHandler Load; - - /// Occurs before the window is destroyed. - event EventHandler Unload; - - /// Occurs when it is time to render a frame. - event EventHandler RenderFrame; - } -} diff --git a/OpenTK/INativeWindow.cs b/OpenTK/INativeWindow.cs index 22f2378a0..610ea64e9 100644 --- a/OpenTK/INativeWindow.cs +++ b/OpenTK/INativeWindow.cs @@ -34,96 +34,136 @@ using OpenTK.Platform; namespace OpenTK { /// Defines the interface for a native window. - public interface INativeWindow : IDisposable { + public abstract class INativeWindow : IDisposable { /// Gets the current contents of the clipboard. - string GetClipboardText(); + public abstract string GetClipboardText(); /// Sets the current contents of the clipboard. - void SetClipboardText( string value ); + public abstract void SetClipboardText(string value); /// Gets or sets the of the window. - Icon Icon { get; set; } + public abstract Icon Icon { get; set; } /// Gets a System.Boolean that indicates whether this window has input focus. - bool Focused { get; } + public abstract bool Focused { get; } /// Gets or sets a System.Boolean that indicates whether the window is visible. - bool Visible { get; set; } + public abstract bool Visible { get; set; } /// Gets a System.Boolean that indicates whether the window has been created and has not been destroyed. - bool Exists { get; } + public abstract bool Exists { get; } /// Gets the for this window. - IWindowInfo WindowInfo { get; } + public abstract IWindowInfo WindowInfo { get; } /// Gets or sets the for this window. - WindowState WindowState { get; set; } + public abstract WindowState WindowState { get; set; } /// Gets or sets a structure the contains the external bounds of this window, in screen coordinates. /// External bounds include the title bar, borders and drawing area of the window. - Rectangle Bounds { get; set; } + public abstract Rectangle Bounds { get; set; } /// Gets or sets a structure that contains the location of this window on the desktop. - Point Location { get; set; } + public abstract Point Location { get; set; } /// Gets or sets a structure that contains the external size of this window. - Size Size { get; set; } + public abstract Size Size { get; set; } /// Gets or sets a structure that contains the internal bounds of this window, in client coordinates. /// The internal bounds include the drawing area of the window, but exclude the titlebar and window borders. - Rectangle ClientRectangle { get; set; } + public abstract Rectangle ClientRectangle { get; set; } /// Gets or sets a structure that contains the internal size this window. - Size ClientSize { get; set; } + public abstract Size ClientSize { get; set; } /// Closes this window. - void Close(); + public abstract void Close(); /// Processes pending window events. - void ProcessEvents(); + public abstract void ProcessEvents(); /// Transforms the specified point from screen to client coordinates. /// A to transform. /// The point transformed to client coordinates. - Point PointToClient(Point point); + public abstract Point PointToClient(Point point); /// Transforms the specified point from client to screen coordinates. /// A to transform. /// The point transformed to screen coordinates. - Point PointToScreen(Point point); + public abstract Point PointToScreen(Point point); + /*public virtual Point PointToScreen(Point point) { + // Here we use the fact that PointToClient just translates the point, and PointToScreen + // should perform the inverse operation. + Point trans = PointToClient(Point.Empty); + point.X -= trans.X; + point.Y -= trans.Y; + return point; + }*/ /// Gets or sets the cursor position in screen coordinates. - Point DesktopCursorPos { get; set; } + public abstract Point DesktopCursorPos { get; set; } /// Gets or sets whether the cursor is visible in the window. - bool CursorVisible { get; set; } + public abstract bool CursorVisible { get; set; } /// Occurs whenever the window is moved. - event EventHandler Move; + public event EventHandler Move; + protected void RaiseMove() { + if (Move != null) Move(this, EventArgs.Empty); + } /// Occurs whenever the window is resized. - event EventHandler Resize; + public event EventHandler Resize; + protected void RaiseResize() { + if (Resize != null) Resize(this, EventArgs.Empty); + } /// Occurs when the window is about to close. - event EventHandler Closing; + public event EventHandler Closing; + protected void RaiseClosing() { + if (Closing != null) Closing(this, EventArgs.Empty); + } /// Occurs after the window has closed. - event EventHandler Closed; - - /// Occurs when the window is disposed. - event EventHandler Disposed; + public event EventHandler Closed; + protected void RaiseClosed() { + if (Closed != null) Closed(this, EventArgs.Empty); + } /// Occurs when the property of the window changes. - event EventHandler VisibleChanged; + public event EventHandler VisibleChanged; + protected void RaiseVisibleChanged() { + if (VisibleChanged != null) VisibleChanged(this, EventArgs.Empty); + } /// Occurs when the property of the window changes. - event EventHandler FocusedChanged; + public event EventHandler FocusedChanged; + protected void RaiseFocusedChanged() { + if (FocusedChanged != null) FocusedChanged(this, EventArgs.Empty); + } /// Occurs when the property of the window changes. - event EventHandler WindowStateChanged; + public event EventHandler WindowStateChanged; + protected void RaiseWindowStateChanged() { + if (WindowStateChanged != null) WindowStateChanged(this, EventArgs.Empty); + } /// Occurs whenever a character is typed. - event EventHandler KeyPress; + public event EventHandler KeyPress; + KeyPressEventArgs pressArgs = new KeyPressEventArgs(); + protected void RaiseKeyPress(char key) { + pressArgs.KeyChar = key; + if (KeyPress != null) KeyPress(this, pressArgs); + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize( this ); + } + + protected abstract void Dispose(bool calledManually); + + ~INativeWindow() { Dispose(false); } } } diff --git a/OpenTK/NativeWindow.cs b/OpenTK/NativeWindow.cs deleted file mode 100644 index 47f6faa4e..000000000 --- a/OpenTK/NativeWindow.cs +++ /dev/null @@ -1,348 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; -using System.ComponentModel; -using System.Drawing; -using OpenTK.Graphics; -using OpenTK.Input; -using OpenTK.Platform; - -namespace OpenTK { - - /// Instances of this class implement the interface on the current platform. - public class NativeWindow : INativeWindow { - - private readonly INativeWindow implementation; - private bool disposed, events; - - /// Constructs a new centered NativeWindow with the specified attributes. - /// The width of the NativeWindow in pixels. - /// The height of the NativeWindow in pixels. - /// The title of the NativeWindow. - /// GameWindow options specifying window appearance and behavior. - /// The OpenTK.Graphics.GraphicsMode of the NativeWindow. - /// The OpenTK.Graphics.DisplayDevice to construct the NativeWindow in. - /// If width or height is less than 1. - /// If mode or device is null. - public NativeWindow(int width, int height, string title, GraphicsMode mode, DisplayDevice device) - : this(device.Bounds.Left + (device.Bounds.Width - width) / 2, - device.Bounds.Top + (device.Bounds.Height - height) / 2, - width, height, title, mode, device) { } - - public NativeWindow(int width, int height, string title, GameWindowFlags flags, GraphicsMode mode, DisplayDevice device) : this(width, height, title, mode, device) {} - - /// Constructs a new NativeWindow with the specified attributes. - /// Horizontal screen space coordinate of the NativeWindow's origin. - /// Vertical screen space coordinate of the NativeWindow's origin. - /// The width of the NativeWindow in pixels. - /// The height of the NativeWindow in pixels. - /// The title of the NativeWindow. - /// GameWindow options specifying window appearance and behavior. - /// The OpenTK.Graphics.GraphicsMode of the NativeWindow. - /// The OpenTK.Graphics.DisplayDevice to construct the NativeWindow in. - /// If width or height is less than 1. - /// If mode or device is null. - public NativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { - // TODO: Should a constraint be added for the position? - if (width < 1) - throw new ArgumentOutOfRangeException("width", "Must be greater than zero."); - if (height < 1) - throw new ArgumentOutOfRangeException("height", "Must be greater than zero."); - if (mode == null) - throw new ArgumentNullException("mode"); - if (device == null) - throw new ArgumentNullException("device"); - - implementation = Factory.Default.CreateNativeWindow(x, y, width, height, title, mode, device); - } - - /// Closes the NativeWindow. - public void Close() { - EnsureUndisposed(); - implementation.Close(); - } - - /// Gets the current contents of the clipboard. - public string GetClipboardText() { - EnsureUndisposed(); return implementation.GetClipboardText(); - } - - /// Sets the current contents of the clipboard. - public void SetClipboardText(string value) { - EnsureUndisposed(); implementation.SetClipboardText(value); - } - - /// Transforms the specified point from screen to client coordinates. - /// A to transform. - /// The point transformed to client coordinates. - public Point PointToClient(Point point) { - return implementation.PointToClient(point); - } - - /// Transforms the specified point from client to screen coordinates. - /// A to transform. - /// The point transformed to screen coordinates. - public Point PointToScreen(Point point) { - // Here we use the fact that PointToClient just translates the point, and PointToScreen - // should perform the inverse operation. - Point trans = PointToClient(Point.Empty); - point.X -= trans.X; - point.Y -= trans.Y; - return point; - } - - /// Processes operating system events until the NativeWindow becomes idle. - public void ProcessEvents() { - ProcessEvents(false); - } - - /// Gets or sets a structure that contains the external bounds of this window, in screen coordinates. - /// External bounds include the title bar, borders and drawing area of the window. - public Rectangle Bounds { - get { EnsureUndisposed(); return implementation.Bounds; } - set { EnsureUndisposed(); implementation.Bounds = value; } - } - - /// Gets or sets a structure that contains the internal bounds of this window, in client coordinates. - /// The internal bounds include the drawing area of the window, but exclude the titlebar and window borders. - public Rectangle ClientRectangle { - get { EnsureUndisposed(); return implementation.ClientRectangle; } - set { EnsureUndisposed(); implementation.ClientRectangle = value; } - } - - /// Gets or sets a structure that contains the internal size this window. - public Size ClientSize { - get { EnsureUndisposed(); return implementation.ClientSize; } - set { EnsureUndisposed(); implementation.ClientSize = value; - } - } - - /// Gets a value indicating whether a render window exists. - public bool Exists { - get { - return IsDisposed ? false : implementation.Exists; // TODO: Should disposed be ignored instead? - } - } - - /// Gets a System.Boolean that indicates whether this NativeWindow has input focus. - public bool Focused { - get { EnsureUndisposed(); return implementation.Focused; } - } - - /// Gets or sets the System.Drawing.Icon for this GameWindow. - public Icon Icon { - get { EnsureUndisposed(); return implementation.Icon; } - set { EnsureUndisposed(); implementation.Icon = value; } - } - - /// Gets or sets a structure that contains the location of this window on the desktop. - public Point Location { - get { EnsureUndisposed(); return implementation.Location; } - set { EnsureUndisposed(); implementation.Location = value; } - } - - /// Gets or sets a structure that contains the external size of this window. - public Size Size { - get { EnsureUndisposed(); return implementation.Size; } - set { EnsureUndisposed(); implementation.Size = value; } - } - - /// Gets or sets a System.Boolean that indicates whether this NativeWindow is visible. - public bool Visible { - get { EnsureUndisposed(); return implementation.Visible; } - set { EnsureUndisposed(); implementation.Visible = value; } - } - - /// Gets the of this window. - public IWindowInfo WindowInfo { - get { EnsureUndisposed(); return implementation.WindowInfo; } - } - - /// Gets or states the state of the NativeWindow. - public virtual WindowState WindowState { - get { return implementation.WindowState; } - set { implementation.WindowState = value; } - } - - /// Sets whether the cursor is visible in the window. - public bool CursorVisible { - get { return implementation.CursorVisible; } - set { implementation.CursorVisible = value; } - } - - /// Gets or sets the cursor position in screen coordinates. - public Point DesktopCursorPos { - get { return implementation.DesktopCursorPos; } - set { implementation.DesktopCursorPos = value; } - } - - /// Occurs after the window has closed. - public event EventHandler Closed; - - /// Occurs when the window is about to close. - public event EventHandler Closing; - - /// Occurs when the window is disposed. - public event EventHandler Disposed; - - /// Occurs when the property of the window changes. - public event EventHandler FocusedChanged; - - /// Occurs whenever a character is typed. - public event EventHandler KeyPress; - - /// Occurs whenever the window is moved. - public event EventHandler Move; - - /// Occurs whenever the window is resized. - public event EventHandler Resize; - - /// Occurs when the property of the window changes. - public event EventHandler VisibleChanged; - - /// Occurs when the property of the window changes. - public event EventHandler WindowStateChanged; - - /// Releases all non-managed resources belonging to this NativeWindow. - public virtual void Dispose() { - if (!IsDisposed) { - implementation.Dispose(); - GC.SuppressFinalize(this); - IsDisposed = true; - } - } - - /// Ensures that this NativeWindow has not been disposed. - /// If this NativeWindow has been disposed. - protected void EnsureUndisposed() { - if (disposed) throw new ObjectDisposedException(GetType().Name); - } - - /// Gets or sets a , which indicates whether this instance has been disposed. - protected bool IsDisposed { - get { return disposed; } - set { disposed = value; } - } - - /// Called when the NativeWindow has closed. - /// Not used. - protected virtual void OnClosed(object sender, EventArgs e) { - if (Closed != null) Closed(this, e); - } - - /// Called when the NativeWindow is about to close. - /// The for this event. - /// Set e.Cancel to true in order to stop the NativeWindow from closing. - protected virtual void OnClosing(object sender, CancelEventArgs e) { - if (Closing != null) Closing(this, e); - } - - /// Called when the NativeWindow is disposed. - protected virtual void OnDisposed(object sender, EventArgs e) { - if (Disposed != null) Disposed(this, e); - } - - /// Called when the property of the NativeWindow has changed. - protected virtual void OnFocusedChanged(object sender, EventArgs e) { - if (FocusedChanged != null) FocusedChanged(this, e); - } - - /// Called when a character is typed. - /// The for this event. - protected virtual void OnKeyPress(object sender, KeyPressEventArgs e) { - if (KeyPress != null) KeyPress(this, e); - } - - /// Called when the NativeWindow is moved. - protected virtual void OnMove(object sender, EventArgs e) { - if (Move != null) Move(this, e); - } - - /// Called when the NativeWindow is resized. - /// Not used. - protected virtual void OnResize(object sender, EventArgs e) { - if (Resize != null) Resize(this, e); - } - - /// Called when the property of the NativeWindow has changed. - protected virtual void OnVisibleChanged(object sender, EventArgs e) { - if (VisibleChanged != null) VisibleChanged(this, e); - } - - /// Called when the WindowState of this NativeWindow has changed. - protected virtual void OnWindowStateChanged(object sender, EventArgs e) { - if (WindowStateChanged != null) WindowStateChanged(this, e); - } - - /// Processes operating system events until the NativeWindow becomes idle. - /// If true, the state of underlying system event propagation will be preserved, otherwise event propagation will be enabled if it has not been already. - protected void ProcessEvents(bool retainEvents) { - EnsureUndisposed(); - if (!retainEvents && !events) Events = true; - implementation.ProcessEvents(); - } - - private void OnClosedInternal(object sender, EventArgs e) { - OnClosed(null, e); - Events = false; - } - - private bool Events { - set { - if (value) { - if (events) { - throw new InvalidOperationException("Event propagation is already enabled."); - } - implementation.Closed += OnClosed; - implementation.Closing += OnClosing; - implementation.Disposed += OnDisposed; - implementation.FocusedChanged += OnFocusedChanged; - implementation.KeyPress += OnKeyPress; - implementation.Move += OnMove; - implementation.Resize += OnResize; - implementation.VisibleChanged += OnVisibleChanged; - implementation.WindowStateChanged += OnWindowStateChanged; - events = true; - } else if (events) { - implementation.Closed -= OnClosed; - implementation.Closing -= OnClosing; - implementation.Disposed -= OnDisposed; - implementation.FocusedChanged -= OnFocusedChanged; - implementation.KeyPress -= OnKeyPress; - implementation.Move -= OnMove; - implementation.Resize -= OnResize; - implementation.VisibleChanged -= OnVisibleChanged; - implementation.WindowStateChanged -= OnWindowStateChanged; - events = false; - } else { - throw new InvalidOperationException("Event propagation is already disabled."); - } - } - } - } -} diff --git a/OpenTK/OpenTK.csproj b/OpenTK/OpenTK.csproj index e01723b61..950ce7fe4 100644 --- a/OpenTK/OpenTK.csproj +++ b/OpenTK/OpenTK.csproj @@ -55,17 +55,12 @@ - - - - - @@ -100,7 +95,6 @@ - @@ -117,7 +111,6 @@ - diff --git a/OpenTK/Platform/IPlatformFactory.cs b/OpenTK/Platform/IPlatformFactory.cs index 8be48d3ea..458774723 100644 --- a/OpenTK/Platform/IPlatformFactory.cs +++ b/OpenTK/Platform/IPlatformFactory.cs @@ -30,16 +30,22 @@ using OpenTK.Graphics; namespace OpenTK.Platform { - interface IPlatformFactory { - INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device); + public interface IPlatformFactory { + INativeWindow CreateWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device); void InitDisplayDeviceDriver(); IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window); } - internal static class Factory { + public static class Factory { public static readonly IPlatformFactory Default; + + public static INativeWindow CreateWindow(int width, int height, string title, GraphicsMode mode, DisplayDevice device) { + int x = device.Bounds.Left + (device.Bounds.Width - width) / 2; + int y = device.Bounds.Top + (device.Bounds.Height - height) / 2; + return Default.CreateWindow(x, y, width, height, title, mode, device); + } static Factory() { if (Configuration.RunningOnWindows) Default = new Windows.WinFactory(); @@ -53,7 +59,7 @@ namespace OpenTK.Platform { namespace OpenTK.Platform.MacOS { class MacOSFactory : IPlatformFactory { - public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { + public INativeWindow CreateWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { return new CarbonWindow(x, y, width, height, title, device); } @@ -70,7 +76,7 @@ namespace OpenTK.Platform.MacOS { namespace OpenTK.Platform.Windows { class WinFactory : IPlatformFactory { - public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { + public INativeWindow CreateWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { return new WinWindow(x, y, width, height, title, device); } @@ -87,7 +93,7 @@ namespace OpenTK.Platform.Windows { namespace OpenTK.Platform.X11 { class X11Factory : IPlatformFactory { - public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { + public INativeWindow CreateWindow(int x, int y, int width, int height, string title, GraphicsMode mode, DisplayDevice device) { return new X11Window(x, y, width, height, title, mode, device); } diff --git a/OpenTK/Platform/MacOS/AglContext.cs b/OpenTK/Platform/MacOS/AglContext.cs index 670ecfcd3..80bd7d57f 100644 --- a/OpenTK/Platform/MacOS/AglContext.cs +++ b/OpenTK/Platform/MacOS/AglContext.cs @@ -10,7 +10,7 @@ using AGLPixelFormat = System.IntPtr; namespace OpenTK.Platform.MacOS { - class AglContext : GraphicsContextBase { + class AglContext : IGraphicsContext { bool mVSync = false; // Todo: keep track of which display adapter was specified when the context was created. @@ -253,10 +253,9 @@ namespace OpenTK.Platform.MacOS { #region IDisposable Members - protected override void Dispose(bool disposing) - { - if (IsDisposed || ContextHandle == IntPtr.Zero) - return; + bool IsDisposed; + protected override void Dispose(bool disposing) { + if (IsDisposed || ContextHandle == IntPtr.Zero) return; Debug.Print("Disposing of AGL context."); Agl.aglSetCurrentContext(IntPtr.Zero); diff --git a/OpenTK/Platform/MacOS/CarbonWindow.cs b/OpenTK/Platform/MacOS/CarbonWindow.cs index 5bd63747f..3823c8c66 100644 --- a/OpenTK/Platform/MacOS/CarbonWindow.cs +++ b/OpenTK/Platform/MacOS/CarbonWindow.cs @@ -54,7 +54,6 @@ namespace OpenTK.Platform.MacOS int mTitlebarHeight; WindowState windowState = WindowState.Normal; internal static Dictionary WindowRefs = new Dictionary(); - KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs(); bool mIsActive = false; Icon mIcon; @@ -73,17 +72,8 @@ namespace OpenTK.Platform.MacOS TargetDisplayDevice = device; } - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) { - if (mIsDisposed) - return; + protected override void Dispose(bool disposing) { + if (mIsDisposed) return; Debug.Print("Disposing of CarbonGLNative window."); API.DisposeWindow(window.WindowRef); @@ -97,12 +87,6 @@ namespace OpenTK.Platform.MacOS DisposeUPP(); } - ~CarbonWindow() { - Dispose(false); - } - - #endregion - #region Private Members void DisposeUPP() @@ -260,7 +244,6 @@ namespace OpenTK.Platform.MacOS case KeyboardEventKind.RawKeyRepeat: case KeyboardEventKind.RawKeyUp: GetCharCodes(inEvent, out code, out charCode); - mKeyPressArgs.KeyChar = charCode; break; } @@ -278,7 +261,7 @@ namespace OpenTK.Platform.MacOS case KeyboardEventKind.RawKeyDown: Keyboard.Set(tkKey, true); - OnKeyPress(mKeyPressArgs); + RaiseKeyPress(charCode); return OSStatus.NoError; case KeyboardEventKind.RawKeyUp: @@ -298,24 +281,17 @@ namespace OpenTK.Platform.MacOS switch ((WindowEventKind)evt.EventKind) { case WindowEventKind.WindowClose: - CancelEventArgs cancel = new CancelEventArgs(); - OnClosing(cancel); - - if (cancel.Cancel) - return OSStatus.NoError; - else - return OSStatus.EventNotHandled; + RaiseClosing(); + return OSStatus.EventNotHandled; case WindowEventKind.WindowClosed: mExists = false; - OnClosed(); - + RaiseClosed(); return OSStatus.NoError; case WindowEventKind.WindowBoundsChanged: int thisWidth = ClientRectangle.Width; int thisHeight = ClientRectangle.Height; - LoadSize(); if (thisWidth != ClientRectangle.Width || thisHeight != ClientRectangle.Height) @@ -501,9 +477,7 @@ namespace OpenTK.Platform.MacOS protected void OnResize() { LoadSize(); - if (Resize != null) { - Resize(this, EventArgs.Empty); - } + RaiseResize(); } private void LoadSize() { @@ -522,7 +496,7 @@ namespace OpenTK.Platform.MacOS #region INativeWindow Members IntPtr pbStr, utf16, utf8; - public string GetClipboardText() { + public override string GetClipboardText() { IntPtr pbRef = GetPasteboard(); API.PasteboardSynchronize( pbRef ); @@ -564,7 +538,7 @@ namespace OpenTK.Platform.MacOS return Encoding.UTF8.GetString( text ); } - public void SetClipboardText( string value ) { + public override void SetClipboardText( string value ) { IntPtr pbRef = GetPasteboard(); OSStatus err = API.PasteboardClear( pbRef ); if( err != OSStatus.NoError ) @@ -595,31 +569,31 @@ namespace OpenTK.Platform.MacOS return pbRef; } - public void ProcessEvents() { + public override void ProcessEvents() { API.ProcessEvents(); } - public Point PointToClient(Point point) { + public override Point PointToClient(Point point) { IntPtr handle = window.WindowRef; Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); return new Point(point.X - r.X, point.Y - r.Y); } - public Point PointToScreen(Point point) { + public override Point PointToScreen(Point point) { IntPtr handle = window.WindowRef; Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); return new Point(point.X + r.X, point.Y + r.Y); } - public bool Exists { + public override bool Exists { get { return mExists; } } - public IWindowInfo WindowInfo { + public override IWindowInfo WindowInfo { get { return window; } } - public Icon Icon { + public override Icon Icon { get { return mIcon; } set { SetIcon(value); } } @@ -677,7 +651,7 @@ namespace OpenTK.Platform.MacOS } } - public bool Visible { + public override bool Visible { get { return API.IsWindowVisible(window.WindowRef); } set { if (value && Visible == false) @@ -687,11 +661,11 @@ namespace OpenTK.Platform.MacOS } } - public bool Focused { + public override bool Focused { get { return this.mIsActive; } } - public Rectangle Bounds { + public override Rectangle Bounds { get { return bounds; } set { Location = value.Location; @@ -699,17 +673,17 @@ namespace OpenTK.Platform.MacOS } } - public Point Location { + public override Point Location { get { return Bounds.Location; } set { SetLocation((short)value.X, (short)value.Y); } } - public Size Size { + public override Size Size { get { return bounds.Size; } set { SetSize((short)value.Width, (short)value.Height); } } - public Rectangle ClientRectangle { + public override Rectangle ClientRectangle { get { return clientRectangle; } set { // just set the size, and ignore the location value. @@ -718,7 +692,7 @@ namespace OpenTK.Platform.MacOS } } - public Size ClientSize { + public override Size ClientSize { get { return clientRectangle.Size; } set { API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true); @@ -726,36 +700,28 @@ namespace OpenTK.Platform.MacOS } } - public void Close() { - CancelEventArgs e = new CancelEventArgs(); - OnClosing(e); - if (e.Cancel) return; - - OnClosed(); + public override void Close() { + RaiseClosed(); Dispose(); } - public WindowState WindowState { - get - { + public override WindowState WindowState { + get { if (windowState == WindowState.Fullscreen) return WindowState.Fullscreen; if (Carbon.API.IsWindowCollapsed(window.WindowRef)) return WindowState.Minimized; - if (Carbon.API.IsWindowInStandardState(window.WindowRef)) - { + if (Carbon.API.IsWindowInStandardState(window.WindowRef)) { return WindowState.Maximized; } return WindowState.Normal; } - set - { - if (value == WindowState) - return; - + + set { + if (value == WindowState) return; Debug.Print("Switching window state from {0} to {1}", WindowState, value); WindowState oldState = WindowState; @@ -813,71 +779,29 @@ namespace OpenTK.Platform.MacOS break; } - OnWindowStateChanged(); + RaiseWindowStateChanged(); OnResize(); } #region --- Event wrappers --- - private void OnKeyPress(KeyPressEventArgs keyPressArgs) - { - if (KeyPress != null) - KeyPress(this, keyPressArgs); - } - - - private void OnWindowStateChanged() - { - if (WindowStateChanged != null) - WindowStateChanged(this, EventArgs.Empty); - } - - protected virtual void OnClosing(CancelEventArgs e) - { - if (Closing != null) - Closing(this, e); - } - - protected virtual void OnClosed() - { - if (Closed != null) - Closed(this, EventArgs.Empty); - } - - - private void OnActivate() - { + private void OnActivate() { mIsActive = true; - if (FocusedChanged != null) - FocusedChanged(this, EventArgs.Empty); + RaiseFocusedChanged(); } - private void OnDeactivate() - { + + private void OnDeactivate() { mIsActive = false; - if (FocusedChanged != null) - FocusedChanged(this, EventArgs.Empty); + RaiseFocusedChanged(); } #endregion - public event EventHandler Load; - public event EventHandler Unload; - public event EventHandler Move; - public event EventHandler Resize; - public event EventHandler Closing; - public event EventHandler Closed; - public event EventHandler Disposed; - public event EventHandler ClientSizeChanged; - public event EventHandler VisibleChanged; - public event EventHandler FocusedChanged; - public event EventHandler WindowStateChanged; - public event EventHandler KeyPress; - #endregion #region IInputDriver Members - public Point DesktopCursorPos { + public override Point DesktopCursorPos { get { HIPoint point = default( HIPoint ); // NOTE: HIGetMousePosition is only available on OSX 10.5 or later @@ -894,7 +818,7 @@ namespace OpenTK.Platform.MacOS } bool visible = true; - public bool CursorVisible { + public override bool CursorVisible { get { return visible; } set { visible = value; diff --git a/OpenTK/Platform/NullContext.cs b/OpenTK/Platform/NullContext.cs deleted file mode 100644 index bd7665939..000000000 --- a/OpenTK/Platform/NullContext.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using OpenTK.Graphics; - -namespace OpenTK.Platform { - - internal sealed class NullContext : GraphicsContextBase { - - public NullContext() { - Debug.Print( "doing nothing" ); - } - - public override void SwapBuffers() { - } - - public override void MakeCurrent( IWindowInfo window ) { - } - - public override bool IsCurrent { - get { return true; } - } - - public override bool VSync { - get { return true; } - set { } - } - - public override void LoadAll() { - } - - public override IntPtr GetAddress(string funcName) { - return IntPtr.Zero; - } - - public override string ToString() { - return "(empty)"; - } - - protected override void Dispose(bool calledManually) { - } - } -} diff --git a/OpenTK/Platform/Windows/API.cs b/OpenTK/Platform/Windows/API.cs index d0798fe74..9efb074b1 100644 --- a/OpenTK/Platform/Windows/API.cs +++ b/OpenTK/Platform/Windows/API.cs @@ -100,6 +100,10 @@ namespace OpenTK.Platform.Windows { [DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity] //internal static extern bool ScreenToClient(IntPtr hWnd, ref POINT point); internal static extern bool ScreenToClient(IntPtr hWnd, ref Point point); + + [DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity] + //internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT point); + internal static extern bool ClientToScreen(IntPtr hWnd, ref Point point); [DllImport("user32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity] internal extern static bool GetClientRect(IntPtr windowHandle, out Win32Rectangle clientRectangle); diff --git a/OpenTK/Platform/Windows/WinGLContext.cs b/OpenTK/Platform/Windows/WinGLContext.cs index 98ed0a1aa..5067b731e 100644 --- a/OpenTK/Platform/Windows/WinGLContext.cs +++ b/OpenTK/Platform/Windows/WinGLContext.cs @@ -16,7 +16,7 @@ namespace OpenTK.Platform.Windows { /// Provides methods to create and control an opengl context on the Windows platform. /// This class supports OpenTK, and is not intended for use by OpenTK programs. /// - internal sealed class WinGLContext : GraphicsContextBase + internal sealed class WinGLContext : IGraphicsContext { static IntPtr opengl32Handle; const string opengl32Name = "OPENGL32.DLL"; @@ -162,28 +162,13 @@ namespace OpenTK.Platform.Windows { } protected override void Dispose(bool calledManually) { - if (IsDisposed) return; - - if (calledManually) { - DestroyContext(); - } else { - Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?", ContextHandle); - } - IsDisposed = true; - } - - private void DestroyContext() { if (ContextHandle == IntPtr.Zero) return; - try { + if (calledManually) { // This will fail if the user calls Dispose() on thread X when the context is current on thread Y. - if (!Wgl.wglDeleteContext(ContextHandle)) - Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}", - ContextHandle.ToString(), Marshal.GetLastWin32Error()); - } catch (AccessViolationException e) { - Debug.Print("An access violation occured while destroying the OpenGL context. Please report at http://www.opentk.com."); - Debug.Print("Marshal.GetLastWin32Error(): {0}", Marshal.GetLastWin32Error().ToString()); - Debug.Print(e.ToString()); + Wgl.wglDeleteContext(ContextHandle); + } else { + Debug.Print("=== [Warning] OpenGL context leaked ==="); } ContextHandle = IntPtr.Zero; } diff --git a/OpenTK/Platform/Windows/WinWindow.cs b/OpenTK/Platform/Windows/WinWindow.cs index 307f632c4..0db991b92 100644 --- a/OpenTK/Platform/Windows/WinWindow.cs +++ b/OpenTK/Platform/Windows/WinWindow.cs @@ -58,7 +58,6 @@ namespace OpenTK.Platform.Windows static readonly WinKeyMap KeyMap = new WinKeyMap(); const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys. - KeyPressEventArgs key_press = new KeyPressEventArgs(); public WinWindow(int x, int y, int width, int height, string title, DisplayDevice device) { WindowProcedureDelegate = WindowProcedure; @@ -85,8 +84,8 @@ namespace OpenTK.Platform.Windows bool new_focused_state = Focused; focused = (wParam.ToInt64() & 0xFFFF) != 0; - if (new_focused_state != Focused && FocusedChanged != null) - FocusedChanged(this, EventArgs.Empty); + if (new_focused_state != Focused) + RaiseFocusedChanged(); break; case WindowMessage.ENTERMENULOOP: @@ -104,8 +103,7 @@ namespace OpenTK.Platform.Windows Point new_location = new Point(pos->x, pos->y); if (Location != new_location) { bounds.Location = new_location; - if (Move != null) - Move(this, EventArgs.Empty); + RaiseMove(); } Size new_size = new Size(pos->cx, pos->cy); @@ -121,8 +119,8 @@ namespace OpenTK.Platform.Windows bounds.X, bounds.Y, bounds.Width, bounds.Height, SetWindowPosFlags.NOZORDER | SetWindowPosFlags.NOOWNERZORDER | SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING); - if (suppress_resize <= 0 && Resize != null) - Resize(this, EventArgs.Empty); + + if (suppress_resize <= 0) RaiseResize(); } } break; @@ -150,8 +148,7 @@ namespace OpenTK.Platform.Windows if (new_state != windowState) { windowState = new_state; - if (WindowStateChanged != null) - WindowStateChanged(this, EventArgs.Empty); + RaiseWindowStateChanged(); } break; @@ -160,10 +157,7 @@ namespace OpenTK.Platform.Windows #region Input events case WindowMessage.CHAR: - key_press.KeyChar = (char)wParam.ToInt64(); - - if (KeyPress != null) - KeyPress(this, key_press); + RaiseKeyPress((char)wParam.ToInt64()); break; case WindowMessage.MOUSEMOVE: @@ -309,27 +303,16 @@ namespace OpenTK.Platform.Windows break; case WindowMessage.CLOSE: - System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs(); - - if (Closing != null) - Closing(this, e); - - if (!e.Cancel) { - DestroyWindow(); - break; - } - - return IntPtr.Zero; + RaiseClosing(); + DestroyWindow(); + break; case WindowMessage.DESTROY: exists = false; API.UnregisterClass(ClassName, Instance); window.Dispose(); - - if (Closed != null) - Closed(this, EventArgs.Empty); - + RaiseClosed(); break; #endregion @@ -409,7 +392,7 @@ namespace OpenTK.Platform.Windows const uint GMEM_MOVEABLE = 2; const uint CF_UNICODETEXT = 13, CF_TEXT = 1; - public unsafe string GetClipboardText() { + public override unsafe string GetClipboardText() { // retry up to 10 times for (int i = 0; i < 10; i++) { if (!API.OpenClipboard(window.winHandle)) { @@ -435,7 +418,7 @@ namespace OpenTK.Platform.Windows return ""; } - public unsafe void SetClipboardText( string value ) { + public override unsafe void SetClipboardText( string value ) { UIntPtr dstSize = (UIntPtr)((value.Length + 1) * Marshal.SystemDefaultCharSize); // retry up to 10 times for (int i = 0; i < 10; i++) { @@ -466,7 +449,7 @@ namespace OpenTK.Platform.Windows dst2[numChars] = '\0'; } - public Rectangle Bounds { + public override Rectangle Bounds { get { return bounds; } set { // Note: the bounds variable is updated when the resize/move message arrives. @@ -474,7 +457,7 @@ namespace OpenTK.Platform.Windows } } - public Point Location { + public override Point Location { get { return Bounds.Location; } set { // Note: the bounds variable is updated when the resize/move message arrives. @@ -482,7 +465,7 @@ namespace OpenTK.Platform.Windows } } - public Size Size { + public override Size Size { get { return Bounds.Size; } set { // Note: the bounds variable is updated when the resize/move message arrives. @@ -490,7 +473,7 @@ namespace OpenTK.Platform.Windows } } - public Rectangle ClientRectangle { + public override Rectangle ClientRectangle { get { if (client_rectangle.Width == 0) client_rectangle.Width = 1; @@ -502,7 +485,7 @@ namespace OpenTK.Platform.Windows } } - public Size ClientSize { + public override Size ClientSize { get { return ClientRectangle.Size; } set { WindowStyle style = (WindowStyle)API.GetWindowLong(window.winHandle, GetWindowLongOffsets.STYLE); @@ -512,7 +495,7 @@ namespace OpenTK.Platform.Windows } } - public Icon Icon { + public override Icon Icon { get { return icon; } set { icon = value; @@ -526,11 +509,11 @@ namespace OpenTK.Platform.Windows } } - public bool Focused { + public override bool Focused { get { return focused; } } - public bool Visible { + public override bool Visible { get { return API.IsWindowVisible(window.winHandle); } set { if (value) { @@ -545,13 +528,13 @@ namespace OpenTK.Platform.Windows } } - public bool Exists { get { return exists; } } + public override bool Exists { get { return exists; } } - public void Close() { + public override void Close() { API.PostMessage(window.winHandle, WindowMessage.CLOSE, IntPtr.Zero, IntPtr.Zero); } - public WindowState WindowState { + public override WindowState WindowState { get { return windowState; } set { if (WindowState == value) @@ -648,7 +631,7 @@ namespace OpenTK.Platform.Windows } } - public Point PointToClient(Point point) { + public override Point PointToClient(Point point) { if (!API.ScreenToClient(window.winHandle, ref point)) throw new InvalidOperationException(String.Format( "Could not convert point {0} from client to screen coordinates. Windows error: {1}", @@ -656,25 +639,18 @@ namespace OpenTK.Platform.Windows return point; } + + public override Point PointToScreen(Point point) { + if (!API.ClientToScreen(window.winHandle, ref point)) + throw new InvalidOperationException(String.Format( + "Could not convert point {0} from client to screen coordinates. Windows error: {1}", + point.ToString(), Marshal.GetLastWin32Error())); - public Point PointToScreen(Point p) { - throw new NotImplementedException(); + return point; } - public event EventHandler Move; - public event EventHandler Resize; - public event EventHandler Closing; - public event EventHandler Closed; - public event EventHandler Disposed; - public event EventHandler IconChanged; - public event EventHandler ClientSizeChanged; - public event EventHandler VisibleChanged; - public event EventHandler FocusedChanged; - public event EventHandler WindowStateChanged; - public event EventHandler KeyPress; - MSG msg; - public void ProcessEvents() { + public override void ProcessEvents() { while( API.PeekMessage(ref msg, IntPtr.Zero, 0, 0, 1) ) { API.TranslateMessage(ref msg); API.DispatchMessage(ref msg); @@ -684,11 +660,11 @@ namespace OpenTK.Platform.Windows focused = foreground == window.winHandle; } - public IWindowInfo WindowInfo { + public override IWindowInfo WindowInfo { get { return window; } } - public Point DesktopCursorPos { + public override Point DesktopCursorPos { get { POINT pos = default( POINT ); API.GetCursorPos( ref pos ); @@ -698,7 +674,7 @@ namespace OpenTK.Platform.Windows } bool cursorVisible = true; - public bool CursorVisible { + public override bool CursorVisible { get { return cursorVisible; } set { cursorVisible = value; @@ -706,27 +682,17 @@ namespace OpenTK.Platform.Windows } } - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - void Dispose(bool calledManually) { - if (!disposed) { - if (calledManually) { - // Safe to clean managed resources - DestroyWindow(); - if (Icon != null) - Icon.Dispose(); - } else { - Debug.Print("[Warning] INativeWindow leaked ({0}). Did you forget to call INativeWindow.Dispose()?", this); - } - disposed = true; + protected override void Dispose(bool calledManually) { + if (disposed) return; + + if (calledManually) { + // Safe to clean managed resources + DestroyWindow(); + if (Icon != null) Icon.Dispose(); + } else { + Debug.Print("=== [Warning] INativeWindow leaked ==="); } - } - - ~WinWindow() { - Dispose(false); + disposed = true; } } } diff --git a/OpenTK/Platform/X11/X11GLContext.cs b/OpenTK/Platform/X11/X11GLContext.cs index 44608cccc..ca5666cc8 100644 --- a/OpenTK/Platform/X11/X11GLContext.cs +++ b/OpenTK/Platform/X11/X11GLContext.cs @@ -13,7 +13,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. - internal sealed class X11GLContext : GraphicsContextBase { + internal sealed class X11GLContext : IGraphicsContext { IntPtr Display; X11WindowInfo currentWindow; @@ -28,7 +28,7 @@ namespace OpenTK.Platform.X11 { Debug.Print( "Creating X11GLContext context: " ); currentWindow = (X11WindowInfo)window; - Display = API.DefaultDisplay; + Display = API.DefaultDisplay; XVisualInfo info = currentWindow.VisualInfo; Mode = GetGraphicsMode( info ); // Cannot pass a Property by reference. @@ -105,19 +105,18 @@ namespace OpenTK.Platform.X11 { } protected override void Dispose(bool manuallyCalled) { - if (!IsDisposed) { - if (manuallyCalled) { - IntPtr display = Display; - - if (IsCurrent) { - Glx.glXMakeCurrent(display, IntPtr.Zero, IntPtr.Zero); - } - Glx.glXDestroyContext(display, ContextHandle); + if (ContextHandle == IntPtr.Zero) return; + + if (manuallyCalled) { + IntPtr display = Display; + if (IsCurrent) { + Glx.glXMakeCurrent(display, IntPtr.Zero, IntPtr.Zero); } + Glx.glXDestroyContext(display, ContextHandle); } else { - Debug.Print("[Warning] {0} leaked.", this.GetType().Name); + Debug.Print("=== [Warning] OpenGL context leaked ==="); } - IsDisposed = true; + ContextHandle = IntPtr.Zero; } internal static GraphicsMode SelectGraphicsMode( GraphicsMode template, out XVisualInfo info ) { @@ -153,7 +152,7 @@ namespace OpenTK.Platform.X11 { static unsafe IntPtr SelectVisual( int[] visualAttribs ) { int major = 0, minor = 0; if( !Glx.glXQueryVersion( API.DefaultDisplay, ref major, ref minor ) ) - throw new InvalidOperationException( "glXQueryVersion failed, potentially corrupt OpenGL driver" ); + throw new InvalidOperationException( "glXQueryVersion failed, potentially corrupt OpenGL driver" ); int screen = API.XDefaultScreen( API.DefaultDisplay ); if( major >= 1 && minor >= 3 ) { diff --git a/OpenTK/Platform/X11/X11Window.cs b/OpenTK/Platform/X11/X11Window.cs index 2936ae4e5..89291ee8d 100644 --- a/OpenTK/Platform/X11/X11Window.cs +++ b/OpenTK/Platform/X11/X11Window.cs @@ -77,7 +77,6 @@ namespace OpenTK.Platform.X11 { // Keyboard input readonly byte[] ascii = new byte[16]; readonly char[] chars = new char[16]; - readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs(); X11KeyMap keymap = new X11KeyMap(); int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server. @@ -145,7 +144,7 @@ namespace OpenTK.Platform.X11 { e.ConfigureEvent.height = height; RefreshWindowBounds(ref e); - Debug.Print("X11GLNative window created successfully (id: {0}).", Handle); + Debug.Print("X11GLNative window created successfully (id: {0}).", window.WindowHandle); SetupInput(); exists = true; } @@ -279,8 +278,7 @@ namespace OpenTK.Platform.X11 { Point newLoc = new Point(e.ConfigureEvent.x - borderLeft, e.ConfigureEvent.y - borderTop); if (Location != newLoc) { bounds.Location = newLoc; - if (Move != null) - Move(this, EventArgs.Empty); + RaiseMove(); } // Note: width and height denote the internal (client) size. @@ -288,13 +286,11 @@ namespace OpenTK.Platform.X11 { Size newSize = new Size( e.ConfigureEvent.width + borderLeft + borderRight, e.ConfigureEvent.height + borderTop + borderBottom); + if (bounds.Size != newSize) { bounds.Size = newSize; client_rectangle.Size = new Size(e.ConfigureEvent.width, e.ConfigureEvent.height); - - if (this.Resize != null) { - Resize(this, EventArgs.Empty); - } + RaiseResize(); } } @@ -305,7 +301,7 @@ namespace OpenTK.Platform.X11 { API.XCheckTypedWindowEvent(window.Display, window.WindowHandle, XEventName.SelectionRequest, ref e); } - public unsafe void ProcessEvents() { + public override unsafe void ProcessEvents() { // Process all pending events while (Exists && window != null) { if (!GetPendingEvent ()) break; @@ -318,8 +314,7 @@ namespace OpenTK.Platform.X11 { bool previous_visible = visible; visible = e.type == XEventName.MapNotify; if (visible != previous_visible) - if (VisibleChanged != null) - VisibleChanged(this, EventArgs.Empty); + RaiseVisibleChanged(); } break; case XEventName.CreateNotify: @@ -329,17 +324,11 @@ namespace OpenTK.Platform.X11 { case XEventName.ClientMessage: if (!isExiting && e.ClientMessageEvent.ptr1 == wm_destroy) { Debug.Print("Exit message received."); - CancelEventArgs ce = new CancelEventArgs(); - if (Closing != null) - Closing(this, ce); - - if (!ce.Cancel) { - isExiting = true; - - DestroyWindow(); - if (Closed != null) - Closed(this, EventArgs.Empty); - } + RaiseClosing(); + + isExiting = true; + DestroyWindow(); + RaiseClosed(); } break; case XEventName.DestroyNotify: @@ -357,15 +346,10 @@ namespace OpenTK.Platform.X11 { int status = API.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero); Encoding.Default.GetChars(ascii, 0, status, chars, 0); - EventHandler key_press = KeyPress; - if (key_press != null) { - for (int i = 0; i < status; i++) { - // ignore NULL char after non-ASCII input char, like ä or å on Finnish keyboard layout - if (chars[i] == '\0') continue; - - KPEventArgs.KeyChar = chars[i]; - key_press(this, KPEventArgs); - } + for (int i = 0; i < status; i++) { + // ignore NULL char after non-ASCII input char, like ä or å on Finnish keyboard layout + if (chars[i] == '\0') continue; + RaiseKeyPress(chars[i]); } break; @@ -402,8 +386,8 @@ namespace OpenTK.Platform.X11 { { bool previous_focus = has_focus; has_focus = e.type == XEventName.FocusIn; - if (has_focus != previous_focus && FocusedChanged != null) - FocusedChanged(this, EventArgs.Empty); + if (has_focus != previous_focus) + RaiseFocusedChanged(); } break; case XEventName.MappingNotify: @@ -416,8 +400,7 @@ namespace OpenTK.Platform.X11 { case XEventName.PropertyNotify: if (e.PropertyEvent.atom == net_wm_state) { - if (WindowStateChanged != null) - WindowStateChanged (this, EventArgs.Empty); + RaiseWindowStateChanged(); } //if (e.PropertyEvent.atom == net_frame_extents) { @@ -494,7 +477,7 @@ namespace OpenTK.Platform.X11 { return e.SelectionRequestEvent.target; } - public string GetClipboardText() { + public override string GetClipboardText() { IntPtr owner = API.XGetSelectionOwner(window.Display, xa_clipboard); if (owner == IntPtr.Zero) return ""; // no window owner @@ -510,12 +493,12 @@ namespace OpenTK.Platform.X11 { return ""; } - public void SetClipboardText(string value) { + public override void SetClipboardText(string value) { clipboard_copy_text = value; API.XSetSelectionOwner(window.Display, xa_clipboard, window.WinHandle, IntPtr.Zero); } - public Rectangle Bounds { + public override Rectangle Bounds { get { return bounds; } set { API.XMoveResizeWindow( @@ -525,7 +508,7 @@ namespace OpenTK.Platform.X11 { } } - public Point Location { + public override Point Location { get { return Bounds.Location; } set { API.XMoveWindow(window.Display, window.WindowHandle, value.X, value.Y); @@ -533,7 +516,7 @@ namespace OpenTK.Platform.X11 { } } - public Size Size { + public override Size Size { get { return Bounds.Size; } set { int width = value.Width - borderLeft - borderRight; @@ -545,7 +528,7 @@ namespace OpenTK.Platform.X11 { } } - public Rectangle ClientRectangle { + public override Rectangle ClientRectangle { get { if (client_rectangle.Width == 0) client_rectangle.Width = 1; @@ -559,12 +542,12 @@ namespace OpenTK.Platform.X11 { } } - public Size ClientSize { + public override Size ClientSize { get { return ClientRectangle.Size; } set { ClientRectangle = new Rectangle(Point.Empty, value); } } - public Icon Icon { + public override Icon Icon { get { return icon; } set { if (value == icon) @@ -615,11 +598,11 @@ namespace OpenTK.Platform.X11 { } } - public bool Focused { + public override bool Focused { get { return has_focus; } } - public WindowState WindowState { + public override WindowState WindowState { get { IntPtr actual_atom, nitems, bytes_after, prop = IntPtr.Zero; int actual_format; @@ -709,19 +692,7 @@ namespace OpenTK.Platform.X11 { } } - public event EventHandler Load; - public event EventHandler Unload; - public event EventHandler Move; - public event EventHandler Resize; - public event EventHandler Closing; - public event EventHandler Closed; - public event EventHandler Disposed; - public event EventHandler VisibleChanged; - public event EventHandler FocusedChanged; - public event EventHandler WindowStateChanged; - public event EventHandler KeyPress; - - public Point DesktopCursorPos { + public override Point DesktopCursorPos { get { IntPtr root, child; int rootX, rootY, childX, childY, mask; @@ -735,7 +706,7 @@ namespace OpenTK.Platform.X11 { } bool cursorVisible = true; - public bool CursorVisible { + public override bool CursorVisible { get { return cursorVisible; } set { cursorVisible = value; @@ -758,16 +729,11 @@ namespace OpenTK.Platform.X11 { } /// Returns true if a render window/context exists. - public bool Exists { + public override bool Exists { get { return exists; } } - /// Gets the current window handle. - public IntPtr Handle { - get { return window.WindowHandle; } - } - - public bool Visible { + public override bool Visible { get { return visible; } set { if (value && !visible) { @@ -778,11 +744,11 @@ namespace OpenTK.Platform.X11 { } } - public IWindowInfo WindowInfo { + public override IWindowInfo WindowInfo { get { return window; } } - public void Close() { + public override void Close() { XEvent ev = new XEvent(); ev.type = XEventName.ClientMessage; ev.ClientMessageEvent.format = 32; @@ -794,33 +760,28 @@ namespace OpenTK.Platform.X11 { API.XFlush(window.Display); } - public void DestroyWindow() { + void DestroyWindow() { Debug.Print("X11GLNative shutdown sequence initiated."); API.XSync(window.Display, true); API.XDestroyWindow(window.Display, window.WindowHandle); exists = false; } - public Point PointToClient(Point point) { + public override Point PointToClient(Point point) { int ox, oy; IntPtr child; API.XTranslateCoordinates(window.Display, window.RootWindow, window.WindowHandle, point.X, point.Y, out ox, out oy, out child); return new Point( ox, oy ); } - public Point PointToScreen(Point point) { + public override Point PointToScreen(Point point) { int ox, oy; IntPtr child; API.XTranslateCoordinates(window.Display, window.WindowHandle, window.RootWindow, point.X, point.Y, out ox, out oy, out child); return new Point( ox, oy ); } - public void Dispose() { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool manuallyCalled) { + protected override void Dispose(bool manuallyCalled) { if (disposed) return; if (manuallyCalled) { if (window != null && window.WindowHandle != IntPtr.Zero) { @@ -831,13 +792,9 @@ namespace OpenTK.Platform.X11 { window = null; } } else { - Debug.Print("[Warning] {0} leaked.", this.GetType().Name); + Debug.Print("=== [Warning] INativeWindow leaked ==="); } disposed = true; } - - ~X11Window() { - this.Dispose(false); - } } } \ No newline at end of file diff --git a/OpenTK/SharpDX.Direct3D/Structures.cs b/OpenTK/SharpDX.Direct3D/Structures.cs index 93f09a7e9..bb43b00a6 100644 --- a/OpenTK/SharpDX.Direct3D/Structures.cs +++ b/OpenTK/SharpDX.Direct3D/Structures.cs @@ -24,7 +24,21 @@ using System.Runtime.InteropServices; namespace SharpDX.Direct3D9 { [StructLayout(LayoutKind.Sequential)] - public struct PresentParameters { + public struct LockedRectangle { + public int Pitch; + public IntPtr DataPointer; + } + + [StructLayout(LayoutKind.Sequential)] + public struct D3DRect { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PresentParameters { public int BackBufferWidth; public int BackBufferHeight; public Format BackBufferFormat; @@ -33,8 +47,8 @@ namespace SharpDX.Direct3D9 { public int MultiSampleQuality; public SwapEffect SwapEffect; public IntPtr DeviceWindowHandle; - public RawBool Windowed; - public RawBool EnableAutoDepthStencil; + public int Windowed; + public int EnableAutoDepthStencil; public Format AutoDepthStencilFormat; public PresentFlags PresentFlags; public int FullScreenRefreshRateInHz; diff --git a/OpenTK/SharpDX/Raw.cs b/OpenTK/SharpDX/Raw.cs deleted file mode 100644 index c750e7c19..000000000 --- a/OpenTK/SharpDX/Raw.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Runtime.InteropServices; - -namespace SharpDX { - - [StructLayout(LayoutKind.Sequential, Size = 4)] - public struct RawBool { - private int boolValue; - - public RawBool(bool boolValue) { - this.boolValue = boolValue ? 1 : 0; - } - - public static implicit operator bool(RawBool booleanValue) { - return booleanValue.boolValue != 0; - } - - public static implicit operator RawBool(bool boolValue) { - return new RawBool(boolValue); - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct LockedRectangle { - - /// Gets the number of bytes per row. - public int Pitch; - - /// Pointer to the data. - public IntPtr DataPointer; - } - - [StructLayout(LayoutKind.Sequential)] - public struct D3DRect { - public int Left; - public int Top; - public int Right; - public int Bottom; - } -}