From a12b394607ede0444c58e5ce07473b6dacb88cce Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Fri, 8 Nov 2013 10:39:08 +0100 Subject: [PATCH 01/16] Load ES30 and OpenGL4 entry points --- OpenTK.sln | 115 +++++++++++------- .../Examples/OpenTK/Test/GameWindowStates.cs | 2 +- Source/OpenTK/Graphics/GraphicsContext.cs | 2 +- Source/OpenTK/Graphics/GraphicsMode.cs | 53 +------- .../OpenTK/Platform/DesktopGraphicsContext.cs | 2 + .../Platform/EmbeddedGraphicsContext.cs | 1 + 6 files changed, 82 insertions(+), 93 deletions(-) diff --git a/OpenTK.sln b/OpenTK.sln index 0c991156..9ab581b5 100644 --- a/OpenTK.sln +++ b/OpenTK.sln @@ -1,25 +1,52 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "Source\OpenTK\OpenTK.csproj", "{A37A7E14-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK.Compatibility", "Source\Compatibility\OpenTK.Compatibility.csproj", "{62C0DB35-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK.Examples", "Source\Examples\OpenTK.Examples.csproj", "{868E37B3-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK.GLControl", "Source\GLControl\OpenTK.GLControl.csproj", "{A625BE88-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build.Installer.Nsis", "Installers\Nsis\Build.Installer.Nsis.csproj", "{ADC34399-7613-44D2-90B2-19250F06FE7A}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build.Docs", "Documentation\Build.Docs.csproj", "{650C6F3D-33B5-4216-9536-956AB42C0624}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator.Bind", "Source\Bind\Generator.Bind.csproj", "{31D19132-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator.Convert", "Source\Converter\Generator.Convert.csproj", "{5FDFF4B6-0000-0000-0000-000000000000}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build.UpdateVersion", "Source\Build.UpdateVersion\Build.UpdateVersion.csproj", "{75DC22B1-113F-4A66-96B9-2FF8208C10E8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Build.Installer.Zip", "Installers\Zip\Build.Installer.Zip.csproj", "{ADC34399-7613-44D2-90B2-19250F06FE7B}" + ProjectSection(ProjectDependencies) = postProject + {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -29,6 +56,45 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {ADC34399-7613-44D2-90B2-19250F06FE7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ADC34399-7613-44D2-90B2-19250F06FE7A}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {ADC34399-7613-44D2-90B2-19250F06FE7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {650C6F3D-33B5-4216-9536-956AB42C0624}.Release|Any CPU.ActiveCfg = Release|Any CPU {31D19132-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {31D19132-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {31D19132-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -43,19 +109,6 @@ Global {5FDFF4B6-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FDFF4B6-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62C0DB35-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Documentation|Any CPU.Build.0 = Documentation|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {650C6F3D-33B5-4216-9536-956AB42C0624}.Release|Any CPU.ActiveCfg = Release|Any CPU {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -64,42 +117,16 @@ Global {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {75DC22B1-113F-4A66-96B9-2FF8208C10E8}.Release|Any CPU.Build.0 = Release|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {868E37B3-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {ADC34399-7613-44D2-90B2-19250F06FE7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ADC34399-7613-44D2-90B2-19250F06FE7A}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU - {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU - {ADC34399-7613-44D2-90B2-19250F06FE7A}.Nsis|Any CPU.Build.0 = Nsis|Any CPU - {ADC34399-7613-44D2-90B2-19250F06FE7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7B}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = Source\Examples\OpenTK.Examples.csproj - EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Source\Examples\OpenTK.Examples.csproj + EndGlobalSection EndGlobal diff --git a/Source/Examples/OpenTK/Test/GameWindowStates.cs b/Source/Examples/OpenTK/Test/GameWindowStates.cs index d5e0bf2d..eda29cce 100644 --- a/Source/Examples/OpenTK/Test/GameWindowStates.cs +++ b/Source/Examples/OpenTK/Test/GameWindowStates.cs @@ -30,7 +30,7 @@ namespace Examples.Tests public GameWindowStates() : base(800, 600, GraphicsMode.Default, "Test", GameWindowFlags.Default, - DisplayDevice.GetDisplay(DisplayIndex.Second), 3, 0, GraphicsContextFlags.Embedded) + DisplayDevice.GetDisplay(DisplayIndex.Second), 1, 0, GraphicsContextFlags.Embedded) { VSync = VSyncMode.On; Keyboard.KeyRepeat = true; diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index 38ad336e..c9c57432 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -2,7 +2,7 @@ // // The Open Toolkit Library License // -// Copyright (c) 2006 - 2010 the Open Toolkit library. +// Copyright (c) 2006 - 2013 Stefanos Apostolopoulos // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/Source/OpenTK/Graphics/GraphicsMode.cs b/Source/OpenTK/Graphics/GraphicsMode.cs index 06b6d3f6..1ef4bd0a 100644 --- a/Source/OpenTK/Graphics/GraphicsMode.cs +++ b/Source/OpenTK/Graphics/GraphicsMode.cs @@ -25,19 +25,10 @@ namespace OpenTK.Graphics static IGraphicsMode implementation; static readonly object SyncRoot = new object(); - #region --- Constructors --- + #region Constructors - #region static GraphicsMode() - - static GraphicsMode() - { - lock (SyncRoot) - { - implementation = Platform.Factory.Default.CreateGraphicsMode(); - } - } - - #endregion + // Disable BeforeFieldInit + static GraphicsMode() { } #region internal GraphicsMode(GraphicsMode mode) @@ -180,7 +171,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return index; } set { index = value; } @@ -197,7 +187,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return color_format; } private set { color_format = value; } @@ -214,7 +203,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return accumulator_format; } private set { accumulator_format = value; } @@ -232,7 +220,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return depth; } private set { depth = value; } @@ -250,7 +237,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return stencil; } private set { stencil = value; } @@ -267,7 +253,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return samples; } private set { samples = value; } @@ -284,7 +269,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return stereo; } private set { stereo = value; } @@ -302,7 +286,6 @@ namespace OpenTK.Graphics { get { - LazySelectGraphicsMode(); return buffers; } private set { buffers = value; } @@ -321,9 +304,9 @@ namespace OpenTK.Graphics { if (defaultMode == null) { - Debug.Print("Creating default GraphicsMode ({0}, {1}, {2}, {3}, {4}, {5}, {6}).", - 32, 24, 8, 0, 0, 2, false); - defaultMode = new GraphicsMode(32, 24, 8, 0, 0, 2, false); + Debug.Print("Creating default GraphicsMode ({0}, {1}, {2}).", + 32, 24, 8); + defaultMode = new GraphicsMode(null, 32, 24, 8, 0, 0, 2, false); } return defaultMode; } @@ -334,30 +317,6 @@ namespace OpenTK.Graphics #endregion - #region --- Private Methods --- - - // Queries the implementation for the actual graphics mode if this hasn't been done already. - // This method allows for lazy evaluation of the actual GraphicsMode and should be called - // by all GraphicsMode properties. - void LazySelectGraphicsMode() - { - if (index == null) - { - GraphicsMode mode = implementation.SelectGraphicsMode(color_format, depth, stencil, samples, accumulator_format, buffers, stereo); - - Index = mode.Index; - ColorFormat = mode.ColorFormat; - Depth = mode.Depth; - Stencil = mode.Stencil; - Samples = mode.Samples; - AccumulatorFormat = mode.AccumulatorFormat; - Buffers = mode.Buffers; - Stereo = mode.Stereo; - } - } - - #endregion - #region --- Overrides --- /// Returns a System.String describing the current GraphicsFormat. diff --git a/Source/OpenTK/Platform/DesktopGraphicsContext.cs b/Source/OpenTK/Platform/DesktopGraphicsContext.cs index f7355b62..e636ec93 100644 --- a/Source/OpenTK/Platform/DesktopGraphicsContext.cs +++ b/Source/OpenTK/Platform/DesktopGraphicsContext.cs @@ -36,9 +36,11 @@ namespace OpenTK.Platform public override void LoadAll() { new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints(); + new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints(); new OpenTK.Graphics.ES10.GL().LoadEntryPoints(); new OpenTK.Graphics.ES11.GL().LoadEntryPoints(); new OpenTK.Graphics.ES20.GL().LoadEntryPoints(); + new OpenTK.Graphics.ES30.GL().LoadEntryPoints(); } } } diff --git a/Source/OpenTK/Platform/EmbeddedGraphicsContext.cs b/Source/OpenTK/Platform/EmbeddedGraphicsContext.cs index 2ac37638..fb98bb8d 100644 --- a/Source/OpenTK/Platform/EmbeddedGraphicsContext.cs +++ b/Source/OpenTK/Platform/EmbeddedGraphicsContext.cs @@ -38,6 +38,7 @@ namespace OpenTK.Platform new OpenTK.Graphics.ES10.GL().LoadEntryPoints(); new OpenTK.Graphics.ES11.GL().LoadEntryPoints(); new OpenTK.Graphics.ES20.GL().LoadEntryPoints(); + new OpenTK.Graphics.ES30.GL().LoadEntryPoints(); } } } \ No newline at end of file From 2cd91bd0a0a34549c3e7c69739096b594870b33d Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Fri, 8 Nov 2013 10:41:58 +0100 Subject: [PATCH 02/16] Remove static init of GetCurrentContext The static initializer of GetCurrentContext would always default to the desktop PlatformFactory, which caused problems when trying to run OpenGL ES code on the desktop. The initializer is now removed and GetCurrentContext is set in the context constructor, before creating any contexts. --- Source/OpenTK/Graphics/GraphicsContext.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index c9c57432..bcd9dc49 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -131,7 +131,6 @@ namespace OpenTK.Graphics case true: factory = Factory.Embedded; break; } - implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); // Note: this approach does not allow us to mix native and EGL contexts in the same process. // This should not be a problem, as this use-case is not interesting for regular applications. // Note 2: some platforms may not support a direct way of getting the current context @@ -140,12 +139,10 @@ namespace OpenTK.Graphics // declaration). if (GetCurrentContext == null) { - GetCurrentContextDelegate temp = factory.CreateGetCurrentGraphicsContext(); - if (temp != null) - { - GetCurrentContext = temp; - } + GetCurrentContext = factory.CreateGetCurrentGraphicsContext(); } + + implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); } available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); @@ -321,8 +318,7 @@ namespace OpenTK.Graphics #region public static IGraphicsContext CurrentContext internal delegate ContextHandle GetCurrentContextDelegate(); - internal static GetCurrentContextDelegate GetCurrentContext = - Platform.Factory.Default.CreateGetCurrentGraphicsContext(); + internal static GetCurrentContextDelegate GetCurrentContext; /// /// Gets the GraphicsContext that is current in the calling thread. From c9b905d235e625c045f30aaf359b45de43c73c75 Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Fri, 8 Nov 2013 10:42:48 +0100 Subject: [PATCH 03/16] Stronger check for ES support It is not enough to check for EGL, we also need to check that ContextProfileFlags.ES is set. --- Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs index e7ea0a09..997e1610 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs @@ -125,7 +125,7 @@ namespace OpenTK.Platform.SDL2 int profile; SDL.GL.GetAttribute(ContextAttribute.CONTEXT_PROFILE_MASK, out profile); - if (egl != 0) + if (egl != 0 && (profile & (int)ContextProfileFlags.ES) != 0) { context_flags |= GraphicsContextFlags.Embedded; } From a51540e8d9de679ba649a2b68f326f32da8bebdf Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Fri, 8 Nov 2013 10:46:27 +0100 Subject: [PATCH 04/16] Updated WGL init sequence WinGraphicsMode no longer creates a temporary context in order to create the list of available modes. Instead, it requires to be passed an existing context in its constructor. WinGLContext now creates one temporary context in its static constructor and hands that to WinGraphicsMode. WinFactory no longer supports the CreateGraphicsMode API. This API will be removed in the future, because the link because contexts and modes cannot be separated in the general case. --- Source/OpenTK/Platform/Windows/WinFactory.cs | 2 +- .../OpenTK/Platform/Windows/WinGLContext.cs | 95 ++++++----- .../Platform/Windows/WinGraphicsMode.cs | 158 ++++++++---------- 3 files changed, 131 insertions(+), 124 deletions(-) diff --git a/Source/OpenTK/Platform/Windows/WinFactory.cs b/Source/OpenTK/Platform/Windows/WinFactory.cs index f5ae318a..74f27038 100644 --- a/Source/OpenTK/Platform/Windows/WinFactory.cs +++ b/Source/OpenTK/Platform/Windows/WinFactory.cs @@ -89,7 +89,7 @@ namespace OpenTK.Platform.Windows public virtual IGraphicsMode CreateGraphicsMode() { - return new WinGraphicsMode(); + throw new NotSupportedException(); } public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver() diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index 0fc6fb82..c866e447 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -36,11 +36,43 @@ namespace OpenTK.Platform.Windows bool vsync_supported; + static readonly IGraphicsMode ModeSelector; + #region --- Contructors --- static WinGLContext() { - Init(); + // Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl. + if (opengl32Handle == IntPtr.Zero) + { + opengl32Handle = Functions.LoadLibrary(opengl32Name); + if (opengl32Handle == IntPtr.Zero) + throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}", + opengl32Name, Marshal.GetLastWin32Error())); + Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle)); + } + + // We need to create a temp context in order to load + // wgl extensions (e.g. for multisampling or GL3). + // We cannot rely on OpenTK.Platform.Wgl until we + // create the context and call Wgl.LoadAll(). + Debug.Print("Creating temporary context for wgl extensions."); + using (INativeWindow native = new NativeWindow()) + { + // Create temporary context and load WGL entry points + WinWindowInfo window = native.WindowInfo as WinWindowInfo; + ContextHandle temp_context = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); + Wgl.Imports.MakeCurrent(window.DeviceContext, temp_context.Handle); + Wgl.LoadAll(); + + // Query graphics modes + ModeSelector = new WinGraphicsMode(temp_context, window.DeviceContext); + + // Destroy temporary context + Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero); + Wgl.Imports.DeleteContext(temp_context.Handle); + wgl_loaded = true; + } } public WinGLContext(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext, @@ -56,11 +88,8 @@ namespace OpenTK.Platform.Windows if (window.Handle == IntPtr.Zero) throw new ArgumentException("window", "Must be a valid window."); - Mode = format; - Debug.Print("OpenGL will be bound to window:{0} on thread:{1}", window.Handle, System.Threading.Thread.CurrentThread.ManagedThreadId); - SetGraphicsModePFD(format, (WinWindowInfo)window); lock (LoadLock) { @@ -71,18 +100,11 @@ namespace OpenTK.Platform.Windows // side-effects (i.e. the old contexts can still be handled // using the new entry points.) // Sigh... - // if (!wgl_loaded) - { - // We need to create a temp context in order to load wgl extensions (e.g. for multisampling or GL3). - // We cannot rely on OpenTK.Platform.Wgl until we create the context and call Wgl.LoadAll(). - Debug.Print("Creating temporary context for wgl extensions."); - ContextHandle temp_context = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); - Wgl.Imports.MakeCurrent(window.DeviceContext, temp_context.Handle); - Wgl.LoadAll(); - Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero); - Wgl.Imports.DeleteContext(temp_context.Handle); - wgl_loaded = true; - } + //if (!wgl_loaded) + //{ + //} + + Mode = SetGraphicsModePFD(format, (WinWindowInfo)window); if (Wgl.Delegates.wglCreateContextAttribsARB != null) { @@ -281,22 +303,35 @@ namespace OpenTK.Platform.Windows #region SetGraphicsModePFD // Note: there is no relevant ARB function. - internal static void SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window) + internal static GraphicsMode SetGraphicsModePFD(GraphicsMode mode, WinWindowInfo window) { Debug.Write("Setting pixel format... "); + if (window == null) + throw new ArgumentNullException("window", "Must point to a valid window."); if (!mode.Index.HasValue) - throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); - - if (window == null) throw new ArgumentNullException("window", "Must point to a valid window."); + { + mode = ModeSelector.SelectGraphicsMode( + mode.ColorFormat, mode.Depth, mode.Stencil, + mode.Samples, mode.AccumulatorFormat, + mode.Buffers, mode.Stereo); + } PixelFormatDescriptor pfd = new PixelFormatDescriptor(); - Functions.DescribePixelFormat(window.DeviceContext, (int)mode.Index.Value, + Functions.DescribePixelFormat( + window.DeviceContext, (int)mode.Index.Value, API.PixelFormatDescriptorSize, ref pfd); + Debug.WriteLine(mode.Index.ToString()); + if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd)) + { throw new GraphicsContextException(String.Format( - "Requested GraphicsMode not available. SetPixelFormat error: {0}", Marshal.GetLastWin32Error())); + "Requested GraphicsMode not available. SetPixelFormat error: {0}", + Marshal.GetLastWin32Error())); + } + + return mode; } #endregion @@ -314,22 +349,6 @@ namespace OpenTK.Platform.Windows #endregion - static internal void Init() - { - lock (SyncRoot) - { - // Dynamically load the OpenGL32.dll in order to use the extension loading capabilities of Wgl. - if (opengl32Handle == IntPtr.Zero) - { - opengl32Handle = Functions.LoadLibrary(opengl32Name); - if (opengl32Handle == IntPtr.Zero) - throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}", - opengl32Name, Marshal.GetLastWin32Error())); - Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", opengl32Handle)); - } - } - } - #endregion #region Overrides diff --git a/Source/OpenTK/Platform/Windows/WinGraphicsMode.cs b/Source/OpenTK/Platform/Windows/WinGraphicsMode.cs index f679f82a..677e40d0 100644 --- a/Source/OpenTK/Platform/Windows/WinGraphicsMode.cs +++ b/Source/OpenTK/Platform/Windows/WinGraphicsMode.cs @@ -46,19 +46,16 @@ namespace OpenTK.Platform.Windows #region Constructors - public WinGraphicsMode() + public WinGraphicsMode(ContextHandle context, IntPtr device) { lock (SyncRoot) { - using (INativeWindow native = new NativeWindow()) - { - modes.AddRange(GetModesARB(native)); - if (modes.Count == 0) - modes.AddRange(GetModesPFD(native)); - if (modes.Count == 0) - throw new GraphicsModeException( - "No GraphicsMode available. This should never happen, please report a bug at http://www.opentk.com"); - } + modes.AddRange(GetModesARB(context, device)); + if (modes.Count == 0) + modes.AddRange(GetModesPFD(context, device)); + if (modes.Count == 0) + throw new GraphicsModeException( + "No GraphicsMode available. This should never happen, please report a bug at http://www.opentk.com"); modes.Sort(new GraphicsModeComparer()); } } @@ -127,11 +124,9 @@ namespace OpenTK.Platform.Windows #region GetModesPFD - IEnumerable GetModesPFD(INativeWindow native) + IEnumerable GetModesPFD(ContextHandle context, IntPtr device) { - WinWindowInfo window = native.WindowInfo as WinWindowInfo; - IntPtr deviceContext = ((WinWindowInfo)window).DeviceContext; - Debug.WriteLine(String.Format("Device context: {0}", deviceContext)); + Debug.WriteLine(String.Format("Device context: {0}", device)); Debug.WriteLine("Retrieving PFD pixel formats... "); PixelFormatDescriptor pfd = new PixelFormatDescriptor(); @@ -152,7 +147,7 @@ namespace OpenTK.Platform.Windows // Iterate through all accelerated formats first. Afterwards, iterate through non-accelerated formats. // This should fix issue #2224, which causes OpenTK to fail on VMs without hardware acceleration. int pixel = 0; - while (DescribePixelFormat(deviceContext, ++pixel, API.PixelFormatDescriptorSize, ref pfd) != 0) + while (DescribePixelFormat(device, ++pixel, API.PixelFormatDescriptorSize, ref pfd) != 0) { // Ignore non-accelerated formats. if (!generic_allowed && (pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0) @@ -176,90 +171,83 @@ namespace OpenTK.Platform.Windows #region GetModesARB - IEnumerable GetModesARB(INativeWindow native) + IEnumerable GetModesARB(ContextHandle context, IntPtr device) { - using (IGraphicsContext context = new GraphicsContext( - new GraphicsMode(new IntPtr(2), new ColorFormat(), 0, 0, 0, new ColorFormat(), 2, false), - (WinWindowInfo)native.WindowInfo, 1, 0, GraphicsContextFlags.Default)) + // See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt + // for more details + Debug.Write("Retrieving ARB pixel formats.... "); + if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null) { - WinWindowInfo window = (WinWindowInfo)native.WindowInfo; + Debug.WriteLine("failed."); + yield break; + } - // See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt - // for more details - Debug.Write("Retrieving ARB pixel formats.... "); - if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null) - { - Debug.WriteLine("failed."); - yield break; - } + int[] attribs = new int[] + { + (int)WGL_ARB_pixel_format.AccelerationArb, - int[] attribs = new int[] - { - (int)WGL_ARB_pixel_format.AccelerationArb, - - (int)WGL_ARB_pixel_format.RedBitsArb, - (int)WGL_ARB_pixel_format.GreenBitsArb, - (int)WGL_ARB_pixel_format.BlueBitsArb, - (int)WGL_ARB_pixel_format.AlphaBitsArb, - (int)WGL_ARB_pixel_format.ColorBitsArb, + (int)WGL_ARB_pixel_format.RedBitsArb, + (int)WGL_ARB_pixel_format.GreenBitsArb, + (int)WGL_ARB_pixel_format.BlueBitsArb, + (int)WGL_ARB_pixel_format.AlphaBitsArb, + (int)WGL_ARB_pixel_format.ColorBitsArb, - (int)WGL_ARB_pixel_format.DepthBitsArb, - (int)WGL_ARB_pixel_format.StencilBitsArb, + (int)WGL_ARB_pixel_format.DepthBitsArb, + (int)WGL_ARB_pixel_format.StencilBitsArb, - (int)WGL_ARB_multisample.SampleBuffersArb, - (int)WGL_ARB_multisample.SamplesArb, + (int)WGL_ARB_multisample.SampleBuffersArb, + (int)WGL_ARB_multisample.SamplesArb, - (int)WGL_ARB_pixel_format.AccumRedBitsArb, - (int)WGL_ARB_pixel_format.AccumGreenBitsArb, - (int)WGL_ARB_pixel_format.AccumBlueBitsArb, - (int)WGL_ARB_pixel_format.AccumAlphaBitsArb, - (int)WGL_ARB_pixel_format.AccumBitsArb, + (int)WGL_ARB_pixel_format.AccumRedBitsArb, + (int)WGL_ARB_pixel_format.AccumGreenBitsArb, + (int)WGL_ARB_pixel_format.AccumBlueBitsArb, + (int)WGL_ARB_pixel_format.AccumAlphaBitsArb, + (int)WGL_ARB_pixel_format.AccumBitsArb, - (int)WGL_ARB_pixel_format.DoubleBufferArb, - (int)WGL_ARB_pixel_format.StereoArb, - 0 - }; + (int)WGL_ARB_pixel_format.DoubleBufferArb, + (int)WGL_ARB_pixel_format.StereoArb, + 0 + }; - int[] values = new int[attribs.Length]; + int[] values = new int[attribs.Length]; - int[] attribs_values = new int[] + int[] attribs_values = new int[] + { + (int)WGL_ARB_pixel_format.AccelerationArb, + (int)WGL_ARB_pixel_format.FullAccelerationArb, + (int)WGL_ARB_pixel_format.SupportOpenglArb, 1, + (int)WGL_ARB_pixel_format.DrawToWindowArb, 1, + 0, 0 + }; + + int[] num_formats = new int[1]; + // Get the number of available formats + if (Wgl.Arb.ChoosePixelFormat(device, attribs_values, null, 0, null, num_formats)) + { + // Create an array big enough to hold all available formats and get those formats + int[] pixel = new int[num_formats[0]]; + + if (Wgl.Arb.ChoosePixelFormat(device, attribs_values, null, pixel.Length, pixel, num_formats)) { - (int)WGL_ARB_pixel_format.AccelerationArb, - (int)WGL_ARB_pixel_format.FullAccelerationArb, - (int)WGL_ARB_pixel_format.SupportOpenglArb, 1, - (int)WGL_ARB_pixel_format.DrawToWindowArb, 1, - 0, 0 - }; - - int[] num_formats = new int[1]; - // Get the number of available formats - if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, 0, null, num_formats)) - { - // Create an array big enough to hold all available formats and get those formats - int[] pixel = new int[num_formats[0]]; - - if (Wgl.Arb.ChoosePixelFormat(window.DeviceContext, attribs_values, null, pixel.Length, pixel, num_formats)) + foreach (int p in pixel) { - foreach (int p in pixel) + // Find out what we really got as a format: + if (!Wgl.Arb.GetPixelFormatAttrib(device, p, 0, attribs.Length - 1, attribs, values)) { - // Find out what we really got as a format: - if (!Wgl.Arb.GetPixelFormatAttrib(window.DeviceContext, p, 0, attribs.Length - 1, attribs, values)) - { - Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p); - continue; - } - - GraphicsMode mode = new GraphicsMode(new IntPtr(p), - new ColorFormat(values[1], values[2], values[3], values[4]), - values[6], - values[7], - values[8] != 0 ? values[9] : 0, - new ColorFormat(values[10], values[11], values[12], values[13]), - values[15] == 1 ? 2 : 1, - values[16] == 1 ? true : false); - - yield return mode; + Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p); + continue; } + + GraphicsMode mode = new GraphicsMode(new IntPtr(p), + new ColorFormat(values[1], values[2], values[3], values[4]), + values[6], + values[7], + values[8] != 0 ? values[9] : 0, + new ColorFormat(values[10], values[11], values[12], values[13]), + values[15] == 1 ? 2 : 1, + values[16] == 1 ? true : false); + + yield return mode; } } } From 28fa768257a410e160ae63159fbd7cab95fabc08 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Sun, 13 Oct 2013 22:35:20 +0200 Subject: [PATCH 05/16] Fixed platform detection for Android Conflicts: Source/OpenTK/Configuration.cs --- Source/OpenTK/Configuration.cs | 25 +++++++++++++++++++++- Source/OpenTK/Platform/SDL2/Sdl2Factory.cs | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Source/OpenTK/Configuration.cs b/Source/OpenTK/Configuration.cs index 4ee7bb5f..98b21d68 100644 --- a/Source/OpenTK/Configuration.cs +++ b/Source/OpenTK/Configuration.cs @@ -38,7 +38,10 @@ namespace OpenTK /// Provides information about the underlying OS and runtime. public static class Configuration { - static bool runningOnWindows, runningOnUnix, runningOnX11, runningOnMacOS, runningOnLinux, runningOnMono; + static bool runningOnWindows, runningOnUnix, runningOnX11, runningOnMacOS, runningOnLinux; + static bool runningOnMono; + static bool runningOnAndroid; + static bool? sdl2supported; volatile static bool initialized; readonly static object InitLock = new object(); @@ -114,6 +117,26 @@ namespace OpenTK #endregion + #region public static bool RunningOnAndroid + + /// + /// Gets a System.Boolean indicating whether + /// OpenTK is running on an Android device. + /// + public static bool RunningOnAndroid + { + get + { +#if ANDROID + return true; +#else + return false; +#endif + } + } + + #endregion + #region --- Private Methods --- #region private static string DetectUnixKernel() diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs index 4992f243..63350756 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs @@ -76,6 +76,8 @@ namespace OpenTK.Platform.SDL2 current = OpenTK.Platform.X11.Glx.GetCurrentContext(); else if (Configuration.RunningOnMacOS) current = OpenTK.Platform.MacOS.Cgl.GetCurrentContext(); + else if (Configuration.RunningOnAndroid) + current = OpenTK.Platform.Egl.Egl.GetCurrentContext(); else throw new NotSupportedException("Unknown platform, please report to http://www.opentk.com"); From eba7e59253c30e743078aafdbc4149a67eb70656 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Mon, 14 Oct 2013 01:00:18 +0200 Subject: [PATCH 06/16] Fixed ES rendering. --- Source/OpenTK/Graphics/ES11/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/OpenTK/Graphics/ES11/Helper.cs b/Source/OpenTK/Graphics/ES11/Helper.cs index c8308447..4037c0eb 100644 --- a/Source/OpenTK/Graphics/ES11/Helper.cs +++ b/Source/OpenTK/Graphics/ES11/Helper.cs @@ -12,7 +12,7 @@ namespace OpenTK.Graphics.ES11 public sealed partial class GL : GraphicsBindingsBase { - const string Library = "libGLES.dll"; + const string Library = "GLESv1_CM"; static readonly object sync_root = new object(); #region --- Protected Members --- From 29fe1052dee481af89178cc5462cd9f26a6dd22d Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Tue, 15 Oct 2013 00:17:59 +0200 Subject: [PATCH 07/16] Added SDL_GL_GetCurrentContext method and TouchMouseID constant. SDL_GL_GetCurrentContext will allow us to replace the weird implementation in Sdl2Factory.CreateGetCurrentGraphicsContext() and the latter to disable mouse emulation if we wish to. Conflicts: Source/OpenTK/Platform/SDL2/Sdl2.cs --- Source/OpenTK/Platform/SDL2/Sdl2.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2.cs b/Source/OpenTK/Platform/SDL2/Sdl2.cs index 0dd1bbb6..0efe3c8a 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2.cs @@ -23,6 +23,9 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // +using System.Runtime.InteropServices; + + #endregion using System; @@ -294,6 +297,9 @@ namespace OpenTK.Platform.SDL2 [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetAttribute", ExactSpelling = true)] public static extern int GetAttribute(ContextAttribute attr, out int value); + [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetCurrentContext", ExactSpelling = true)] + public static extern IntPtr GetCurrentContext(); + [SuppressUnmanagedCodeSecurity] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GL_GetDrawableSize", ExactSpelling = true)] public static extern void GetDrawableSize(IntPtr window, out int w, out int h); @@ -1170,6 +1176,25 @@ namespace OpenTK.Platform.SDL2 public uint Which; public int X; public int Y; + + public enum EventType : uint + { + /* Touch events */ + FingerDown = 0x700, + FingerUp, + FingerMotion, + + /* Gesture events */ + DollarGesture = 0x800, + DollarRecord, + MultiGesture, + } + + public const uint TouchMouseID = 0xffffffff; + + public static class GL + { + } } struct Rect From e0ffd9b42d1dbb3bf85624c7c24dcb11246d9132 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Tue, 15 Oct 2013 00:18:41 +0200 Subject: [PATCH 08/16] More sane Sdl2Factory.CreateGetCurrentContext() implementation --- Source/OpenTK/Platform/SDL2/Sdl2Factory.cs | 14 +------------- Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs index 63350756..18a40a55 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs @@ -69,19 +69,7 @@ namespace OpenTK.Platform.SDL2 // so we need to implement our own. return (GraphicsContext.GetCurrentContextDelegate)delegate { - IntPtr current; - if (Configuration.RunningOnWindows) - current = OpenTK.Platform.Windows.Wgl.Imports.GetCurrentContext(); - else if (Configuration.RunningOnX11) - current = OpenTK.Platform.X11.Glx.GetCurrentContext(); - else if (Configuration.RunningOnMacOS) - current = OpenTK.Platform.MacOS.Cgl.GetCurrentContext(); - else if (Configuration.RunningOnAndroid) - current = OpenTK.Platform.Egl.Egl.GetCurrentContext(); - else - throw new NotSupportedException("Unknown platform, please report to http://www.opentk.com"); - - return new ContextHandle(current); + return Sdl2GraphicsContext.GetCurrentContext(); }; } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs index 997e1610..b423b684 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs @@ -254,6 +254,15 @@ namespace OpenTK.Platform.SDL2 #endregion + #region Public Members + + public static ContextHandle GetCurrentContext() + { + return new ContextHandle(SDL.GL.GetCurrentContext()); + } + + #endregion + #region GraphicsContextBase Members public override void SwapBuffers() From 5a2fc1e41156f934d8a16482ba528714eefae1f5 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Tue, 15 Oct 2013 00:20:00 +0200 Subject: [PATCH 09/16] Added missing doc comment --- Source/OpenTK/Input/MouseState.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/OpenTK/Input/MouseState.cs b/Source/OpenTK/Input/MouseState.cs index 44acc9c3..eee3a0aa 100644 --- a/Source/OpenTK/Input/MouseState.cs +++ b/Source/OpenTK/Input/MouseState.cs @@ -180,6 +180,10 @@ namespace OpenTK.Input get { return Wheel; } } + /// + /// Gets a value indicating whether this instance is connected. + /// + /// true if this instance is connected; otherwise, false. public bool IsConnected { get { return is_connected; } From f77a6b11c34f7b207a095a97be763f5ca7d2062b Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Fri, 8 Nov 2013 17:31:54 +0100 Subject: [PATCH 10/16] SDL_GL_GetAttribute requires a valid context Calling SDL_GL_GetAttribute when context construction has failed leads to erroneous behavior. This call should only be made when a context has been constructed correctly. --- .../OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs index b423b684..26b528e8 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2GraphicsContext.cs @@ -65,16 +65,17 @@ namespace OpenTK.Platform.SDL2 { SetGLAttributes(mode, shareContext, major, minor, flags); SdlContext = new ContextHandle(SDL.GL.CreateContext(Window.Handle)); + if (SdlContext == ContextHandle.Zero) + { + var error = SDL.GetError(); + Debug.Print("SDL2 failed to create OpenGL context: {0}", error); + throw new GraphicsContextException(error); + } + Mode = GetGLAttributes(SdlContext, out flags); - Debug.Print("SDL2 created GraphicsContext (mode: {0}) (flags: {1}", + Debug.Print("SDL2 created GraphicsContext (mode: {0}) (flags: {1})", Mode, flags); } - if (SdlContext == ContextHandle.Zero) - { - var error = SDL.GetError(); - Debug.Print("SDL2 failed to create OpenGL context: {0}", error); - throw new GraphicsContextException(error); - } Handle = GraphicsContext.GetCurrentContext(); } From 6edaf8c3cfff5d26b055606cac312a6f2105f4d2 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Fri, 8 Nov 2013 18:44:02 +0100 Subject: [PATCH 11/16] Deduplicate MacOSGraphicsMode and AglContext The IGraphicsMode interface is gradually being removed and the MacOSFactory will now throw an exception if an instance is requested. AglContext no longer duplicates MacOSGraphicsMode functionality. --- Source/OpenTK/Platform/MacOS/AglContext.cs | 75 +++++-------------- Source/OpenTK/Platform/MacOS/MacOSFactory.cs | 2 +- .../Platform/MacOS/MacOSGraphicsMode.cs | 28 ++++--- 3 files changed, 38 insertions(+), 67 deletions(-) diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index afa89627..ee5a468e 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -47,18 +47,18 @@ namespace OpenTK.Platform.MacOS // Todo: keep track of which display adapter was specified when the context was created. // IntPtr displayID; - GraphicsMode graphics_mode; CarbonWindowInfo carbonWindow; IntPtr shareContextRef; DisplayDevice device; bool mIsFullscreen = false; + readonly MacOSGraphicsMode ModeSelector = new MacOSGraphicsMode(); + public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) { Debug.Print("Context Type: {0}", shareContext); Debug.Print("Window info: {0}", window); - - this.graphics_mode = mode; + this.carbonWindow = (CarbonWindowInfo)window; if (shareContext is AglContext) @@ -105,50 +105,7 @@ namespace OpenTK.Platform.MacOS } void CreateContext(GraphicsMode mode, CarbonWindowInfo carbonWindow, IntPtr shareContextRef, bool fullscreen) { - List aglAttributes = new List(); - Debug.Print("AGL pixel format attributes:"); - Debug.Indent(); - - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RGBA); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RED_SIZE, mode.ColorFormat.Red); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_GREEN_SIZE, mode.ColorFormat.Green); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_BLUE_SIZE, mode.ColorFormat.Blue); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ALPHA_SIZE, mode.ColorFormat.Alpha); - - if (mode.Depth > 0) - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DEPTH_SIZE, mode.Depth); - - if (mode.Stencil > 0) - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_STENCIL_SIZE, mode.Stencil); - - if (mode.AccumulatorFormat.BitsPerPixel > 0) - { - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_RED_SIZE, mode.AccumulatorFormat.Red); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_GREEN_SIZE, mode.AccumulatorFormat.Green); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_BLUE_SIZE, mode.AccumulatorFormat.Blue); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_ALPHA_SIZE, mode.AccumulatorFormat.Alpha); - } - - if (mode.Samples > 1) - { - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1); - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples); - } - - if (fullscreen) - { - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_FULLSCREEN); - } - AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_NONE); - - Debug.Unindent(); - - Debug.Write("Attribute array: "); - for (int i = 0; i < aglAttributes.Count; i++) - Debug.Write(aglAttributes[i].ToString() + " "); - Debug.WriteLine(""); AGLPixelFormat myAGLPixelFormat; @@ -166,11 +123,13 @@ namespace OpenTK.Platform.MacOS if (status != OSStatus.NoError) throw new MacOSException(status, "DMGetGDeviceByDisplayID failed."); - myAGLPixelFormat = Agl.aglChoosePixelFormat(ref gdevice, 1, aglAttributes.ToArray()); + myAGLPixelFormat = ModeSelector.SelectPixelFormat( + mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, + mode.AccumulatorFormat, mode.Buffers, mode.Stereo, + true, gdevice); Agl.AglError err = Agl.GetError(); - - if (err == Agl.AglError.BadPixelFormat) + if (myAGLPixelFormat == IntPtr.Zero || err == Agl.AglError.BadPixelFormat) { Debug.Print("Failed to create full screen pixel format."); Debug.Print("Trying again to create a non-fullscreen pixel format."); @@ -179,21 +138,23 @@ namespace OpenTK.Platform.MacOS return; } } - else { - myAGLPixelFormat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, aglAttributes.ToArray()); - + myAGLPixelFormat = ModeSelector.SelectPixelFormat( + mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, + mode.AccumulatorFormat, mode.Buffers, mode.Stereo, + false, IntPtr.Zero); MyAGLReportError("aglChoosePixelFormat"); } - Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef); // create the context and share it with the share reference. Handle = new ContextHandle(Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); MyAGLReportError("aglCreateContext"); - + + Mode = ModeSelector.GetGraphicsModeFromPixelFormat(myAGLPixelFormat); + // Free the pixel format from memory. Agl.aglDestroyPixelFormat(myAGLPixelFormat); MyAGLReportError("aglDestroyPixelFormat"); @@ -205,7 +166,6 @@ namespace OpenTK.Platform.MacOS Update(carbonWindow); MakeCurrent(carbonWindow); - Debug.Print("context: {0}", Handle.Handle); } @@ -290,10 +250,11 @@ namespace OpenTK.Platform.MacOS windowPort = API.GetWindowPort(controlOwner); } - else + { windowPort = API.GetWindowPort(carbonWindow.Handle); - + } + return windowPort; } public override void Update(IWindowInfo window) diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs index 142ef76d..ad540311 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs @@ -76,7 +76,7 @@ namespace OpenTK.Platform.MacOS public virtual IGraphicsMode CreateGraphicsMode() { - return new MacOSGraphicsMode(); + throw new NotSupportedException(); } public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver() diff --git a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs index 28d49f2b..604973e2 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs @@ -42,15 +42,17 @@ namespace OpenTK.Platform.MacOS public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo) { - IntPtr pixelformat = SelectPixelFormat(color, depth, stencil, samples, accum, buffers, stereo); + IntPtr pixelformat = SelectPixelFormat( + color, depth, stencil, samples, accum, buffers, stereo, + false, IntPtr.Zero); return GetGraphicsModeFromPixelFormat(pixelformat); } #endregion - #region Private Members + #region Internal Members - GraphicsMode GetGraphicsModeFromPixelFormat(IntPtr pixelformat) + internal GraphicsMode GetGraphicsModeFromPixelFormat(IntPtr pixelformat) { int r, g, b, a; Agl.aglDescribePixelFormat(pixelformat, Agl.PixelFormatAttribute.AGL_RED_SIZE, out r); @@ -73,8 +75,8 @@ namespace OpenTK.Platform.MacOS depth, stencil, samples, new ColorFormat(ar, ag, ab, aa), buffers + 1, stereo != 0); } - IntPtr SelectPixelFormat(ColorFormat color, int depth, int stencil, int samples, - ColorFormat accum, int buffers, bool stereo) + internal IntPtr SelectPixelFormat(ColorFormat color, int depth, int stencil, int samples, + ColorFormat accum, int buffers, bool stereo, bool fullscreen, IntPtr device) { List attribs = new List(); @@ -140,14 +142,22 @@ namespace OpenTK.Platform.MacOS attribs.Add((int)Agl.PixelFormatAttribute.AGL_STEREO); } + if (fullscreen) + { + attribs.Add((int)Agl.PixelFormatAttribute.AGL_FULLSCREEN); + } + attribs.Add(0); attribs.Add(0); - IntPtr pixelformat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, attribs.ToArray()); - if (pixelformat == IntPtr.Zero) + IntPtr pixelformat = IntPtr.Zero; + if (device != IntPtr.Zero) { - throw new GraphicsModeException(String.Format( - "[Error] Failed to select GraphicsMode, error {0}.", Agl.GetError())); + pixelformat = Agl.aglChoosePixelFormat(ref device, 0, attribs.ToArray()); + } + else + { + pixelformat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, attribs.ToArray()); } return pixelformat; } From 3c7163466786963af23834bacebdf6255fd38cda Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Sat, 9 Nov 2013 11:07:37 +0100 Subject: [PATCH 12/16] Temp context not necessary for GLX GLX entry points are not bound to a specific context. This means that, unlike WGL, GLX does not require a temporary context in order to load its entry points! --- Source/OpenTK/Platform/X11/X11GLContext.cs | 37 +++++++--------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index d16393e0..3275aa88 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -64,37 +64,22 @@ namespace OpenTK.Platform.X11 if (!glx_loaded) { - Debug.WriteLine("Creating temporary context to load GLX extensions."); - - // Create a temporary context to obtain the necessary function pointers. - XVisualInfo visual = currentWindow.VisualInfo; - IntPtr ctx = IntPtr.Zero; - - using (new XLock(Display)) - { - ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, true); - if (ctx == IntPtr.Zero) - ctx = Glx.CreateContext(Display, ref visual, IntPtr.Zero, false); - } - - if (ctx != IntPtr.Zero) - { - new Glx().LoadEntryPoints(); - using (new XLock(Display)) - { - Glx.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero); - //Glx.DestroyContext(Display, ctx); - } - glx_loaded = true; - } + // GLX entry points are not bound to a context. + // This means we can load them without creating + // a context first! (unlike WGL) + // See http://dri.freedesktop.org/wiki/glXGetProcAddressNeverReturnsNULL/ + // for more details. + Debug.WriteLine("Loading GLX entry points."); + new Glx().LoadEntryPoints(); + glx_loaded = true; } - + // Try using the new context creation method. If it fails, fall back to the old one. // For each of these methods, we try two times to create a context: // one with the "direct" flag intact, the other with the flag inversed. // HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through - // GLX_ARB_create_context, including hideous input lag, no vsync and other. Use legacy context - // creation if the user doesn't request a 3.0+ context. + // GLX_ARB_create_context, including hideous input lag, no vsync and other madness. + // Use legacy context creation if the user doesn't request a 3.0+ context. if ((major * 10 + minor >= 30) && Glx.Delegates.glXCreateContextAttribsARB != null) { Debug.Write("Using GLX_ARB_create_context... "); From 2725b3cd0866faf0352245944308c843c8c1302c Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Sat, 9 Nov 2013 11:16:14 +0100 Subject: [PATCH 13/16] Fix support for 3.2+ contexts (issue 3111) glXGetProcAddress may return a non-null value even if a function is not supported by the server. We need to check the extension string using any GLX extensions. Fixes issue http://www.opentk.com/node/3111 "GLX extension support is not checked correctly". Furthermore, mode selection is now performed explicitly by the X11GLContext constructor. --- Source/OpenTK/Platform/X11/Bindings/Glx.cs | 3 ++ Source/OpenTK/Platform/X11/X11Factory.cs | 2 +- Source/OpenTK/Platform/X11/X11GLContext.cs | 44 ++++++++++++++++++---- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Source/OpenTK/Platform/X11/Bindings/Glx.cs b/Source/OpenTK/Platform/X11/Bindings/Glx.cs index 84d02466..08e9e8c9 100644 --- a/Source/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/Source/OpenTK/Platform/X11/Bindings/Glx.cs @@ -231,11 +231,14 @@ namespace OpenTK.Platform.X11 { DebugBit = 0x0001, ForwardCompatibleBit = 0x0002, + CoreProfileBit = 0x00000001, + CompatibilityProfileBit = 0x00000002, MajorVersion = 0x2091, MinorVersion = 0x2092, LayerPlane = 0x2093, Flags = 0x2094, ErrorInvalidVersion = 0x2095, + ProfileMask = 0x9126 } enum ErrorCode : int diff --git a/Source/OpenTK/Platform/X11/X11Factory.cs b/Source/OpenTK/Platform/X11/X11Factory.cs index d62f618d..8b8344df 100644 --- a/Source/OpenTK/Platform/X11/X11Factory.cs +++ b/Source/OpenTK/Platform/X11/X11Factory.cs @@ -77,7 +77,7 @@ namespace OpenTK.Platform.X11 public virtual IGraphicsMode CreateGraphicsMode() { - return new X11GraphicsMode(); + throw new NotSupportedException(); } public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver() diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 3275aa88..c8f4328a 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -33,6 +33,8 @@ namespace OpenTK.Platform.X11 int swap_interval = 1; // As defined in GLX_SGI_swap_control bool glx_loaded; + readonly X11GraphicsMode ModeSelector = new X11GraphicsMode(); + #endregion #region --- Constructors --- @@ -45,7 +47,9 @@ namespace OpenTK.Platform.X11 if (window == null) throw new ArgumentNullException("window"); - Mode = mode; + Mode = ModeSelector.SelectGraphicsMode( + mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, + mode.AccumulatorFormat, mode.Buffers, mode.Stereo); // Do not move this lower, as almost everything requires the Display // property to be correctly set. @@ -80,7 +84,7 @@ namespace OpenTK.Platform.X11 // HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through // GLX_ARB_create_context, including hideous input lag, no vsync and other madness. // Use legacy context creation if the user doesn't request a 3.0+ context. - if ((major * 10 + minor >= 30) && Glx.Delegates.glXCreateContextAttribsARB != null) + if ((major * 10 + minor >= 30) && SupportsCreateContextAttribs(Display, currentWindow)) { Debug.Write("Using GLX_ARB_create_context... "); @@ -104,9 +108,10 @@ namespace OpenTK.Platform.X11 attributes.Add(minor); if (flags != 0) { -#warning "This is not entirely correct: Embedded is not a valid flag! We need to add a GetARBContextFlags(GraphicsContextFlags) method." attributes.Add((int)ArbCreateContext.Flags); - attributes.Add((int)flags); + attributes.Add((int)GetARBContextFlags(flags)); + attributes.Add((int)ArbCreateContext.ProfileMask); + attributes.Add((int)GetARBProfileFlags(flags)); } // According to the docs, " specifies a list of attributes for the context. // The list consists of a sequence of pairs terminated by the @@ -225,23 +230,46 @@ namespace OpenTK.Platform.X11 #endregion - bool SupportsExtension(X11WindowInfo window, string e) + ArbCreateContext GetARBContextFlags(GraphicsContextFlags flags) + { + ArbCreateContext result = 0; + result |= (flags & GraphicsContextFlags.Debug) != 0 ? ArbCreateContext.DebugBit : 0; + return result; + } + + ArbCreateContext GetARBProfileFlags(GraphicsContextFlags flags) + { + ArbCreateContext result = 0; + result |= (flags & GraphicsContextFlags.ForwardCompatible) != 0 ? + ArbCreateContext.ForwardCompatibleBit : ArbCreateContext.CompatibilityProfileBit; + return result; + } + + static bool SupportsExtension(IntPtr display, X11WindowInfo window, string e) { if (window == null) throw new ArgumentNullException("window"); if (e == null) throw new ArgumentNullException("e"); - if (window.Display != Display) + if (window.Display != display) throw new InvalidOperationException(); string extensions = null; - using (new XLock(Display)) + using (new XLock(display)) { - extensions = Glx.QueryExtensionsString(Display, window.Screen); + extensions = Glx.QueryExtensionsString(display, window.Screen); } return !String.IsNullOrEmpty(extensions) && extensions.Contains(e); } + static bool SupportsCreateContextAttribs(IntPtr display, X11WindowInfo window) + { + return + SupportsExtension(display, window, "GLX_ARB_create_context") && + SupportsExtension(display, window, "GLX_ARB_create_context_profile") && + Glx.Delegates.glXCreateContextAttribsARB != null; + } + #endregion #region --- IGraphicsContext Members --- From 62d67917362c5777c901641fcd41aee59d645b41 Mon Sep 17 00:00:00 2001 From: parallels Date: Sat, 9 Nov 2013 18:50:53 +0100 Subject: [PATCH 14/16] Use glXGetProcAddressARB According to the Linux OpenGL ABI, glXGetProcAddressARB must be statically exported by libGL. This does *not* hold true for glXGetProcAddress. We must used the ARB version instead. Furthermore, glx entry points, unlike wgl, do not depend on any specific OpenGL context. This means we can load them in the constructor of the Glx class. --- Source/OpenTK/Platform/X11/Bindings/Glx.cs | 15 ++++++++++++++- Source/OpenTK/Platform/X11/GlxHelper.cs | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Source/OpenTK/Platform/X11/Bindings/Glx.cs b/Source/OpenTK/Platform/X11/Bindings/Glx.cs index 08e9e8c9..c5e3ccb6 100644 --- a/Source/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/Source/OpenTK/Platform/X11/Bindings/Glx.cs @@ -352,7 +352,7 @@ namespace OpenTK.Platform.X11 public partial class Arb { - #region CreateContextAttribs + #region CreateContextAttri unsafe public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs) { @@ -371,6 +371,19 @@ namespace OpenTK.Platform.X11 } #endregion + + #region GetProcAddress + + // The linux OpenGL ABI 3.6 (1999) requires + // that glXGetProcAddressARB be available as + // a static export. The same is *not* true + // for glXGetProcAddress, so we should use + // glXGetProcAddressARB instead. + // See http://www.opengl.org/registry/ABI/ + [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] + public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName); + + #endregion } internal static partial class Delegates diff --git a/Source/OpenTK/Platform/X11/GlxHelper.cs b/Source/OpenTK/Platform/X11/GlxHelper.cs index 3ec38c1b..36d4022f 100644 --- a/Source/OpenTK/Platform/X11/GlxHelper.cs +++ b/Source/OpenTK/Platform/X11/GlxHelper.cs @@ -20,17 +20,28 @@ namespace OpenTK.Platform.X11 const string Library = "libGL.so.1"; static readonly object sync_root = new object(); - // Disable BeforeFieldInit optimization. - static Glx() { } + static Glx() + { + // GLX entry points are not bound to a context. + // This means we can load them without creating + // a context first! (unlike WGL) + // See + // for more details. + Debug.WriteLine("Loading GLX entry points."); + new Glx().LoadEntryPoints(); + } protected override object SyncRoot { get { return sync_root; } } - protected override IntPtr GetAddress (string funcname) + protected override IntPtr GetAddress(string funcname) { - return Glx.GetProcAddress(funcname); + // We must use glXGetProcAddressARB, *not* + // glXGetProcAddress. See comment on function + // signature. + return Glx.Arb.GetProcAddress(funcname); } #if false From b08e59e8610bbc9578ca44f01708c352e9b34318 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Sat, 9 Nov 2013 18:55:17 +0100 Subject: [PATCH 15/16] Allow non-realized GraphicsMode It is now possible to pass a non-realized GraphicsMode to the X11GLContext and X11GLNative constructors. A non-realized GraphicsMode is a GraphicsMode with a null Index (i.e. which has not passed through SelectGraphicsMode()). --- Source/OpenTK/Platform/X11/X11GLContext.cs | 18 ++---------------- Source/OpenTK/Platform/X11/X11GLNative.cs | 10 +++++++--- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index c8f4328a..df840cd8 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -31,8 +31,6 @@ namespace OpenTK.Platform.X11 X11WindowInfo currentWindow; bool vsync_supported; int swap_interval = 1; // As defined in GLX_SGI_swap_control - bool glx_loaded; - readonly X11GraphicsMode ModeSelector = new X11GraphicsMode(); #endregion @@ -56,7 +54,7 @@ namespace OpenTK.Platform.X11 Display = ((X11WindowInfo)window).Display; currentWindow = (X11WindowInfo)window; - currentWindow.VisualInfo = SelectVisual(mode, currentWindow); + currentWindow.VisualInfo = SelectVisual(Mode, currentWindow); ContextHandle shareHandle = shared != null ? (shared as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero; @@ -66,18 +64,6 @@ namespace OpenTK.Platform.X11 Debug.WriteLine(shareHandle.Handle == IntPtr.Zero ? "not shared... " : String.Format("shared with ({0})... ", shareHandle)); - if (!glx_loaded) - { - // GLX entry points are not bound to a context. - // This means we can load them without creating - // a context first! (unlike WGL) - // See http://dri.freedesktop.org/wiki/glXGetProcAddressNeverReturnsNULL/ - // for more details. - Debug.WriteLine("Loading GLX entry points."); - new Glx().LoadEntryPoints(); - glx_loaded = true; - } - // Try using the new context creation method. If it fails, fall back to the old one. // For each of these methods, we try two times to create a context: // one with the "direct" flag intact, the other with the flag inversed. @@ -95,7 +81,7 @@ namespace OpenTK.Platform.X11 IntPtr* fbconfigs = Glx.ChooseFBConfig(Display, currentWindow.Screen, new int[] { (int)GLXAttribute.VISUAL_ID, - (int)mode.Index, + (int)Mode.Index, 0 }, out count); diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 3a1a3020..0e4ef49f 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -144,7 +144,11 @@ namespace OpenTK.Platform.X11 using (new XLock(window.Display)) { if (!mode.Index.HasValue) - throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); + { + mode = new X11GraphicsMode().SelectGraphicsMode( + mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, + mode.AccumulatorFormat, mode.Buffers, mode.Stereo); + } info.VisualID = mode.Index.Value; int dummy; @@ -1347,8 +1351,8 @@ namespace OpenTK.Platform.X11 public event EventHandler WindowBorderChanged = delegate { }; public event EventHandler WindowStateChanged = delegate { }; public event EventHandler KeyDown = delegate { }; - public event EventHandler KeyPress = delegate { }; - public event EventHandler KeyUp = delegate { }; + public event EventHandler KeyPress = delegate { }; + public event EventHandler KeyUp = delegate { }; public event EventHandler MouseEnter = delegate { }; public event EventHandler MouseLeave = delegate { }; From dc093f8fa9edb3cdcb6f3442127ac67ef143f0a5 Mon Sep 17 00:00:00 2001 From: Stefanos A Date: Sat, 9 Nov 2013 18:55:35 +0100 Subject: [PATCH 16/16] Added mapping for libXi On Debian-based distributions, libXi.so does not exist. We have to lookup libXi.so.6 instead. --- Source/OpenTK/OpenTK.dll.config | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/OpenTK/OpenTK.dll.config b/Source/OpenTK/OpenTK.dll.config index a404f98c..758e3ad7 100644 --- a/Source/OpenTK/OpenTK.dll.config +++ b/Source/OpenTK/OpenTK.dll.config @@ -5,6 +5,7 @@ +