From fdd693a4f113e0e55352c0a191f6a78216c1f7f9 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Tue, 17 Oct 2006 19:34:49 +0000 Subject: [PATCH] Framework: Updates to mode switching under windows plus a little refactoring. --- OpenTK.sln | 10 ++ Source/Examples/OpenGL/GLSL/Lesson01/Cube.cs | 6 +- Source/Framework/Framework.cs | 71 ++++++++++---- Source/Framework/FrameworkImplementation.cs | 3 +- Source/Framework/OpenTK.Framework.csproj | 3 - Source/Framework/WindowsImplementation.cs | 99 ++++++++++---------- Source/Framework/X11Implementation.cs | 5 - Source/OpenGL/OpenGL/Bindings/GL.cs | 1 - Source/OpenGL/OpenGL/Structures.cs | 35 +++++++ Source/Platform/Windows/WinAPI.cs | 35 +++++-- changelog.txt | 12 ++- todo.txt | 13 +-- 12 files changed, 191 insertions(+), 102 deletions(-) diff --git a/OpenTK.sln b/OpenTK.sln index b04391c8..2edc5f46 100644 --- a/OpenTK.sln +++ b/OpenTK.sln @@ -65,6 +65,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Specifications", "Specifica Source\OpenGL\Specifications\wglext.spec = Source\OpenGL\Specifications\wglext.spec EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{91C9E74A-12CE-4770-82F4-C257CC4A4046}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GLSL.Lesson02", "Source\Examples\OpenGL\GLSL\Lesson02\GLSL.Lesson02.csproj", "{8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -95,6 +99,10 @@ Global {26B55626-4EAB-4CAE-82FE-93CD6564D9EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {26B55626-4EAB-4CAE-82FE-93CD6564D9EA}.Release|Any CPU.ActiveCfg = Release|Any CPU {26B55626-4EAB-4CAE-82FE-93CD6564D9EA}.Release|Any CPU.Build.0 = Release|Any CPU + {8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,7 +122,9 @@ Global {1EDDE592-3923-4898-9006-3D69579E1745} = {2F3FEAD4-0FBD-48CC-AFA0-29FFF28284C2} {D26F26AC-2154-4900-93EB-66E5A7761D05} = {2F3FEAD4-0FBD-48CC-AFA0-29FFF28284C2} {70FA6EE8-62C6-437F-AD82-117F2D9CDE68} = {C6E60A87-12B4-444A-BE03-7E980EAC0172} + {91C9E74A-12CE-4770-82F4-C257CC4A4046} = {C6E60A87-12B4-444A-BE03-7E980EAC0172} {46980D11-67FA-4B33-903F-BC9D8A4FE60F} = {70FA6EE8-62C6-437F-AD82-117F2D9CDE68} + {8814A9FE-F6B2-4BE1-82D5-1E9F02BD9B4B} = {70FA6EE8-62C6-437F-AD82-117F2D9CDE68} {26B55626-4EAB-4CAE-82FE-93CD6564D9EA} = {508EF114-8C2A-470D-89FE-5AC15B336B4C} EndGlobalSection EndGlobal diff --git a/Source/Examples/OpenGL/GLSL/Lesson01/Cube.cs b/Source/Examples/OpenGL/GLSL/Lesson01/Cube.cs index c706b625..83a468f1 100644 --- a/Source/Examples/OpenGL/GLSL/Lesson01/Cube.cs +++ b/Source/Examples/OpenGL/GLSL/Lesson01/Cube.cs @@ -17,9 +17,10 @@ using OpenTK.OpenGL; namespace OpenTK.Examples.OpenGL.GLSL { - public partial class Cube : OpenTK.Frameworks.Framework + public class Cube : OpenTK.Frameworks.Framework { #region Shaders + string[] vertex_shader_source = { "void main() {", @@ -32,6 +33,7 @@ namespace OpenTK.Examples.OpenGL.GLSL { "void main() { gl_FragColor = gl_Color; }\0" }; + #endregion static float angle; @@ -153,7 +155,7 @@ namespace OpenTK.Examples.OpenGL.GLSL break; case Keys.F1: - //this.Fullscreen = !this.Fullscreen; + this.SetResolution(this.Width, this.Height, this.ColorDepth, !this.Fullscreen); break; } } diff --git a/Source/Framework/Framework.cs b/Source/Framework/Framework.cs index 8b7c42c5..a90103cb 100644 --- a/Source/Framework/Framework.cs +++ b/Source/Framework/Framework.cs @@ -28,7 +28,7 @@ namespace OpenTK.Frameworks public GLContext Context { get { return _context; } - protected set { _context = value; } + private set { _context = value; } } #endregion @@ -52,7 +52,7 @@ namespace OpenTK.Frameworks public OpenTK.OpenGL.ColorDepth ColorDepth { get { return _color_depth; } - set { _color_depth = value; } + private set { _color_depth = value; } } #endregion @@ -64,7 +64,7 @@ namespace OpenTK.Frameworks public int ZDepth { get { return _z_depth; } - set { _z_depth = value; } + private set { _z_depth = value; } } #endregion @@ -76,7 +76,7 @@ namespace OpenTK.Frameworks public int StencilDepth { get { return _stencil_depth; } - set { _stencil_depth = value; } + private set { _stencil_depth = value; } } #endregion @@ -88,7 +88,7 @@ namespace OpenTK.Frameworks public Size DesktopResolution { get { return _desktop_resolution; } - protected set { _desktop_resolution = value; } + private set { _desktop_resolution = value; } } #endregion @@ -100,7 +100,19 @@ namespace OpenTK.Frameworks public float DesktopRefreshRate { get { return _desktop_refresh_rate; } - protected set { _desktop_refresh_rate = value; } + private set { _desktop_refresh_rate = value; } + } + + #endregion + + #region DesktopColorDepth property + + private OpenTK.OpenGL.ColorDepth _desktop_color_depth; + + public OpenTK.OpenGL.ColorDepth DesktopColorDepth + { + get { return _desktop_color_depth; } + private set { _desktop_color_depth = value; } } #endregion @@ -113,7 +125,7 @@ namespace OpenTK.Frameworks public Framework() { - Setup(null, 640, 480, new OpenTK.OpenGL.ColorDepth(8, 8, 8, 8), 16, 0, false); + Setup(null, 800, 600, new OpenTK.OpenGL.ColorDepth(8, 8, 8, 8), 16, 0, false); } @@ -124,13 +136,10 @@ namespace OpenTK.Frameworks #endregion - public void Setup(string title, int width, int height, OpenTK.OpenGL.ColorDepth color, int depth, int stencil, bool fullscreen) + #region Setup(string title, int width, int height, OpenTK.OpenGL.ColorDepth color, int depth, int stencil, bool fullscreen) + + private void Setup(string title, int width, int height, OpenTK.OpenGL.ColorDepth color, int depth, int stencil, bool fullscreen) { - // Initialise components. - ColorDepth = color; - ZDepth = depth; - StencilDepth = stencil; - // Set platform. try { @@ -140,7 +149,8 @@ namespace OpenTK.Frameworks } else if (Environment.OSVersion.Platform == PlatformID.Unix) { - Implementation = new X11Implementation(); + //Implementation = new X11Implementation(); + throw new PlatformNotSupportedException("The platform on which you are trying to run this program is not currently supported. Sorry for the inconvenience."); } else { @@ -162,6 +172,11 @@ namespace OpenTK.Frameworks // //Context.MakeCurrent(); //} + // Initialise components. + ColorDepth = color; + ZDepth = depth; + StencilDepth = stencil; + Context = GLContext.Create(this, color, depth, stencil); // Code taken from NeHe tutorials @@ -172,9 +187,7 @@ namespace OpenTK.Frameworks //this.SetStyle(ControlStyles.ResizeRedraw, true); // Redraw On Resize this.SetStyle(ControlStyles.UserPaint, true); // We'll Handle Painting Ourselves - this.Size = new Size(width, height); - Fullscreen = Implementation.SetResolution(fullscreen); - this.Size = new Size(width, height); // Force the window to change to the requested resolution. + Implementation.SetResolution(width, height, color, fullscreen); if (title == null) title = "OpenTK Windows application"; @@ -183,6 +196,8 @@ namespace OpenTK.Frameworks Application.Idle += new EventHandler(OnIdle); } + #endregion + #region Event Handlers /// @@ -194,14 +209,32 @@ namespace OpenTK.Frameworks { while (Implementation.IsIdle()) { - if (ActiveForm != this) - Thread.Sleep(100); + //if (ActiveForm != this) + // Thread.Sleep(100); OnPaint(null); } } #endregion + #region Public member functions + + /// + /// Requests mode change. The parameters are hints for the mode, which may or may not be + /// possible according to the hardware. + /// + /// The horizontal resolution in pixels. + /// The vertical resolution in pixels. + /// The color depth. + /// Set to true to set a fullscreen mode or false to set a windowed mode. + /// True if the mode set was fullscreen, false otherwise. + public void SetResolution(int width, int height, OpenTK.OpenGL.ColorDepth color, bool fullscreen) + { + Implementation.SetResolution(width, height, color, fullscreen); + } + + #endregion + #region IDisposable Members void IDisposable.Dispose() diff --git a/Source/Framework/FrameworkImplementation.cs b/Source/Framework/FrameworkImplementation.cs index 820543ac..590ae5e5 100644 --- a/Source/Framework/FrameworkImplementation.cs +++ b/Source/Framework/FrameworkImplementation.cs @@ -19,8 +19,7 @@ namespace OpenTK.Frameworks public abstract bool IsIdle(); public abstract void Setup(); //abstract public void CloseWindow(); - public abstract bool SetResolution(int width, int height, OpenTK.OpenGL.ColorDepth color, bool fullscreen); - public abstract bool SetResolution(bool fullscreen); + public abstract void SetResolution(int width, int height, OpenTK.OpenGL.ColorDepth color, bool fullscreen); } } } diff --git a/Source/Framework/OpenTK.Framework.csproj b/Source/Framework/OpenTK.Framework.csproj index 3ac5840e..46e5bbca 100644 --- a/Source/Framework/OpenTK.Framework.csproj +++ b/Source/Framework/OpenTK.Framework.csproj @@ -47,9 +47,6 @@ Form - - Form - diff --git a/Source/Framework/WindowsImplementation.cs b/Source/Framework/WindowsImplementation.cs index c81a25fa..0dca3178 100644 --- a/Source/Framework/WindowsImplementation.cs +++ b/Source/Framework/WindowsImplementation.cs @@ -48,20 +48,41 @@ namespace OpenTK.Frameworks override public void Setup() { + Api.DeviceMode device_mode = new Api.DeviceMode(); + Api.EnumDisplaySettings(null, Api.Constants.ENUM_REGISTRY_SETTINGS, device_mode); + + framework.DesktopResolution = new Size(device_mode.PelsWidth, device_mode.PelsHeight); + framework.DesktopRefreshRate = device_mode.DisplayFrequency; + framework.DesktopColorDepth = new OpenTK.OpenGL.ColorDepth(device_mode.BitsPerPel); } - public override bool SetResolution(int width, int height, OpenTK.OpenGL.ColorDepth color, bool fullscreen) + public override void SetResolution(int width, int height, OpenTK.OpenGL.ColorDepth color, bool fullscreen) { + if (framework.Size == new Size(width, height) && framework.ColorDepth == color && framework.Fullscreen == fullscreen) + return; + + // If we want to change to a fullscreen mode if (fullscreen) { Application.Idle -= framework.OnIdle; - //framework.Context.Dispose(); - Api.DeviceMode ScreenSettings = new Api.DeviceMode(); // Device Mode - ScreenSettings.Size = (short)Marshal.SizeOf(ScreenSettings); // Size Of The Devmode Structure - ScreenSettings.PelsWidth = width; // Selected Screen Width - ScreenSettings.PelsHeight = height; // Selected Screen Height - ScreenSettings.BitsPerPel = color.Alpha + // Selected Bits Per Pixel + if (framework.WindowState == FormWindowState.Maximized) + { + Rectangle bounds = framework.RestoreBounds; + framework.WindowState = FormWindowState.Normal; + width = bounds.Width; + height = bounds.Height; + //framework.Size = new Size(bounds.Width, bounds.Height); + //framework.Bounds = new Rectangle(0, 0, bounds.Width, bounds.Height); + } + + //if (color != framework.ColorDepth) + // framework.Context.Dispose(); + + Api.DeviceMode ScreenSettings = new Api.DeviceMode(); + ScreenSettings.PelsWidth = width; // Selected Screen Width + ScreenSettings.PelsHeight = height; // Selected Screen Height + ScreenSettings.BitsPerPel = color.Alpha + // Selected Bits Per Pixel color.Red + color.Green + color.Blue; @@ -71,8 +92,10 @@ namespace OpenTK.Frameworks Application.Idle += framework.OnIdle; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. - if (Api.ChangeDisplaySettings(ref ScreenSettings, Api.Constants.CDS_FULLSCREEN) == Api.Constants.DISP_CHANGE_SUCCESSFUL) + if (Api.ChangeDisplaySettings(ScreenSettings, Api.Constants.CDS_FULLSCREEN) == Api.Constants.DISP_CHANGE_SUCCESSFUL) { + framework.Fullscreen = true; + framework.FormBorderStyle = FormBorderStyle.None; framework.StartPosition = FormStartPosition.Manual; framework.Location = new System.Drawing.Point(0, 0); @@ -82,60 +105,36 @@ namespace OpenTK.Frameworks Cursor.Hide(); framework.Size = new Size(width, height); - - return true; } else { - return false; + // If mode change wasn't possible. + framework.Fullscreen = false; + framework.Size = new Size(width, height); } } - - framework.Size = new Size(width, height); - - return false; - } - - public override bool SetResolution(bool fullscreen) - { - if (fullscreen) + else { - Application.Idle -= framework.OnIdle; - //framework.Context.Dispose(); + // If we already are in fullscreen mode and we want to change to windowed mode. - Api.DeviceMode ScreenSettings = new Api.DeviceMode(); // Device Mode - ScreenSettings.Size = (short)Marshal.SizeOf(ScreenSettings); // Size Of The Devmode Structure - ScreenSettings.PelsWidth = framework.Width; // Selected Screen Width - ScreenSettings.PelsHeight = framework.Height; // Selected Screen Height - ScreenSettings.BitsPerPel = framework.ColorDepth.Alpha + // Selected Bits Per Pixel - framework.ColorDepth.Red + - framework.ColorDepth.Green + - framework.ColorDepth.Blue; - ScreenSettings.Fields = Api.Constants.DM_BITSPERPEL | Api.Constants.DM_PELSWIDTH | Api.Constants.DM_PELSHEIGHT; - - //framework.Context = GLContext.Create(framework, framework.ColorDepth, 16, 0); - Application.Idle += framework.OnIdle; - - // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. - if (Api.ChangeDisplaySettings(ref ScreenSettings, Api.Constants.CDS_FULLSCREEN) == Api.Constants.DISP_CHANGE_SUCCESSFUL) + if (framework.Fullscreen) { - framework.FormBorderStyle = FormBorderStyle.None; - framework.StartPosition = FormStartPosition.Manual; - framework.Location = new System.Drawing.Point(0, 0); - //framework.Region = new Region(new Rectangle(0, 0, width, height)); - framework.Capture = true; + Application.Idle -= framework.OnIdle; + + // Restore display settings + Api.ChangeDisplaySettings(null, 0); + framework.FormBorderStyle = FormBorderStyle.Sizable; + framework.StartPosition = FormStartPosition.WindowsDefaultLocation; + framework.Capture = false; framework.SetTopLevel(true); - Cursor.Hide(); + Cursor.Show(); - return true; - } - else - { - return false; + Application.Idle += framework.OnIdle; } + + framework.Fullscreen = false; + framework.Size = new Size(width, height); } - - return false; } } } diff --git a/Source/Framework/X11Implementation.cs b/Source/Framework/X11Implementation.cs index d0ca699d..08d7c54b 100644 --- a/Source/Framework/X11Implementation.cs +++ b/Source/Framework/X11Implementation.cs @@ -48,11 +48,6 @@ namespace OpenTK.Frameworks { throw new Exception("The method or operation is not implemented."); } - - public override bool SetResolution(bool fullscreen) - { - throw new Exception("The method or operation is not implemented."); - } } } } diff --git a/Source/OpenGL/OpenGL/Bindings/GL.cs b/Source/OpenGL/OpenGL/Bindings/GL.cs index 82c89e13..b3d38ceb 100644 --- a/Source/OpenGL/OpenGL/Bindings/GL.cs +++ b/Source/OpenGL/OpenGL/Bindings/GL.cs @@ -17888,4 +17888,3 @@ namespace OpenTK.OpenGL #endregion static Constructor } } - diff --git a/Source/OpenGL/OpenGL/Structures.cs b/Source/OpenGL/OpenGL/Structures.cs index 352e623c..fb2ae0ff 100644 --- a/Source/OpenGL/OpenGL/Structures.cs +++ b/Source/OpenGL/OpenGL/Structures.cs @@ -12,6 +12,28 @@ namespace OpenTK.OpenGL public struct ColorDepth { + public ColorDepth(int bpp) + { + Red = Green = Blue = Alpha = 0; + + switch (bpp) + { + case 32: + Red = Green = Blue = Alpha = 8; + break; + case 24: + Red = Green = Blue = 8; + break; + case 16: + Red = Blue = 5; + Green = 6; + break; + case 15: + Red = Green = Blue = 5; + break; + } + } + public ColorDepth(byte red, byte green, byte blue, byte alpha) { Red = red; @@ -21,6 +43,19 @@ namespace OpenTK.OpenGL } public byte Red, Green, Blue, Alpha; + + public static bool operator ==(ColorDepth left, ColorDepth right) + { + return left.Red == right.Red && + left.Green == right.Green && + left.Blue == right.Blue && + left.Alpha == right.Alpha; + } + + public static bool operator !=(ColorDepth left, ColorDepth right) + { + return !(left == right); + } } #endregion diff --git a/Source/Platform/Windows/WinAPI.cs b/Source/Platform/Windows/WinAPI.cs index 4d082efa..1a6b53b0 100644 --- a/Source/Platform/Windows/WinAPI.cs +++ b/Source/Platform/Windows/WinAPI.cs @@ -56,6 +56,7 @@ namespace OpenTK.Platform.Windows public const int DISP_CHANGE_FAILED = -1; // (found in WinUSER.h) + public const int ENUM_REGISTRY_SETTINGS = -2; public const int ENUM_CURRENT_SETTINGS = -1; } #endregion @@ -400,10 +401,17 @@ namespace OpenTK.Platform.Windows /// /// [DllImport("user32.dll", SetLastError = true)] - public static extern int ChangeDisplaySettings(ref DeviceMode device_mode, int flags); + public static extern int ChangeDisplaySettings(DeviceMode device_mode, int flags); #endregion int ChangeDisplaySettings(ref Gdi.DEVMODE devMode, int flags) - + #region EnumDisplaySettings + + [DllImport("user32.dll", SetLastError = true)] + public static extern int EnumDisplaySettings([MarshalAs(UnmanagedType.LPTStr)] string device_name, int graphics_mode, DeviceMode device_mode); + + #endregion + + // *********** Never use GetLastError! ************ //#region GetLastError @@ -579,15 +587,21 @@ namespace OpenTK.Platform.Windows } #endregion - #region DeviceMode struct + #region DeviceMode class + [StructLayout(LayoutKind.Sequential)] - public struct DeviceMode + public class DeviceMode { + public DeviceMode() + { + Size = (short)Marshal.SizeOf(this); + } + [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string DeviceName; public short SpecVersion; public short DriverVersion; - public short Size; + private short Size; public short DriverExtra; public int Fields; public short Orientation; @@ -620,16 +634,21 @@ namespace OpenTK.Platform.Windows public int PanningWidth; public int PanningHeight; } - #endregion + + #endregion DeviceMode class #endregion - + + #region Callbacks + [UnmanagedFunctionPointerAttribute(CallingConvention.Winapi)] public delegate void WindowProcedureEventHandler(object sender, WindowProcedureEventArgs e); public class WindowProcedureEventArgs : EventArgs { - public System.Windows.Forms.Message Msg; + public Message Msg; } + + #endregion } } diff --git a/changelog.txt b/changelog.txt index 81518b57..061e3db2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,10 +3,16 @@ OpenTK 0.3.6 OpenTK 0.3.5 -> 0.3.6 + Updates to OpenTK.OpenGL.Bind (see that changelog for more info). - + Revamped GL class (is self contained) + + Revamped GL class (it is self contained now). + Revamped GLContext class (it is no longer bound to the GL class initialisation). -+ Directory structure updates (Documentation folder for each project, plus main Documentation folder) -+ Framework updates (cleaner implementation, new namespace). ++ Directory structure updates. + + Now every project has its own documentation. + + The spec files for OpenGL now reside in the Source/OpenTK/OpenGL directory. ++ Framework updates: + + Cleaner implementation. + + New namespace. + + Supports basic mode sswitching under windows (the code is not robust enough, yet). ++ Added very basic GLX and X bindings, just enough to create a basic OpenGL window. OpenTK 0.3.4 -> 0.3.5 diff --git a/todo.txt b/todo.txt index e75c2d76..5d096252 100644 --- a/todo.txt +++ b/todo.txt @@ -1,18 +1,13 @@ Todo: -+ + + Update directory structure (specs shouldn't reside in the top directory) ++ + + Restore the Extensions. + + + Fully implement Framework class. + + + Correct the Dispose methods to correctly clean resources (they should also call GC.SupressFinalize(true)) -+ + + Add basic GLX bindings (in progress) -+ + + Add basic X bindings (in progress) -+ + + Add context creation support for X (needs fixing) -+ + + Test X support. ++ + + Fix X support in the framework. + + + Add the CLS compliant attribute to the GL class. + + + Clean up the build system for windows .Net, and add build system for linux Mono and windows Mono. -+ + Add docs to each project. -+ + Add cross-platform way for defining the Application.Idle handler (needs testing) + + Probably something like Nant? ++ + Document projects (source and manuals). + + Add more constructors to the Context classes. -+ + Add comments and documentation (faqs, pitfalls, best practices). -+ + Add a cross-platform build system (probably NAnt?) + Add more examples. + Find out what is needed for the MacOS platform (how to do function loading and window management without X11). + Add full bindings for glu, wgl, glx and agl (probably generated automatically).