├── .gitattributes ├── .gitignore ├── README.md ├── SilkRenderer.WPF ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Common │ ├── DesignTimeHelper.cs │ ├── FramebufferBase.cs │ ├── GameBase.cs │ ├── MathHelper.cs │ └── SilkColor.cs ├── Direct3D9 │ ├── Framebuffer.cs │ ├── GameControl.cs │ ├── RenderContext.cs │ └── Sample │ │ ├── MiniTri.xaml │ │ └── MiniTri.xaml.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── OpenGL │ ├── Common │ │ ├── Camera.cs │ │ └── Shader.cs │ ├── Framebuffer.cs │ ├── GameControl.cs │ ├── RenderContext.cs │ ├── Sample │ │ ├── ExampleScene.xaml │ │ ├── ExampleScene.xaml.cs │ │ ├── Materials.xaml │ │ ├── Materials.xaml.cs │ │ └── Shaders │ │ │ ├── lighting.frag │ │ │ ├── shader.frag │ │ │ └── shader.vert │ └── Settings.cs └── SilkRenderer.WPF.csproj ├── SilkRenderer.WinUI ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── Common │ ├── FramebufferBase.cs │ ├── GameBase.cs │ ├── ISwapChainPanelNative.cs │ ├── MathHelper.cs │ └── SilkColor.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── OpenGL │ ├── Common │ │ ├── Camera.cs │ │ └── Shader.cs │ ├── Framebuffer.cs │ ├── GameControl.cs │ ├── RenderContext.cs │ ├── Sample │ │ ├── ExampleScene.xaml │ │ ├── ExampleScene.xaml.cs │ │ ├── Materials.xaml │ │ ├── Materials.xaml.cs │ │ └── Shaders │ │ │ ├── lighting.frag │ │ │ ├── shader.frag │ │ │ └── shader.vert │ └── Settings.cs ├── Package.appxmanifest ├── Properties │ └── launchSettings.json ├── SilkRenderer.WinUI.csproj └── app.manifest └── SilkRenderer.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SilkRenderer 2 | ## WPF、WinUI3 使用 Silk.NET 绘制示例(OpenGL、DirectX) 3 | 4 | ## WPF、WinUI3 Use Silk.NET to draw examples (OpenGL, DirectX) 5 | 6 | ### 注意事项 7 | 该项目代码结构较为复杂、混乱,仅供参考学习。 8 | 9 | ### Precautions 10 | The project code structure is rather complex, messy, and is only for reference and learning purposes. 11 | 12 | ### 项目说明 13 | - 本项目是一个使用 Silk.NET 绘制图形的示例项目,包含了 WPF 和 WinUI3 两个项目,分别使用 OpenGL 和 DirectX 两种渲染方式。 14 | - 渲染模式依靠 OpenTK 提供的渲染思路,使用 NV_DX_Interop 扩展实现 DirectX 与 OpenGL 之间的交互。 15 | - 使用该方式进行渲染,能够极大提高 WPF 和 WinUI3 的图形性能,同时也能够接入不同的图形库。 16 | 17 | ### Project Description 18 | - This project is an example project that uses Silk.NET to draw graphics. It contains two projects, WPF and WinUI3, which use OpenGL and DirectX rendering respectively. 19 | - The rendering mode relies on the rendering ideas provided by OpenTK and uses the NV_DX_Interop extension to implement interaction between DirectX and OpenGL. 20 | - Using this rendering method can greatly improve the graphics performance of WPF and WinUI3, and can also access different graphics libraries. 21 | 22 | ### 项目结构 23 | - RenderContext:渲染上下文,用户管理 OpenGL 和 DirectX 的渲染环境。 24 | - Framebuffer:帧缓冲,用户管理 OpenGL 和 DirectX 的帧缓冲。 25 | - GameControl:渲染控件,管理上下文和渲染。 26 | 27 | ### Project Structure 28 | - RenderContext: Rendering context, user management OpenGL and DirectX rendering environment. 29 | - Framebuffer: Frame buffer, user management OpenGL and DirectX frame buffer. 30 | - GameControl: Rendering control, management context and rendering. 31 | 32 | ![image](https://github.com/qian-o/SilkRenderer/assets/84434846/fbc9e032-cfcb-453c-a3de-da8f88d78c3a) 33 | 34 | ![image](https://github.com/qian-o/SilkRenderer/assets/84434846/43046f40-f496-4258-ba0f-7c0d437ab2b9) 35 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace SilkRenderer.WPF; 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application 8 | { 9 | } 10 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] 11 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Common/DesignTimeHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Media; 4 | 5 | namespace SilkRenderer.WPF.Common; 6 | 7 | public static class DesignTimeHelper 8 | { 9 | public static void DrawDesign(Control control, DrawingContext drawingContext) 10 | { 11 | if (control.Visibility == Visibility.Visible && control.ActualWidth > 0 && control.ActualHeight > 0) 12 | { 13 | drawingContext.DrawRectangle(Brushes.Black, 14 | new Pen(Brushes.DarkBlue, 2.0), 15 | new Rect(0, 0, control.ActualWidth, control.ActualHeight)); 16 | 17 | drawingContext.DrawLine(new Pen(Brushes.DarkBlue, 2.0), 18 | new Point(0.0, 0.0), 19 | new Point(control.ActualWidth, control.ActualHeight)); 20 | drawingContext.DrawLine(new Pen(Brushes.DarkBlue, 2.0), 21 | new Point(control.ActualWidth, 0.0), 22 | new Point(0.0, control.ActualHeight)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Common/FramebufferBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Interop; 3 | 4 | namespace SilkRenderer.WPF.Common; 5 | public abstract class FramebufferBase : IDisposable 6 | { 7 | public abstract int FramebufferWidth { get; } 8 | 9 | public abstract int FramebufferHeight { get; } 10 | 11 | public abstract D3DImage D3dImage { get; } 12 | 13 | public abstract void Dispose(); 14 | } 15 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Common/GameBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Media; 9 | 10 | namespace SilkRenderer.WPF.Common; 11 | 12 | public abstract class GameBase : Control where TFrame : FramebufferBase 13 | { 14 | public static readonly DependencyProperty FpsProperty = DependencyProperty.Register(nameof(Fps), typeof(int), typeof(GameBase), new PropertyMetadata(0)); 15 | 16 | protected readonly Stopwatch _stopwatch = Stopwatch.StartNew(); 17 | private readonly List _fpsSample = new(); 18 | 19 | protected TimeSpan _lastRenderTime = TimeSpan.FromSeconds(-1); 20 | protected TimeSpan _lastFrameStamp; 21 | 22 | protected TFrame Framebuffer { get; set; } 23 | public int Fps 24 | { 25 | get { return (int)GetValue(FpsProperty); } 26 | set { SetValue(FpsProperty, value); } 27 | } 28 | 29 | public abstract event Action Ready; 30 | public abstract event Action Render; 31 | public abstract event Action UpdateFrame; 32 | 33 | public void Start() 34 | { 35 | if (!DesignerProperties.GetIsInDesignMode(this)) 36 | { 37 | IsVisibleChanged += (_, e) => 38 | { 39 | if ((bool)e.NewValue) 40 | { 41 | CompositionTarget.Rendering += CompositionTarget_Rendering; 42 | } 43 | else 44 | { 45 | CompositionTarget.Rendering -= CompositionTarget_Rendering; 46 | } 47 | }; 48 | 49 | Loaded += (_, _) => InvalidateVisual(); 50 | 51 | OnStart(); 52 | } 53 | } 54 | 55 | private void CompositionTarget_Rendering(object sender, EventArgs e) 56 | { 57 | RenderingEventArgs args = (RenderingEventArgs)e; 58 | 59 | if (_lastRenderTime != args.RenderingTime) 60 | { 61 | InvalidateVisual(); 62 | 63 | _fpsSample.Add(Convert.ToInt32(1000.0d / (args.RenderingTime.TotalMilliseconds - _lastRenderTime.TotalMilliseconds))); 64 | // 样本数 30 65 | if (_fpsSample.Count == 30) 66 | { 67 | Fps = Convert.ToInt32(_fpsSample.Average()); 68 | _fpsSample.Clear(); 69 | } 70 | 71 | _lastRenderTime = args.RenderingTime; 72 | } 73 | } 74 | 75 | protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 76 | { 77 | if (!DesignerProperties.GetIsInDesignMode(this)) 78 | { 79 | OnSizeChanged(sizeInfo); 80 | } 81 | } 82 | 83 | protected override void OnRender(DrawingContext drawingContext) 84 | { 85 | if (DesignerProperties.GetIsInDesignMode(this)) 86 | { 87 | DesignTimeHelper.DrawDesign(this, drawingContext); 88 | } 89 | else 90 | { 91 | if (Framebuffer != null && Framebuffer.D3dImage.IsFrontBufferAvailable) 92 | { 93 | OnDraw(drawingContext); 94 | 95 | _stopwatch.Restart(); 96 | } 97 | } 98 | } 99 | 100 | protected abstract void OnStart(); 101 | protected abstract void OnDraw(DrawingContext drawingContext); 102 | protected abstract void OnSizeChanged(SizeChangedInfo sizeInfo); 103 | } 104 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Common/SilkColor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using DrawingColor = System.Drawing.Color; 4 | using MediaColor = System.Windows.Media.Color; 5 | 6 | namespace SilkRenderer.WPF.Common; 7 | 8 | public struct SilkColor 9 | { 10 | public byte R { get; set; } 11 | public byte G { get; set; } 12 | public byte B { get; set; } 13 | public byte A { get; set; } 14 | 15 | // 16 | // 摘要: 17 | // Zero color. 18 | public static readonly SilkColor Zero = FromBgra(0); 19 | 20 | // 21 | // 摘要: 22 | // Transparent color. 23 | public static readonly SilkColor Transparent = FromBgra(0); 24 | 25 | // 26 | // 摘要: 27 | // AliceBlue color. 28 | public static readonly SilkColor AliceBlue = FromBgra(4293982463u); 29 | 30 | // 31 | // 摘要: 32 | // AntiqueWhite color. 33 | public static readonly SilkColor AntiqueWhite = FromBgra(4294634455u); 34 | 35 | // 36 | // 摘要: 37 | // Aqua color. 38 | public static readonly SilkColor Aqua = FromBgra(4278255615u); 39 | 40 | // 41 | // 摘要: 42 | // Aquamarine color. 43 | public static readonly SilkColor Aquamarine = FromBgra(4286578644u); 44 | 45 | // 46 | // 摘要: 47 | // Azure color. 48 | public static readonly SilkColor Azure = FromBgra(4293984255u); 49 | 50 | // 51 | // 摘要: 52 | // Beige color. 53 | public static readonly SilkColor Beige = FromBgra(4294309340u); 54 | 55 | // 56 | // 摘要: 57 | // Bisque color. 58 | public static readonly SilkColor Bisque = FromBgra(4294960324u); 59 | 60 | // 61 | // 摘要: 62 | // Black color. 63 | public static readonly SilkColor Black = FromBgra(4278190080u); 64 | 65 | // 66 | // 摘要: 67 | // BlanchedAlmond color. 68 | public static readonly SilkColor BlanchedAlmond = FromBgra(4294962125u); 69 | 70 | // 71 | // 摘要: 72 | // Blue color. 73 | public static readonly SilkColor Blue = FromBgra(4278190335u); 74 | 75 | // 76 | // 摘要: 77 | // BlueViolet color. 78 | public static readonly SilkColor BlueViolet = FromBgra(4287245282u); 79 | 80 | // 81 | // 摘要: 82 | // Brown color. 83 | public static readonly SilkColor Brown = FromBgra(4289014314u); 84 | 85 | // 86 | // 摘要: 87 | // BurlyWood color. 88 | public static readonly SilkColor BurlyWood = FromBgra(4292786311u); 89 | 90 | // 91 | // 摘要: 92 | // CadetBlue color. 93 | public static readonly SilkColor CadetBlue = FromBgra(4284456608u); 94 | 95 | // 96 | // 摘要: 97 | // Chartreuse color. 98 | public static readonly SilkColor Chartreuse = FromBgra(4286578432u); 99 | 100 | // 101 | // 摘要: 102 | // Chocolate color. 103 | public static readonly SilkColor Chocolate = FromBgra(4291979550u); 104 | 105 | // 106 | // 摘要: 107 | // Coral color. 108 | public static readonly SilkColor Coral = FromBgra(4294934352u); 109 | 110 | // 111 | // 摘要: 112 | // CornflowerBlue color. 113 | public static readonly SilkColor CornflowerBlue = FromBgra(4284782061u); 114 | 115 | // 116 | // 摘要: 117 | // Cornsilk color. 118 | public static readonly SilkColor Cornsilk = FromBgra(4294965468u); 119 | 120 | // 121 | // 摘要: 122 | // Crimson color. 123 | public static readonly SilkColor Crimson = FromBgra(4292613180u); 124 | 125 | // 126 | // 摘要: 127 | // Cyan color. 128 | public static readonly SilkColor Cyan = FromBgra(4278255615u); 129 | 130 | // 131 | // 摘要: 132 | // DarkBlue color. 133 | public static readonly SilkColor DarkBlue = FromBgra(4278190219u); 134 | 135 | // 136 | // 摘要: 137 | // DarkCyan color. 138 | public static readonly SilkColor DarkCyan = FromBgra(4278225803u); 139 | 140 | // 141 | // 摘要: 142 | // DarkGoldenrod color. 143 | public static readonly SilkColor DarkGoldenrod = FromBgra(4290283019u); 144 | 145 | // 146 | // 摘要: 147 | // DarkGray color. 148 | public static readonly SilkColor DarkGray = FromBgra(4289309097u); 149 | 150 | // 151 | // 摘要: 152 | // DarkGreen color. 153 | public static readonly SilkColor DarkGreen = FromBgra(4278215680u); 154 | 155 | // 156 | // 摘要: 157 | // DarkKhaki color. 158 | public static readonly SilkColor DarkKhaki = FromBgra(4290623339u); 159 | 160 | // 161 | // 摘要: 162 | // DarkMagenta color. 163 | public static readonly SilkColor DarkMagenta = FromBgra(4287299723u); 164 | 165 | // 166 | // 摘要: 167 | // DarkOliveGreen color. 168 | public static readonly SilkColor DarkOliveGreen = FromBgra(4283788079u); 169 | 170 | // 171 | // 摘要: 172 | // DarkOrange color. 173 | public static readonly SilkColor DarkOrange = FromBgra(4294937600u); 174 | 175 | // 176 | // 摘要: 177 | // DarkOrchid color. 178 | public static readonly SilkColor DarkOrchid = FromBgra(4288230092u); 179 | 180 | // 181 | // 摘要: 182 | // DarkRed color. 183 | public static readonly SilkColor DarkRed = FromBgra(4287299584u); 184 | 185 | // 186 | // 摘要: 187 | // DarkSalmon color. 188 | public static readonly SilkColor DarkSalmon = FromBgra(4293498490u); 189 | 190 | // 191 | // 摘要: 192 | // DarkSeaGreen color. 193 | public static readonly SilkColor DarkSeaGreen = FromBgra(4287609995u); 194 | 195 | // 196 | // 摘要: 197 | // DarkSlateBlue color. 198 | public static readonly SilkColor DarkSlateBlue = FromBgra(4282924427u); 199 | 200 | // 201 | // 摘要: 202 | // DarkSlateGray color. 203 | public static readonly SilkColor DarkSlateGray = FromBgra(4281290575u); 204 | 205 | // 206 | // 摘要: 207 | // DarkTurquoise color. 208 | public static readonly SilkColor DarkTurquoise = FromBgra(4278243025u); 209 | 210 | // 211 | // 摘要: 212 | // DarkViolet color. 213 | public static readonly SilkColor DarkViolet = FromBgra(4287889619u); 214 | 215 | // 216 | // 摘要: 217 | // DeepPink color. 218 | public static readonly SilkColor DeepPink = FromBgra(4294907027u); 219 | 220 | // 221 | // 摘要: 222 | // DeepSkyBlue color. 223 | public static readonly SilkColor DeepSkyBlue = FromBgra(4278239231u); 224 | 225 | // 226 | // 摘要: 227 | // DimGray color. 228 | public static readonly SilkColor DimGray = FromBgra(4285098345u); 229 | 230 | // 231 | // 摘要: 232 | // DodgerBlue color. 233 | public static readonly SilkColor DodgerBlue = FromBgra(4280193279u); 234 | 235 | // 236 | // 摘要: 237 | // Firebrick color. 238 | public static readonly SilkColor Firebrick = FromBgra(4289864226u); 239 | 240 | // 241 | // 摘要: 242 | // FloralWhite color. 243 | public static readonly SilkColor FloralWhite = FromBgra(4294966000u); 244 | 245 | // 246 | // 摘要: 247 | // ForestGreen color. 248 | public static readonly SilkColor ForestGreen = FromBgra(4280453922u); 249 | 250 | // 251 | // 摘要: 252 | // Fuchsia color. 253 | public static readonly SilkColor Fuchsia = FromBgra(4294902015u); 254 | 255 | // 256 | // 摘要: 257 | // Gainsboro color. 258 | public static readonly SilkColor Gainsboro = FromBgra(4292664540u); 259 | 260 | // 261 | // 摘要: 262 | // GhostWhite color. 263 | public static readonly SilkColor GhostWhite = FromBgra(4294506751u); 264 | 265 | // 266 | // 摘要: 267 | // Gold color. 268 | public static readonly SilkColor Gold = FromBgra(4294956800u); 269 | 270 | // 271 | // 摘要: 272 | // Goldenrod color. 273 | public static readonly SilkColor Goldenrod = FromBgra(4292519200u); 274 | 275 | // 276 | // 摘要: 277 | // Gray color. 278 | public static readonly SilkColor Gray = FromBgra(4286611584u); 279 | 280 | // 281 | // 摘要: 282 | // Green color. 283 | public static readonly SilkColor Green = FromBgra(4278222848u); 284 | 285 | // 286 | // 摘要: 287 | // GreenYellow color. 288 | public static readonly SilkColor GreenYellow = FromBgra(4289593135u); 289 | 290 | // 291 | // 摘要: 292 | // Honeydew color. 293 | public static readonly SilkColor Honeydew = FromBgra(4293984240u); 294 | 295 | // 296 | // 摘要: 297 | // HotPink color. 298 | public static readonly SilkColor HotPink = FromBgra(4294928820u); 299 | 300 | // 301 | // 摘要: 302 | // IndianRed color. 303 | public static readonly SilkColor IndianRed = FromBgra(4291648604u); 304 | 305 | // 306 | // 摘要: 307 | // Indigo color. 308 | public static readonly SilkColor Indigo = FromBgra(4283105410u); 309 | 310 | // 311 | // 摘要: 312 | // Ivory color. 313 | public static readonly SilkColor Ivory = FromBgra(4294967280u); 314 | 315 | // 316 | // 摘要: 317 | // Khaki color. 318 | public static readonly SilkColor Khaki = FromBgra(4293977740u); 319 | 320 | // 321 | // 摘要: 322 | // Lavender color. 323 | public static readonly SilkColor Lavender = FromBgra(4293322490u); 324 | 325 | // 326 | // 摘要: 327 | // LavenderBlush color. 328 | public static readonly SilkColor LavenderBlush = FromBgra(4294963445u); 329 | 330 | // 331 | // 摘要: 332 | // LawnGreen color. 333 | public static readonly SilkColor LawnGreen = FromBgra(4286381056u); 334 | 335 | // 336 | // 摘要: 337 | // LemonChiffon color. 338 | public static readonly SilkColor LemonChiffon = FromBgra(4294965965u); 339 | 340 | // 341 | // 摘要: 342 | // LightBlue color. 343 | public static readonly SilkColor LightBlue = FromBgra(4289583334u); 344 | 345 | // 346 | // 摘要: 347 | // LightCoral color. 348 | public static readonly SilkColor LightCoral = FromBgra(4293951616u); 349 | 350 | // 351 | // 摘要: 352 | // LightCyan color. 353 | public static readonly SilkColor LightCyan = FromBgra(4292935679u); 354 | 355 | // 356 | // 摘要: 357 | // LightGoldenrodYellow color. 358 | public static readonly SilkColor LightGoldenrodYellow = FromBgra(4294638290u); 359 | 360 | // 361 | // 摘要: 362 | // LightGray color. 363 | public static readonly SilkColor LightGray = FromBgra(4292072403u); 364 | 365 | // 366 | // 摘要: 367 | // LightGreen color. 368 | public static readonly SilkColor LightGreen = FromBgra(4287688336u); 369 | 370 | // 371 | // 摘要: 372 | // LightPink color. 373 | public static readonly SilkColor LightPink = FromBgra(4294948545u); 374 | 375 | // 376 | // 摘要: 377 | // LightSalmon color. 378 | public static readonly SilkColor LightSalmon = FromBgra(4294942842u); 379 | 380 | // 381 | // 摘要: 382 | // LightSeaGreen color. 383 | public static readonly SilkColor LightSeaGreen = FromBgra(4280332970u); 384 | 385 | // 386 | // 摘要: 387 | // LightSkyBlue color. 388 | public static readonly SilkColor LightSkyBlue = FromBgra(4287090426u); 389 | 390 | // 391 | // 摘要: 392 | // LightSlateGray color. 393 | public static readonly SilkColor LightSlateGray = FromBgra(4286023833u); 394 | 395 | // 396 | // 摘要: 397 | // LightSteelBlue color. 398 | public static readonly SilkColor LightSteelBlue = FromBgra(4289774814u); 399 | 400 | // 401 | // 摘要: 402 | // LightYellow color. 403 | public static readonly SilkColor LightYellow = FromBgra(4294967264u); 404 | 405 | // 406 | // 摘要: 407 | // Lime color. 408 | public static readonly SilkColor Lime = FromBgra(4278255360u); 409 | 410 | // 411 | // 摘要: 412 | // LimeGreen color. 413 | public static readonly SilkColor LimeGreen = FromBgra(4281519410u); 414 | 415 | // 416 | // 摘要: 417 | // Linen color. 418 | public static readonly SilkColor Linen = FromBgra(4294635750u); 419 | 420 | // 421 | // 摘要: 422 | // Magenta color. 423 | public static readonly SilkColor Magenta = FromBgra(4294902015u); 424 | 425 | // 426 | // 摘要: 427 | // Maroon color. 428 | public static readonly SilkColor Maroon = FromBgra(4286578688u); 429 | 430 | // 431 | // 摘要: 432 | // MediumAquamarine color. 433 | public static readonly SilkColor MediumAquamarine = FromBgra(4284927402u); 434 | 435 | // 436 | // 摘要: 437 | // MediumBlue color. 438 | public static readonly SilkColor MediumBlue = FromBgra(4278190285u); 439 | 440 | // 441 | // 摘要: 442 | // MediumOrchid color. 443 | public static readonly SilkColor MediumOrchid = FromBgra(4290401747u); 444 | 445 | // 446 | // 摘要: 447 | // MediumPurple color. 448 | public static readonly SilkColor MediumPurple = FromBgra(4287852763u); 449 | 450 | // 451 | // 摘要: 452 | // MediumSeaGreen color. 453 | public static readonly SilkColor MediumSeaGreen = FromBgra(4282168177u); 454 | 455 | // 456 | // 摘要: 457 | // MediumSlateBlue color. 458 | public static readonly SilkColor MediumSlateBlue = FromBgra(4286277870u); 459 | 460 | // 461 | // 摘要: 462 | // MediumSpringGreen color. 463 | public static readonly SilkColor MediumSpringGreen = FromBgra(4278254234u); 464 | 465 | // 466 | // 摘要: 467 | // MediumTurquoise color. 468 | public static readonly SilkColor MediumTurquoise = FromBgra(4282962380u); 469 | 470 | // 471 | // 摘要: 472 | // MediumVioletRed color. 473 | public static readonly SilkColor MediumVioletRed = FromBgra(4291237253u); 474 | 475 | // 476 | // 摘要: 477 | // MidnightBlue color. 478 | public static readonly SilkColor MidnightBlue = FromBgra(4279834992u); 479 | 480 | // 481 | // 摘要: 482 | // MintCream color. 483 | public static readonly SilkColor MintCream = FromBgra(4294311930u); 484 | 485 | // 486 | // 摘要: 487 | // MistyRose color. 488 | public static readonly SilkColor MistyRose = FromBgra(4294960353u); 489 | 490 | // 491 | // 摘要: 492 | // Moccasin color. 493 | public static readonly SilkColor Moccasin = FromBgra(4294960309u); 494 | 495 | // 496 | // 摘要: 497 | // NavajoWhite color. 498 | public static readonly SilkColor NavajoWhite = FromBgra(4294958765u); 499 | 500 | // 501 | // 摘要: 502 | // Navy color. 503 | public static readonly SilkColor Navy = FromBgra(4278190208u); 504 | 505 | // 506 | // 摘要: 507 | // OldLace color. 508 | public static readonly SilkColor OldLace = FromBgra(4294833638u); 509 | 510 | // 511 | // 摘要: 512 | // Olive color. 513 | public static readonly SilkColor Olive = FromBgra(4286611456u); 514 | 515 | // 516 | // 摘要: 517 | // OliveDrab color. 518 | public static readonly SilkColor OliveDrab = FromBgra(4285238819u); 519 | 520 | // 521 | // 摘要: 522 | // Orange color. 523 | public static readonly SilkColor Orange = FromBgra(4294944000u); 524 | 525 | // 526 | // 摘要: 527 | // OrangeRed color. 528 | public static readonly SilkColor OrangeRed = FromBgra(4294919424u); 529 | 530 | // 531 | // 摘要: 532 | // Orchid color. 533 | public static readonly SilkColor Orchid = FromBgra(4292505814u); 534 | 535 | // 536 | // 摘要: 537 | // PaleGoldenrod color. 538 | public static readonly SilkColor PaleGoldenrod = FromBgra(4293847210u); 539 | 540 | // 541 | // 摘要: 542 | // PaleGreen color. 543 | public static readonly SilkColor PaleGreen = FromBgra(4288215960u); 544 | 545 | // 546 | // 摘要: 547 | // PaleTurquoise color. 548 | public static readonly SilkColor PaleTurquoise = FromBgra(4289720046u); 549 | 550 | // 551 | // 摘要: 552 | // PaleVioletRed color. 553 | public static readonly SilkColor PaleVioletRed = FromBgra(4292571283u); 554 | 555 | // 556 | // 摘要: 557 | // PapayaWhip color. 558 | public static readonly SilkColor PapayaWhip = FromBgra(4294963157u); 559 | 560 | // 561 | // 摘要: 562 | // PeachPuff color. 563 | public static readonly SilkColor PeachPuff = FromBgra(4294957753u); 564 | 565 | // 566 | // 摘要: 567 | // Peru color. 568 | public static readonly SilkColor Peru = FromBgra(4291659071u); 569 | 570 | // 571 | // 摘要: 572 | // Pink color. 573 | public static readonly SilkColor Pink = FromBgra(4294951115u); 574 | 575 | // 576 | // 摘要: 577 | // Plum color. 578 | public static readonly SilkColor Plum = FromBgra(4292714717u); 579 | 580 | // 581 | // 摘要: 582 | // PowderBlue color. 583 | public static readonly SilkColor PowderBlue = FromBgra(4289781990u); 584 | 585 | // 586 | // 摘要: 587 | // Purple color. 588 | public static readonly SilkColor Purple = FromBgra(4286578816u); 589 | 590 | // 591 | // 摘要: 592 | // Red color. 593 | public static readonly SilkColor Red = FromBgra(4294901760u); 594 | 595 | // 596 | // 摘要: 597 | // RosyBrown color. 598 | public static readonly SilkColor RosyBrown = FromBgra(4290547599u); 599 | 600 | // 601 | // 摘要: 602 | // RoyalBlue color. 603 | public static readonly SilkColor RoyalBlue = FromBgra(4282477025u); 604 | 605 | // 606 | // 摘要: 607 | // SaddleBrown color. 608 | public static readonly SilkColor SaddleBrown = FromBgra(4287317267u); 609 | 610 | // 611 | // 摘要: 612 | // Salmon color. 613 | public static readonly SilkColor Salmon = FromBgra(4294606962u); 614 | 615 | // 616 | // 摘要: 617 | // SandyBrown color. 618 | public static readonly SilkColor SandyBrown = FromBgra(4294222944u); 619 | 620 | // 621 | // 摘要: 622 | // SeaGreen color. 623 | public static readonly SilkColor SeaGreen = FromBgra(4281240407u); 624 | 625 | // 626 | // 摘要: 627 | // SeaShell color. 628 | public static readonly SilkColor SeaShell = FromBgra(4294964718u); 629 | 630 | // 631 | // 摘要: 632 | // Sienna color. 633 | public static readonly SilkColor Sienna = FromBgra(4288696877u); 634 | 635 | // 636 | // 摘要: 637 | // Silver color. 638 | public static readonly SilkColor Silver = FromBgra(4290822336u); 639 | 640 | // 641 | // 摘要: 642 | // SkyBlue color. 643 | public static readonly SilkColor SkyBlue = FromBgra(4287090411u); 644 | 645 | // 646 | // 摘要: 647 | // SlateBlue color. 648 | public static readonly SilkColor SlateBlue = FromBgra(4285160141u); 649 | 650 | // 651 | // 摘要: 652 | // SlateGray color. 653 | public static readonly SilkColor SlateGray = FromBgra(4285563024u); 654 | 655 | // 656 | // 摘要: 657 | // Snow color. 658 | public static readonly SilkColor Snow = FromBgra(4294966010u); 659 | 660 | // 661 | // 摘要: 662 | // SpringGreen color. 663 | public static readonly SilkColor SpringGreen = FromBgra(4278255487u); 664 | 665 | // 666 | // 摘要: 667 | // SteelBlue color. 668 | public static readonly SilkColor SteelBlue = FromBgra(4282811060u); 669 | 670 | // 671 | // 摘要: 672 | // Tan color. 673 | public static readonly SilkColor Tan = FromBgra(4291998860u); 674 | 675 | // 676 | // 摘要: 677 | // Teal color. 678 | public static readonly SilkColor Teal = FromBgra(4278222976u); 679 | 680 | // 681 | // 摘要: 682 | // Thistle color. 683 | public static readonly SilkColor Thistle = FromBgra(4292394968u); 684 | 685 | // 686 | // 摘要: 687 | // Tomato color. 688 | public static readonly SilkColor Tomato = FromBgra(4294927175u); 689 | 690 | // 691 | // 摘要: 692 | // Turquoise color. 693 | public static readonly SilkColor Turquoise = FromBgra(4282441936u); 694 | 695 | // 696 | // 摘要: 697 | // Violet color. 698 | public static readonly SilkColor Violet = FromBgra(4293821166u); 699 | 700 | // 701 | // 摘要: 702 | // Wheat color. 703 | public static readonly SilkColor Wheat = FromBgra(4294303411u); 704 | 705 | // 706 | // 摘要: 707 | // White color. 708 | public static readonly SilkColor White = FromBgra(uint.MaxValue); 709 | 710 | // 711 | // 摘要: 712 | // WhiteSmoke color. 713 | public static readonly SilkColor WhiteSmoke = FromBgra(4294309365u); 714 | 715 | // 716 | // 摘要: 717 | // Yellow color. 718 | public static readonly SilkColor Yellow = FromBgra(4294967040u); 719 | 720 | // 721 | // 摘要: 722 | // YellowGreen color. 723 | public static readonly SilkColor YellowGreen = FromBgra(4288335154u); 724 | 725 | public SilkColor(byte red, byte green, byte blue, byte alpha = 255) 726 | { 727 | R = red; 728 | G = green; 729 | B = blue; 730 | A = alpha; 731 | } 732 | public SilkColor(float red, float green, float blue, float alpha = 1.0f) 733 | { 734 | R = ToByte(red); 735 | G = ToByte(green); 736 | B = ToByte(blue); 737 | A = ToByte(alpha); 738 | } 739 | public SilkColor(int rgba) 740 | { 741 | A = (byte)((uint)(rgba >> 24) & 0xFFu); 742 | B = (byte)((uint)(rgba >> 16) & 0xFFu); 743 | G = (byte)((uint)(rgba >> 8) & 0xFFu); 744 | R = (byte)((uint)rgba & 0xFFu); 745 | } 746 | public SilkColor(uint rgba) 747 | { 748 | A = (byte)((rgba >> 24) & 0xFFu); 749 | B = (byte)((rgba >> 16) & 0xFFu); 750 | G = (byte)((rgba >> 8) & 0xFFu); 751 | R = (byte)(rgba & 0xFFu); 752 | } 753 | 754 | public readonly int ToBgra() => B | (G << 8) | (R << 16) | (A << 24); 755 | public readonly int ToRgba() => R | (G << 8) | (B << 16) | (A << 24); 756 | public readonly int ToAbgr() => A | (B << 8) | (G << 16) | (R << 24); 757 | 758 | public static SilkColor FromDrawingColor(DrawingColor color) 759 | { 760 | return new SilkColor(color.R, color.G, color.B, color.A); 761 | } 762 | public static SilkColor FromMediaColor(MediaColor color) 763 | { 764 | return new SilkColor(color.R, color.G, color.B, color.A); 765 | } 766 | 767 | public static SilkColor FromBgra(int color) 768 | { 769 | return new SilkColor((byte)((uint)(color >> 16) & 0xFFu), (byte)((uint)(color >> 8) & 0xFFu), (byte)((uint)color & 0xFFu), (byte)((uint)(color >> 24) & 0xFFu)); 770 | } 771 | public static SilkColor FromBgra(uint color) 772 | { 773 | return FromBgra((int)color); 774 | } 775 | 776 | public static SilkColor FromRgba(int color) 777 | { 778 | return new SilkColor(color); 779 | } 780 | public static SilkColor FromRgba(uint color) 781 | { 782 | return new SilkColor(color); 783 | } 784 | 785 | public static SilkColor FromAbgr(int color) 786 | { 787 | return new SilkColor((byte)(color >> 24), (byte)(color >> 16), (byte)(color >> 8), (byte)color); 788 | } 789 | public static SilkColor FromAbgr(uint color) 790 | { 791 | return FromAbgr((int)color); 792 | } 793 | 794 | public static SilkColor FromHsv(Vector4 hsv) 795 | { 796 | float num = hsv.X * 360f; 797 | float y = hsv.Y; 798 | float z = hsv.Z; 799 | float num2 = z * y; 800 | float num3 = num / 60f; 801 | float num4 = num2 * (1f - Math.Abs(num3 % 2f - 1f)); 802 | float num5; 803 | float num6; 804 | float num7; 805 | if (num3 >= 0f && num3 < 1f) 806 | { 807 | num5 = num2; 808 | num6 = num4; 809 | num7 = 0f; 810 | } 811 | else if (num3 >= 1f && num3 < 2f) 812 | { 813 | num5 = num4; 814 | num6 = num2; 815 | num7 = 0f; 816 | } 817 | else if (num3 >= 2f && num3 < 3f) 818 | { 819 | num5 = 0f; 820 | num6 = num2; 821 | num7 = num4; 822 | } 823 | else if (num3 >= 3f && num3 < 4f) 824 | { 825 | num5 = 0f; 826 | num6 = num4; 827 | num7 = num2; 828 | } 829 | else if (num3 >= 4f && num3 < 5f) 830 | { 831 | num5 = num4; 832 | num6 = 0f; 833 | num7 = num2; 834 | } 835 | else if (num3 >= 5f && num3 < 6f) 836 | { 837 | num5 = num2; 838 | num6 = 0f; 839 | num7 = num4; 840 | } 841 | else 842 | { 843 | num5 = 0f; 844 | num6 = 0f; 845 | num7 = 0f; 846 | } 847 | 848 | float num8 = z - num2; 849 | return new SilkColor(hsv.W, num5 + num8, num6 + num8, num7 + num8); 850 | } 851 | 852 | public static DrawingColor ByDrawingColor(SilkColor color) 853 | { 854 | return DrawingColor.FromArgb(color.A, color.R, color.G, color.B); 855 | } 856 | public static MediaColor ByMediaColor(SilkColor color) 857 | { 858 | return MediaColor.FromArgb(color.A, color.R, color.G, color.B); 859 | } 860 | 861 | private static byte ToByte(float component) 862 | { 863 | return ToByte((int)(component * 255f)); 864 | } 865 | public static byte ToByte(int value) 866 | { 867 | return (byte)((value >= 0) ? ((value > 255) ? 255u : ((uint)value)) : 0u); 868 | } 869 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/Direct3D9/Framebuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Interop; 3 | using Silk.NET.Direct3D9; 4 | using SilkRenderer.WPF.Common; 5 | 6 | namespace SilkRenderer.WPF.Direct3D9; 7 | 8 | public unsafe class Framebuffer : FramebufferBase 9 | { 10 | public RenderContext Context { get; } 11 | 12 | public override int FramebufferWidth { get; } 13 | 14 | public override int FramebufferHeight { get; } 15 | 16 | public override D3DImage D3dImage { get; } 17 | 18 | public Framebuffer(RenderContext context, int framebufferWidth, int framebufferHeight) 19 | { 20 | Context = context; 21 | FramebufferWidth = framebufferWidth; 22 | FramebufferHeight = framebufferHeight; 23 | 24 | IDirect3DSurface9* surface; 25 | context.Device->CreateRenderTarget((uint)FramebufferWidth, (uint)FramebufferHeight, context.Format, MultisampleType.MultisampleNone, 0, 0, &surface, null); 26 | context.Device->SetRenderTarget(0, surface); 27 | 28 | D3dImage = new D3DImage(); 29 | D3dImage.Lock(); 30 | D3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, (IntPtr)surface); 31 | D3dImage.Unlock(); 32 | } 33 | 34 | public override void Dispose() 35 | { 36 | GC.SuppressFinalize(this); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Direct3D9/GameControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Media; 4 | using Silk.NET.Direct3D9; 5 | using SilkRenderer.WPF.Common; 6 | using Rect = System.Windows.Rect; 7 | 8 | namespace SilkRenderer.WPF.Direct3D9; 9 | 10 | public unsafe class GameControl : GameBase 11 | { 12 | private RenderContext _context; 13 | 14 | public IDirect3DDevice9Ex* Device { get; private set; } 15 | public Format Format { get; private set; } 16 | 17 | public override event Action Ready; 18 | public override event Action Render; 19 | public override event Action UpdateFrame; 20 | 21 | protected override void OnStart() 22 | { 23 | if (_context == null) 24 | { 25 | _context = new RenderContext(); 26 | Device = _context.Device; 27 | Format = _context.Format; 28 | 29 | Ready?.Invoke(); 30 | } 31 | } 32 | 33 | protected override void OnSizeChanged(SizeChangedInfo sizeInfo) 34 | { 35 | if (_context != null && sizeInfo.NewSize.Width > 0 && sizeInfo.NewSize.Height > 0) 36 | { 37 | Framebuffer?.Dispose(); 38 | Framebuffer = new Framebuffer(_context, (int)sizeInfo.NewSize.Width, (int)sizeInfo.NewSize.Height); 39 | } 40 | } 41 | 42 | protected override void OnDraw(DrawingContext drawingContext) 43 | { 44 | Framebuffer.D3dImage.Lock(); 45 | 46 | Render?.Invoke(_stopwatch.Elapsed - _lastFrameStamp); 47 | 48 | Framebuffer.D3dImage.AddDirtyRect(new Int32Rect(0, 0, Framebuffer.FramebufferWidth, Framebuffer.FramebufferHeight)); 49 | Framebuffer.D3dImage.Unlock(); 50 | 51 | Rect rect = new(0, 0, Framebuffer.D3dImage.Width, Framebuffer.D3dImage.Height); 52 | drawingContext.DrawImage(Framebuffer.D3dImage, rect); 53 | 54 | UpdateFrame?.Invoke(this, _stopwatch.Elapsed - _lastFrameStamp); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Direct3D9/RenderContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Silk.NET.Direct3D9; 3 | 4 | namespace SilkRenderer.WPF.Direct3D9; 5 | 6 | public unsafe class RenderContext 7 | { 8 | public IDirect3DDevice9Ex* Device { get; } 9 | 10 | public Format Format { get; } 11 | 12 | public RenderContext() 13 | { 14 | IDirect3D9Ex* direct3D9; 15 | IDirect3DDevice9Ex* device; 16 | D3D9.GetApi(null).Direct3DCreate9Ex(D3D9.SdkVersion, &direct3D9); 17 | 18 | Displaymodeex pMode = new((uint)sizeof(Displaymodeex)); 19 | direct3D9->GetAdapterDisplayModeEx(D3D9.AdapterDefault, ref pMode, null); 20 | 21 | PresentParameters presentParameters = new() 22 | { 23 | Windowed = 1, 24 | SwapEffect = Swapeffect.Discard, 25 | HDeviceWindow = 0, 26 | PresentationInterval = 0, 27 | BackBufferFormat = pMode.Format, 28 | BackBufferWidth = 1, 29 | BackBufferHeight = 1, 30 | AutoDepthStencilFormat = Format.Unknown, 31 | BackBufferCount = 1, 32 | EnableAutoDepthStencil = 0, 33 | Flags = 0, 34 | FullScreenRefreshRateInHz = 0, 35 | MultiSampleQuality = 0, 36 | MultiSampleType = MultisampleType.MultisampleNone 37 | }; 38 | direct3D9->CreateDeviceEx(D3D9.AdapterDefault, Devtype.Hal, 0, D3D9.CreateHardwareVertexprocessing | D3D9.CreateMultithreaded | D3D9.CreatePuredevice, ref presentParameters, (Displaymodeex*)IntPtr.Zero, &device); 39 | 40 | Device = device; 41 | Format = pMode.Format; 42 | } 43 | 44 | public static Format MakeFourCC(byte c1, byte c2, byte c3, byte c4) 45 | { 46 | return (Format)((((((c4 << 8) | c3) << 8) | c2) << 8) | c1); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Direct3D9/Sample/MiniTri.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/Direct3D9/Sample/MiniTri.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Numerics; 4 | using System.Runtime.InteropServices; 5 | using System.Windows.Controls; 6 | using Silk.NET.Direct3D9; 7 | using Silk.NET.Maths; 8 | using SilkRenderer.WPF.Common; 9 | 10 | namespace SilkRenderer.WPF.Direct3D9.Sample; 11 | 12 | public unsafe partial class MiniTri : UserControl 13 | { 14 | [StructLayout(LayoutKind.Sequential)] 15 | struct Vertex 16 | { 17 | public Vector4 Position; 18 | public uint Color; 19 | } 20 | 21 | private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); 22 | private readonly Vertex[] _vertices = 23 | { 24 | new Vertex() { Color = (uint)SilkColor.Red.ToBgra(), Position = new Vector4(400.0f, 100.0f, 0.5f, 1.0f) }, 25 | new Vertex() { Color = (uint)SilkColor.Blue.ToBgra(), Position = new Vector4(650.0f, 500.0f, 0.5f, 1.0f) }, 26 | new Vertex() { Color = (uint)SilkColor.Green.ToBgra(), Position = new Vector4(150.0f, 500.0f, 0.5f, 1.0f) } 27 | }; 28 | private readonly Vertexelement9[] _vertexelements = 29 | { 30 | new Vertexelement9(0, 0, 3, 0, 9, 0), 31 | new Vertexelement9(0, 16, 4, 0, 10, 0), 32 | new Vertexelement9(255, 0, 17, 0, 0, 0) 33 | }; 34 | 35 | private IDirect3DVertexBuffer9* _ppVertexBuffer; 36 | private IDirect3DVertexDeclaration9* _ppDecl; 37 | 38 | public MiniTri() 39 | { 40 | InitializeComponent(); 41 | 42 | Game.Ready += Game_Ready; 43 | Game.Render += Game_Render; 44 | Game.Start(); 45 | } 46 | 47 | private void Game_Ready() 48 | { 49 | fixed (Vertex* ptr = &_vertices[0]) 50 | { 51 | fixed (Vertexelement9* vertexElems = &_vertexelements[0]) 52 | { 53 | void* ppbData; 54 | Game.Device->CreateVertexBuffer(3 * 20, D3D9.UsageWriteonly, 0, Pool.Default, ref _ppVertexBuffer, null); 55 | _ppVertexBuffer->Lock(0, 0, &ppbData, 0); 56 | System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(ppbData, ptr, (uint)(sizeof(Vertex) * _vertices.Length)); 57 | _ppVertexBuffer->Unlock(); 58 | 59 | Game.Device->CreateVertexDeclaration(vertexElems, ref _ppDecl); 60 | } 61 | } 62 | } 63 | 64 | private void Game_Render(TimeSpan obj) 65 | { 66 | float hue = (float)_stopwatch.Elapsed.TotalSeconds * 0.15f % 1; 67 | Vector4 vector = new(1.0f * hue, 1.0f * 0.75f, 1.0f * 0.75f, 1.0f); 68 | 69 | Game.Device->Clear(0, null, D3D9.ClearTarget, (uint)SilkColor.FromHsv(vector).ToBgra(), 1.0f, 0); 70 | Game.Device->BeginScene(); 71 | 72 | Game.Device->SetStreamSource(0, _ppVertexBuffer, 0, 20); 73 | Game.Device->SetVertexDeclaration(_ppDecl); 74 | Game.Device->DrawPrimitive(Primitivetype.Trianglelist, 0, 1); 75 | 76 | Game.Device->EndScene(); 77 | Game.Device->Present((Box2D*)IntPtr.Zero, (Box2D*)IntPtr.Zero, 1, (RGNData*)IntPtr.Zero); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace SilkRenderer.WPF; 4 | 5 | /// 6 | /// Interaction logic for MainWindow.xaml 7 | /// 8 | public partial class MainWindow : Window 9 | { 10 | public MainWindow() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Common/Camera.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using SilkRenderer.WPF.Common; 4 | 5 | namespace SilkRenderer.WPF.OpenGL.Common; 6 | 7 | // This is the camera class as it could be set up after the tutorials on the website. 8 | // It is important to note there are a few ways you could have set up this camera. 9 | // For example, you could have also managed the player input inside the camera class, 10 | // and a lot of the properties could have been made into functions. 11 | 12 | // TL;DR: This is just one of many ways in which we could have set up the camera. 13 | // Check out the web version if you don't know why we are doing a specific thing or want to know more about the code. 14 | public class Camera 15 | { 16 | // Those vectors are directions pointing outwards from the camera to define how it rotated. 17 | private Vector3 _front = -Vector3.UnitZ; 18 | 19 | private Vector3 _up = Vector3.UnitY; 20 | 21 | private Vector3 _right = Vector3.UnitX; 22 | 23 | // Rotation around the X axis (radians) 24 | private float _pitch; 25 | 26 | // Rotation around the Y axis (radians) 27 | private float _yaw = -MathHelper.PiOver2; // Without this, you would be started rotated 90 degrees right. 28 | 29 | // The field of view of the camera (radians) 30 | private float _fov = MathHelper.PiOver2; 31 | 32 | public Camera(Vector3 position, float aspectRatio) 33 | { 34 | Position = position; 35 | AspectRatio = aspectRatio; 36 | } 37 | 38 | // The position of the camera 39 | public Vector3 Position { get; set; } 40 | 41 | // This is simply the aspect ratio of the viewport, used for the projection matrix. 42 | public float AspectRatio { private get; set; } 43 | 44 | public Vector3 Front => _front; 45 | 46 | public Vector3 Up => _up; 47 | 48 | public Vector3 Right => _right; 49 | 50 | // We convert from degrees to radians as soon as the property is set to improve performance. 51 | public float Pitch 52 | { 53 | get => MathHelper.RadiansToDegrees(_pitch); 54 | set 55 | { 56 | // We clamp the pitch value between -89 and 89 to prevent the camera from going upside down, and a bunch 57 | // of weird "bugs" when you are using euler angles for rotation. 58 | // If you want to read more about this you can try researching a topic called gimbal lock 59 | var angle = MathHelper.Clamp(value, -89f, 89f); 60 | _pitch = MathHelper.DegreesToRadians(angle); 61 | UpdateVectors(); 62 | } 63 | } 64 | 65 | // We convert from degrees to radians as soon as the property is set to improve performance. 66 | public float Yaw 67 | { 68 | get => MathHelper.RadiansToDegrees(_yaw); 69 | set 70 | { 71 | _yaw = MathHelper.DegreesToRadians(value); 72 | UpdateVectors(); 73 | } 74 | } 75 | 76 | // The field of view (FOV) is the vertical angle of the camera view. 77 | // This has been discussed more in depth in a previous tutorial, 78 | // but in this tutorial, you have also learned how we can use this to simulate a zoom feature. 79 | // We convert from degrees to radians as soon as the property is set to improve performance. 80 | public float Fov 81 | { 82 | get => MathHelper.RadiansToDegrees(_fov); 83 | set 84 | { 85 | var angle = MathHelper.Clamp(value, 1f, 90f); 86 | _fov = MathHelper.DegreesToRadians(angle); 87 | } 88 | } 89 | 90 | // Get the view matrix using the amazing LookAt function described more in depth on the web tutorials 91 | public Matrix4x4 GetViewMatrix() 92 | { 93 | return Matrix4x4.CreateLookAt(Position, Position + _front, _up); 94 | } 95 | 96 | // Get the projection matrix using the same method we have used up until this point 97 | public Matrix4x4 GetProjectionMatrix() 98 | { 99 | return Matrix4x4.CreatePerspectiveFieldOfView(_fov, AspectRatio, 0.01f, 100f); 100 | } 101 | 102 | // This function is going to update the direction vertices using some of the math learned in the web tutorials. 103 | private void UpdateVectors() 104 | { 105 | // First, the front matrix is calculated using some basic trigonometry. 106 | _front.X = MathF.Cos(_pitch) * MathF.Cos(_yaw); 107 | _front.Y = MathF.Sin(_pitch); 108 | _front.Z = MathF.Cos(_pitch) * MathF.Sin(_yaw); 109 | 110 | // We need to make sure the vectors are all normalized, as otherwise we would get some funky results. 111 | _front = Vector3.Normalize(_front); 112 | 113 | // Calculate both the right and the up vector using cross product. 114 | // Note that we are calculating the right from the global up; this behaviour might 115 | // not be what you need for all cameras so keep this in mind if you do not want a FPS camera. 116 | _right = Vector3.Normalize(Vector3.Cross(_front, Vector3.UnitY)); 117 | _up = Vector3.Normalize(Vector3.Cross(_right, _front)); 118 | } 119 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Common/Shader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Numerics; 5 | using Silk.NET.OpenGL; 6 | 7 | namespace SilkRenderer.WPF.OpenGL.Common; 8 | 9 | // A simple class meant to help create shaders. 10 | public class Shader 11 | { 12 | public readonly uint Handle; 13 | 14 | private readonly Dictionary _uniformLocations; 15 | 16 | // This is how you create a simple shader. 17 | // Shaders are written in GLSL, which is a language very similar to C in its semantics. 18 | // The GLSL source is compiled *at runtime*, so it can optimize itself for the graphics card it's currently being used on. 19 | // A commented example of GLSL can be found in shader.vert. 20 | public Shader(string vertPath, string fragPath) 21 | { 22 | // There are several different types of shaders, but the only two you need for basic rendering are the vertex and fragment shaders. 23 | // The vertex shader is responsible for moving around vertices, and uploading that data to the fragment shader. 24 | // The vertex shader won't be too important here, but they'll be more important later. 25 | // The fragment shader is responsible for then converting the vertices to "fragments", which represent all the data OpenGL needs to draw a pixel. 26 | // The fragment shader is what we'll be using the most here. 27 | 28 | // Load vertex shader and compile 29 | string shaderSource = File.ReadAllText(vertPath); 30 | 31 | // GL.CreateShader will create an empty shader (obviously). The ShaderType enum denotes which type of shader will be created. 32 | uint vertexShader = RenderContext.GL.CreateShader(ShaderType.VertexShader); 33 | 34 | // Now, bind the GLSL source code 35 | RenderContext.GL.ShaderSource(vertexShader, shaderSource); 36 | 37 | // And then compile 38 | CompileShader(vertexShader); 39 | 40 | // We do the same for the fragment shader. 41 | shaderSource = File.ReadAllText(fragPath); 42 | var fragmentShader = RenderContext.GL.CreateShader(ShaderType.FragmentShader); 43 | RenderContext.GL.ShaderSource(fragmentShader, shaderSource); 44 | CompileShader(fragmentShader); 45 | 46 | // These two shaders must then be merged into a shader program, which can then be used by OpenGL. 47 | // To do this, create a program... 48 | Handle = RenderContext.GL.CreateProgram(); 49 | 50 | // Attach both shaders... 51 | RenderContext.GL.AttachShader(Handle, vertexShader); 52 | RenderContext.GL.AttachShader(Handle, fragmentShader); 53 | 54 | // And then link them together. 55 | LinkProgram(Handle); 56 | 57 | // When the shader program is linked, it no longer needs the individual shaders attached to it; the compiled code is copied into the shader program. 58 | // Detach them, and then delete them. 59 | RenderContext.GL.DetachShader(Handle, vertexShader); 60 | RenderContext.GL.DetachShader(Handle, fragmentShader); 61 | RenderContext.GL.DeleteShader(fragmentShader); 62 | RenderContext.GL.DeleteShader(vertexShader); 63 | 64 | // The shader is now ready to go, but first, we're going to cache all the shader uniform locations. 65 | // Querying this from the shader is very slow, so we do it once on initialization and reuse those values 66 | // later. 67 | 68 | // First, we have to get the number of active uniforms in the shader. 69 | RenderContext.GL.GetProgram(Handle, GLEnum.ActiveUniforms, out var numberOfUniforms); 70 | 71 | // Next, allocate the dictionary to hold the locations. 72 | _uniformLocations = new Dictionary(); 73 | 74 | // Loop over all the uniforms, 75 | for (uint i = 0; i < numberOfUniforms; i++) 76 | { 77 | // get the name of this uniform, 78 | var key = RenderContext.GL.GetActiveUniform(Handle, i, out _, out _); 79 | 80 | // get the location, 81 | var location = RenderContext.GL.GetUniformLocation(Handle, key); 82 | 83 | // and then add it to the dictionary. 84 | _uniformLocations.Add(key, location); 85 | } 86 | } 87 | 88 | private static void CompileShader(uint shader) 89 | { 90 | // Try to compile the shader 91 | RenderContext.GL.CompileShader(shader); 92 | 93 | // Check for compilation errors 94 | RenderContext.GL.GetShader(shader, GLEnum.CompileStatus, out var code); 95 | if (code != (int)GLEnum.True) 96 | { 97 | // We can use `GL.GetShaderInfoLog(shader)` to get information about the error. 98 | var infoLog = RenderContext.GL.GetShaderInfoLog(shader); 99 | throw new Exception($"Error occurred whilst compiling Shader({shader}).\n\n{infoLog}"); 100 | } 101 | } 102 | 103 | private static void LinkProgram(uint program) 104 | { 105 | // We link the program 106 | RenderContext.GL.LinkProgram(program); 107 | 108 | // Check for linking errors 109 | RenderContext.GL.GetProgram(program, GLEnum.LinkStatus, out var code); 110 | if (code != (int)GLEnum.True) 111 | { 112 | // We can use `GL.GetProgramInfoLog(program)` to get information about the error. 113 | throw new Exception($"Error occurred whilst linking Program({program})"); 114 | } 115 | } 116 | 117 | // A wrapper function that enables the shader program. 118 | public void Use() 119 | { 120 | RenderContext.GL.UseProgram(Handle); 121 | } 122 | 123 | public void Discard() 124 | { 125 | if (RenderContext.GL.IsProgram(Handle)) 126 | { 127 | RenderContext.GL.UseProgram(0); 128 | } 129 | } 130 | 131 | // The shader sources provided with this project use hardcoded layout(location)-s. If you want to do it dynamically, 132 | // you can omit the layout(location=X) lines in the vertex shader, and use this in VertexAttribPointer instead of the hardcoded values. 133 | public int GetAttribLocation(string attribName) 134 | { 135 | return RenderContext.GL.GetAttribLocation(Handle, attribName); 136 | } 137 | 138 | // Uniform setters 139 | // Uniforms are variables that can be set by user code, instead of reading them from the VBO. 140 | // You use VBOs for vertex-related data, and uniforms for almost everything else. 141 | 142 | // Setting a uniform is almost always the exact same, so I'll explain it here once, instead of in every method: 143 | // 1. Bind the program you want to set the uniform on 144 | // 2. Get a handle to the location of the uniform with GL.GetUniformLocation. 145 | // 3. Use the appropriate GL.Uniform* function to set the uniform. 146 | 147 | /// 148 | /// Set a uniform int on this shader. 149 | /// 150 | /// The name of the uniform 151 | /// The data to set 152 | public void SetInt(string name, int data) 153 | { 154 | RenderContext.GL.UseProgram(Handle); 155 | RenderContext.GL.Uniform1(_uniformLocations[name], data); 156 | } 157 | 158 | /// 159 | /// Set a uniform float on this shader. 160 | /// 161 | /// The name of the uniform 162 | /// The data to set 163 | public void SetFloat(string name, float data) 164 | { 165 | RenderContext.GL.UseProgram(Handle); 166 | RenderContext.GL.Uniform1(_uniformLocations[name], data); 167 | } 168 | 169 | /// 170 | /// Set a uniform Matrix4 on this shader 171 | /// 172 | /// The name of the uniform 173 | /// The data to set 174 | /// 175 | /// 176 | /// The matrix is transposed before being sent to the shader. 177 | /// 178 | /// 179 | public unsafe void SetMatrix4(string name, Matrix4x4 data) 180 | { 181 | RenderContext.GL.UseProgram(Handle); 182 | RenderContext.GL.UniformMatrix4(_uniformLocations[name], 1, true, (float*)&data); 183 | } 184 | 185 | /// 186 | /// Set a uniform Vector3 on this shader. 187 | /// 188 | /// The name of the uniform 189 | /// The data to set 190 | public void SetVector3(string name, Vector3 data) 191 | { 192 | RenderContext.GL.UseProgram(Handle); 193 | RenderContext.GL.Uniform3(_uniformLocations[name], data); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Framebuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Interop; 3 | using System.Windows.Media; 4 | using Silk.NET.Direct3D9; 5 | using Silk.NET.OpenGL; 6 | using Silk.NET.WGL.Extensions.NV; 7 | using SilkRenderer.WPF.Common; 8 | 9 | namespace SilkRenderer.WPF.OpenGL; 10 | 11 | public unsafe class Framebuffer : FramebufferBase 12 | { 13 | public RenderContext Context { get; } 14 | 15 | public override int FramebufferWidth { get; } 16 | 17 | public override int FramebufferHeight { get; } 18 | 19 | public uint GLFramebufferHandle { get; } 20 | 21 | public uint GLSharedTextureHandle { get; } 22 | 23 | public uint GLDepthRenderBufferHandle { get; } 24 | 25 | public IntPtr DxInteropRegisteredHandle { get; } 26 | 27 | public override D3DImage D3dImage { get; } 28 | 29 | public TranslateTransform TranslateTransform { get; } 30 | 31 | public ScaleTransform FlipYTransform { get; } 32 | 33 | public Framebuffer(RenderContext context, int framebufferWidth, int framebufferHeight) 34 | { 35 | Context = context; 36 | FramebufferWidth = framebufferWidth; 37 | FramebufferHeight = framebufferHeight; 38 | 39 | IDirect3DDevice9Ex* device = (IDirect3DDevice9Ex*)context.DxDeviceHandle; 40 | IDirect3DSurface9* surface; 41 | void* surfacePtr = (void*)IntPtr.Zero; 42 | device->CreateRenderTarget((uint)FramebufferWidth, (uint)FramebufferHeight, context.Format, MultisampleType.MultisampleNone, 0, 0, &surface, &surfacePtr); 43 | 44 | RenderContext.NVDXInterop.DxsetResourceShareHandle(surface, (nint)surfacePtr); 45 | 46 | GLFramebufferHandle = RenderContext.GL.GenFramebuffer(); 47 | GLSharedTextureHandle = RenderContext.GL.GenTexture(); 48 | 49 | DxInteropRegisteredHandle = RenderContext.NVDXInterop.DxregisterObject(context.GlDeviceHandle, surface, GLSharedTextureHandle, (NV)TextureTarget.Texture2D, NV.AccessReadWriteNV); 50 | 51 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GLFramebufferHandle); 52 | RenderContext.GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, GLSharedTextureHandle, 0); 53 | 54 | GLDepthRenderBufferHandle = RenderContext.GL.GenRenderbuffer(); 55 | RenderContext.GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, GLDepthRenderBufferHandle); 56 | RenderContext.GL.RenderbufferStorage((GLEnum)RenderbufferTarget.Renderbuffer, GLEnum.Depth24Stencil8, (uint)FramebufferWidth, (uint)FramebufferHeight); 57 | 58 | RenderContext.GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, GLDepthRenderBufferHandle); 59 | RenderContext.GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.StencilAttachment, RenderbufferTarget.Renderbuffer, GLDepthRenderBufferHandle); 60 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 61 | 62 | D3dImage = new D3DImage(); 63 | D3dImage.Lock(); 64 | D3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, (IntPtr)surface); 65 | D3dImage.Unlock(); 66 | 67 | TranslateTransform = new TranslateTransform(0, FramebufferHeight); 68 | FlipYTransform = new ScaleTransform(1, -1); 69 | } 70 | 71 | public override void Dispose() 72 | { 73 | RenderContext.GL.DeleteFramebuffer(GLFramebufferHandle); 74 | RenderContext.GL.DeleteRenderbuffer(GLDepthRenderBufferHandle); 75 | RenderContext.GL.DeleteTexture(GLSharedTextureHandle); 76 | RenderContext.NVDXInterop.DxunregisterObject(Context.GlDeviceHandle, DxInteropRegisteredHandle); 77 | 78 | GC.SuppressFinalize(this); 79 | } 80 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/GameControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Media; 4 | using Silk.NET.Maths; 5 | using Silk.NET.OpenGL; 6 | using Silk.NET.WGL.Extensions.NV; 7 | using SilkRenderer.WPF.Common; 8 | 9 | namespace SilkRenderer.WPF.OpenGL; 10 | 11 | public class GameControl : GameBase 12 | { 13 | private RenderContext _context; 14 | 15 | public Settings Setting { get; set; } = new Settings(); 16 | 17 | public override event Action Ready; 18 | public override event Action Render; 19 | public override event Action UpdateFrame; 20 | 21 | protected override void OnStart() 22 | { 23 | if (_context == null) 24 | { 25 | _context = new RenderContext(Setting); 26 | 27 | Ready?.Invoke(); 28 | } 29 | } 30 | 31 | protected override void OnSizeChanged(SizeChangedInfo sizeInfo) 32 | { 33 | if (_context != null && sizeInfo.NewSize.Width > 0 && sizeInfo.NewSize.Height > 0) 34 | { 35 | Framebuffer?.Dispose(); 36 | Framebuffer = new Framebuffer(_context, (int)sizeInfo.NewSize.Width, (int)sizeInfo.NewSize.Height); 37 | } 38 | } 39 | 40 | protected override void OnDraw(DrawingContext drawingContext) 41 | { 42 | Framebuffer.D3dImage.Lock(); 43 | 44 | RenderContext.NVDXInterop.DxlockObjects(_context.GlDeviceHandle, 1, new[] { Framebuffer.DxInteropRegisteredHandle }); 45 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, Framebuffer.GLFramebufferHandle); 46 | 47 | RenderContext.GL.Viewport(new Rectangle(0, 0, Framebuffer.FramebufferWidth, Framebuffer.FramebufferHeight)); 48 | Render?.Invoke(_stopwatch.Elapsed - _lastFrameStamp); 49 | 50 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 51 | RenderContext.NVDXInterop.DxunlockObjects(_context.GlDeviceHandle, 1, new[] { Framebuffer.DxInteropRegisteredHandle }); 52 | 53 | Framebuffer.D3dImage.AddDirtyRect(new Int32Rect(0, 0, Framebuffer.FramebufferWidth, Framebuffer.FramebufferHeight)); 54 | Framebuffer.D3dImage.Unlock(); 55 | 56 | drawingContext.PushTransform(Framebuffer.TranslateTransform); 57 | drawingContext.PushTransform(Framebuffer.FlipYTransform); 58 | 59 | Rect rect = new(0, 0, Framebuffer.D3dImage.Width, Framebuffer.D3dImage.Height); 60 | drawingContext.DrawImage(Framebuffer.D3dImage, rect); 61 | 62 | drawingContext.Pop(); 63 | drawingContext.Pop(); 64 | 65 | UpdateFrame?.Invoke(this, _stopwatch.Elapsed - _lastFrameStamp); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/RenderContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Silk.NET.Core.Contexts; 4 | using Silk.NET.Direct3D9; 5 | using Silk.NET.OpenGL; 6 | using Silk.NET.WGL.Extensions.NV; 7 | using Silk.NET.Windowing; 8 | 9 | namespace SilkRenderer.WPF.OpenGL; 10 | 11 | public unsafe class RenderContext 12 | { 13 | private static Settings _sharedContextSettings; 14 | private static int _sharedContextReferenceCount; 15 | 16 | public static GL GL { get; private set; } 17 | 18 | public static NVDXInterop NVDXInterop { get; private set; } 19 | 20 | public Format Format { get; } 21 | 22 | public IntPtr DxDeviceHandle { get; } 23 | 24 | public IntPtr GlDeviceHandle { get; } 25 | 26 | public RenderContext(Settings settings) 27 | { 28 | IDirect3D9Ex* direct3D9; 29 | IDirect3DDevice9Ex* device; 30 | D3D9.GetApi(null).Direct3DCreate9Ex(D3D9.SdkVersion, &direct3D9); 31 | 32 | Displaymodeex pMode = new((uint)sizeof(Displaymodeex)); 33 | direct3D9->GetAdapterDisplayModeEx(D3D9.AdapterDefault, ref pMode, null); 34 | Format = pMode.Format; 35 | 36 | PresentParameters presentParameters = new() 37 | { 38 | Windowed = 1, 39 | SwapEffect = Swapeffect.Discard, 40 | HDeviceWindow = 0, 41 | PresentationInterval = 0, 42 | BackBufferFormat = Format, 43 | BackBufferWidth = 1, 44 | BackBufferHeight = 1, 45 | AutoDepthStencilFormat = Format.Unknown, 46 | BackBufferCount = 1, 47 | EnableAutoDepthStencil = 0, 48 | Flags = 0, 49 | FullScreenRefreshRateInHz = 0, 50 | MultiSampleQuality = 0, 51 | MultiSampleType = MultisampleType.MultisampleNone 52 | }; 53 | direct3D9->CreateDeviceEx(D3D9.AdapterDefault, Devtype.Hal, 0, D3D9.CreateHardwareVertexprocessing | D3D9.CreateMultithreaded | D3D9.CreatePuredevice, ref presentParameters, (Displaymodeex*)IntPtr.Zero, &device); 54 | 55 | DxDeviceHandle = (IntPtr)device; 56 | 57 | GetOrCreateSharedOpenGLContext(settings); 58 | 59 | GlDeviceHandle = NVDXInterop.DxopenDevice(device); 60 | } 61 | 62 | private static void GetOrCreateSharedOpenGLContext(Settings settings) 63 | { 64 | if (_sharedContextSettings == null) 65 | { 66 | WindowOptions options = WindowOptions.Default; 67 | 68 | options.API = new GraphicsAPI(ContextAPI.OpenGL, settings.GraphicsProfile, settings.GraphicsContextFlags, new APIVersion(settings.MajorVersion, settings.MinorVersion)); 69 | options.IsVisible = false; 70 | 71 | IWindow window = Window.Create(options); 72 | 73 | window.Initialize(); 74 | 75 | GL = window.CreateOpenGL(); 76 | NVDXInterop = new(GL.Context); 77 | 78 | _sharedContextSettings = settings; 79 | } 80 | 81 | Interlocked.Increment(ref _sharedContextReferenceCount); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/ExampleScene.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/ExampleScene.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Numerics; 4 | using System.Windows; 5 | using System.Windows.Controls; 6 | using Silk.NET.OpenGL; 7 | using SilkRenderer.WPF.Common; 8 | 9 | namespace SilkRenderer.WPF.OpenGL.Sample; 10 | 11 | public partial class ExampleScene : UserControl 12 | { 13 | private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); 14 | uint vao; 15 | uint shaderProgram; 16 | 17 | public ExampleScene() 18 | { 19 | InitializeComponent(); 20 | 21 | Game.Setting = new Settings() 22 | { 23 | MajorVersion = 4, 24 | MinorVersion = 5, 25 | OpenGlProfile = Silk.NET.GLFW.OpenGlProfile.Compat 26 | }; 27 | Game.Loaded += Game_Loaded; 28 | Game.Render += Game_Render; 29 | Game.Start(); 30 | } 31 | 32 | private unsafe void Game_Loaded(object sender, RoutedEventArgs e) 33 | { 34 | GL gl = RenderContext.GL; 35 | gl.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); 36 | 37 | float[] vertices = { 38 | -0.5f, -0.5f, 0.0f, 39 | 0.5f, -0.5f, 0.0f, 40 | 0.0f, 0.5f, 0.0f 41 | }; 42 | 43 | gl.GenBuffers(1, out uint vbo); 44 | gl.BindBuffer(GLEnum.ArrayBuffer, vbo); 45 | gl.BufferData(GLEnum.ArrayBuffer, (nuint)vertices.Length * sizeof(float), vertices, GLEnum.StaticDraw); 46 | 47 | gl.GenVertexArrays(1, out vao); 48 | gl.BindVertexArray(vao); 49 | gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), null); 50 | gl.EnableVertexAttribArray(0); 51 | 52 | string vertexShaderSource = @" 53 | #version 330 core 54 | layout (location = 0) in vec3 aPos; 55 | void main() 56 | { 57 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 58 | } 59 | "; 60 | 61 | string fragmentShaderSource = @" 62 | #version 330 core 63 | out vec4 FragColor; 64 | void main() 65 | { 66 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 67 | } 68 | "; 69 | 70 | uint vertexShader = gl.CreateShader(GLEnum.VertexShader); 71 | gl.ShaderSource(vertexShader, vertexShaderSource); 72 | gl.CompileShader(vertexShader); 73 | 74 | uint fragmentShader = gl.CreateShader(GLEnum.FragmentShader); 75 | gl.ShaderSource(fragmentShader, fragmentShaderSource); 76 | gl.CompileShader(fragmentShader); 77 | 78 | shaderProgram = gl.CreateProgram(); 79 | gl.AttachShader(shaderProgram, vertexShader); 80 | gl.AttachShader(shaderProgram, fragmentShader); 81 | gl.LinkProgram(shaderProgram); 82 | 83 | gl.DeleteShader(vertexShader); 84 | gl.DeleteShader(fragmentShader); 85 | 86 | } 87 | 88 | private void Game_Render(TimeSpan obj) 89 | { 90 | GL gl = RenderContext.GL; 91 | 92 | float hue = (float)_stopwatch.Elapsed.TotalSeconds * 0.15f % 1; 93 | 94 | gl.Disable(EnableCap.DepthTest); 95 | 96 | gl.ClearColor(SilkColor.ByDrawingColor(SilkColor.FromHsv(new Vector4(1.0f * hue, 1.0f * 0.75f, 1.0f * 0.75f, 1.0f)))); 97 | gl.Clear(ClearBufferMask.ColorBufferBit); 98 | 99 | gl.UseProgram(shaderProgram); 100 | gl.BindVertexArray(vao); 101 | gl.DrawArrays(GLEnum.Triangles, 0, 3); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/Materials.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/Materials.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Input; 6 | using Silk.NET.OpenGL; 7 | using Silk.NET.Windowing; 8 | using SilkRenderer.WPF.OpenGL.Common; 9 | using Shader = SilkRenderer.WPF.OpenGL.Common.Shader; 10 | 11 | namespace SilkRenderer.WPF.OpenGL.Sample; 12 | 13 | public partial class Materials : UserControl 14 | { 15 | const float cameraSpeed = 1.5f; 16 | const float sensitivity = 0.2f; 17 | 18 | private readonly float[] _vertices = 19 | { 20 | // Position Normal 21 | -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // Front face 22 | 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 23 | 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 24 | 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 25 | -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 26 | -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 27 | 28 | -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // Back face 29 | 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 30 | 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 31 | 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 32 | -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 33 | -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 34 | 35 | -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // Left face 36 | -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 37 | -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 38 | -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 39 | -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 40 | -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 41 | 42 | 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Right face 43 | 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 44 | 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 45 | 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 46 | 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 47 | 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 48 | 49 | -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, // Bottom face 50 | 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 51 | 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 52 | 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 53 | -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 54 | -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 55 | 56 | -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Top face 57 | 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 58 | 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 59 | 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 60 | -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 61 | -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f 62 | }; 63 | 64 | private readonly Vector3 _lightPos = new(1.2f, 1.0f, 2.0f); 65 | 66 | private uint _vertexBufferObject; 67 | 68 | private uint _vaoModel; 69 | 70 | private uint _vaoLamp; 71 | 72 | private Shader _lampShader; 73 | 74 | private Shader _lightingShader; 75 | 76 | private Camera _camera; 77 | 78 | private bool _firstMove = true; 79 | 80 | private Vector2 _lastPos; 81 | 82 | public Materials() 83 | { 84 | InitializeComponent(); 85 | 86 | Game.Setting = new Settings() 87 | { 88 | MajorVersion = 4, 89 | MinorVersion = 5, 90 | GraphicsProfile = ContextProfile.Compatability 91 | }; 92 | Game.Ready += Game_Ready; 93 | Game.Render += Game_Render; 94 | Game.UpdateFrame += Game_UpdateFrame; 95 | Game.Start(); 96 | } 97 | 98 | private void Game_Ready() 99 | { 100 | _vertexBufferObject = RenderContext.GL.GenBuffer(); 101 | RenderContext.GL.BindBuffer(GLEnum.ArrayBuffer, _vertexBufferObject); 102 | RenderContext.GL.BufferData(GLEnum.ArrayBuffer, (uint)_vertices.Length * sizeof(float), _vertices, GLEnum.StaticDraw); 103 | 104 | _lightingShader = new Shader("OpenGL/Sample/Shaders/shader.vert", "OpenGL/Sample/Shaders/lighting.frag"); 105 | _lampShader = new Shader("OpenGL/Sample/Shaders/shader.vert", "OpenGL/Sample/Shaders/shader.frag"); 106 | 107 | { 108 | _vaoModel = RenderContext.GL.GenVertexArray(); 109 | RenderContext.GL.BindVertexArray(_vaoModel); 110 | 111 | var positionLocation = _lightingShader.GetAttribLocation("aPos"); 112 | RenderContext.GL.EnableVertexAttribArray((uint)positionLocation); 113 | RenderContext.GL.VertexAttribPointer((uint)positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); 114 | 115 | var normalLocation = _lightingShader.GetAttribLocation("aNormal"); 116 | RenderContext.GL.EnableVertexAttribArray((uint)normalLocation); 117 | RenderContext.GL.VertexAttribPointer((uint)normalLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float)); 118 | 119 | RenderContext.GL.BindVertexArray(0); 120 | } 121 | 122 | { 123 | _vaoLamp = RenderContext.GL.GenVertexArray(); 124 | RenderContext.GL.BindVertexArray(_vaoLamp); 125 | 126 | var positionLocation = _lampShader.GetAttribLocation("aPos"); 127 | RenderContext.GL.EnableVertexAttribArray((uint)positionLocation); 128 | RenderContext.GL.VertexAttribPointer((uint)positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); 129 | 130 | RenderContext.GL.BindVertexArray(0); 131 | } 132 | 133 | _camera = new Camera(Vector3.UnitZ * 3, 0); 134 | 135 | RenderContext.GL.BindBuffer(GLEnum.ArrayBuffer, 0); 136 | } 137 | 138 | private void Game_Render(TimeSpan obj) 139 | { 140 | _camera.AspectRatio = (float)(ActualWidth / ActualHeight); 141 | 142 | RenderContext.GL.Enable(EnableCap.DepthTest); 143 | 144 | RenderContext.GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f); 145 | RenderContext.GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 146 | RenderContext.GL.BindVertexArray(_vaoModel); 147 | _lightingShader.Use(); 148 | 149 | _lightingShader.SetMatrix4("model", Matrix4x4.Identity); 150 | _lightingShader.SetMatrix4("view", _camera.GetViewMatrix()); 151 | _lightingShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); 152 | 153 | _lightingShader.SetVector3("viewPos", _camera.Position); 154 | 155 | // Here we set the material values of the cube, the material struct is just a container so to access 156 | // the underlying values we simply type "material.value" to get the location of the uniform 157 | _lightingShader.SetVector3("material.ambient", new Vector3(1.0f, 0.5f, 0.31f)); 158 | _lightingShader.SetVector3("material.diffuse", new Vector3(1.0f, 0.5f, 0.31f)); 159 | _lightingShader.SetVector3("material.specular", new Vector3(0.5f, 0.5f, 0.5f)); 160 | _lightingShader.SetFloat("material.shininess", 32.0f); 161 | 162 | // This is where we change the lights color over time using the sin function 163 | Vector3 lightColor; 164 | float time = DateTime.Now.Second + DateTime.Now.Millisecond / 1000f; 165 | lightColor.X = (MathF.Sin(time * 2.0f) + 1) / 2f; 166 | lightColor.Y = (MathF.Sin(time * 0.7f) + 1) / 2f; 167 | lightColor.Z = (MathF.Sin(time * 1.3f) + 1) / 2f; 168 | 169 | // The ambient light is less intensive than the diffuse light in order to make it less dominant 170 | Vector3 ambientColor = lightColor * new Vector3(0.2f); 171 | Vector3 diffuseColor = lightColor * new Vector3(0.5f); 172 | 173 | _lightingShader.SetVector3("light.position", _lightPos); 174 | _lightingShader.SetVector3("light.ambient", ambientColor); 175 | _lightingShader.SetVector3("light.diffuse", diffuseColor); 176 | _lightingShader.SetVector3("light.specular", new Vector3(1.0f, 1.0f, 1.0f)); 177 | 178 | RenderContext.GL.DrawArrays(PrimitiveType.Triangles, 0, 36); 179 | 180 | RenderContext.GL.BindVertexArray(_vaoLamp); 181 | 182 | _lampShader.Use(); 183 | 184 | Matrix4x4 lampMatrix = Matrix4x4.Identity; 185 | lampMatrix *= Matrix4x4.CreateScale(0.2f); 186 | lampMatrix *= Matrix4x4.CreateTranslation(_lightPos); 187 | 188 | _lampShader.SetMatrix4("model", lampMatrix); 189 | _lampShader.SetMatrix4("view", _camera.GetViewMatrix()); 190 | _lampShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); 191 | 192 | RenderContext.GL.DrawArrays(PrimitiveType.Triangles, 0, 36); 193 | 194 | _lightingShader.Discard(); 195 | _lampShader.Discard(); 196 | 197 | RenderContext.GL.BindVertexArray(0); 198 | } 199 | 200 | private void Game_UpdateFrame(object arg1, TimeSpan arg2) 201 | { 202 | if (Keyboard.IsKeyDown(Key.W)) 203 | { 204 | _camera.Position += _camera.Front * cameraSpeed * (float)arg2.TotalSeconds; 205 | } 206 | if (Keyboard.IsKeyDown(Key.S)) 207 | { 208 | _camera.Position -= _camera.Front * cameraSpeed * (float)arg2.TotalSeconds; 209 | } 210 | if (Keyboard.IsKeyDown(Key.A)) 211 | { 212 | _camera.Position -= _camera.Right * cameraSpeed * (float)arg2.TotalSeconds; 213 | } 214 | if (Keyboard.IsKeyDown(Key.D)) 215 | { 216 | _camera.Position += _camera.Right * cameraSpeed * (float)arg2.TotalSeconds; 217 | } 218 | if (Keyboard.IsKeyDown(Key.E)) 219 | { 220 | _camera.Position += _camera.Up * cameraSpeed * (float)arg2.TotalSeconds; 221 | } 222 | if (Keyboard.IsKeyDown(Key.Q)) 223 | { 224 | _camera.Position -= _camera.Up * cameraSpeed * (float)arg2.TotalSeconds; 225 | } 226 | 227 | if (Mouse.RightButton == MouseButtonState.Pressed) 228 | { 229 | Cursor = Cursors.None; 230 | 231 | Point point = Mouse.GetPosition((Control)arg1); 232 | float x = Convert.ToSingle(point.X); 233 | float y = Convert.ToSingle(point.Y); 234 | 235 | if (_firstMove) 236 | { 237 | _lastPos = new Vector2(x, y); 238 | _firstMove = false; 239 | } 240 | else 241 | { 242 | var deltaX = x - _lastPos.X; 243 | var deltaY = y - _lastPos.Y; 244 | _lastPos = new Vector2(x, y); 245 | 246 | _camera.Yaw += deltaX * sensitivity; 247 | _camera.Pitch -= deltaY * sensitivity; 248 | } 249 | } 250 | else 251 | { 252 | Cursor = null; 253 | 254 | _firstMove = true; 255 | } 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/Shaders/lighting.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | //The material is a collection of some values that we talked about in the last tutorial, 3 | //some crucial elements to the phong model. 4 | struct Material { 5 | vec3 ambient; 6 | vec3 diffuse; 7 | vec3 specular; 8 | 9 | float shininess; //Shininess is the power the specular light is raised to 10 | }; 11 | //The light contains all the values from the light source, how the ambient diffuse and specular values are from the light source. 12 | //This is technically what we were using in the last episode as we were only applying the phong model directly to the light. 13 | struct Light { 14 | vec3 position; 15 | 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | }; 20 | //We create the light and the material struct as uniforms. 21 | uniform Light light; 22 | uniform Material material; 23 | //We still need the view position. 24 | uniform vec3 viewPos; 25 | 26 | out vec4 FragColor; 27 | 28 | in vec3 Normal; 29 | in vec3 FragPos; 30 | 31 | void main() 32 | { 33 | //ambient 34 | vec3 ambient = light.ambient * material.ambient; //Remember to use the material here. 35 | 36 | //diffuse 37 | vec3 norm = normalize(Normal); 38 | vec3 lightDir = normalize(light.position - FragPos); 39 | float diff = max(dot(norm, lightDir), 0.0); 40 | vec3 diffuse = light.diffuse * (diff * material.diffuse); //Remember to use the material here. 41 | 42 | //specular 43 | vec3 viewDir = normalize(viewPos - FragPos); 44 | vec3 reflectDir = reflect(-lightDir, norm); 45 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 46 | vec3 specular = light.specular * (spec * material.specular); //Remember to use the material here. 47 | 48 | //Now the result sum has changed a bit, since we now set the objects color in each element, we now dont have to 49 | //multiply the light with the object here, instead we do it for each element seperatly. This allows much better control 50 | //over how each element is applied to different objects. 51 | vec3 result = ambient + diffuse + specular; 52 | FragColor = vec4(result, 1.0); 53 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/Shaders/shader.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 7 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Sample/Shaders/shader.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | uniform mat4 model; 6 | uniform mat4 view; 7 | uniform mat4 projection; 8 | 9 | out vec3 Normal; 10 | out vec3 FragPos; 11 | 12 | void main() 13 | { 14 | gl_Position = vec4(aPos, 1.0) * model * view * projection; 15 | FragPos = vec3(vec4(aPos, 1.0) * model); 16 | Normal = aNormal * mat3(transpose(inverse(model))); 17 | } -------------------------------------------------------------------------------- /SilkRenderer.WPF/OpenGL/Settings.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Silk.NET.GLFW; 3 | using Silk.NET.Windowing; 4 | 5 | namespace SilkRenderer.WPF.OpenGL; 6 | 7 | public class Settings 8 | { 9 | public int MajorVersion { get; set; } = 3; 10 | 11 | public int MinorVersion { get; set; } = 3; 12 | 13 | public ContextFlags GraphicsContextFlags { get; set; } = ContextFlags.Default; 14 | 15 | public ContextProfile GraphicsProfile { get; set; } = ContextProfile.Core; 16 | 17 | public OpenGlProfile OpenGlProfile { get; set; } = OpenGlProfile.Core; 18 | 19 | public static bool WouldResultInSameContext([NotNull] Settings a, [NotNull] Settings b) 20 | { 21 | if (a.MajorVersion != b.MajorVersion) 22 | { 23 | return false; 24 | } 25 | 26 | if (a.MinorVersion != b.MinorVersion) 27 | { 28 | return false; 29 | } 30 | 31 | if (a.GraphicsProfile != b.GraphicsProfile) 32 | { 33 | return false; 34 | } 35 | 36 | if (a.GraphicsContextFlags != b.GraphicsContextFlags) 37 | { 38 | return false; 39 | } 40 | 41 | return true; 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SilkRenderer.WPF/SilkRenderer.WPF.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net7.0-windows 6 | disable 7 | true 8 | x64 9 | True 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | PreserveNewest 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/App.xaml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | 3 | namespace SilkRenderer.WinUI; 4 | 5 | public partial class App : Application 6 | { 7 | public static Window MainWindow { get; set; } 8 | 9 | public App() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | protected override void OnLaunched(LaunchActivatedEventArgs args) 15 | { 16 | MainWindow = new MainWindow(); 17 | MainWindow.Activate(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: ComVisible(false)] 5 | 6 | 7 | [assembly: Guid("fedef0b9-929a-41c0-a468-d990f94c9155")] 8 | 9 | [assembly: DisableRuntimeMarshalling] 10 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/StoreLogo.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qian-o/SilkRenderer/c53847c7beca9dede31e43cb008e3be5a4757423/SilkRenderer.WinUI/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Common/FramebufferBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SilkRenderer.WinUI.Common; 4 | public abstract class FramebufferBase : IDisposable 5 | { 6 | public abstract int FramebufferWidth { get; protected set; } 7 | 8 | public abstract int FramebufferHeight { get; protected set; } 9 | 10 | public abstract IntPtr SwapChainHandle { get; protected set; } 11 | 12 | public abstract void Dispose(); 13 | } 14 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Common/GameBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using Microsoft.UI.Xaml; 6 | using Microsoft.UI.Xaml.Controls; 7 | using Microsoft.UI.Xaml.Media; 8 | 9 | namespace SilkRenderer.WinUI.Common; 10 | 11 | public abstract class GameBase : ContentControl where TFrame : FramebufferBase 12 | { 13 | public static readonly DependencyProperty FpsProperty = DependencyProperty.Register(nameof(Fps), typeof(int), typeof(GameBase), new PropertyMetadata(0)); 14 | 15 | protected Stopwatch _stopwatch = Stopwatch.StartNew(); 16 | private readonly List _fpsSample = new(); 17 | 18 | protected TimeSpan _lastRenderTime = TimeSpan.FromSeconds(-1); 19 | protected TimeSpan _lastFrameStamp; 20 | 21 | protected TFrame Framebuffer { get; set; } 22 | public int Fps 23 | { 24 | get { return (int)GetValue(FpsProperty); } 25 | set { SetValue(FpsProperty, value); } 26 | } 27 | 28 | public abstract event Action Ready; 29 | public abstract event Action Render; 30 | public abstract event Action UpdateFrame; 31 | 32 | protected abstract void OnStart(); 33 | protected abstract void OnDraw(); 34 | protected abstract void OnSizeChanged(SizeChangedEventArgs sizeInfo); 35 | 36 | protected GameBase() 37 | { 38 | SizeChanged += GameBase_SizeChanged; 39 | } 40 | 41 | private void GameBase_SizeChanged(object sender, SizeChangedEventArgs e) 42 | { 43 | OnSizeChanged(e); 44 | } 45 | 46 | private void CompositionTarget_Rendering(object sender, object e) 47 | { 48 | RenderingEventArgs args = (RenderingEventArgs)e; 49 | 50 | if (_lastRenderTime != args.RenderingTime) 51 | { 52 | InvalidateVisual(); 53 | 54 | _fpsSample.Add(Convert.ToInt32(1000.0d / (args.RenderingTime.TotalMilliseconds - _lastRenderTime.TotalMilliseconds))); 55 | // 样本数 30 56 | if (_fpsSample.Count == 30) 57 | { 58 | Fps = Convert.ToInt32(_fpsSample.Average()); 59 | _fpsSample.Clear(); 60 | } 61 | 62 | _lastRenderTime = args.RenderingTime; 63 | } 64 | } 65 | 66 | private void InvalidateVisual() 67 | { 68 | if (Framebuffer != null) 69 | { 70 | OnDraw(); 71 | 72 | _stopwatch.Restart(); 73 | } 74 | } 75 | 76 | public void Start() 77 | { 78 | Unloaded += (_, _) => 79 | { 80 | EffectiveViewportChanged -= GameBase_EffectiveViewportChanged; 81 | 82 | CompositionTarget.Rendering -= CompositionTarget_Rendering; 83 | }; 84 | 85 | Loaded += (_, _) => 86 | { 87 | EffectiveViewportChanged += GameBase_EffectiveViewportChanged; 88 | 89 | InvalidateVisual(); 90 | }; 91 | 92 | OnStart(); 93 | } 94 | 95 | private void GameBase_EffectiveViewportChanged(FrameworkElement sender, EffectiveViewportChangedEventArgs args) 96 | { 97 | CompositionTarget.Rendering -= CompositionTarget_Rendering; 98 | 99 | if (args.EffectiveViewport.Width != 1 && args.EffectiveViewport.Height != 1) 100 | { 101 | CompositionTarget.Rendering += CompositionTarget_Rendering; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Common/ISwapChainPanelNative.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using Silk.NET.Core.Native; 4 | 5 | namespace SilkRenderer.WinUI.Common; 6 | 7 | [ComImport] 8 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 9 | [Guid("63aad0b8-7c24-40ff-85a8-640d944cc325")] 10 | public interface ISwapChainPanelNative 11 | { 12 | [PreserveSig] HResult SetSwapChain([In] IntPtr swapChain); 13 | [PreserveSig] ulong Release(); 14 | } 15 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Common/SilkColor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using DrawingColor = System.Drawing.Color; 4 | 5 | namespace SilkRenderer.WinUI.Common; 6 | 7 | public struct SilkColor 8 | { 9 | public byte R { get; set; } 10 | public byte G { get; set; } 11 | public byte B { get; set; } 12 | public byte A { get; set; } 13 | 14 | // 15 | // 摘要: 16 | // Zero color. 17 | public static readonly SilkColor Zero = FromBgra(0); 18 | 19 | // 20 | // 摘要: 21 | // Transparent color. 22 | public static readonly SilkColor Transparent = FromBgra(0); 23 | 24 | // 25 | // 摘要: 26 | // AliceBlue color. 27 | public static readonly SilkColor AliceBlue = FromBgra(4293982463u); 28 | 29 | // 30 | // 摘要: 31 | // AntiqueWhite color. 32 | public static readonly SilkColor AntiqueWhite = FromBgra(4294634455u); 33 | 34 | // 35 | // 摘要: 36 | // Aqua color. 37 | public static readonly SilkColor Aqua = FromBgra(4278255615u); 38 | 39 | // 40 | // 摘要: 41 | // Aquamarine color. 42 | public static readonly SilkColor Aquamarine = FromBgra(4286578644u); 43 | 44 | // 45 | // 摘要: 46 | // Azure color. 47 | public static readonly SilkColor Azure = FromBgra(4293984255u); 48 | 49 | // 50 | // 摘要: 51 | // Beige color. 52 | public static readonly SilkColor Beige = FromBgra(4294309340u); 53 | 54 | // 55 | // 摘要: 56 | // Bisque color. 57 | public static readonly SilkColor Bisque = FromBgra(4294960324u); 58 | 59 | // 60 | // 摘要: 61 | // Black color. 62 | public static readonly SilkColor Black = FromBgra(4278190080u); 63 | 64 | // 65 | // 摘要: 66 | // BlanchedAlmond color. 67 | public static readonly SilkColor BlanchedAlmond = FromBgra(4294962125u); 68 | 69 | // 70 | // 摘要: 71 | // Blue color. 72 | public static readonly SilkColor Blue = FromBgra(4278190335u); 73 | 74 | // 75 | // 摘要: 76 | // BlueViolet color. 77 | public static readonly SilkColor BlueViolet = FromBgra(4287245282u); 78 | 79 | // 80 | // 摘要: 81 | // Brown color. 82 | public static readonly SilkColor Brown = FromBgra(4289014314u); 83 | 84 | // 85 | // 摘要: 86 | // BurlyWood color. 87 | public static readonly SilkColor BurlyWood = FromBgra(4292786311u); 88 | 89 | // 90 | // 摘要: 91 | // CadetBlue color. 92 | public static readonly SilkColor CadetBlue = FromBgra(4284456608u); 93 | 94 | // 95 | // 摘要: 96 | // Chartreuse color. 97 | public static readonly SilkColor Chartreuse = FromBgra(4286578432u); 98 | 99 | // 100 | // 摘要: 101 | // Chocolate color. 102 | public static readonly SilkColor Chocolate = FromBgra(4291979550u); 103 | 104 | // 105 | // 摘要: 106 | // Coral color. 107 | public static readonly SilkColor Coral = FromBgra(4294934352u); 108 | 109 | // 110 | // 摘要: 111 | // CornflowerBlue color. 112 | public static readonly SilkColor CornflowerBlue = FromBgra(4284782061u); 113 | 114 | // 115 | // 摘要: 116 | // Cornsilk color. 117 | public static readonly SilkColor Cornsilk = FromBgra(4294965468u); 118 | 119 | // 120 | // 摘要: 121 | // Crimson color. 122 | public static readonly SilkColor Crimson = FromBgra(4292613180u); 123 | 124 | // 125 | // 摘要: 126 | // Cyan color. 127 | public static readonly SilkColor Cyan = FromBgra(4278255615u); 128 | 129 | // 130 | // 摘要: 131 | // DarkBlue color. 132 | public static readonly SilkColor DarkBlue = FromBgra(4278190219u); 133 | 134 | // 135 | // 摘要: 136 | // DarkCyan color. 137 | public static readonly SilkColor DarkCyan = FromBgra(4278225803u); 138 | 139 | // 140 | // 摘要: 141 | // DarkGoldenrod color. 142 | public static readonly SilkColor DarkGoldenrod = FromBgra(4290283019u); 143 | 144 | // 145 | // 摘要: 146 | // DarkGray color. 147 | public static readonly SilkColor DarkGray = FromBgra(4289309097u); 148 | 149 | // 150 | // 摘要: 151 | // DarkGreen color. 152 | public static readonly SilkColor DarkGreen = FromBgra(4278215680u); 153 | 154 | // 155 | // 摘要: 156 | // DarkKhaki color. 157 | public static readonly SilkColor DarkKhaki = FromBgra(4290623339u); 158 | 159 | // 160 | // 摘要: 161 | // DarkMagenta color. 162 | public static readonly SilkColor DarkMagenta = FromBgra(4287299723u); 163 | 164 | // 165 | // 摘要: 166 | // DarkOliveGreen color. 167 | public static readonly SilkColor DarkOliveGreen = FromBgra(4283788079u); 168 | 169 | // 170 | // 摘要: 171 | // DarkOrange color. 172 | public static readonly SilkColor DarkOrange = FromBgra(4294937600u); 173 | 174 | // 175 | // 摘要: 176 | // DarkOrchid color. 177 | public static readonly SilkColor DarkOrchid = FromBgra(4288230092u); 178 | 179 | // 180 | // 摘要: 181 | // DarkRed color. 182 | public static readonly SilkColor DarkRed = FromBgra(4287299584u); 183 | 184 | // 185 | // 摘要: 186 | // DarkSalmon color. 187 | public static readonly SilkColor DarkSalmon = FromBgra(4293498490u); 188 | 189 | // 190 | // 摘要: 191 | // DarkSeaGreen color. 192 | public static readonly SilkColor DarkSeaGreen = FromBgra(4287609995u); 193 | 194 | // 195 | // 摘要: 196 | // DarkSlateBlue color. 197 | public static readonly SilkColor DarkSlateBlue = FromBgra(4282924427u); 198 | 199 | // 200 | // 摘要: 201 | // DarkSlateGray color. 202 | public static readonly SilkColor DarkSlateGray = FromBgra(4281290575u); 203 | 204 | // 205 | // 摘要: 206 | // DarkTurquoise color. 207 | public static readonly SilkColor DarkTurquoise = FromBgra(4278243025u); 208 | 209 | // 210 | // 摘要: 211 | // DarkViolet color. 212 | public static readonly SilkColor DarkViolet = FromBgra(4287889619u); 213 | 214 | // 215 | // 摘要: 216 | // DeepPink color. 217 | public static readonly SilkColor DeepPink = FromBgra(4294907027u); 218 | 219 | // 220 | // 摘要: 221 | // DeepSkyBlue color. 222 | public static readonly SilkColor DeepSkyBlue = FromBgra(4278239231u); 223 | 224 | // 225 | // 摘要: 226 | // DimGray color. 227 | public static readonly SilkColor DimGray = FromBgra(4285098345u); 228 | 229 | // 230 | // 摘要: 231 | // DodgerBlue color. 232 | public static readonly SilkColor DodgerBlue = FromBgra(4280193279u); 233 | 234 | // 235 | // 摘要: 236 | // Firebrick color. 237 | public static readonly SilkColor Firebrick = FromBgra(4289864226u); 238 | 239 | // 240 | // 摘要: 241 | // FloralWhite color. 242 | public static readonly SilkColor FloralWhite = FromBgra(4294966000u); 243 | 244 | // 245 | // 摘要: 246 | // ForestGreen color. 247 | public static readonly SilkColor ForestGreen = FromBgra(4280453922u); 248 | 249 | // 250 | // 摘要: 251 | // Fuchsia color. 252 | public static readonly SilkColor Fuchsia = FromBgra(4294902015u); 253 | 254 | // 255 | // 摘要: 256 | // Gainsboro color. 257 | public static readonly SilkColor Gainsboro = FromBgra(4292664540u); 258 | 259 | // 260 | // 摘要: 261 | // GhostWhite color. 262 | public static readonly SilkColor GhostWhite = FromBgra(4294506751u); 263 | 264 | // 265 | // 摘要: 266 | // Gold color. 267 | public static readonly SilkColor Gold = FromBgra(4294956800u); 268 | 269 | // 270 | // 摘要: 271 | // Goldenrod color. 272 | public static readonly SilkColor Goldenrod = FromBgra(4292519200u); 273 | 274 | // 275 | // 摘要: 276 | // Gray color. 277 | public static readonly SilkColor Gray = FromBgra(4286611584u); 278 | 279 | // 280 | // 摘要: 281 | // Green color. 282 | public static readonly SilkColor Green = FromBgra(4278222848u); 283 | 284 | // 285 | // 摘要: 286 | // GreenYellow color. 287 | public static readonly SilkColor GreenYellow = FromBgra(4289593135u); 288 | 289 | // 290 | // 摘要: 291 | // Honeydew color. 292 | public static readonly SilkColor Honeydew = FromBgra(4293984240u); 293 | 294 | // 295 | // 摘要: 296 | // HotPink color. 297 | public static readonly SilkColor HotPink = FromBgra(4294928820u); 298 | 299 | // 300 | // 摘要: 301 | // IndianRed color. 302 | public static readonly SilkColor IndianRed = FromBgra(4291648604u); 303 | 304 | // 305 | // 摘要: 306 | // Indigo color. 307 | public static readonly SilkColor Indigo = FromBgra(4283105410u); 308 | 309 | // 310 | // 摘要: 311 | // Ivory color. 312 | public static readonly SilkColor Ivory = FromBgra(4294967280u); 313 | 314 | // 315 | // 摘要: 316 | // Khaki color. 317 | public static readonly SilkColor Khaki = FromBgra(4293977740u); 318 | 319 | // 320 | // 摘要: 321 | // Lavender color. 322 | public static readonly SilkColor Lavender = FromBgra(4293322490u); 323 | 324 | // 325 | // 摘要: 326 | // LavenderBlush color. 327 | public static readonly SilkColor LavenderBlush = FromBgra(4294963445u); 328 | 329 | // 330 | // 摘要: 331 | // LawnGreen color. 332 | public static readonly SilkColor LawnGreen = FromBgra(4286381056u); 333 | 334 | // 335 | // 摘要: 336 | // LemonChiffon color. 337 | public static readonly SilkColor LemonChiffon = FromBgra(4294965965u); 338 | 339 | // 340 | // 摘要: 341 | // LightBlue color. 342 | public static readonly SilkColor LightBlue = FromBgra(4289583334u); 343 | 344 | // 345 | // 摘要: 346 | // LightCoral color. 347 | public static readonly SilkColor LightCoral = FromBgra(4293951616u); 348 | 349 | // 350 | // 摘要: 351 | // LightCyan color. 352 | public static readonly SilkColor LightCyan = FromBgra(4292935679u); 353 | 354 | // 355 | // 摘要: 356 | // LightGoldenrodYellow color. 357 | public static readonly SilkColor LightGoldenrodYellow = FromBgra(4294638290u); 358 | 359 | // 360 | // 摘要: 361 | // LightGray color. 362 | public static readonly SilkColor LightGray = FromBgra(4292072403u); 363 | 364 | // 365 | // 摘要: 366 | // LightGreen color. 367 | public static readonly SilkColor LightGreen = FromBgra(4287688336u); 368 | 369 | // 370 | // 摘要: 371 | // LightPink color. 372 | public static readonly SilkColor LightPink = FromBgra(4294948545u); 373 | 374 | // 375 | // 摘要: 376 | // LightSalmon color. 377 | public static readonly SilkColor LightSalmon = FromBgra(4294942842u); 378 | 379 | // 380 | // 摘要: 381 | // LightSeaGreen color. 382 | public static readonly SilkColor LightSeaGreen = FromBgra(4280332970u); 383 | 384 | // 385 | // 摘要: 386 | // LightSkyBlue color. 387 | public static readonly SilkColor LightSkyBlue = FromBgra(4287090426u); 388 | 389 | // 390 | // 摘要: 391 | // LightSlateGray color. 392 | public static readonly SilkColor LightSlateGray = FromBgra(4286023833u); 393 | 394 | // 395 | // 摘要: 396 | // LightSteelBlue color. 397 | public static readonly SilkColor LightSteelBlue = FromBgra(4289774814u); 398 | 399 | // 400 | // 摘要: 401 | // LightYellow color. 402 | public static readonly SilkColor LightYellow = FromBgra(4294967264u); 403 | 404 | // 405 | // 摘要: 406 | // Lime color. 407 | public static readonly SilkColor Lime = FromBgra(4278255360u); 408 | 409 | // 410 | // 摘要: 411 | // LimeGreen color. 412 | public static readonly SilkColor LimeGreen = FromBgra(4281519410u); 413 | 414 | // 415 | // 摘要: 416 | // Linen color. 417 | public static readonly SilkColor Linen = FromBgra(4294635750u); 418 | 419 | // 420 | // 摘要: 421 | // Magenta color. 422 | public static readonly SilkColor Magenta = FromBgra(4294902015u); 423 | 424 | // 425 | // 摘要: 426 | // Maroon color. 427 | public static readonly SilkColor Maroon = FromBgra(4286578688u); 428 | 429 | // 430 | // 摘要: 431 | // MediumAquamarine color. 432 | public static readonly SilkColor MediumAquamarine = FromBgra(4284927402u); 433 | 434 | // 435 | // 摘要: 436 | // MediumBlue color. 437 | public static readonly SilkColor MediumBlue = FromBgra(4278190285u); 438 | 439 | // 440 | // 摘要: 441 | // MediumOrchid color. 442 | public static readonly SilkColor MediumOrchid = FromBgra(4290401747u); 443 | 444 | // 445 | // 摘要: 446 | // MediumPurple color. 447 | public static readonly SilkColor MediumPurple = FromBgra(4287852763u); 448 | 449 | // 450 | // 摘要: 451 | // MediumSeaGreen color. 452 | public static readonly SilkColor MediumSeaGreen = FromBgra(4282168177u); 453 | 454 | // 455 | // 摘要: 456 | // MediumSlateBlue color. 457 | public static readonly SilkColor MediumSlateBlue = FromBgra(4286277870u); 458 | 459 | // 460 | // 摘要: 461 | // MediumSpringGreen color. 462 | public static readonly SilkColor MediumSpringGreen = FromBgra(4278254234u); 463 | 464 | // 465 | // 摘要: 466 | // MediumTurquoise color. 467 | public static readonly SilkColor MediumTurquoise = FromBgra(4282962380u); 468 | 469 | // 470 | // 摘要: 471 | // MediumVioletRed color. 472 | public static readonly SilkColor MediumVioletRed = FromBgra(4291237253u); 473 | 474 | // 475 | // 摘要: 476 | // MidnightBlue color. 477 | public static readonly SilkColor MidnightBlue = FromBgra(4279834992u); 478 | 479 | // 480 | // 摘要: 481 | // MintCream color. 482 | public static readonly SilkColor MintCream = FromBgra(4294311930u); 483 | 484 | // 485 | // 摘要: 486 | // MistyRose color. 487 | public static readonly SilkColor MistyRose = FromBgra(4294960353u); 488 | 489 | // 490 | // 摘要: 491 | // Moccasin color. 492 | public static readonly SilkColor Moccasin = FromBgra(4294960309u); 493 | 494 | // 495 | // 摘要: 496 | // NavajoWhite color. 497 | public static readonly SilkColor NavajoWhite = FromBgra(4294958765u); 498 | 499 | // 500 | // 摘要: 501 | // Navy color. 502 | public static readonly SilkColor Navy = FromBgra(4278190208u); 503 | 504 | // 505 | // 摘要: 506 | // OldLace color. 507 | public static readonly SilkColor OldLace = FromBgra(4294833638u); 508 | 509 | // 510 | // 摘要: 511 | // Olive color. 512 | public static readonly SilkColor Olive = FromBgra(4286611456u); 513 | 514 | // 515 | // 摘要: 516 | // OliveDrab color. 517 | public static readonly SilkColor OliveDrab = FromBgra(4285238819u); 518 | 519 | // 520 | // 摘要: 521 | // Orange color. 522 | public static readonly SilkColor Orange = FromBgra(4294944000u); 523 | 524 | // 525 | // 摘要: 526 | // OrangeRed color. 527 | public static readonly SilkColor OrangeRed = FromBgra(4294919424u); 528 | 529 | // 530 | // 摘要: 531 | // Orchid color. 532 | public static readonly SilkColor Orchid = FromBgra(4292505814u); 533 | 534 | // 535 | // 摘要: 536 | // PaleGoldenrod color. 537 | public static readonly SilkColor PaleGoldenrod = FromBgra(4293847210u); 538 | 539 | // 540 | // 摘要: 541 | // PaleGreen color. 542 | public static readonly SilkColor PaleGreen = FromBgra(4288215960u); 543 | 544 | // 545 | // 摘要: 546 | // PaleTurquoise color. 547 | public static readonly SilkColor PaleTurquoise = FromBgra(4289720046u); 548 | 549 | // 550 | // 摘要: 551 | // PaleVioletRed color. 552 | public static readonly SilkColor PaleVioletRed = FromBgra(4292571283u); 553 | 554 | // 555 | // 摘要: 556 | // PapayaWhip color. 557 | public static readonly SilkColor PapayaWhip = FromBgra(4294963157u); 558 | 559 | // 560 | // 摘要: 561 | // PeachPuff color. 562 | public static readonly SilkColor PeachPuff = FromBgra(4294957753u); 563 | 564 | // 565 | // 摘要: 566 | // Peru color. 567 | public static readonly SilkColor Peru = FromBgra(4291659071u); 568 | 569 | // 570 | // 摘要: 571 | // Pink color. 572 | public static readonly SilkColor Pink = FromBgra(4294951115u); 573 | 574 | // 575 | // 摘要: 576 | // Plum color. 577 | public static readonly SilkColor Plum = FromBgra(4292714717u); 578 | 579 | // 580 | // 摘要: 581 | // PowderBlue color. 582 | public static readonly SilkColor PowderBlue = FromBgra(4289781990u); 583 | 584 | // 585 | // 摘要: 586 | // Purple color. 587 | public static readonly SilkColor Purple = FromBgra(4286578816u); 588 | 589 | // 590 | // 摘要: 591 | // Red color. 592 | public static readonly SilkColor Red = FromBgra(4294901760u); 593 | 594 | // 595 | // 摘要: 596 | // RosyBrown color. 597 | public static readonly SilkColor RosyBrown = FromBgra(4290547599u); 598 | 599 | // 600 | // 摘要: 601 | // RoyalBlue color. 602 | public static readonly SilkColor RoyalBlue = FromBgra(4282477025u); 603 | 604 | // 605 | // 摘要: 606 | // SaddleBrown color. 607 | public static readonly SilkColor SaddleBrown = FromBgra(4287317267u); 608 | 609 | // 610 | // 摘要: 611 | // Salmon color. 612 | public static readonly SilkColor Salmon = FromBgra(4294606962u); 613 | 614 | // 615 | // 摘要: 616 | // SandyBrown color. 617 | public static readonly SilkColor SandyBrown = FromBgra(4294222944u); 618 | 619 | // 620 | // 摘要: 621 | // SeaGreen color. 622 | public static readonly SilkColor SeaGreen = FromBgra(4281240407u); 623 | 624 | // 625 | // 摘要: 626 | // SeaShell color. 627 | public static readonly SilkColor SeaShell = FromBgra(4294964718u); 628 | 629 | // 630 | // 摘要: 631 | // Sienna color. 632 | public static readonly SilkColor Sienna = FromBgra(4288696877u); 633 | 634 | // 635 | // 摘要: 636 | // Silver color. 637 | public static readonly SilkColor Silver = FromBgra(4290822336u); 638 | 639 | // 640 | // 摘要: 641 | // SkyBlue color. 642 | public static readonly SilkColor SkyBlue = FromBgra(4287090411u); 643 | 644 | // 645 | // 摘要: 646 | // SlateBlue color. 647 | public static readonly SilkColor SlateBlue = FromBgra(4285160141u); 648 | 649 | // 650 | // 摘要: 651 | // SlateGray color. 652 | public static readonly SilkColor SlateGray = FromBgra(4285563024u); 653 | 654 | // 655 | // 摘要: 656 | // Snow color. 657 | public static readonly SilkColor Snow = FromBgra(4294966010u); 658 | 659 | // 660 | // 摘要: 661 | // SpringGreen color. 662 | public static readonly SilkColor SpringGreen = FromBgra(4278255487u); 663 | 664 | // 665 | // 摘要: 666 | // SteelBlue color. 667 | public static readonly SilkColor SteelBlue = FromBgra(4282811060u); 668 | 669 | // 670 | // 摘要: 671 | // Tan color. 672 | public static readonly SilkColor Tan = FromBgra(4291998860u); 673 | 674 | // 675 | // 摘要: 676 | // Teal color. 677 | public static readonly SilkColor Teal = FromBgra(4278222976u); 678 | 679 | // 680 | // 摘要: 681 | // Thistle color. 682 | public static readonly SilkColor Thistle = FromBgra(4292394968u); 683 | 684 | // 685 | // 摘要: 686 | // Tomato color. 687 | public static readonly SilkColor Tomato = FromBgra(4294927175u); 688 | 689 | // 690 | // 摘要: 691 | // Turquoise color. 692 | public static readonly SilkColor Turquoise = FromBgra(4282441936u); 693 | 694 | // 695 | // 摘要: 696 | // Violet color. 697 | public static readonly SilkColor Violet = FromBgra(4293821166u); 698 | 699 | // 700 | // 摘要: 701 | // Wheat color. 702 | public static readonly SilkColor Wheat = FromBgra(4294303411u); 703 | 704 | // 705 | // 摘要: 706 | // White color. 707 | public static readonly SilkColor White = FromBgra(uint.MaxValue); 708 | 709 | // 710 | // 摘要: 711 | // WhiteSmoke color. 712 | public static readonly SilkColor WhiteSmoke = FromBgra(4294309365u); 713 | 714 | // 715 | // 摘要: 716 | // Yellow color. 717 | public static readonly SilkColor Yellow = FromBgra(4294967040u); 718 | 719 | // 720 | // 摘要: 721 | // YellowGreen color. 722 | public static readonly SilkColor YellowGreen = FromBgra(4288335154u); 723 | 724 | public SilkColor(byte red, byte green, byte blue, byte alpha = 255) 725 | { 726 | R = red; 727 | G = green; 728 | B = blue; 729 | A = alpha; 730 | } 731 | public SilkColor(float red, float green, float blue, float alpha = 1.0f) 732 | { 733 | R = ToByte(red); 734 | G = ToByte(green); 735 | B = ToByte(blue); 736 | A = ToByte(alpha); 737 | } 738 | public SilkColor(int rgba) 739 | { 740 | A = (byte)((uint)(rgba >> 24) & 0xFFu); 741 | B = (byte)((uint)(rgba >> 16) & 0xFFu); 742 | G = (byte)((uint)(rgba >> 8) & 0xFFu); 743 | R = (byte)((uint)rgba & 0xFFu); 744 | } 745 | public SilkColor(uint rgba) 746 | { 747 | A = (byte)((rgba >> 24) & 0xFFu); 748 | B = (byte)((rgba >> 16) & 0xFFu); 749 | G = (byte)((rgba >> 8) & 0xFFu); 750 | R = (byte)(rgba & 0xFFu); 751 | } 752 | 753 | public readonly int ToBgra() => B | (G << 8) | (R << 16) | (A << 24); 754 | public readonly int ToRgba() => R | (G << 8) | (B << 16) | (A << 24); 755 | public readonly int ToAbgr() => A | (B << 8) | (G << 16) | (R << 24); 756 | 757 | public static SilkColor FromBgra(int color) 758 | { 759 | return new SilkColor((byte)((uint)(color >> 16) & 0xFFu), (byte)((uint)(color >> 8) & 0xFFu), (byte)((uint)color & 0xFFu), (byte)((uint)(color >> 24) & 0xFFu)); 760 | } 761 | public static SilkColor FromBgra(uint color) 762 | { 763 | return FromBgra((int)color); 764 | } 765 | 766 | public static SilkColor FromRgba(int color) 767 | { 768 | return new SilkColor(color); 769 | } 770 | public static SilkColor FromRgba(uint color) 771 | { 772 | return new SilkColor(color); 773 | } 774 | 775 | public static SilkColor FromAbgr(int color) 776 | { 777 | return new SilkColor((byte)(color >> 24), (byte)(color >> 16), (byte)(color >> 8), (byte)color); 778 | } 779 | public static SilkColor FromAbgr(uint color) 780 | { 781 | return FromAbgr((int)color); 782 | } 783 | 784 | public static SilkColor FromHsv(Vector4 hsv) 785 | { 786 | float num = hsv.X * 360f; 787 | float y = hsv.Y; 788 | float z = hsv.Z; 789 | float num2 = z * y; 790 | float num3 = num / 60f; 791 | float num4 = num2 * (1f - Math.Abs(num3 % 2f - 1f)); 792 | float num5; 793 | float num6; 794 | float num7; 795 | if (num3 >= 0f && num3 < 1f) 796 | { 797 | num5 = num2; 798 | num6 = num4; 799 | num7 = 0f; 800 | } 801 | else if (num3 >= 1f && num3 < 2f) 802 | { 803 | num5 = num4; 804 | num6 = num2; 805 | num7 = 0f; 806 | } 807 | else if (num3 >= 2f && num3 < 3f) 808 | { 809 | num5 = 0f; 810 | num6 = num2; 811 | num7 = num4; 812 | } 813 | else if (num3 >= 3f && num3 < 4f) 814 | { 815 | num5 = 0f; 816 | num6 = num4; 817 | num7 = num2; 818 | } 819 | else if (num3 >= 4f && num3 < 5f) 820 | { 821 | num5 = num4; 822 | num6 = 0f; 823 | num7 = num2; 824 | } 825 | else if (num3 >= 5f && num3 < 6f) 826 | { 827 | num5 = num2; 828 | num6 = 0f; 829 | num7 = num4; 830 | } 831 | else 832 | { 833 | num5 = 0f; 834 | num6 = 0f; 835 | num7 = 0f; 836 | } 837 | 838 | float num8 = z - num2; 839 | return new SilkColor(hsv.W, num5 + num8, num6 + num8, num7 + num8); 840 | } 841 | 842 | public static DrawingColor ByDrawingColor(SilkColor color) 843 | { 844 | return DrawingColor.FromArgb(color.A, color.R, color.G, color.B); 845 | } 846 | 847 | private static byte ToByte(float component) 848 | { 849 | return ToByte((int)(component * 255f)); 850 | } 851 | public static byte ToByte(int value) 852 | { 853 | return (byte)((value >= 0) ? ((value > 255) ? 255u : ((uint)value)) : 0u); 854 | } 855 | } 856 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 22 | 24 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | using Microsoft.UI.Xaml.Controls; 3 | using Microsoft.UI.Xaml.Input; 4 | using SilkRenderer.WinUI.OpenGL.Sample; 5 | 6 | namespace SilkRenderer.WinUI; 7 | 8 | public sealed partial class MainWindow : Window 9 | { 10 | public MainWindow() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | private void Materials_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) 16 | { 17 | Materials materials = (Materials)sender; 18 | 19 | if (Grid.GetColumn(materials) == 1) 20 | { 21 | Grid.SetColumn(materials, 0); 22 | Grid.SetRow(materials, 0); 23 | 24 | Grid.SetColumnSpan(materials, 2); 25 | Grid.SetRowSpan(materials, 2); 26 | } 27 | else 28 | { 29 | Grid.SetColumn(materials, 1); 30 | Grid.SetRow(materials, 1); 31 | 32 | Grid.SetColumnSpan(materials, 1); 33 | Grid.SetRowSpan(materials, 1); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Common/Camera.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using SilkRenderer.WinUI.Common; 4 | 5 | namespace SilkRenderer.WinUI.OpenGL.Common; 6 | 7 | // This is the camera class as it could be set up after the tutorials on the website. 8 | // It is important to note there are a few ways you could have set up this camera. 9 | // For example, you could have also managed the player input inside the camera class, 10 | // and a lot of the properties could have been made into functions. 11 | 12 | // TL;DR: This is just one of many ways in which we could have set up the camera. 13 | // Check out the web version if you don't know why we are doing a specific thing or want to know more about the code. 14 | public class Camera 15 | { 16 | // Those vectors are directions pointing outwards from the camera to define how it rotated. 17 | private Vector3 _front = -Vector3.UnitZ; 18 | 19 | private Vector3 _up = Vector3.UnitY; 20 | 21 | private Vector3 _right = Vector3.UnitX; 22 | 23 | // Rotation around the X axis (radians) 24 | private float _pitch; 25 | 26 | // Rotation around the Y axis (radians) 27 | private float _yaw = -MathHelper.PiOver2; // Without this, you would be started rotated 90 degrees right. 28 | 29 | // The field of view of the camera (radians) 30 | private float _fov = MathHelper.PiOver2; 31 | 32 | public Camera(Vector3 position, float aspectRatio) 33 | { 34 | Position = position; 35 | AspectRatio = aspectRatio; 36 | } 37 | 38 | // The position of the camera 39 | public Vector3 Position { get; set; } 40 | 41 | // This is simply the aspect ratio of the viewport, used for the projection matrix. 42 | public float AspectRatio { private get; set; } 43 | 44 | public Vector3 Front => _front; 45 | 46 | public Vector3 Up => _up; 47 | 48 | public Vector3 Right => _right; 49 | 50 | // We convert from degrees to radians as soon as the property is set to improve performance. 51 | public float Pitch 52 | { 53 | get => MathHelper.RadiansToDegrees(_pitch); 54 | set 55 | { 56 | // We clamp the pitch value between -89 and 89 to prevent the camera from going upside down, and a bunch 57 | // of weird "bugs" when you are using euler angles for rotation. 58 | // If you want to read more about this you can try researching a topic called gimbal lock 59 | var angle = MathHelper.Clamp(value, -89f, 89f); 60 | _pitch = MathHelper.DegreesToRadians(angle); 61 | UpdateVectors(); 62 | } 63 | } 64 | 65 | // We convert from degrees to radians as soon as the property is set to improve performance. 66 | public float Yaw 67 | { 68 | get => MathHelper.RadiansToDegrees(_yaw); 69 | set 70 | { 71 | _yaw = MathHelper.DegreesToRadians(value); 72 | UpdateVectors(); 73 | } 74 | } 75 | 76 | // The field of view (FOV) is the vertical angle of the camera view. 77 | // This has been discussed more in depth in a previous tutorial, 78 | // but in this tutorial, you have also learned how we can use this to simulate a zoom feature. 79 | // We convert from degrees to radians as soon as the property is set to improve performance. 80 | public float Fov 81 | { 82 | get => MathHelper.RadiansToDegrees(_fov); 83 | set 84 | { 85 | var angle = MathHelper.Clamp(value, 1f, 90f); 86 | _fov = MathHelper.DegreesToRadians(angle); 87 | } 88 | } 89 | 90 | // Get the view matrix using the amazing LookAt function described more in depth on the web tutorials 91 | public Matrix4x4 GetViewMatrix() 92 | { 93 | return Matrix4x4.CreateLookAt(Position, Position + _front, _up); 94 | } 95 | 96 | // Get the projection matrix using the same method we have used up until this point 97 | public Matrix4x4 GetProjectionMatrix() 98 | { 99 | return Matrix4x4.CreatePerspectiveFieldOfView(_fov, AspectRatio, 0.01f, 100f); 100 | } 101 | 102 | // This function is going to update the direction vertices using some of the math learned in the web tutorials. 103 | private void UpdateVectors() 104 | { 105 | // First, the front matrix is calculated using some basic trigonometry. 106 | _front.X = MathF.Cos(_pitch) * MathF.Cos(_yaw); 107 | _front.Y = MathF.Sin(_pitch); 108 | _front.Z = MathF.Cos(_pitch) * MathF.Sin(_yaw); 109 | 110 | // We need to make sure the vectors are all normalized, as otherwise we would get some funky results. 111 | _front = Vector3.Normalize(_front); 112 | 113 | // Calculate both the right and the up vector using cross product. 114 | // Note that we are calculating the right from the global up; this behaviour might 115 | // not be what you need for all cameras so keep this in mind if you do not want a FPS camera. 116 | _right = Vector3.Normalize(Vector3.Cross(_front, Vector3.UnitY)); 117 | _up = Vector3.Normalize(Vector3.Cross(_right, _front)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Common/Shader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Numerics; 5 | using Silk.NET.OpenGL; 6 | 7 | namespace SilkRenderer.WinUI.OpenGL.Common; 8 | 9 | // A simple class meant to help create shaders. 10 | public class Shader 11 | { 12 | public readonly uint Handle; 13 | 14 | private readonly Dictionary _uniformLocations; 15 | 16 | // This is how you create a simple shader. 17 | // Shaders are written in GLSL, which is a language very similar to C in its semantics. 18 | // The GLSL source is compiled *at runtime*, so it can optimize itself for the graphics card it's currently being used on. 19 | // A commented example of GLSL can be found in shader.vert. 20 | public Shader(string vertPath, string fragPath) 21 | { 22 | // There are several different types of shaders, but the only two you need for basic rendering are the vertex and fragment shaders. 23 | // The vertex shader is responsible for moving around vertices, and uploading that data to the fragment shader. 24 | // The vertex shader won't be too important here, but they'll be more important later. 25 | // The fragment shader is responsible for then converting the vertices to "fragments", which represent all the data OpenGL needs to draw a pixel. 26 | // The fragment shader is what we'll be using the most here. 27 | 28 | // Load vertex shader and compile 29 | string shaderSource = File.ReadAllText(vertPath); 30 | 31 | // GL.CreateShader will create an empty shader (obviously). The ShaderType enum denotes which type of shader will be created. 32 | uint vertexShader = RenderContext.GL.CreateShader(ShaderType.VertexShader); 33 | 34 | // Now, bind the GLSL source code 35 | RenderContext.GL.ShaderSource(vertexShader, shaderSource); 36 | 37 | // And then compile 38 | CompileShader(vertexShader); 39 | 40 | // We do the same for the fragment shader. 41 | shaderSource = File.ReadAllText(fragPath); 42 | var fragmentShader = RenderContext.GL.CreateShader(ShaderType.FragmentShader); 43 | RenderContext.GL.ShaderSource(fragmentShader, shaderSource); 44 | CompileShader(fragmentShader); 45 | 46 | // These two shaders must then be merged into a shader program, which can then be used by OpenGL. 47 | // To do this, create a program... 48 | Handle = RenderContext.GL.CreateProgram(); 49 | 50 | // Attach both shaders... 51 | RenderContext.GL.AttachShader(Handle, vertexShader); 52 | RenderContext.GL.AttachShader(Handle, fragmentShader); 53 | 54 | // And then link them together. 55 | LinkProgram(Handle); 56 | 57 | // When the shader program is linked, it no longer needs the individual shaders attached to it; the compiled code is copied into the shader program. 58 | // Detach them, and then delete them. 59 | RenderContext.GL.DetachShader(Handle, vertexShader); 60 | RenderContext.GL.DetachShader(Handle, fragmentShader); 61 | RenderContext.GL.DeleteShader(fragmentShader); 62 | RenderContext.GL.DeleteShader(vertexShader); 63 | 64 | // The shader is now ready to go, but first, we're going to cache all the shader uniform locations. 65 | // Querying this from the shader is very slow, so we do it once on initialization and reuse those values 66 | // later. 67 | 68 | // First, we have to get the number of active uniforms in the shader. 69 | RenderContext.GL.GetProgram(Handle, GLEnum.ActiveUniforms, out var numberOfUniforms); 70 | 71 | // Next, allocate the dictionary to hold the locations. 72 | _uniformLocations = new Dictionary(); 73 | 74 | // Loop over all the uniforms, 75 | for (uint i = 0; i < numberOfUniforms; i++) 76 | { 77 | // get the name of this uniform, 78 | var key = RenderContext.GL.GetActiveUniform(Handle, i, out _, out _); 79 | 80 | // get the location, 81 | var location = RenderContext.GL.GetUniformLocation(Handle, key); 82 | 83 | // and then add it to the dictionary. 84 | _uniformLocations.Add(key, location); 85 | } 86 | } 87 | 88 | private static void CompileShader(uint shader) 89 | { 90 | // Try to compile the shader 91 | RenderContext.GL.CompileShader(shader); 92 | 93 | // Check for compilation errors 94 | RenderContext.GL.GetShader(shader, GLEnum.CompileStatus, out var code); 95 | if (code != (int)GLEnum.True) 96 | { 97 | // We can use `GL.GetShaderInfoLog(shader)` to get information about the error. 98 | var infoLog = RenderContext.GL.GetShaderInfoLog(shader); 99 | throw new Exception($"Error occurred whilst compiling Shader({shader}).\n\n{infoLog}"); 100 | } 101 | } 102 | 103 | private static void LinkProgram(uint program) 104 | { 105 | // We link the program 106 | RenderContext.GL.LinkProgram(program); 107 | 108 | // Check for linking errors 109 | RenderContext.GL.GetProgram(program, GLEnum.LinkStatus, out var code); 110 | if (code != (int)GLEnum.True) 111 | { 112 | // We can use `GL.GetProgramInfoLog(program)` to get information about the error. 113 | throw new Exception($"Error occurred whilst linking Program({program})"); 114 | } 115 | } 116 | 117 | // A wrapper function that enables the shader program. 118 | public void Use() 119 | { 120 | RenderContext.GL.UseProgram(Handle); 121 | } 122 | 123 | public void Discard() 124 | { 125 | if (RenderContext.GL.IsProgram(Handle)) 126 | { 127 | RenderContext.GL.UseProgram(0); 128 | } 129 | } 130 | 131 | // The shader sources provided with this project use hardcoded layout(location)-s. If you want to do it dynamically, 132 | // you can omit the layout(location=X) lines in the vertex shader, and use this in VertexAttribPointer instead of the hardcoded values. 133 | public int GetAttribLocation(string attribName) 134 | { 135 | return RenderContext.GL.GetAttribLocation(Handle, attribName); 136 | } 137 | 138 | // Uniform setters 139 | // Uniforms are variables that can be set by user code, instead of reading them from the VBO. 140 | // You use VBOs for vertex-related data, and uniforms for almost everything else. 141 | 142 | // Setting a uniform is almost always the exact same, so I'll explain it here once, instead of in every method: 143 | // 1. Bind the program you want to set the uniform on 144 | // 2. Get a handle to the location of the uniform with GL.GetUniformLocation. 145 | // 3. Use the appropriate GL.Uniform* function to set the uniform. 146 | 147 | /// 148 | /// Set a uniform int on this shader. 149 | /// 150 | /// The name of the uniform 151 | /// The data to set 152 | public void SetInt(string name, int data) 153 | { 154 | RenderContext.GL.UseProgram(Handle); 155 | RenderContext.GL.Uniform1(_uniformLocations[name], data); 156 | } 157 | 158 | /// 159 | /// Set a uniform float on this shader. 160 | /// 161 | /// The name of the uniform 162 | /// The data to set 163 | public void SetFloat(string name, float data) 164 | { 165 | RenderContext.GL.UseProgram(Handle); 166 | RenderContext.GL.Uniform1(_uniformLocations[name], data); 167 | } 168 | 169 | /// 170 | /// Set a uniform Matrix4 on this shader 171 | /// 172 | /// The name of the uniform 173 | /// The data to set 174 | /// 175 | /// 176 | /// The matrix is transposed before being sent to the shader. 177 | /// 178 | /// 179 | public unsafe void SetMatrix4(string name, Matrix4x4 data) 180 | { 181 | RenderContext.GL.UseProgram(Handle); 182 | RenderContext.GL.UniformMatrix4(_uniformLocations[name], 1, true, (float*)&data); 183 | } 184 | 185 | /// 186 | /// Set a uniform Vector3 on this shader. 187 | /// 188 | /// The name of the uniform 189 | /// The data to set 190 | public void SetVector3(string name, Vector3 data) 191 | { 192 | RenderContext.GL.UseProgram(Handle); 193 | RenderContext.GL.Uniform3(_uniformLocations[name], data); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Framebuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Microsoft.UI.Xaml.Media; 4 | using Silk.NET.Core.Native; 5 | using Silk.NET.Direct3D11; 6 | using Silk.NET.DXGI; 7 | using Silk.NET.OpenGL; 8 | using Silk.NET.WGL.Extensions.NV; 9 | using SilkRenderer.WinUI.Common; 10 | 11 | namespace SilkRenderer.WinUI.OpenGL; 12 | 13 | public unsafe class Framebuffer : FramebufferBase 14 | { 15 | public RenderContext Context { get; } 16 | 17 | public override int FramebufferWidth { get; protected set; } 18 | 19 | public override int FramebufferHeight { get; protected set; } 20 | 21 | public uint GLColorRenderbufferHandle { get; set; } 22 | 23 | public uint GLDepthRenderBufferHandle { get; set; } 24 | 25 | public uint GLFramebufferHandle { get; set; } 26 | 27 | public IntPtr DxInteropColorHandle { get; set; } 28 | 29 | public override IntPtr SwapChainHandle { get; protected set; } 30 | 31 | public TranslateTransform TranslateTransform { get; } 32 | 33 | public ScaleTransform FlipYTransform { get; } 34 | 35 | public Framebuffer(RenderContext context, int framebufferWidth, int framebufferHeight) 36 | { 37 | Context = context; 38 | FramebufferWidth = framebufferWidth; 39 | FramebufferHeight = framebufferHeight; 40 | 41 | IDXGISwapChain1* swapChain; 42 | 43 | // SwapChain 44 | { 45 | SwapChainDesc1 swapChainDesc = new() 46 | { 47 | Width = (uint)FramebufferWidth, 48 | Height = (uint)FramebufferHeight, 49 | Format = Format.FormatB8G8R8A8Unorm, 50 | Stereo = 0, 51 | SampleDesc = new SampleDesc() 52 | { 53 | Count = 1, 54 | Quality = 0 55 | }, 56 | BufferUsage = DXGI.UsageRenderTargetOutput, 57 | BufferCount = 2, 58 | Scaling = Scaling.Stretch, 59 | SwapEffect = SwapEffect.FlipSequential, 60 | Flags = 0, 61 | }; 62 | 63 | ((IDXGIFactory2*)Context.DxDeviceFactory)->CreateSwapChainForComposition((IUnknown*)Context.DxDeviceHandle, &swapChainDesc, null, &swapChain); 64 | 65 | SwapChainHandle = (IntPtr)swapChain; 66 | } 67 | 68 | GLFramebufferHandle = RenderContext.GL.GenFramebuffer(); 69 | 70 | TranslateTransform = new TranslateTransform 71 | { 72 | X = 0, 73 | Y = FramebufferHeight 74 | }; 75 | FlipYTransform = new ScaleTransform 76 | { 77 | ScaleX = 1, 78 | ScaleY = -1 79 | }; 80 | } 81 | 82 | public void Begin() 83 | { 84 | ID3D11Texture2D* colorbuffer; 85 | 86 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GLFramebufferHandle); 87 | 88 | // Texture2D 89 | { 90 | Guid guid = typeof(ID3D11Texture2D).GetTypeInfo().GUID; 91 | ((IDXGISwapChain1*)SwapChainHandle)->GetBuffer(0, &guid, (void**)&colorbuffer); 92 | } 93 | 94 | // GL 95 | { 96 | GLColorRenderbufferHandle = RenderContext.GL.GenRenderbuffer(); 97 | GLDepthRenderBufferHandle = RenderContext.GL.GenRenderbuffer(); 98 | 99 | DxInteropColorHandle = RenderContext.NVDXInterop.DxregisterObject(Context.GlDeviceHandle, (void*)colorbuffer, (uint)GLColorRenderbufferHandle, (NV)RenderbufferTarget.Renderbuffer, NV.AccessReadWriteNV); 100 | RenderContext.GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, RenderbufferTarget.Renderbuffer, GLColorRenderbufferHandle); 101 | 102 | RenderContext.GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, GLDepthRenderBufferHandle); 103 | RenderContext.GL.RenderbufferStorage(GLEnum.Renderbuffer, GLEnum.Depth24Stencil8, (uint)FramebufferWidth, (uint)FramebufferHeight); 104 | RenderContext.GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, (uint)GLDepthRenderBufferHandle); 105 | RenderContext.GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.StencilAttachment, RenderbufferTarget.Renderbuffer, (uint)GLDepthRenderBufferHandle); 106 | } 107 | 108 | colorbuffer->Release(); 109 | 110 | RenderContext.NVDXInterop.DxlockObjects(Context.GlDeviceHandle, 1, new[] { DxInteropColorHandle }); 111 | 112 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GLFramebufferHandle); 113 | RenderContext.GL.Viewport(0, 0, (uint)FramebufferWidth, (uint)FramebufferHeight); 114 | } 115 | 116 | public void End() 117 | { 118 | RenderContext.GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 119 | 120 | RenderContext.NVDXInterop.DxunlockObjects(Context.GlDeviceHandle, 1, new[] { DxInteropColorHandle }); 121 | 122 | RenderContext.NVDXInterop.DxunregisterObject(Context.GlDeviceHandle, DxInteropColorHandle); 123 | 124 | RenderContext.GL.DeleteRenderbuffer(GLColorRenderbufferHandle); 125 | RenderContext.GL.DeleteRenderbuffer(GLDepthRenderBufferHandle); 126 | 127 | ((IDXGISwapChain1*)SwapChainHandle)->Present(1, 0); 128 | } 129 | 130 | public void UpdateSize(int framebufferWidth, int framebufferHeight) 131 | { 132 | FramebufferWidth = framebufferWidth; 133 | FramebufferHeight = framebufferHeight; 134 | 135 | ((IDXGISwapChain1*)SwapChainHandle)->ResizeBuffers(2, (uint)framebufferWidth, (uint)framebufferHeight, Format.FormatUnknown, 0); 136 | 137 | TranslateTransform.Y = FramebufferHeight; 138 | } 139 | 140 | public override void Dispose() 141 | { 142 | RenderContext.GL.DeleteFramebuffer(GLFramebufferHandle); 143 | 144 | RenderContext.NVDXInterop.DxunregisterObject(Context.GlDeviceHandle, DxInteropColorHandle); 145 | RenderContext.GL.DeleteRenderbuffer(GLColorRenderbufferHandle); 146 | RenderContext.GL.DeleteRenderbuffer(GLDepthRenderBufferHandle); 147 | 148 | GC.SuppressFinalize(this); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/GameControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.UI.Xaml; 3 | using Microsoft.UI.Xaml.Controls; 4 | using Microsoft.UI.Xaml.Media; 5 | using SilkRenderer.WinUI.Common; 6 | using WinRT; 7 | 8 | namespace SilkRenderer.WinUI.OpenGL; 9 | 10 | public unsafe class GameControl : GameBase 11 | { 12 | private RenderContext _context; 13 | private SwapChainPanel _swapChainPanel; 14 | 15 | public Settings Setting { get; set; } = new Settings(); 16 | 17 | public override event Action Ready; 18 | public override event Action Render; 19 | public override event Action UpdateFrame; 20 | 21 | protected override void OnStart() 22 | { 23 | if (_context == null) 24 | { 25 | _context = new RenderContext(Setting); 26 | _swapChainPanel = new SwapChainPanel(); 27 | 28 | HorizontalContentAlignment = HorizontalAlignment.Stretch; 29 | VerticalContentAlignment = VerticalAlignment.Stretch; 30 | Content = _swapChainPanel; 31 | 32 | Ready?.Invoke(); 33 | } 34 | } 35 | 36 | protected override void OnSizeChanged(SizeChangedEventArgs sizeInfo) 37 | { 38 | if (_context != null && sizeInfo.NewSize.Width > 0 && sizeInfo.NewSize.Height > 0) 39 | { 40 | if (Framebuffer == null) 41 | { 42 | Framebuffer = new Framebuffer(_context, (int)ActualWidth, (int)ActualHeight); 43 | 44 | TransformGroup transformGroup = new(); 45 | transformGroup.Children.Add(Framebuffer.FlipYTransform); 46 | transformGroup.Children.Add(Framebuffer.TranslateTransform); 47 | _swapChainPanel.RenderTransform = transformGroup; 48 | 49 | _swapChainPanel.As().SetSwapChain(Framebuffer.SwapChainHandle); 50 | } 51 | else 52 | { 53 | Framebuffer?.UpdateSize((int)ActualWidth, (int)ActualHeight); 54 | } 55 | } 56 | } 57 | 58 | protected override void OnDraw() 59 | { 60 | Framebuffer.Begin(); 61 | 62 | Render?.Invoke(_stopwatch.Elapsed - _lastFrameStamp); 63 | 64 | Framebuffer.End(); 65 | 66 | UpdateFrame?.Invoke(this, _stopwatch.Elapsed - _lastFrameStamp); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/RenderContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Threading; 4 | using Silk.NET.Core.Contexts; 5 | using Silk.NET.Core.Native; 6 | using Silk.NET.Direct3D11; 7 | using Silk.NET.DXGI; 8 | using Silk.NET.OpenGL; 9 | using Silk.NET.WGL.Extensions.NV; 10 | using Silk.NET.Windowing; 11 | 12 | namespace SilkRenderer.WinUI.OpenGL; 13 | 14 | public unsafe class RenderContext 15 | { 16 | private static Settings _sharedContextSettings; 17 | private static int _sharedContextReferenceCount; 18 | 19 | public static GL GL { get; private set; } 20 | 21 | public static NVDXInterop NVDXInterop { get; private set; } 22 | 23 | public Format Format { get; } 24 | 25 | public IntPtr DxDeviceFactory { get; } 26 | 27 | public IntPtr DxDeviceHandle { get; } 28 | 29 | public IntPtr DxDeviceContext { get; } 30 | 31 | public IntPtr GlDeviceHandle { get; } 32 | 33 | public RenderContext(Settings settings) 34 | { 35 | IDXGIFactory2* factory; 36 | ID3D11Device* device; 37 | ID3D11DeviceContext* devCtx; 38 | 39 | // Factory 40 | { 41 | Guid guid = typeof(IDXGIFactory2).GetTypeInfo().GUID; 42 | DXGI.GetApi(null).CreateDXGIFactory2(0, &guid, (void**)&factory); 43 | } 44 | 45 | // Device 46 | { 47 | D3D11.GetApi(null).CreateDevice(null, D3DDriverType.Hardware, 0, 0, null, 0, D3D11.SdkVersion, &device, null, &devCtx); 48 | } 49 | 50 | DxDeviceFactory = (IntPtr)factory; 51 | DxDeviceHandle = (IntPtr)device; 52 | DxDeviceContext = (IntPtr)devCtx; 53 | 54 | GetOrCreateSharedOpenGLContext(settings); 55 | 56 | GlDeviceHandle = NVDXInterop.DxopenDevice(device); 57 | } 58 | 59 | private static void GetOrCreateSharedOpenGLContext(Settings settings) 60 | { 61 | if (_sharedContextSettings == null) 62 | { 63 | WindowOptions options = WindowOptions.Default; 64 | 65 | options.API = new GraphicsAPI(ContextAPI.OpenGL, settings.GraphicsProfile, settings.GraphicsContextFlags, new APIVersion(settings.MajorVersion, settings.MinorVersion)); 66 | options.IsVisible = false; 67 | 68 | IWindow window = Window.Create(options); 69 | 70 | window.Initialize(); 71 | 72 | GL = window.CreateOpenGL(); 73 | NVDXInterop = new(GL.Context); 74 | 75 | _sharedContextSettings = settings; 76 | } 77 | 78 | Interlocked.Increment(ref _sharedContextReferenceCount); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/ExampleScene.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/ExampleScene.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Numerics; 4 | using Microsoft.UI.Xaml.Controls; 5 | using Silk.NET.OpenGL; 6 | using Silk.NET.Windowing; 7 | using SilkRenderer.WinUI.Common; 8 | 9 | namespace SilkRenderer.WinUI.OpenGL.Sample; 10 | 11 | public sealed partial class ExampleScene : UserControl 12 | { 13 | private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); 14 | uint vao; 15 | uint shaderProgram; 16 | 17 | public ExampleScene() 18 | { 19 | InitializeComponent(); 20 | 21 | Game.Setting = new Settings() 22 | { 23 | MajorVersion = 4, 24 | MinorVersion = 5, 25 | GraphicsProfile = ContextProfile.Compatability 26 | }; 27 | Game.Loaded += Game_Loaded; 28 | Game.Render += Game_Render; 29 | Game.Start(); 30 | } 31 | 32 | private unsafe void Game_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) 33 | { 34 | GL gl = RenderContext.GL; 35 | gl.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); 36 | 37 | float[] vertices = { 38 | -0.5f, -0.5f, 0.0f, 39 | 0.5f, -0.5f, 0.0f, 40 | 0.0f, 0.5f, 0.0f 41 | }; 42 | 43 | gl.GenBuffers(1, out uint vbo); 44 | gl.BindBuffer(GLEnum.ArrayBuffer, vbo); 45 | gl.BufferData(GLEnum.ArrayBuffer, (nuint)vertices.Length * sizeof(float), vertices, GLEnum.StaticDraw); 46 | 47 | gl.GenVertexArrays(1, out vao); 48 | gl.BindVertexArray(vao); 49 | gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), null); 50 | gl.EnableVertexAttribArray(0); 51 | 52 | string vertexShaderSource = @" 53 | #version 330 core 54 | layout (location = 0) in vec3 aPos; 55 | void main() 56 | { 57 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 58 | } 59 | "; 60 | 61 | string fragmentShaderSource = @" 62 | #version 330 core 63 | out vec4 FragColor; 64 | void main() 65 | { 66 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 67 | } 68 | "; 69 | 70 | uint vertexShader = gl.CreateShader(GLEnum.VertexShader); 71 | gl.ShaderSource(vertexShader, vertexShaderSource); 72 | gl.CompileShader(vertexShader); 73 | 74 | uint fragmentShader = gl.CreateShader(GLEnum.FragmentShader); 75 | gl.ShaderSource(fragmentShader, fragmentShaderSource); 76 | gl.CompileShader(fragmentShader); 77 | 78 | shaderProgram = gl.CreateProgram(); 79 | gl.AttachShader(shaderProgram, vertexShader); 80 | gl.AttachShader(shaderProgram, fragmentShader); 81 | gl.LinkProgram(shaderProgram); 82 | 83 | gl.DeleteShader(vertexShader); 84 | gl.DeleteShader(fragmentShader); 85 | } 86 | 87 | private void Game_Render(TimeSpan obj) 88 | { 89 | GL gl = RenderContext.GL; 90 | 91 | float hue = (float)_stopwatch.Elapsed.TotalSeconds * 0.15f % 1; 92 | 93 | gl.Disable(EnableCap.DepthTest); 94 | 95 | gl.ClearColor(SilkColor.ByDrawingColor(SilkColor.FromHsv(new Vector4(1.0f * hue, 1.0f * 0.75f, 1.0f * 0.75f, 1.0f)))); 96 | gl.Clear(ClearBufferMask.ColorBufferBit); 97 | 98 | gl.UseProgram(shaderProgram); 99 | gl.BindVertexArray(vao); 100 | gl.DrawArrays(GLEnum.Triangles, 0, 3); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/Materials.xaml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/Materials.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Numerics; 4 | using System.Runtime.InteropServices; 5 | using Microsoft.UI.Xaml.Controls; 6 | using Silk.NET.OpenGL; 7 | using Silk.NET.Windowing; 8 | using SilkRenderer.WinUI.OpenGL.Common; 9 | using Shader = SilkRenderer.WinUI.OpenGL.Common.Shader; 10 | 11 | namespace SilkRenderer.WinUI.OpenGL.Sample; 12 | 13 | public sealed partial class Materials : UserControl 14 | { 15 | [LibraryImport("user32.dll")] 16 | [return: MarshalAs(UnmanagedType.Bool)] 17 | public static partial bool GetAsyncKeyState(VirtualKeyCodes vKey); 18 | 19 | [LibraryImport("user32.dll")] 20 | [return: MarshalAs(UnmanagedType.Bool)] 21 | public static partial bool GetCursorPos(out POINT pt); 22 | 23 | [StructLayout(LayoutKind.Sequential)] 24 | public struct POINT 25 | { 26 | public int X; 27 | public int Y; 28 | } 29 | 30 | public enum VirtualKeyCodes 31 | { 32 | VK_LBUTTON = 0x01, 33 | VK_RBUTTON = 0x02, 34 | 35 | W = 0x57, 36 | A = 0x41, 37 | S = 0x53, 38 | D = 0x44, 39 | E = 0x45, 40 | Q = 0x51 41 | } 42 | 43 | const float cameraSpeed = 1.5f; 44 | const float sensitivity = 0.2f; 45 | 46 | private readonly float[] _vertices = 47 | { 48 | // Position Normal 49 | -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // Front face 50 | 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 51 | 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 52 | 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 53 | -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 54 | -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 55 | 56 | -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // Back face 57 | 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 58 | 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 59 | 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 60 | -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 61 | -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 62 | 63 | -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // Left face 64 | -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 65 | -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 66 | -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 67 | -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 68 | -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 69 | 70 | 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Right face 71 | 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 72 | 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 73 | 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 74 | 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 75 | 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 76 | 77 | -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, // Bottom face 78 | 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 79 | 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 80 | 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 81 | -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 82 | -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 83 | 84 | -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Top face 85 | 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 86 | 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 87 | 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 88 | -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 89 | -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f 90 | }; 91 | 92 | private readonly Vector3 _lightPos = new(1.2f, 1.0f, 2.0f); 93 | 94 | private uint _vertexBufferObject; 95 | 96 | private uint _vaoModel; 97 | 98 | private uint _vaoLamp; 99 | 100 | private Shader _lampShader; 101 | 102 | private Shader _lightingShader; 103 | 104 | private Camera _camera; 105 | 106 | private bool _firstMove = true; 107 | 108 | private Vector2 _lastPos; 109 | 110 | public Materials() 111 | { 112 | InitializeComponent(); 113 | 114 | Game.Setting = new Settings() 115 | { 116 | MajorVersion = 4, 117 | MinorVersion = 5, 118 | GraphicsProfile = ContextProfile.Compatability 119 | }; 120 | Game.Ready += Game_Ready; 121 | Game.Render += Game_Render; 122 | Game.UpdateFrame += Game_UpdateFrame; 123 | Game.Start(); 124 | } 125 | 126 | private void Game_Ready() 127 | { 128 | RenderContext.GL.Enable(EnableCap.DepthTest); 129 | 130 | _vertexBufferObject = RenderContext.GL.GenBuffer(); 131 | RenderContext.GL.BindBuffer(GLEnum.ArrayBuffer, _vertexBufferObject); 132 | RenderContext.GL.BufferData(GLEnum.ArrayBuffer, (uint)_vertices.Length * sizeof(float), ref _vertices[0], GLEnum.StaticDraw); 133 | 134 | string path = AppDomain.CurrentDomain.BaseDirectory; 135 | 136 | _lightingShader = new Shader(Path.Combine(path, "OpenGL/Sample/Shaders/shader.vert"), Path.Combine(path, "OpenGL/Sample/Shaders/lighting.frag")); 137 | _lampShader = new Shader(Path.Combine(path, "OpenGL/Sample/Shaders/shader.vert"), Path.Combine(path, "OpenGL/Sample/Shaders/shader.frag")); 138 | 139 | { 140 | _vaoModel = RenderContext.GL.GenVertexArray(); 141 | RenderContext.GL.BindVertexArray(_vaoModel); 142 | 143 | var positionLocation = _lightingShader.GetAttribLocation("aPos"); 144 | RenderContext.GL.EnableVertexAttribArray((uint)positionLocation); 145 | RenderContext.GL.VertexAttribPointer((uint)positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); 146 | 147 | var normalLocation = _lightingShader.GetAttribLocation("aNormal"); 148 | RenderContext.GL.EnableVertexAttribArray((uint)normalLocation); 149 | RenderContext.GL.VertexAttribPointer((uint)normalLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float)); 150 | } 151 | 152 | { 153 | _vaoLamp = RenderContext.GL.GenVertexArray(); 154 | RenderContext.GL.BindVertexArray(_vaoLamp); 155 | 156 | var positionLocation = _lampShader.GetAttribLocation("aPos"); 157 | RenderContext.GL.EnableVertexAttribArray((uint)positionLocation); 158 | RenderContext.GL.VertexAttribPointer((uint)positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); 159 | } 160 | 161 | _camera = new Camera(Vector3.UnitZ * 3, 0); 162 | } 163 | 164 | private void Game_Render(TimeSpan obj) 165 | { 166 | _camera.AspectRatio = (float)(ActualWidth / ActualHeight); 167 | 168 | RenderContext.GL.Enable(EnableCap.DepthTest); 169 | 170 | RenderContext.GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f); 171 | RenderContext.GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 172 | RenderContext.GL.BindVertexArray(_vaoModel); 173 | _lightingShader.Use(); 174 | 175 | _lightingShader.SetMatrix4("model", Matrix4x4.Identity); 176 | _lightingShader.SetMatrix4("view", _camera.GetViewMatrix()); 177 | _lightingShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); 178 | 179 | _lightingShader.SetVector3("viewPos", _camera.Position); 180 | 181 | // Here we set the material values of the cube, the material struct is just a container so to access 182 | // the underlying values we simply type "material.value" to get the location of the uniform 183 | _lightingShader.SetVector3("material.ambient", new Vector3(1.0f, 0.5f, 0.31f)); 184 | _lightingShader.SetVector3("material.diffuse", new Vector3(1.0f, 0.5f, 0.31f)); 185 | _lightingShader.SetVector3("material.specular", new Vector3(0.5f, 0.5f, 0.5f)); 186 | _lightingShader.SetFloat("material.shininess", 32.0f); 187 | 188 | // This is where we change the lights color over time using the sin function 189 | Vector3 lightColor; 190 | float time = DateTime.Now.Second + DateTime.Now.Millisecond / 1000f; 191 | lightColor.X = (MathF.Sin(time * 2.0f) + 1) / 2f; 192 | lightColor.Y = (MathF.Sin(time * 0.7f) + 1) / 2f; 193 | lightColor.Z = (MathF.Sin(time * 1.3f) + 1) / 2f; 194 | 195 | // The ambient light is less intensive than the diffuse light in order to make it less dominant 196 | Vector3 ambientColor = lightColor * new Vector3(0.2f); 197 | Vector3 diffuseColor = lightColor * new Vector3(0.5f); 198 | 199 | _lightingShader.SetVector3("light.position", _lightPos); 200 | _lightingShader.SetVector3("light.ambient", ambientColor); 201 | _lightingShader.SetVector3("light.diffuse", diffuseColor); 202 | _lightingShader.SetVector3("light.specular", new Vector3(1.0f, 1.0f, 1.0f)); 203 | 204 | RenderContext.GL.DrawArrays(PrimitiveType.Triangles, 0, 36); 205 | 206 | RenderContext.GL.BindVertexArray(_vaoLamp); 207 | 208 | _lampShader.Use(); 209 | 210 | Matrix4x4 lampMatrix = Matrix4x4.Identity; 211 | lampMatrix *= Matrix4x4.CreateScale(0.2f); 212 | lampMatrix *= Matrix4x4.CreateTranslation(_lightPos); 213 | 214 | _lampShader.SetMatrix4("model", lampMatrix); 215 | _lampShader.SetMatrix4("view", _camera.GetViewMatrix()); 216 | _lampShader.SetMatrix4("projection", _camera.GetProjectionMatrix()); 217 | 218 | RenderContext.GL.DrawArrays(PrimitiveType.Triangles, 0, 36); 219 | 220 | _lightingShader.Discard(); 221 | _lampShader.Discard(); 222 | } 223 | 224 | private void Game_UpdateFrame(object arg1, TimeSpan arg2) 225 | { 226 | if (GetAsyncKeyState(VirtualKeyCodes.W)) 227 | { 228 | _camera.Position += _camera.Front * cameraSpeed * (float)arg2.TotalSeconds; 229 | } 230 | if (GetAsyncKeyState(VirtualKeyCodes.S)) 231 | { 232 | _camera.Position -= _camera.Front * cameraSpeed * (float)arg2.TotalSeconds; 233 | } 234 | if (GetAsyncKeyState(VirtualKeyCodes.A)) 235 | { 236 | _camera.Position -= _camera.Right * cameraSpeed * (float)arg2.TotalSeconds; 237 | } 238 | if (GetAsyncKeyState(VirtualKeyCodes.D)) 239 | { 240 | _camera.Position += _camera.Right * cameraSpeed * (float)arg2.TotalSeconds; 241 | } 242 | if (GetAsyncKeyState(VirtualKeyCodes.E)) 243 | { 244 | _camera.Position += _camera.Up * cameraSpeed * (float)arg2.TotalSeconds; 245 | } 246 | if (GetAsyncKeyState(VirtualKeyCodes.Q)) 247 | { 248 | _camera.Position -= _camera.Up * cameraSpeed * (float)arg2.TotalSeconds; 249 | } 250 | 251 | if (GetAsyncKeyState(VirtualKeyCodes.VK_RBUTTON)) 252 | { 253 | GetCursorPos(out POINT point); 254 | 255 | float x = Convert.ToSingle(point.X); 256 | float y = Convert.ToSingle(point.Y); 257 | 258 | if (_firstMove) 259 | { 260 | _lastPos = new Vector2(x, y); 261 | _firstMove = false; 262 | } 263 | else 264 | { 265 | var deltaX = x - _lastPos.X; 266 | var deltaY = y - _lastPos.Y; 267 | _lastPos = new Vector2(x, y); 268 | 269 | _camera.Yaw += deltaX * sensitivity; 270 | _camera.Pitch -= deltaY * sensitivity; 271 | } 272 | } 273 | else 274 | { 275 | _firstMove = true; 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/Shaders/lighting.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | //The material is a collection of some values that we talked about in the last tutorial, 3 | //some crucial elements to the phong model. 4 | struct Material { 5 | vec3 ambient; 6 | vec3 diffuse; 7 | vec3 specular; 8 | 9 | float shininess; //Shininess is the power the specular light is raised to 10 | }; 11 | //The light contains all the values from the light source, how the ambient diffuse and specular values are from the light source. 12 | //This is technically what we were using in the last episode as we were only applying the phong model directly to the light. 13 | struct Light { 14 | vec3 position; 15 | 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | }; 20 | //We create the light and the material struct as uniforms. 21 | uniform Light light; 22 | uniform Material material; 23 | //We still need the view position. 24 | uniform vec3 viewPos; 25 | 26 | out vec4 FragColor; 27 | 28 | in vec3 Normal; 29 | in vec3 FragPos; 30 | 31 | void main() 32 | { 33 | //ambient 34 | vec3 ambient = light.ambient * material.ambient; //Remember to use the material here. 35 | 36 | //diffuse 37 | vec3 norm = normalize(Normal); 38 | vec3 lightDir = normalize(light.position - FragPos); 39 | float diff = max(dot(norm, lightDir), 0.0); 40 | vec3 diffuse = light.diffuse * (diff * material.diffuse); //Remember to use the material here. 41 | 42 | //specular 43 | vec3 viewDir = normalize(viewPos - FragPos); 44 | vec3 reflectDir = reflect(-lightDir, norm); 45 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 46 | vec3 specular = light.specular * (spec * material.specular); //Remember to use the material here. 47 | 48 | //Now the result sum has changed a bit, since we now set the objects color in each element, we now dont have to 49 | //multiply the light with the object here, instead we do it for each element seperatly. This allows much better control 50 | //over how each element is applied to different objects. 51 | vec3 result = ambient + diffuse + specular; 52 | FragColor = vec4(result, 1.0); 53 | } -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/Shaders/shader.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 7 | } -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Sample/Shaders/shader.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | uniform mat4 model; 6 | uniform mat4 view; 7 | uniform mat4 projection; 8 | 9 | out vec3 Normal; 10 | out vec3 FragPos; 11 | 12 | void main() 13 | { 14 | gl_Position = vec4(aPos, 1.0) * model * view * projection; 15 | FragPos = vec3(vec4(aPos, 1.0) * model); 16 | Normal = aNormal * mat3(transpose(inverse(model))); 17 | } -------------------------------------------------------------------------------- /SilkRenderer.WinUI/OpenGL/Settings.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Silk.NET.GLFW; 3 | using Silk.NET.Windowing; 4 | 5 | namespace SilkRenderer.WinUI.OpenGL; 6 | 7 | public class Settings 8 | { 9 | public int MajorVersion { get; set; } = 3; 10 | 11 | public int MinorVersion { get; set; } = 3; 12 | 13 | public ContextFlags GraphicsContextFlags { get; set; } = ContextFlags.Default; 14 | 15 | public ContextProfile GraphicsProfile { get; set; } = ContextProfile.Core; 16 | 17 | public OpenGlProfile OpenGlProfile { get; set; } = OpenGlProfile.Core; 18 | 19 | public static bool WouldResultInSameContext([NotNull] Settings a, [NotNull] Settings b) 20 | { 21 | if (a.MajorVersion != b.MajorVersion) 22 | { 23 | return false; 24 | } 25 | 26 | if (a.MinorVersion != b.MinorVersion) 27 | { 28 | return false; 29 | } 30 | 31 | if (a.GraphicsProfile != b.GraphicsProfile) 32 | { 33 | return false; 34 | } 35 | 36 | if (a.GraphicsContextFlags != b.GraphicsContextFlags) 37 | { 38 | return false; 39 | } 40 | 41 | return true; 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 8 | 9 | 13 | 14 | 15 | SilkRenderer.WinUI 16 | 13247 17 | Assets\StoreLogo.png 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "SilkRenderer.WinUI (Package)": { 4 | "commandName": "MsixPackage" 5 | }, 6 | "SilkRenderer.WinUI (Unpackaged)": { 7 | "commandName": "Project" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /SilkRenderer.WinUI/SilkRenderer.WinUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | WinExe 4 | net7.0-windows10.0.19041.0 5 | 10.0.17763.0 6 | SilkRenderer.WinUI 7 | app.manifest 8 | x64 9 | win10-x64 10 | true 11 | true 12 | disable 13 | True 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | 50 | 51 | MSBuild:Compile 52 | 53 | 54 | 55 | 56 | MSBuild:Compile 57 | 58 | 59 | PreserveNewest 60 | 61 | 62 | PreserveNewest 63 | 64 | 65 | PreserveNewest 66 | 67 | 68 | 69 | 74 | 75 | true 76 | 77 | 78 | -------------------------------------------------------------------------------- /SilkRenderer.WinUI/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | true/PM 22 | PerMonitorV2, PerMonitor 23 | 24 | 25 | -------------------------------------------------------------------------------- /SilkRenderer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.33414.496 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SilkRenderer.WPF", "SilkRenderer.WPF\SilkRenderer.WPF.csproj", "{6DC90250-7CF6-403A-9895-52FE38BBFE49}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SilkRenderer.WinUI", "SilkRenderer.WinUI\SilkRenderer.WinUI.csproj", "{F01318DD-01C2-43E0-ACD7-A8954290C01C}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{185C4AE2-44E8-4FDA-B313-6619147A288A}" 11 | ProjectSection(SolutionItems) = preProject 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x64 = Debug|x64 18 | Release|x64 = Release|x64 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {6DC90250-7CF6-403A-9895-52FE38BBFE49}.Debug|x64.ActiveCfg = Debug|x64 22 | {6DC90250-7CF6-403A-9895-52FE38BBFE49}.Debug|x64.Build.0 = Debug|x64 23 | {6DC90250-7CF6-403A-9895-52FE38BBFE49}.Release|x64.ActiveCfg = Release|x64 24 | {6DC90250-7CF6-403A-9895-52FE38BBFE49}.Release|x64.Build.0 = Release|x64 25 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Debug|x64.ActiveCfg = Debug|x64 26 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Debug|x64.Build.0 = Debug|x64 27 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Debug|x64.Deploy.0 = Debug|x64 28 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Release|x64.ActiveCfg = Release|x64 29 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Release|x64.Build.0 = Release|x64 30 | {F01318DD-01C2-43E0-ACD7-A8954290C01C}.Release|x64.Deploy.0 = Release|x64 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | GlobalSection(ExtensibilityGlobals) = postSolution 36 | SolutionGuid = {24669798-86C9-4120-83F9-6E90A41326BF} 37 | EndGlobalSection 38 | EndGlobal 39 | --------------------------------------------------------------------------------