├── OpenTK
├── OpenTK.dll
├── OpenTK.GLControl.dll
└── OpenTK.Compatibility.dll
├── WpfOpenTK.v12.suo
├── OtkWpfControl
├── Automization.png
├── App.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── App.xaml.cs
├── App.xaml
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Scene.cs
├── OtkWpfControl.csproj
└── OtkWpfControl.cs
├── OpenGLviaFramebuffer
├── Automization.png
├── App.xaml.cs
├── App.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── App.xaml
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Renderer.cs
├── OpenGLviaFramebuffer.csproj
└── FrameBufferHandler.cs
├── OpenGLviaWinformsHost
├── App.config
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── App.xaml.cs
├── MainWindow.xaml
├── App.xaml
├── MainWindow.xaml.cs
└── OpenGLviaWinformsHost.csproj
├── .gitignore
├── README.md
├── .github
└── workflows
│ └── ContiniousIntegrationBuild.yml
└── WpfOpenTK.sln
/OpenTK/OpenTK.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/OpenTK/OpenTK.dll
--------------------------------------------------------------------------------
/WpfOpenTK.v12.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/WpfOpenTK.v12.suo
--------------------------------------------------------------------------------
/OpenTK/OpenTK.GLControl.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/OpenTK/OpenTK.GLControl.dll
--------------------------------------------------------------------------------
/OpenTK/OpenTK.Compatibility.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/OpenTK/OpenTK.Compatibility.dll
--------------------------------------------------------------------------------
/OtkWpfControl/Automization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/OtkWpfControl/Automization.png
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Automization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/freakinpenguin/OpenTK-WPF/HEAD/OpenGLviaFramebuffer/Automization.png
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace OpenGLviaFramebuffer
2 | {
3 | using System.Windows;
4 |
5 | public partial class App : Application
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/OtkWpfControl/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/OtkWpfControl/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace OpenGLviaWinformsHost
2 | {
3 | using System.Windows;
4 |
5 | ///
6 | /// Interaktionslogik für "App.xaml"
7 | ///
8 | public partial class App : Application
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OtkWpfControl/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace OtkWpfControl
10 | {
11 | ///
12 | /// App.xaml の相互作用ロジック
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/OtkWpfControl/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # この .gitignore ファイルは Microsoft(R) Visual Studio によって自動的に作成されました。
3 | ################################################################################
4 |
5 | /OpenGLviaFramebuffer/bin/Debug
6 | /OpenGLviaFramebuffer/obj/Debug
7 | /OpenGLviaWinformsHost/obj/Debug
8 | /OpenGLviaWinformsHost/bin/Debug
9 | /OtkWpfControl/bin/Debug
10 | /OtkWpfControl/obj/Debug
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | OpenTK-WPF
2 |
3 | 
4 | ==========
5 | Examples of how to using OpenGL via OpenTK in WPF applications
6 |
7 | This solution contains two projects. One project shows the usage of OpenTK in WPF via a WindowsFormsHost and the other by using a Framebuffer object.
8 |
9 | The Framebuffer-approach is a "pure"-WPF-approach, but the WinformsHost-approach is faster (32 vs 48fps).
10 |
11 | Feel free to improve!
12 |
--------------------------------------------------------------------------------
/.github/workflows/ContiniousIntegrationBuild.yml:
--------------------------------------------------------------------------------
1 | name: Continious Integration Build
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 |
11 | build:
12 |
13 | strategy:
14 | matrix:
15 | configuration: [Debug, Release]
16 |
17 | runs-on: windows-latest # For a list of available runner types, refer to
18 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
19 |
20 | env:
21 | Solution_Name: WpfOpenTK.sln
22 |
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v2
26 | with:
27 | fetch-depth: 0
28 |
29 | - name: Setup MSBuild Path
30 | uses: microsoft/setup-msbuild@v1
31 |
32 | - name: Build
33 | run: msbuild $Solution_Name /p:Configuration=Release
34 |
35 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/OtkWpfControl/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OtkWpfControl.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator" , "11.0.0.0" )]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.34014
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenGLviaFramebuffer.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.34014
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenGLviaWinformsHost.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/OtkWpfControl/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/OtkWpfControl/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
8 | // アセンブリに関連付けられている情報を変更するには、
9 | // これらの属性値を変更してください。
10 | [assembly: AssemblyTitle( "OtkWpfControl" )]
11 | [assembly: AssemblyDescription( "" )]
12 | [assembly: AssemblyConfiguration( "" )]
13 | [assembly: AssemblyCompany( "" )]
14 | [assembly: AssemblyProduct( "OtkWpfControl" )]
15 | [assembly: AssemblyCopyright( "Copyright © 2016" )]
16 | [assembly: AssemblyTrademark( "" )]
17 | [assembly: AssemblyCulture( "" )]
18 |
19 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
20 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
21 | // その型の ComVisible 属性を true に設定してください。
22 | [assembly: ComVisible( false )]
23 |
24 | //ローカライズ可能なアプリケーションのビルドを開始するには、
25 | //.csproj ファイルの CultureYouAreCodingWith を
26 | // 内部で設定します。たとえば、
27 | //ソース ファイルで英語を使用している場合、 を en-US に設定します。次に、
28 | //下の NeutralResourceLanguage 属性のコメントを解除します。下の行の "en-US" を
29 | //プロジェクト ファイルの UICulture 設定と一致するよう更新します。
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None , //テーマ固有のリソース ディクショナリが置かれている場所
36 | //(リソースがページ、
37 | //またはアプリケーション リソース ディクショナリに見つからない場合に使用されます)
38 | ResourceDictionaryLocation.SourceAssembly //汎用リソース ディクショナリが置かれている場所
39 | //(リソースがページ、
40 | //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます)
41 | )]
42 |
43 |
44 | // アセンブリのバージョン情報は次の 4 つの値で構成されています:
45 | //
46 | // メジャー バージョン
47 | // マイナー バージョン
48 | // ビルド番号
49 | // Revision
50 | //
51 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
52 | // 既定値にすることができます:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion( "1.0.0.9" )]
55 | [assembly: AssemblyFileVersion( "1.0.0.0" )]
56 |
--------------------------------------------------------------------------------
/WpfOpenTK.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenGLviaFramebuffer", "OpenGLviaFramebuffer\OpenGLviaFramebuffer.csproj", "{AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenGLviaWinformsHost", "OpenGLviaWinformsHost\OpenGLviaWinformsHost.csproj", "{22188DDA-79F1-47C7-A871-530F1D662CEE}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OtkWpfControl", "OtkWpfControl\OtkWpfControl.csproj", "{8D741215-AAAF-4666-AAAA-A5A45F413CC6}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {22188DDA-79F1-47C7-A871-530F1D662CEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {22188DDA-79F1-47C7-A871-530F1D662CEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {22188DDA-79F1-47C7-A871-530F1D662CEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {22188DDA-79F1-47C7-A871-530F1D662CEE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {8D741215-AAAF-4666-AAAA-A5A45F413CC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {8D741215-AAAF-4666-AAAA-A5A45F413CC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {8D741215-AAAF-4666-AAAA-A5A45F413CC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {8D741215-AAAF-4666-AAAA-A5A45F413CC6}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/OtkWpfControl/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 |
12 |
13 | namespace OtkWpfControl
14 | {
15 | ///
16 | /// MainWindow.xaml の相互作用ロジック
17 | ///
18 | public partial class MainWindow : Window
19 | {
20 | public MainWindow()
21 | {
22 | InitializeComponent();
23 | }
24 |
25 | private void OtkWpfControl_Initialized( object sender , EventArgs e )
26 | {
27 | mScene.Initialize();
28 |
29 | // for example, get shader error then notify the error by MessageBox
30 | //var stat = mScene.Initialize();
31 | //if ( stat.Error )
32 | //{
33 | // // まだウインドウが表示されていないからこうしないと例外が出てしまう
34 | // // Sinse the window is not created yet, exceltion will be thrown
35 | // // http://stackoverflow.com/questions/7442943/dispatcher-throws-invalidoperationexception-on-messagebox-show-in-textchanged-ev
36 | // // https://social.msdn.microsoft.com/Forums/vstudio/en-US/44962927-006e-4629-9aa3-100357861442/dispatcher-processing-has-been-suspended-invalidoperationexception-when-calling-showdialog?forum=wpf
37 | // Application.Current.Dispatcher.BeginInvoke
38 | // (
39 | // System.Windows.Threading.DispatcherPriority.Normal ,
40 | // (Action)(() =>
41 | // {
42 | // MessageBox.Show( stat.ErrorMessage , stat.ErrorComponent );
43 | // })
44 | // );
45 |
46 | // Close();
47 | //}
48 | }
49 |
50 | private void OtkWpfControl_Resized( object sender , EventArgs e )
51 | {
52 | var ctrl = sender as OpenTK.WPF.OtkWpfControl;
53 | if ( ctrl != null )
54 | {
55 | mScene.Resize( ctrl.ActualWidth , ctrl.ActualHeight );
56 | }
57 | }
58 |
59 | private void OtkWpfControl_OpenGLDraw( object sender , OpenTK.WPF.OtkWpfControl.OpenGLDrawEventArgs e )
60 | {
61 | var ctrl = sender as OpenTK.WPF.OtkWpfControl;
62 | if ( ctrl != null )
63 | {
64 | // RederingTime is actual time from CompositionTarget.Rendering has started, not the interval
65 | e.Redrawn = mScene.Render( e.RenderingTime );
66 | }
67 | }
68 |
69 | private readonly Scene mScene = new Scene();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/OtkWpfControl/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // このコードはツールによって生成されました。
4 | // ランタイム バージョン:4.0.30319.42000
5 | //
6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7 | // コードが再生成されるときに損失したりします
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OtkWpfControl.Properties
12 | {
13 |
14 |
15 | ///
16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
17 | ///
18 | // このクラスは StronglyTypedResourceBuilder クラスによって ResGen
19 | // または Visual Studio のようなツールを使用して自動生成されました。
20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
21 | // ResGen を実行し直すか、または VS プロジェクトをリビルドします。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "System.Resources.Tools.StronglyTypedResourceBuilder" , "4.0.0.0" )]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( "Microsoft.Performance" , "CA1811:AvoidUncalledPrivateCode" )]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// このクラスで使用されるキャッシュされた ResourceManager インスタンスを返します。
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ( (resourceMan == null) )
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OtkWpfControl.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
56 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace OpenGLviaWinformsHost
2 | {
3 | using System;
4 | using System.Windows;
5 | using System.Windows.Forms;
6 | using System.Windows.Threading;
7 |
8 | using OpenGLviaFramebuffer;
9 |
10 | using OpenTK;
11 | using OpenTK.Graphics.OpenGL;
12 |
13 | using Size = System.Drawing.Size;
14 |
15 | public partial class MainWindow : Window
16 | {
17 | #region Fields
18 |
19 | private int frames;
20 |
21 | private GLControl glcontrol;
22 |
23 | private DateTime lastMeasureTime;
24 |
25 | private Renderer renderer;
26 |
27 | #endregion
28 |
29 | #region Constructors and Destructors
30 |
31 | public MainWindow()
32 | {
33 | this.InitializeComponent();
34 |
35 | this.renderer = new Renderer(new Size(400, 400));
36 |
37 | this.lastMeasureTime = DateTime.Now;
38 | this.frames = 0;
39 |
40 | this.glcontrol = new GLControl();
41 | this.glcontrol.Paint += this.GlcontrolOnPaint;
42 | this.glcontrol.Dock = DockStyle.Fill;
43 | this.Host.Child = this.glcontrol;
44 |
45 | DispatcherTimer timer = new DispatcherTimer();
46 | timer.Interval = TimeSpan.FromMilliseconds(1);
47 | timer.Tick += this.TimerOnTick;
48 | timer.Start();
49 | }
50 |
51 | #endregion
52 |
53 | #region Methods
54 |
55 | private void GlcontrolOnPaint(object sender, PaintEventArgs e)
56 | {
57 | this.glcontrol.MakeCurrent();
58 |
59 | GL.MatrixMode(MatrixMode.Projection);
60 | GL.LoadIdentity();
61 | float halfWidth = (float)(this.glcontrol.Width / 2);
62 | float halfHeight = (float)(this.glcontrol.Height / 2);
63 | GL.Ortho(-halfWidth, halfWidth, halfHeight, -halfHeight, 1000, -1000);
64 | GL.Viewport(this.glcontrol.Size);
65 |
66 | this.renderer.Render();
67 |
68 | GL.Finish();
69 |
70 | this.glcontrol.SwapBuffers();
71 |
72 | this.frames++;
73 | }
74 |
75 | private void TimerOnTick(object sender, EventArgs e)
76 | {
77 | if (DateTime.Now.Subtract(this.lastMeasureTime) > TimeSpan.FromSeconds(1))
78 | {
79 | this.Title = this.frames + "fps";
80 | this.frames = 0;
81 | this.lastMeasureTime = DateTime.Now;
82 | }
83 |
84 | this.glcontrol.Invalidate();
85 | }
86 |
87 | #endregion
88 | }
89 | }
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // Allgemeine Informationen über eine Assembly werden über die folgenden
8 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
9 | // die mit einer Assembly verknüpft sind.
10 | [assembly: AssemblyTitle("Framebuffer")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("Framebuffer")]
15 | [assembly: AssemblyCopyright("Copyright © 2014")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
20 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
21 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
22 | [assembly: ComVisible(false)]
23 |
24 | //Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie
25 | //ImCodeVerwendeteKultur in der .csproj-Datei
26 | //in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
27 | //(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
28 | //des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
29 | //sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
36 | //(wird verwendet, wenn eine Ressource auf der Seite
37 | // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
38 | ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
39 | //(wird verwendet, wenn eine Ressource auf der Seite, in der Anwendung oder einem
40 | // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
41 | )]
42 |
43 |
44 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
45 | //
46 | // Hauptversion
47 | // Nebenversion
48 | // Buildnummer
49 | // Revision
50 | //
51 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
52 | // übernehmen, indem Sie "*" eingeben:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // Allgemeine Informationen über eine Assembly werden über die folgenden
8 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
9 | // die mit einer Assembly verknüpft sind.
10 | [assembly: AssemblyTitle("WpfNativeOpenGLSample")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("WpfNativeOpenGLSample")]
15 | [assembly: AssemblyCopyright("Copyright © 2014")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
20 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
21 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
22 | [assembly: ComVisible(false)]
23 |
24 | //Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie
25 | //ImCodeVerwendeteKultur in der .csproj-Datei
26 | //in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
27 | //(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
28 | //des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
29 | //sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
36 | //(wird verwendet, wenn eine Ressource auf der Seite
37 | // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
38 | ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
39 | //(wird verwendet, wenn eine Ressource auf der Seite, in der Anwendung oder einem
40 | // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
41 | )]
42 |
43 |
44 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
45 | //
46 | // Hauptversion
47 | // Nebenversion
48 | // Buildnummer
49 | // Revision
50 | //
51 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
52 | // übernehmen, indem Sie "*" eingeben:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.18")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace OpenGLviaFramebuffer
2 | {
3 | using System;
4 | using System.Windows;
5 | using System.Windows.Media.Imaging;
6 | using System.Windows.Threading;
7 |
8 | using OpenTK.Graphics.OpenGL;
9 |
10 | using Size = System.Drawing.Size;
11 |
12 | public partial class MainWindow : Window
13 | {
14 | #region Fields
15 |
16 | private WriteableBitmap backbuffer;
17 |
18 | private FrameBufferHandler framebufferHandler;
19 |
20 | private int frames;
21 |
22 | private DateTime lastMeasureTime;
23 |
24 | private Renderer renderer;
25 |
26 | #endregion
27 |
28 | #region Constructors and Destructors
29 |
30 | public MainWindow()
31 | {
32 | this.InitializeComponent();
33 |
34 | this.renderer = new Renderer(new Size(400, 400));
35 | this.framebufferHandler = new FrameBufferHandler();
36 |
37 | DispatcherTimer timer = new DispatcherTimer();
38 | timer.Interval = TimeSpan.FromMilliseconds(1);
39 | timer.Tick += this.TimerOnTick;
40 | timer.Start();
41 | }
42 |
43 | #endregion
44 |
45 | #region Methods
46 |
47 | private void Render()
48 | {
49 | if (this.image.ActualWidth <= 0 || this.image.ActualHeight <= 0)
50 | {
51 | return;
52 | }
53 |
54 | this.framebufferHandler.Prepare( new Size( (int)this.imageContainer.ActualWidth , (int)this.imageContainer.ActualHeight ) );
55 |
56 | GL.MatrixMode( MatrixMode.Projection );
57 | GL.LoadIdentity();
58 | float halfWidth = (float)(this.imageContainer.ActualWidth / 2);
59 | float halfHeight = (float)(this.imageContainer.ActualHeight / 2);
60 | GL.Ortho( -halfWidth , halfWidth , -halfHeight , halfHeight , 1000 , -1000 );
61 | GL.Viewport( 0 , 0 , (int)this.imageContainer.ActualWidth , (int)this.imageContainer.ActualHeight );
62 |
63 | this.renderer.Render();
64 |
65 | GL.Finish();
66 |
67 | this.framebufferHandler.Cleanup(ref this.backbuffer);
68 |
69 | if (this.backbuffer != null)
70 | {
71 | this.image.Source = this.backbuffer;
72 | }
73 |
74 | this.frames++;
75 | }
76 |
77 | private void TimerOnTick(object sender, EventArgs eventArgs)
78 | {
79 | if (DateTime.Now.Subtract(this.lastMeasureTime) > TimeSpan.FromSeconds(1))
80 | {
81 | this.Title = this.frames + "fps";
82 | this.frames = 0;
83 | this.lastMeasureTime = DateTime.Now;
84 | }
85 |
86 | this.Render();
87 | }
88 |
89 | #endregion
90 | }
91 | }
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Renderer.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace OpenGLviaFramebuffer
3 | {
4 | using System;
5 | using System.Drawing;
6 |
7 | using OpenTK;
8 | using OpenTK.Graphics.OpenGL;
9 |
10 | ///
11 | /// The renderer.
12 | ///
13 | public class Renderer
14 | {
15 | #region Fields
16 |
17 | private float angle;
18 |
19 | private int displayList;
20 |
21 | private Size size;
22 |
23 | #endregion
24 |
25 | #region Constructors and Destructors
26 |
27 | public Renderer(Size size)
28 | {
29 | this.size = size;
30 | }
31 |
32 | #endregion
33 |
34 | #region Public Methods and Operators
35 |
36 | public void Render()
37 | {
38 | if ( this.displayList <= 0 )
39 | {
40 | this.displayList = GL.GenLists( 1 );
41 | GL.NewList( this.displayList , ListMode.Compile );
42 |
43 | GL.Color3( Color.Red );
44 |
45 | GL.Begin( PrimitiveType.Points );
46 |
47 | Random rnd = new Random();
48 | for ( int i = 0; i < 1000000; i++ )
49 | {
50 | float factor = 0.2f;
51 | Vector3 position = new Vector3(
52 | rnd.Next(-1000, 1000) * factor,
53 | rnd.Next(-1000, 1000) * factor,
54 | rnd.Next(-1000, 1000) * factor);
55 | GL.Vertex3( position );
56 |
57 | position.Normalize();
58 | GL.Normal3( position );
59 | }
60 |
61 | GL.End();
62 |
63 | GL.EndList();
64 | }
65 |
66 | GL.Enable( EnableCap.Lighting );
67 | GL.Enable( EnableCap.Light0 );
68 | GL.Enable( EnableCap.Blend );
69 | GL.BlendFunc( BlendingFactorSrc.SrcAlpha , BlendingFactorDest.OneMinusSrcAlpha );
70 | GL.Enable( EnableCap.DepthTest );
71 |
72 | GL.ClearColor( Color.FromArgb( 200 , Color.LightBlue ) );
73 | GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
74 |
75 | GL.MatrixMode(MatrixMode.Modelview);
76 | GL.LoadIdentity();
77 |
78 | float halfWidth = this.size.Width * 0.5f;
79 | this.angle += 1f;
80 | GL.Rotate( this.angle , Vector3.UnitZ );
81 | GL.Rotate( this.angle , Vector3.UnitY );
82 | GL.Rotate( this.angle , Vector3.UnitX );
83 | GL.Translate( 0.5f , 0 , 0 );
84 |
85 | GL.CallList( this.displayList );
86 |
87 | GL.MatrixMode( MatrixMode.Modelview );
88 | GL.LoadIdentity();
89 |
90 | GL.Begin( PrimitiveType.Triangles );
91 |
92 | GL.Color4( Color.Green );
93 | GL.Vertex3( 0 , 300 , 0 ); // top of the triangle
94 | GL.Vertex3( 0 , 0 , 0 ); // left-bottom of the triangle
95 | GL.Vertex3( 300 , 0 , 0 ); // right-bottom of the triangle
96 |
97 | GL.End();
98 | }
99 |
100 | #endregion
101 | }
102 | }
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.34014
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenGLviaFramebuffer.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
17 | ///
18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenGLviaFramebuffer.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Dieser Code wurde von einem Tool generiert.
4 | // Laufzeitversion:4.0.30319.34014
5 | //
6 | // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
7 | // der Code erneut generiert wird.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenGLviaWinformsHost.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
17 | ///
18 | // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
19 | // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
20 | // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
21 | // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenGLviaWinformsHost.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
51 | /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/OtkWpfControl/Scene.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | using OpenTK;
5 | using OpenTK.Graphics.OpenGL;
6 |
7 | namespace OtkWpfControl
8 | {
9 | ///
10 | /// The renderer.
11 | ///
12 | public class Scene
13 | {
14 | ///
15 | /// initialize the scene
16 | /// shaders, buffers, basic OpenGL settings
17 | ///
18 | public void Initialize()
19 | {
20 | }
21 |
22 | ///
23 | /// re-initialize size related staffs
24 | ///
25 | ///
26 | ///
27 | public void Resize( double width , double height )
28 | {
29 | this.size = new Size( (int)width , (int)height );
30 |
31 | GL.MatrixMode( MatrixMode.Projection );
32 | GL.LoadIdentity();
33 | float halfWidth = (float)(this.size.Width / 2);
34 | float halfHeight = (float)(this.size.Height / 2);
35 | GL.Ortho( -halfWidth , halfWidth , -halfHeight , halfHeight , 1000 , -1000 );
36 | GL.Viewport( 0 , 0 , (int)this.size.Width , (int)this.size.Height );
37 | }
38 |
39 | ///
40 | /// render a scene , same as OpenGLviaFramebuffer
41 | /// it's better to make animation depending on the time, not the interval nor assuming frame rate
42 | ///
43 | ///
44 | ///
45 | public bool Render( TimeSpan time )
46 | {
47 | if ( this.displayList <= 0 )
48 | {
49 | this.displayList = GL.GenLists( 1 );
50 | GL.NewList( this.displayList , ListMode.Compile );
51 |
52 | GL.Color3( Color.Red );
53 |
54 | GL.Begin( PrimitiveType.Points );
55 |
56 | Random rnd = new Random();
57 | for ( int i = 0; i < 1000000; i++ )
58 | {
59 | float factor = 0.2f;
60 | Vector3 position = new Vector3(
61 | rnd.Next(-1000, 1000) * factor,
62 | rnd.Next(-1000, 1000) * factor,
63 | rnd.Next(-1000, 1000) * factor);
64 | GL.Vertex3( position );
65 |
66 | position.Normalize();
67 | GL.Normal3( position );
68 | }
69 |
70 | GL.End();
71 |
72 | GL.EndList();
73 | }
74 |
75 | GL.Enable( EnableCap.Lighting );
76 | GL.Enable( EnableCap.Light0 );
77 | GL.Enable( EnableCap.Blend );
78 | GL.BlendFunc( BlendingFactorSrc.SrcAlpha , BlendingFactorDest.OneMinusSrcAlpha );
79 | GL.Enable( EnableCap.DepthTest );
80 |
81 | GL.ClearColor( Color.FromArgb( 200 , Color.LightBlue ) );
82 | GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
83 |
84 | GL.MatrixMode(MatrixMode.Modelview);
85 | GL.LoadIdentity();
86 |
87 | float halfWidth = this.size.Width * 0.5f;
88 | this.angle += 1f;
89 | GL.Rotate( this.angle , Vector3.UnitZ );
90 | GL.Rotate( this.angle , Vector3.UnitY );
91 | GL.Rotate( this.angle , Vector3.UnitX );
92 | GL.Translate( 0.5f , 0 , 0 );
93 |
94 | GL.CallList( this.displayList );
95 |
96 | GL.MatrixMode( MatrixMode.Modelview );
97 | GL.LoadIdentity();
98 |
99 | GL.Begin( PrimitiveType.Triangles );
100 |
101 | GL.Color4( Color.Green );
102 | GL.Vertex3( 0 , 300 , 0 ); // top of the triangle
103 | GL.Vertex3( 0 , 0 , 0 ); // left-bottom of the triangle
104 | GL.Vertex3( 300 , 0 , 0 ); // right-bottom of the triangle
105 |
106 | GL.End();
107 |
108 | return true; // continue animation
109 | }
110 |
111 | #region Fields
112 |
113 | private float angle;
114 |
115 | private int displayList;
116 |
117 | private Size size;
118 |
119 | #endregion
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/OtkWpfControl/OtkWpfControl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8D741215-AAAF-4666-AAAA-A5A45F413CC6}
8 | WinExe
9 | Properties
10 | OtkWpfControl
11 | OtkWpfControl
12 | v4.6.1
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 | False
40 | ..\OpenTK\OpenTK.dll
41 |
42 |
43 | False
44 | ..\OpenTK\OpenTK.GLControl.dll
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | 4.0
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | MSBuild:Compile
66 | Designer
67 |
68 |
69 |
70 | MSBuild:Compile
71 | Designer
72 |
73 |
74 | App.xaml
75 | Code
76 |
77 |
78 | MainWindow.xaml
79 | Code
80 |
81 |
82 |
83 |
84 |
85 | Code
86 |
87 |
88 | True
89 | True
90 | Resources.resx
91 |
92 |
93 | True
94 | Settings.settings
95 | True
96 |
97 |
98 | ResXFileCodeGenerator
99 | Resources.Designer.cs
100 |
101 |
102 | SettingsSingleFileGenerator
103 | Settings.Designer.cs
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
121 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/OpenGLviaFramebuffer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {AF0E25E1-6F12-4E3A-A698-BE3A7A5AEE54}
8 | WinExe
9 | Properties
10 | OpenGLviaFramebuffer
11 | OpenGLviaFramebuffer
12 | v4.5
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 | False
39 | ..\OpenTK\OpenTK.dll
40 |
41 |
42 | False
43 | ..\OpenTK\OpenTK.Compatibility.dll
44 |
45 |
46 | False
47 | ..\OpenTK\OpenTK.GLControl.dll
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 4.0
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | MSBuild:Compile
69 | Designer
70 |
71 |
72 |
73 | MSBuild:Compile
74 | Designer
75 |
76 |
77 | App.xaml
78 | Code
79 |
80 |
81 | MainWindow.xaml
82 | Code
83 |
84 |
85 |
86 |
87 |
88 | Code
89 |
90 |
91 | True
92 | True
93 | Resources.resx
94 |
95 |
96 | True
97 | Settings.settings
98 | True
99 |
100 |
101 | ResXFileCodeGenerator
102 | Resources.Designer.cs
103 |
104 |
105 | SettingsSingleFileGenerator
106 | Settings.Designer.cs
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
124 |
--------------------------------------------------------------------------------
/OtkWpfControl/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/OpenGLviaWinformsHost/OpenGLviaWinformsHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {22188DDA-79F1-47C7-A871-530F1D662CEE}
8 | WinExe
9 | Properties
10 | OpenGLviaWinformsHost
11 | OpenGLviaWinformsHost
12 | v4.5
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 | False
39 | ..\OpenTK\OpenTK.dll
40 |
41 |
42 | False
43 | ..\OpenTK\OpenTK.Compatibility.dll
44 |
45 |
46 | False
47 | ..\OpenTK\OpenTK.GLControl.dll
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 4.0
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | MSBuild:Compile
69 | Designer
70 |
71 |
72 | MSBuild:Compile
73 | Designer
74 |
75 |
76 | App.xaml
77 | Code
78 |
79 |
80 | MainWindow.xaml
81 | Code
82 |
83 |
84 |
85 |
86 | Code
87 |
88 |
89 | True
90 | True
91 | Resources.resx
92 |
93 |
94 | True
95 | Settings.settings
96 | True
97 |
98 |
99 | ResXFileCodeGenerator
100 | Resources.Designer.cs
101 |
102 |
103 | SettingsSingleFileGenerator
104 | Settings.Designer.cs
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | {af0e25e1-6f12-4e3a-a698-be3a7a5aee54}
114 | OpenGLviaFramebuffer
115 |
116 |
117 |
118 |
125 |
--------------------------------------------------------------------------------
/OpenGLviaFramebuffer/FrameBufferHandler.cs:
--------------------------------------------------------------------------------
1 | namespace OpenGLviaFramebuffer
2 | {
3 | using System;
4 | using System.Windows;
5 | using System.Windows.Media;
6 | using System.Windows.Media.Imaging;
7 |
8 | using OpenTK;
9 | using OpenTK.Graphics;
10 |
11 | using FramebufferAttachment = OpenTK.Graphics.OpenGL.FramebufferAttachment;
12 | using FramebufferErrorCode = OpenTK.Graphics.OpenGL.FramebufferErrorCode;
13 | using FramebufferTarget = OpenTK.Graphics.OpenGL.FramebufferTarget;
14 | using GL = OpenTK.Graphics.OpenGL.GL;
15 | using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
16 | using PixelInternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat;
17 | using PixelType = OpenTK.Graphics.OpenGL.PixelType;
18 | using RenderbufferStorage = OpenTK.Graphics.OpenGL.RenderbufferStorage;
19 | using RenderbufferTarget = OpenTK.Graphics.OpenGL.RenderbufferTarget;
20 | using Size = System.Drawing.Size;
21 | using TextureMagFilter = OpenTK.Graphics.OpenGL.TextureMagFilter;
22 | using TextureMinFilter = OpenTK.Graphics.OpenGL.TextureMinFilter;
23 | using TextureParameterName = OpenTK.Graphics.OpenGL.TextureParameterName;
24 | using TextureTarget = OpenTK.Graphics.OpenGL.TextureTarget;
25 | using TextureWrapMode = OpenTK.Graphics.OpenGL.TextureWrapMode;
26 |
27 | internal class FrameBufferHandler
28 | {
29 | #region Fields
30 |
31 | private int depthbufferId;
32 |
33 | private int framebufferId;
34 |
35 | private GLControl glControl;
36 |
37 | private bool loaded;
38 |
39 | private Size size;
40 |
41 | private int colorbufferId;
42 |
43 | private byte[] readBuf;
44 |
45 | #endregion
46 |
47 | #region Constructors and Destructors
48 |
49 | public FrameBufferHandler()
50 | {
51 | this.loaded = false;
52 | this.size = Size.Empty;
53 | this.framebufferId = -1;
54 |
55 | this.glControl = new GLControl(new GraphicsMode(DisplayDevice.Default.BitsPerPixel, 16, 0, 4, 0, 2, false));
56 | this.glControl.MakeCurrent();
57 | }
58 |
59 | #endregion
60 |
61 | #region Methods
62 |
63 | internal void Cleanup(ref WriteableBitmap backbuffer)
64 | {
65 | if (backbuffer == null || backbuffer.Width != this.size.Width || backbuffer.Height != this.size.Height)
66 | {
67 | backbuffer = new WriteableBitmap(
68 | this.size.Width,
69 | this.size.Height,
70 | 96,
71 | 96,
72 | PixelFormats.Pbgra32,
73 | BitmapPalettes.WebPalette);
74 | readBuf = new byte[this.size.Width*this.size.Height*4];
75 | }
76 |
77 | GL.ReadPixels( 0 , 0 , this.size.Width , this.size.Height , PixelFormat.Bgra , PixelType.UnsignedByte , readBuf );
78 |
79 | // copy pixels upside down
80 | backbuffer.Lock();
81 |
82 | var src = new Int32Rect( 0 , 0 , (int)backbuffer.Width , 1 );
83 | for ( int y = 0; y<(int)backbuffer.Height; y++ )
84 | {
85 | src.Y = (int)backbuffer.Height - y - 1;
86 | backbuffer.WritePixels( src , readBuf , backbuffer.BackBufferStride , 0 , y );
87 | }
88 |
89 | backbuffer.AddDirtyRect(new Int32Rect(0, 0, (int)backbuffer.Width, (int)backbuffer.Height));
90 | backbuffer.Unlock();
91 | }
92 |
93 | internal void Prepare(Size framebuffersize)
94 | {
95 | if (GraphicsContext.CurrentContext != this.glControl.Context)
96 | {
97 | this.glControl.MakeCurrent();
98 | }
99 |
100 | if (framebuffersize != this.size || this.loaded == false)
101 | {
102 | this.size = framebuffersize;
103 | this.CreateFramebuffer();
104 | }
105 |
106 | GL.BindFramebuffer(FramebufferTarget.Framebuffer, this.framebufferId);
107 | }
108 |
109 | private void CreateFramebuffer()
110 | {
111 | this.glControl.MakeCurrent();
112 |
113 | if (this.framebufferId > 0)
114 | {
115 | GL.DeleteFramebuffer(this.framebufferId);
116 | }
117 |
118 | if (this.depthbufferId > 0)
119 | {
120 | GL.DeleteRenderbuffer(this.depthbufferId);
121 | }
122 |
123 | if ( this.colorbufferId > 0 )
124 | {
125 | GL.DeleteRenderbuffer( this.colorbufferId );
126 | }
127 |
128 | this.framebufferId = GL.GenFramebuffer();
129 | GL.BindFramebuffer(FramebufferTarget.Framebuffer, this.framebufferId);
130 |
131 | this.colorbufferId = GL.GenRenderbuffer();
132 | GL.BindRenderbuffer( RenderbufferTarget.Renderbuffer , this.colorbufferId );
133 | GL.RenderbufferStorage(
134 | RenderbufferTarget.Renderbuffer ,
135 | RenderbufferStorage.Rgba8 ,
136 | this.size.Width ,
137 | this.size.Height );
138 | GL.FramebufferRenderbuffer(
139 | FramebufferTarget.Framebuffer ,
140 | FramebufferAttachment.ColorAttachment0 ,
141 | RenderbufferTarget.Renderbuffer ,
142 | this.colorbufferId );
143 |
144 | this.depthbufferId = GL.GenRenderbuffer();
145 | GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, this.depthbufferId);
146 | GL.RenderbufferStorage(
147 | RenderbufferTarget.Renderbuffer,
148 | RenderbufferStorage.DepthComponent24,
149 | this.size.Width,
150 | this.size.Height);
151 | GL.FramebufferRenderbuffer(
152 | FramebufferTarget.Framebuffer,
153 | FramebufferAttachment.DepthAttachment,
154 | RenderbufferTarget.Renderbuffer,
155 | this.depthbufferId);
156 |
157 | FramebufferErrorCode error = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
158 | if (error != FramebufferErrorCode.FramebufferComplete)
159 | {
160 | throw new Exception();
161 | }
162 |
163 | this.loaded = true;
164 | }
165 |
166 | #endregion
167 | }
168 | }
--------------------------------------------------------------------------------
/OtkWpfControl/OtkWpfControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.ComponentModel;
5 | using System.Diagnostics;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Media;
9 | using System.Windows.Media.Imaging;
10 |
11 | using OpenTK;
12 | using OpenTK.Graphics;
13 |
14 | namespace OpenTK.WPF
15 | {
16 | using FramebufferAttachment = OpenTK.Graphics.OpenGL.FramebufferAttachment;
17 | using FramebufferErrorCode = OpenTK.Graphics.OpenGL.FramebufferErrorCode;
18 | using FramebufferTarget = OpenTK.Graphics.OpenGL.FramebufferTarget;
19 | using GL = OpenTK.Graphics.OpenGL.GL;
20 | using PixelFormat = OpenTK.Graphics.OpenGL.PixelFormat;
21 | using PixelType = OpenTK.Graphics.OpenGL.PixelType;
22 | using RenderbufferStorage = OpenTK.Graphics.OpenGL.RenderbufferStorage;
23 | using RenderbufferTarget = OpenTK.Graphics.OpenGL.RenderbufferTarget;
24 |
25 | public class OtkWpfControl : UserControl
26 | {
27 | #region Dependency Properties
28 |
29 | #region DrawTime
30 |
31 | ///
32 | /// measured drawing time for a frame in milliseconds
33 | ///
34 | private static readonly DependencyProperty DrawTimeProperty = DependencyProperty.Register
35 | (
36 | "DrawTime",
37 | typeof(double),
38 | typeof(OtkWpfControl),
39 | new PropertyMetadata( 0.0 )
40 | );
41 |
42 | public double DrawTime
43 | {
44 | get { return (double)GetValue( DrawTimeProperty ); }
45 | set { SetValue( DrawTimeProperty , value ); }
46 | }
47 |
48 | #endregion DrawTime
49 |
50 | #region VersionMajor
51 |
52 | ///
53 | /// specify OpenGL version major part , default version is 2.0
54 | ///
55 | private static readonly DependencyProperty VersionMajorProperty = DependencyProperty.Register
56 | (
57 | "VersionMajor",
58 | typeof(int),
59 | typeof(OtkWpfControl),
60 | new PropertyMetadata( 2 )
61 | );
62 |
63 | public int VersionMajor
64 | {
65 | get { return (int)GetValue( VersionMajorProperty ); }
66 | set { SetValue( VersionMajorProperty , value ); }
67 | }
68 |
69 | #endregion VersionMajor
70 |
71 | #region VersionMinor
72 |
73 | ///
74 | /// specify OpenGL version minor part , default version is 2.0
75 | ///
76 | private static readonly DependencyProperty VersionMinorProperty = DependencyProperty.Register
77 | (
78 | "VersionMinor",
79 | typeof(int),
80 | typeof(OtkWpfControl),
81 | new PropertyMetadata( 0 )
82 | );
83 |
84 | public int VersionMinor
85 | {
86 | get { return (int)GetValue( VersionMinorProperty ); }
87 | set { SetValue( VersionMinorProperty , value ); }
88 | }
89 |
90 | #endregion VersionMinor
91 |
92 | #endregion Dependency Properties
93 |
94 | #region Events
95 |
96 | ///
97 | /// Occurs when OpenGL should be initialised.
98 | ///
99 | [Description("Called when OpenGL has been initialized."), Category("SharpGL")]
100 | public event EventHandler OpenGLInitialized;
101 |
102 | ///
103 | /// Occurs when the control is resized. This can be used to perform custom projections.
104 | ///
105 | [Description("Called when the control is resized - you can use this to do custom viewport projections."), Category("SharpGL")]
106 | public event EventHandler Resized;
107 |
108 | ///
109 | /// event args for draw timeming
110 | ///
111 | public class OpenGLDrawEventArgs : EventArgs
112 | {
113 | ///
114 | /// true if handler requires drawing (refresh image)
115 | /// initially false , means skip refreshing the image
116 | ///
117 | public bool Redrawn { get; set; }
118 |
119 | ///
120 | /// time from CompositionTarget_Rendering has attached
121 | /// this is not the interval
122 | ///
123 | public TimeSpan RenderingTime { get; set; }
124 | }
125 |
126 | ///
127 | /// Occurs when OpenGL drawing should occur.
128 | ///
129 | [Description("Called whenever OpenGL drawing can should occur."), Category("SharpGL")]
130 | public event EventHandler OpenGLDraw;
131 |
132 | #endregion Events
133 |
134 | ///
135 | /// Initializes a new instance
136 | ///
137 | public OtkWpfControl()
138 | {
139 | Content = mImage;
140 |
141 | Unloaded += OpenGLControl_Unloaded;
142 | Loaded += OpenGLControl_Loaded;
143 | }
144 |
145 | ///
146 | /// When overridden in a derived class, is invoked whenever application code or
147 | /// internal processes call .
148 | ///
149 | public override void OnApplyTemplate()
150 | {
151 | // Call the base.
152 | base.OnApplyTemplate();
153 |
154 | // initialize framebufferhandler for OpeTK
155 | mLoaded = false;
156 | mSize = Size.Empty;
157 | mFramebufferId = -1;
158 |
159 | var gmode = new GraphicsMode( DisplayDevice.Default.BitsPerPixel , 16 , 0 , 4 , 0 , 2 , false );
160 | mTkGlControl = new GLControl( gmode , VersionMajor , VersionMinor , GraphicsContextFlags.Default );
161 | mTkGlControl.MakeCurrent();
162 |
163 | // Fire the OpenGL initialised event.
164 | OpenGLInitialized?.Invoke( this , EventArgs.Empty );
165 | }
166 |
167 | #region Implementation
168 |
169 | #region Event Handlers
170 |
171 | ///
172 | /// Handles the Loaded event of the OpenGLControl control.
173 | ///
174 | /// The source of the event.
175 | /// The Instance containing the event data.
176 | private void OpenGLControl_Loaded( object sender , RoutedEventArgs routedEventArgs )
177 | {
178 | SizeChanged += OpenGLControl_SizeChanged;
179 |
180 | UpdateOpenGLControl( RenderSize );
181 |
182 | // start rendering to be on WPF redering timing
183 | CompositionTarget.Rendering += CompositionTarget_Rendering;
184 | }
185 |
186 | ///
187 | /// Handles the Unloaded event of the OpenGLControl control.
188 | ///
189 | /// The source of the event.
190 | /// The Instance containing the event data.
191 | private void OpenGLControl_Unloaded( object sender , RoutedEventArgs routedEventArgs )
192 | {
193 | SizeChanged -= OpenGLControl_SizeChanged;
194 | CompositionTarget.Rendering -= CompositionTarget_Rendering;
195 | }
196 |
197 | ///
198 | /// Handles the SizeChanged event of the OpenGLControl control.
199 | ///
200 | /// The source of the event.
201 | /// The Instance containing the event data.
202 | private void OpenGLControl_SizeChanged( object sender , SizeChangedEventArgs e )
203 | {
204 | UpdateOpenGLControl( e.NewSize );
205 | }
206 |
207 | ///
208 | /// Handles the WPF redering timming
209 | ///
210 | /// The source of the event.
211 | /// cast RenderingEventArgs to know RenderginTime
212 | private void CompositionTarget_Rendering( object sender , EventArgs e )
213 | {
214 | // https://evanl.wordpress.com/2009/12/06/efficient-optimal-per-frame-eventing-in-wpf/
215 | var args = (RenderingEventArgs)e;
216 | if ( args.RenderingTime == mLast )
217 | {
218 | return;
219 | }
220 | mLast = args.RenderingTime;
221 |
222 | // Start the stopwatch so that we can time the rendering.
223 | mStopwatch.Restart();
224 |
225 | // import from FrameBufferHandler
226 | if ( GraphicsContext.CurrentContext != mTkGlControl.Context )
227 | {
228 | mTkGlControl.MakeCurrent();
229 | }
230 |
231 | var framebuffersize = new Size( ActualWidth , ActualHeight );
232 | if ( framebuffersize != mSize || mLoaded == false )
233 | {
234 | mSize = framebuffersize;
235 | CreateFramebuffer();
236 | GL.Viewport( 0 , 0 , (int)ActualWidth , (int)ActualHeight );
237 | }
238 |
239 | // all of drawing commands will be performed onto the FBO
240 | GL.BindFramebuffer( FramebufferTarget.Framebuffer , mFramebufferId );
241 |
242 | // If there is a draw handler, then call it.
243 | var handler = OpenGLDraw;
244 | if ( handler != null )
245 | {
246 | var ev = new OpenGLDrawEventArgs() { Redrawn=false , RenderingTime = (e as RenderingEventArgs).RenderingTime };
247 | handler( this , ev );
248 | if ( !ev.Redrawn )
249 | {
250 | // handler doesn't draw anything then skip refresh the image
251 | mStopwatch.Stop();
252 | return;
253 | }
254 | }
255 | else
256 | {
257 | GL.Clear( Graphics.OpenGL.ClearBufferMask.ColorBufferBit );
258 | }
259 |
260 | // wait FBO has completed drawing
261 | GL.Finish();
262 |
263 | if ( mDrawnImage == null || mDrawnImage.Width != mSize.Width || mDrawnImage.Height != mSize.Height )
264 | {
265 | // create bitmap for imagesource to be displayed
266 | mDrawnImage = new WriteableBitmap( (int)mSize.Width , (int)mSize.Height , 96 , 96 , PixelFormats.Pbgra32 , BitmapPalettes.WebPalette );
267 |
268 | // (re)assign read buffer
269 | mBackbuffer = new byte[(int)mSize.Width * (int)mSize.Height * 4];
270 | }
271 |
272 | // to avoid image upside down, read to another memory
273 | GL.ReadPixels( 0 , 0 , (int)mSize.Width , (int)mSize.Height , PixelFormat.Bgra , PixelType.UnsignedByte , mBackbuffer );
274 |
275 | // WriteableBitmap should be locked as short as possible
276 | mDrawnImage.Lock();
277 |
278 | // copy pixels upside down
279 | var src = new Int32Rect( 0 , 0 , (int)mDrawnImage.Width , 1 );
280 | for ( int y=0; y<(int)mDrawnImage.Height; y++ )
281 | {
282 | src.Y = (int)mDrawnImage.Height - y - 1;
283 | mDrawnImage.WritePixels( src , mBackbuffer , mDrawnImage.BackBufferStride , 0 , y );
284 | }
285 | mDrawnImage.AddDirtyRect( new Int32Rect( 0 , 0 , (int)mDrawnImage.Width , (int)mDrawnImage.Height ) );
286 |
287 | mDrawnImage.Unlock();
288 |
289 | if ( mBackbuffer != null )
290 | {
291 | // refresh displayed image
292 | mImage.Source = mDrawnImage;
293 | }
294 |
295 | // Stop the stopwatch.
296 | mStopwatch.Stop();
297 |
298 | // Store the frame drawing time.
299 | DrawTime = mStopwatch.Elapsed.TotalMilliseconds;
300 | }
301 |
302 | #endregion Event Handlers
303 |
304 | ///
305 | /// tell handler control being resized
306 | ///
307 | /// The width of the OpenGL drawing area.
308 | /// The height of the OpenGL drawing area.
309 | private void UpdateOpenGLControl( Size framebuffersize )
310 | {
311 | Resized?.Invoke( this , EventArgs.Empty );
312 | }
313 |
314 | ///
315 | /// create FBO for offscreen derndering using a render buffer
316 | ///
317 | private void CreateFramebuffer()
318 | {
319 | mTkGlControl.MakeCurrent();
320 |
321 | if ( mFramebufferId > 0 )
322 | {
323 | GL.DeleteFramebuffer( mFramebufferId );
324 | }
325 |
326 | if ( mColorbufferId > 0 )
327 | {
328 | GL.DeleteRenderbuffer( mColorbufferId );
329 | }
330 |
331 | if ( mDepthbufferId > 0 )
332 | {
333 | GL.DeleteRenderbuffer( mDepthbufferId );
334 | }
335 |
336 | mFramebufferId = GL.GenFramebuffer();
337 | GL.BindFramebuffer( FramebufferTarget.Framebuffer , mFramebufferId );
338 |
339 | mColorbufferId = GL.GenRenderbuffer();
340 | GL.BindRenderbuffer( RenderbufferTarget.Renderbuffer , mColorbufferId );
341 | GL.RenderbufferStorage( RenderbufferTarget.Renderbuffer , RenderbufferStorage.Rgba8 , (int)mSize.Width , (int)mSize.Height );
342 |
343 | mDepthbufferId = GL.GenRenderbuffer();
344 | GL.BindRenderbuffer( RenderbufferTarget.Renderbuffer , mDepthbufferId );
345 | GL.RenderbufferStorage( RenderbufferTarget.Renderbuffer , RenderbufferStorage.DepthComponent24 , (int)mSize.Width , (int)mSize.Height );
346 |
347 | GL.FramebufferRenderbuffer( FramebufferTarget.Framebuffer , FramebufferAttachment.ColorAttachment0 , RenderbufferTarget.Renderbuffer , mColorbufferId );
348 | GL.FramebufferRenderbuffer( FramebufferTarget.Framebuffer , FramebufferAttachment.DepthAttachment , RenderbufferTarget.Renderbuffer , mDepthbufferId );
349 |
350 | var error = GL.CheckFramebufferStatus( FramebufferTarget.Framebuffer );
351 | if ( error != FramebufferErrorCode.FramebufferComplete )
352 | {
353 | throw new Exception( "Failed to create FrameBuffer for OpenGLControl" );
354 | }
355 |
356 | mLoaded = true;
357 | }
358 |
359 | #endregion Implementation
360 |
361 | #region Fields
362 |
363 | private Image mImage = new Image();
364 |
365 | ///
366 | /// A stopwatch used for timing rendering.
367 | ///
368 | protected Stopwatch mStopwatch = new Stopwatch();
369 | private TimeSpan mLast = TimeSpan.Zero;
370 |
371 | private GLControl mTkGlControl; // hidden WinForms control for offscreen rendering
372 |
373 | private byte[] mBackbuffer; // FBO pixels read buffer , create statically to avoid GC
374 | private WriteableBitmap mDrawnImage; // displaying bitmap
375 | private int mFramebufferId; // FBO
376 | private int mColorbufferId; // FBO pixel buffer
377 | private int mDepthbufferId; // FBO depth buffer
378 | private Size mSize; // FBO (drawing) size
379 | private bool mLoaded;
380 |
381 | #endregion Fields
382 | }
383 | }
384 |
--------------------------------------------------------------------------------