├── .config └── dotnet-tools.json ├── .editorconfig ├── .gitignore ├── .paket ├── paket.bootstrapper.exe └── paket.targets ├── GLWpfControl.sln ├── GLWpfControl.sln.DotSettings ├── LICENSE.md ├── README.md ├── RELEASE_NOTES.md ├── build.cmd ├── build.fsx ├── build.fsx.lock ├── build.sh ├── paket.dependencies ├── paket.lock └── src ├── Example ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Example.csproj ├── ExampleScene.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── TabbedMainWindowTest.xaml └── TabbedMainWindowTest.xaml.cs └── GLWpfControl ├── DXGLContext.cs ├── GLWpfControl.cs ├── GLWpfControl.csproj ├── GLWpfControlRenderer.cs ├── GLWpfControlSettings.cs ├── Interop ├── DXInterop.cs ├── Enums.cs └── PresentationParameters.cs ├── NonReloadingTabControl.cs └── paket /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "fake-cli": { 6 | "version": "5.20.4", 7 | "commands": [ 8 | "fake" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | 3 | # IDE0090: Use 'new(...)' 4 | csharp_style_implicit_object_creation_when_type_is_apparent = false 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/vim,osx,linux,macos,emacs,fsharp,csharp,windows,android,monodevelop,intellij+all,visualstudio,xamarinstudio,visualstudiocode 3 | 4 | ### Android ### 5 | # Built application files 6 | *.apk 7 | *.ap_ 8 | 9 | # Files for the ART/Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | out/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | # Intellij 39 | *.iml 40 | .idea/workspace.xml 41 | .idea/tasks.xml 42 | .idea/gradle.xml 43 | .idea/dictionaries 44 | .idea/libraries 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Freeline 50 | freeline.py 51 | freeline/ 52 | freeline_project_description.json 53 | 54 | ### Android Patch ### 55 | gen-external-apklibs 56 | 57 | ### Csharp ### 58 | ## Ignore Visual Studio temporary files, build results, and 59 | ## files generated by popular Visual Studio add-ons. 60 | ## 61 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 62 | 63 | # User-specific files 64 | *.suo 65 | *.user 66 | *.userosscache 67 | *.sln.docstates 68 | 69 | # User-specific files (MonoDevelop/Xamarin Studio) 70 | *.userprefs 71 | 72 | # Build results 73 | [Dd]ebug/ 74 | [Dd]ebugPublic/ 75 | [Rr]elease/ 76 | [Rr]eleases/ 77 | x64/ 78 | x86/ 79 | bld/ 80 | [Bb]in/ 81 | [Oo]bj/ 82 | [Ll]og/ 83 | 84 | # Visual Studio 2015 cache/options directory 85 | .vs/ 86 | # Uncomment if you have tasks that create the project's static files in wwwroot 87 | #wwwroot/ 88 | 89 | # MSTest test Results 90 | [Tt]est[Rr]esult*/ 91 | [Bb]uild[Ll]og.* 92 | 93 | # NUNIT 94 | *.VisualState.xml 95 | TestResult.xml 96 | 97 | # Build Results of an ATL Project 98 | [Dd]ebugPS/ 99 | [Rr]eleasePS/ 100 | dlldata.c 101 | 102 | # .NET Core 103 | project.lock.json 104 | project.fragment.lock.json 105 | artifacts/ 106 | **/Properties/launchSettings.json 107 | 108 | *_i.c 109 | *_p.c 110 | *_i.h 111 | *.ilk 112 | *.meta 113 | *.obj 114 | *.pch 115 | *.pdb 116 | *.pgc 117 | *.pgd 118 | *.rsp 119 | *.sbr 120 | *.tlb 121 | *.tli 122 | *.tlh 123 | *.tmp 124 | *.tmp_proj 125 | *.vspscc 126 | *.vssscc 127 | .builds 128 | *.pidb 129 | *.svclog 130 | *.scc 131 | 132 | # Chutzpah Test files 133 | _Chutzpah* 134 | 135 | # Visual C++ cache files 136 | ipch/ 137 | *.aps 138 | *.ncb 139 | *.opendb 140 | *.opensdf 141 | *.sdf 142 | *.cachefile 143 | *.VC.db 144 | *.VC.VC.opendb 145 | 146 | # Visual Studio profiler 147 | *.psess 148 | *.vsp 149 | *.vspx 150 | *.sap 151 | 152 | # TFS 2012 Local Workspace 153 | $tf/ 154 | 155 | # Guidance Automation Toolkit 156 | *.gpState 157 | 158 | # ReSharper is a .NET coding add-in 159 | _ReSharper*/ 160 | *.[Rr]e[Ss]harper 161 | *.DotSettings.user 162 | 163 | # JustCode is a .NET coding add-in 164 | .JustCode 165 | 166 | # TeamCity is a build add-in 167 | _TeamCity* 168 | 169 | # DotCover is a Code Coverage Tool 170 | *.dotCover 171 | 172 | # Visual Studio code coverage results 173 | *.coverage 174 | *.coveragexml 175 | 176 | # NCrunch 177 | _NCrunch_* 178 | .*crunch*.local.xml 179 | nCrunchTemp_* 180 | 181 | # MightyMoose 182 | *.mm.* 183 | AutoTest.Net/ 184 | 185 | # Web workbench (sass) 186 | .sass-cache/ 187 | 188 | # Installshield output folder 189 | [Ee]xpress/ 190 | 191 | # DocProject is a documentation generator add-in 192 | DocProject/buildhelp/ 193 | DocProject/Help/*.HxT 194 | DocProject/Help/*.HxC 195 | DocProject/Help/*.hhc 196 | DocProject/Help/*.hhk 197 | DocProject/Help/*.hhp 198 | DocProject/Help/Html2 199 | DocProject/Help/html 200 | 201 | # Click-Once directory 202 | publish/ 203 | 204 | # Publish Web Output 205 | *.[Pp]ublish.xml 206 | *.azurePubxml 207 | # TODO: Uncomment the next line to ignore your web deploy settings. 208 | # By default, sensitive information, such as encrypted password 209 | # should be stored in the .pubxml.user file. 210 | #*.pubxml 211 | *.pubxml.user 212 | *.publishproj 213 | 214 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 215 | # checkin your Azure Web App publish settings, but sensitive information contained 216 | # in these scripts will be unencrypted 217 | PublishScripts/ 218 | 219 | # NuGet Packages 220 | *.nupkg 221 | # The packages folder can be ignored because of Package Restore 222 | **/packages/* 223 | # except build/, which is used as an MSBuild target. 224 | !**/packages/build/ 225 | # Uncomment if necessary however generally it will be regenerated when needed 226 | #!**/packages/repositories.config 227 | # NuGet v3's project.json files produces more ignorable files 228 | *.nuget.props 229 | *.nuget.targets 230 | 231 | # Microsoft Azure Build Output 232 | csx/ 233 | *.build.csdef 234 | 235 | # Microsoft Azure Emulator 236 | ecf/ 237 | rcf/ 238 | 239 | # Windows Store app package directories and files 240 | AppPackages/ 241 | BundleArtifacts/ 242 | Package.StoreAssociation.xml 243 | _pkginfo.txt 244 | 245 | # Visual Studio cache files 246 | # files ending in .cache can be ignored 247 | *.[Cc]ache 248 | # but keep track of directories ending in .cache 249 | !*.[Cc]ache/ 250 | 251 | # Others 252 | ClientBin/ 253 | ~$* 254 | *~ 255 | *.dbmdl 256 | *.dbproj.schemaview 257 | *.jfm 258 | *.pfx 259 | *.publishsettings 260 | orleans.codegen.cs 261 | 262 | # Since there are multiple workflows, uncomment next line to ignore bower_components 263 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 264 | #bower_components/ 265 | 266 | # RIA/Silverlight projects 267 | Generated_Code/ 268 | 269 | # Backup & report files from converting an old project file 270 | # to a newer Visual Studio version. Backup files are not needed, 271 | # because we have git ;-) 272 | _UpgradeReport_Files/ 273 | Backup*/ 274 | UpgradeLog*.XML 275 | UpgradeLog*.htm 276 | 277 | # SQL Server files 278 | *.mdf 279 | *.ldf 280 | *.ndf 281 | 282 | # Business Intelligence projects 283 | *.rdl.data 284 | *.bim.layout 285 | *.bim_*.settings 286 | 287 | # Microsoft Fakes 288 | FakesAssemblies/ 289 | 290 | # GhostDoc plugin setting file 291 | *.GhostDoc.xml 292 | 293 | # Node.js Tools for Visual Studio 294 | .ntvs_analysis.dat 295 | node_modules/ 296 | 297 | # Typescript v1 declaration files 298 | typings/ 299 | 300 | # Visual Studio 6 build log 301 | *.plg 302 | 303 | # Visual Studio 6 workspace options file 304 | *.opt 305 | 306 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 307 | *.vbw 308 | 309 | # Visual Studio LightSwitch build output 310 | **/*.HTMLClient/GeneratedArtifacts 311 | **/*.DesktopClient/GeneratedArtifacts 312 | **/*.DesktopClient/ModelManifest.xml 313 | **/*.Server/GeneratedArtifacts 314 | **/*.Server/ModelManifest.xml 315 | _Pvt_Extensions 316 | 317 | # Paket dependency manager 318 | .paket/paket.exe 319 | paket-files/ 320 | *.Restore.targets 321 | 322 | # Build tool temp file 323 | *.template 324 | 325 | ### OpenTK AssemblyInfo files ### 326 | **/AssemblyInfo.cs 327 | **/AssemblyInfo.fs 328 | 329 | # FAKE - F# Make 330 | .fake/ 331 | 332 | # JetBrains Rider 333 | .idea/ 334 | *.sln.iml 335 | 336 | # CodeRush 337 | .cr/ 338 | 339 | # Python Tools for Visual Studio (PTVS) 340 | __pycache__/ 341 | *.pyc 342 | 343 | # Cake - Uncomment if you are using it 344 | # tools/** 345 | # !tools/packages.config 346 | 347 | # Telerik's JustMock configuration file 348 | *.jmconfig 349 | 350 | # BizTalk build output 351 | *.btp.cs 352 | *.btm.cs 353 | *.odx.cs 354 | *.xsd.cs 355 | 356 | ### Emacs ### 357 | # -*- mode: gitignore; -*- 358 | \#*\# 359 | /.emacs.desktop 360 | /.emacs.desktop.lock 361 | *.elc 362 | auto-save-list 363 | tramp 364 | .\#* 365 | 366 | # Org-mode 367 | .org-id-locations 368 | *_archive 369 | 370 | # flymake-mode 371 | *_flymake.* 372 | 373 | # eshell files 374 | /eshell/history 375 | /eshell/lastdir 376 | 377 | # elpa packages 378 | /elpa/ 379 | 380 | # reftex files 381 | *.rel 382 | 383 | # AUCTeX auto folder 384 | /auto/ 385 | 386 | # cask packages 387 | .cask/ 388 | dist/ 389 | 390 | # Flycheck 391 | flycheck_*.el 392 | 393 | # server auth directory 394 | /server/ 395 | 396 | # projectiles files 397 | .projectile 398 | projectile-bookmarks.eld 399 | 400 | # directory configuration 401 | .dir-locals.el 402 | 403 | # saveplace 404 | places 405 | 406 | # url cache 407 | url/cache/ 408 | 409 | # cedet 410 | ede-projects.el 411 | 412 | # smex 413 | smex-items 414 | 415 | # company-statistics 416 | company-statistics-cache.el 417 | 418 | # anaconda-mode 419 | anaconda-mode/ 420 | 421 | ### fsharp ### 422 | lib/debug 423 | lib/release 424 | *.exe 425 | !.paket/paket.bootstrapper.exe 426 | 427 | ### Intellij+all ### 428 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 429 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 430 | 431 | # User-specific stuff: 432 | .idea/**/workspace.xml 433 | .idea/**/tasks.xml 434 | 435 | # Sensitive or high-churn files: 436 | .idea/**/dataSources/ 437 | .idea/**/dataSources.ids 438 | .idea/**/dataSources.xml 439 | .idea/**/dataSources.local.xml 440 | .idea/**/sqlDataSources.xml 441 | .idea/**/dynamic.xml 442 | .idea/**/uiDesigner.xml 443 | 444 | # Gradle: 445 | .idea/**/gradle.xml 446 | .idea/**/libraries 447 | 448 | # CMake 449 | cmake-build-debug/ 450 | 451 | # Mongo Explorer plugin: 452 | .idea/**/mongoSettings.xml 453 | 454 | ## File-based project format: 455 | *.iws 456 | 457 | ## Plugin-specific files: 458 | 459 | # IntelliJ 460 | /out/ 461 | 462 | # mpeltonen/sbt-idea plugin 463 | .idea_modules/ 464 | 465 | # JIRA plugin 466 | atlassian-ide-plugin.xml 467 | 468 | # Cursive Clojure plugin 469 | .idea/replstate.xml 470 | 471 | # Ruby plugin and RubyMine 472 | /.rakeTasks 473 | 474 | # Crashlytics plugin (for Android Studio and IntelliJ) 475 | com_crashlytics_export_strings.xml 476 | crashlytics.properties 477 | crashlytics-build.properties 478 | fabric.properties 479 | 480 | ### Linux ### 481 | 482 | # temporary files which can be created if a process still has a handle open of a deleted file 483 | .fuse_hidden* 484 | 485 | # KDE directory preferences 486 | .directory 487 | 488 | # Linux trash folder which might appear on any partition or disk 489 | .Trash-* 490 | 491 | # .nfs files are created when an open file is removed but is still being accessed 492 | .nfs* 493 | 494 | ### macOS ### 495 | *.DS_Store 496 | .AppleDouble 497 | .LSOverride 498 | 499 | # Icon must end with two \r 500 | Icon 501 | 502 | # Thumbnails 503 | ._* 504 | 505 | # Files that might appear in the root of a volume 506 | .DocumentRevisions-V100 507 | .fseventsd 508 | .Spotlight-V100 509 | .TemporaryItems 510 | .Trashes 511 | .VolumeIcon.icns 512 | .com.apple.timemachine.donotpresent 513 | 514 | # Directories potentially created on remote AFP share 515 | .AppleDB 516 | .AppleDesktop 517 | Network Trash Folder 518 | Temporary Items 519 | .apdisk 520 | 521 | ### MonoDevelop ### 522 | #User Specific 523 | *.usertasks 524 | 525 | #Mono Project Files 526 | *.resources 527 | test-results/ 528 | 529 | ### OSX ### 530 | 531 | # Icon must end with two \r 532 | 533 | # Thumbnails 534 | 535 | # Files that might appear in the root of a volume 536 | 537 | # Directories potentially created on remote AFP share 538 | 539 | ### Vim ### 540 | # swap 541 | [._]*.s[a-v][a-z] 542 | [._]*.sw[a-p] 543 | [._]s[a-v][a-z] 544 | [._]sw[a-p] 545 | # session 546 | Session.vim 547 | # temporary 548 | .netrwhist 549 | # auto-generated tag files 550 | tags 551 | 552 | ### VisualStudioCode ### 553 | .vscode/* 554 | !.vscode/settings.json 555 | !.vscode/tasks.json 556 | !.vscode/launch.json 557 | !.vscode/extensions.json 558 | .history 559 | 560 | ### Windows ### 561 | # Windows thumbnail cache files 562 | Thumbs.db 563 | ehthumbs.db 564 | ehthumbs_vista.db 565 | 566 | # Folder config file 567 | Desktop.ini 568 | 569 | # Recycle Bin used on file shares 570 | $RECYCLE.BIN/ 571 | 572 | # Windows Installer files 573 | *.cab 574 | *.msi 575 | *.msm 576 | *.msp 577 | 578 | # Windows shortcuts 579 | *.lnk 580 | 581 | ### XamarinStudio ### 582 | .packages 583 | 584 | ### Mono Code Coverage ### 585 | TestResults.xml 586 | 587 | ### OpenTK Binding files ### 588 | .bindingsGenerated 589 | src/OpenTK/Graphics/ES10/Enums 590 | src/OpenTK/Graphics/ES10/Wrappers 591 | src/OpenTK/Graphics/ES11/Enums 592 | src/OpenTK/Graphics/ES11/Wrappers 593 | src/OpenTK/Graphics/ES20/Enums 594 | src/OpenTK/Graphics/ES20/Wrappers 595 | src/OpenTK/Graphics/ES30/Enums 596 | src/OpenTK/Graphics/ES30/Wrappers 597 | src/OpenTK/Graphics/ES31/Enums 598 | src/OpenTK/Graphics/ES31/Wrappers 599 | src/OpenTK/Graphics/OpenGL/Enums 600 | src/OpenTK/Graphics/OpenGL/Wrappers 601 | src/OpenTK/Graphics/OpenGL4/Enums 602 | src/OpenTK/Graphics/OpenGL4/Wrappers 603 | 604 | ### Tooling files "" 605 | tools/ 606 | 607 | ### LaTeX ### 608 | ## Core latex/pdflatex auxiliary files: 609 | *.aux 610 | *.lof 611 | *.lot 612 | *.fls 613 | *.out 614 | *.toc 615 | *.fmt 616 | *.fot 617 | *.cb 618 | *.cb2 619 | .*.lb 620 | 621 | ## Intermediate documents: 622 | *.dvi 623 | *.xdv 624 | *-converted-to.* 625 | # these rules might exclude image files for figures etc. 626 | # *.ps 627 | # *.eps 628 | # *.pdf 629 | 630 | ## Generated if empty string is given at "Please type another file name for output:" 631 | .pdf 632 | 633 | ## Bibliography auxiliary files (bibtex/biblatex/biber): 634 | *.bbl 635 | *.bcf 636 | *.blg 637 | *-blx.aux 638 | *-blx.bib 639 | *.run.xml 640 | 641 | ## Build tool auxiliary files: 642 | *.fdb_latexmk 643 | *.synctex 644 | *.synctex(busy) 645 | *.synctex.gz 646 | *.synctex.gz(busy) 647 | *.pdfsync 648 | 649 | ## Build tool directories for auxiliary files 650 | # latexrun 651 | latex.out/ 652 | 653 | ## Auxiliary and intermediate files from other packages: 654 | # algorithms 655 | *.alg 656 | *.loa 657 | 658 | # achemso 659 | acs-*.bib 660 | 661 | # amsthm 662 | *.thm 663 | 664 | # beamer 665 | *.nav 666 | *.pre 667 | *.snm 668 | *.vrb 669 | 670 | # changes 671 | *.soc 672 | 673 | # cprotect 674 | *.cpt 675 | 676 | # elsarticle (documentclass of Elsevier journals) 677 | *.spl 678 | 679 | # endnotes 680 | *.ent 681 | 682 | # fixme 683 | *.lox 684 | 685 | # feynmf/feynmp 686 | *.mf 687 | *.mp 688 | *.t[1-9] 689 | *.t[1-9][0-9] 690 | *.tfm 691 | 692 | # glossaries 693 | *.acn 694 | *.acr 695 | *.glg 696 | *.glo 697 | *.gls 698 | *.glsdefs 699 | 700 | # gnuplottex 701 | *-gnuplottex-* 702 | 703 | # gregoriotex 704 | *.gaux 705 | *.gtex 706 | 707 | # htlatex 708 | *.4ct 709 | *.4tc 710 | *.idv 711 | *.lg 712 | *.trc 713 | *.xref 714 | 715 | # hyperref 716 | *.brf 717 | 718 | # knitr 719 | *-concordance.tex 720 | # TODO Comment the next line if you want to keep your tikz graphics files 721 | *.tikz 722 | *-tikzDictionary 723 | 724 | # listings 725 | *.lol 726 | 727 | # makeidx 728 | *.idx 729 | *.ilg 730 | *.ind 731 | *.ist 732 | 733 | # minitoc 734 | *.maf 735 | *.mlf 736 | *.mlt 737 | *.mtc[0-9]* 738 | *.slf[0-9]* 739 | *.slt[0-9]* 740 | *.stc[0-9]* 741 | 742 | # minted 743 | _minted* 744 | *.pyg 745 | 746 | # morewrites 747 | *.mw 748 | 749 | # nomencl 750 | *.nlg 751 | *.nlo 752 | *.nls 753 | 754 | # pax 755 | *.pax 756 | 757 | # pdfpcnotes 758 | *.pdfpc 759 | 760 | # sagetex 761 | *.sagetex.sage 762 | *.sagetex.py 763 | *.sagetex.scmd 764 | 765 | # scrwfile 766 | *.wrt 767 | 768 | # sympy 769 | *.sout 770 | *.sympy 771 | sympy-plots-for-*.tex/ 772 | 773 | # pdfcomment 774 | *.upa 775 | *.upb 776 | 777 | # pythontex 778 | *.pytxcode 779 | pythontex-files-*/ 780 | 781 | # thmtools 782 | *.loe 783 | 784 | # TikZ & PGF 785 | *.dpth 786 | *.md5 787 | *.auxlock 788 | 789 | # todonotes 790 | *.tdo 791 | 792 | # easy-todo 793 | *.lod 794 | 795 | # xmpincl 796 | *.xmpi 797 | 798 | # xindy 799 | *.xdy 800 | 801 | # xypic precompiled matrices 802 | *.xyc 803 | 804 | # endfloat 805 | *.ttt 806 | *.fff 807 | 808 | # Latexian 809 | TSWLatexianTemp* 810 | 811 | ## Editors: 812 | # WinEdt 813 | *.bak 814 | *.sav 815 | 816 | # Texpad 817 | .texpadtmp 818 | 819 | # LyX 820 | *.lyx~ 821 | 822 | # Kile 823 | *.backup 824 | 825 | # KBibTeX 826 | *~[0-9]* 827 | 828 | # auto folder when using emacs and auctex 829 | auto/* 830 | *.el 831 | 832 | # expex forward references with \gathertags 833 | *-tags.tex 834 | 835 | # standalone packages 836 | *.sta 837 | 838 | ### LaTeX Patch ### 839 | # glossaries 840 | *.glstex 841 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentk/GLWpfControl/f354d51715565a30ecd41bf9df370c42f32ed957/.paket/paket.bootstrapper.exe -------------------------------------------------------------------------------- /.paket/paket.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | true 8 | $(MSBuildThisFileDirectory) 9 | $(MSBuildThisFileDirectory)..\ 10 | /Library/Frameworks/Mono.framework/Commands/mono 11 | mono 12 | 13 | 14 | 15 | $(PaketToolsPath)paket.exe 16 | $(PaketToolsPath)paket.bootstrapper.exe 17 | "$(PaketExePath)" 18 | $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" 19 | "$(PaketBootStrapperExePath)" $(PaketBootStrapperCommandArgs) 20 | $(MonoPath) --runtime=v4.0.30319 $(PaketBootStrapperExePath) $(PaketBootStrapperCommandArgs) 21 | 22 | $(MSBuildProjectDirectory)\paket.references 23 | $(MSBuildStartupDirectory)\paket.references 24 | $(MSBuildProjectFullPath).paket.references 25 | $(PaketCommand) restore --references-files "$(PaketReferences)" 26 | $(PaketBootStrapperCommand) 27 | 28 | RestorePackages; $(BuildDependsOn); 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /GLWpfControl.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32516.85 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{F02DE1CD-94DB-4F38-8B0A-833B2A357E2E}" 7 | ProjectSection(SolutionItems) = preProject 8 | build.cmd = build.cmd 9 | build.fsx = build.fsx 10 | build.sh = build.sh 11 | paket.dependencies = paket.dependencies 12 | paket.lock = paket.lock 13 | EndProjectSection 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{8A911F4A-8A01-4B86-959B-27CA1CDA2C1B}" 16 | ProjectSection(SolutionItems) = preProject 17 | src\GLWpfControl\paket.template = src\GLWpfControl\paket.template 18 | README.md = README.md 19 | RELEASE_NOTES.md = RELEASE_NOTES.md 20 | EndProjectSection 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GLWpfControl", "src\GLWpfControl\GLWpfControl.csproj", "{E201C66F-F247-4E23-AB4D-0EB50005091D}" 23 | EndProject 24 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "src\Example\Example.csproj", "{7E12D07B-0DD6-4288-A4F8-92EB75848ECF}" 25 | EndProject 26 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{441E95E4-0A78-4121-A68C-C778C8050489}" 27 | ProjectSection(SolutionItems) = preProject 28 | .editorconfig = .editorconfig 29 | EndProjectSection 30 | EndProject 31 | Global 32 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 33 | Debug|Any CPU = Debug|Any CPU 34 | Debug|x64 = Debug|x64 35 | Release|Any CPU = Release|Any CPU 36 | Release|x64 = Release|x64 37 | EndGlobalSection 38 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 39 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Debug|x64.ActiveCfg = Debug|x64 42 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Debug|x64.Build.0 = Debug|x64 43 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Release|x64.ActiveCfg = Release|x64 46 | {E201C66F-F247-4E23-AB4D-0EB50005091D}.Release|x64.Build.0 = Release|x64 47 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Debug|x64.ActiveCfg = Debug|x64 50 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Debug|x64.Build.0 = Debug|x64 51 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Release|x64.ActiveCfg = Release|x64 54 | {7E12D07B-0DD6-4288-A4F8-92EB75848ECF}.Release|x64.Build.0 = Release|x64 55 | EndGlobalSection 56 | GlobalSection(SolutionProperties) = preSolution 57 | HideSolutionNode = FALSE 58 | EndGlobalSection 59 | GlobalSection(ExtensibilityGlobals) = postSolution 60 | SolutionGuid = {97CD4768-306D-4862-9FE0-1ED5261AA0D4} 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /GLWpfControl.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | GL 3 | True 4 | True -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 varon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## GLWpfControl - A fast OpenGL Control for WPF 2 | ![Nuget](https://img.shields.io/nuget/v/OpenTK.GLWpfControl.svg?color=green) 3 | 4 | A native control for WPF in OpenTK 3.x and 4.x. 5 | 6 | Supported configurations: 7 | - .Net Framework for OpenTK 3.x (the 3.x series NuGet packages) 8 | - .Net Core for OpenTK 4.x (the 4.x series NuGet packages) 9 | 10 | Since version 3.0.0, we're using full OpenGL/DirectX interop via OpenGL extensions - [NV_DX_interop](https://www.khronos.org/registry/OpenGL/extensions/NV/WGL_NV_DX_interop.txt). 11 | This should run almost everywhere with **AMAZING PERFORMANCE** and is fully supported on Intel, AMD and Nvidia graphics. 12 | 13 | This offers a way more clean solution than embedding GLControl and totally solves [the airspace problem](https://stackoverflow.com/questions/8006092/controls-dont-show-over-winforms-host). 14 | As controls can be layered, nested and structured over your 3D view. 15 | 16 | ## Getting started: 17 | 18 | 1. [Install via NuGet](https://www.nuget.org/packages/OpenTK.GLWpfControl) 19 | 2. In your window, include GLWpfControl. 20 | ```XML 21 | 25 | ``` 26 | 3. Add the control into a container (Grid, StackPanel, etc.) and add a handler method to the render event. 27 | 28 | ```XML 29 | 30 | ... 31 | 34 | ... 35 | 36 | ``` 37 | 4. In the code behind add to the constructor, after the InitializeComponents call, a call to the start method of the GLWpfControl. 38 | ```CS 39 | public MainWindow() { 40 | InitializeComponent(); 41 | // [...] 42 | var settings = new GLWpfControlSettings 43 | { 44 | MajorVersion = 3, 45 | MinorVersion = 6 46 | }; 47 | OpenTkControl.Start(settings); 48 | } 49 | ``` 50 | 5. You can now render in the OnRender handler. 51 | ```CS 52 | private void OpenTkControl_OnRender(TimeSpan delta) { 53 | GL.ClearColor(Color4.Blue); 54 | GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 55 | } 56 | ``` 57 | For additional examples, see [MainWindow.xaml](https://github.com/opentk/GLWpfControl/blob/master/src/Example/MainWindow.xaml) and [MainWindow.xaml.cs](https://github.com/opentk/GLWpfControl/blob/master/src/Example/MainWindow.xaml.cs) in the example project. 58 | 59 | ### I can't receive keyboard input when my control doesn't have keyboard focus! 60 | 61 | WPF by design only sends keyboard events to the control that has keybaord focus. To be able to get keyboard focus a control needs to have `Focusable==true` (this is the default for GLWpfControl) and `IsVisible==true`. 62 | 63 | If you however need to get keyboard events idependent of keyboard focus you will have to use the `Keyboard.AddPreview*` functions. 64 | These functions allow you to register a preview event that is called before the control with keyboard focus gets the keyboard event. 65 | 66 | This replaces the old `CanInvokeOnHandledEvents` and `RegisterToEventsDirectly` settings. 67 | 68 | See [Example](./src/Example/TabbedMainWindowTest.xaml.cs) for an example how to set this up. 69 | 70 | ## Build instructions 71 | 72 | 1. Clone repository 73 | ```shell 74 | $ git clone https://github.com/varon/GLWpfControl.git 75 | $ cd GLWpfControl 76 | ``` 77 | or for SSH 78 | ```shell 79 | $ git clone git@github.com:varon/GLWpfControl.git 80 | $ cd GLWpfControl 81 | ``` 82 | 2. Run `build.cmd` or `build.sh`. 83 | 3. Develop as normal in whatever IDE you like. 84 | 85 | 86 | ## Planned features 87 | 88 | #### DX-Hijacking rendering 89 | 90 | It's possible to bypass the RTT that takes place in WPF D3dImage by stealing the actual D3d handle from WPF and drawing manually. 91 | This is incredibly challenging, but would offer APEX performance as zero indirection is required. 92 | Currently more of an idea than a work in progress. 93 | Contributions welcome - Drop by the [Discord](https://discord.gg/6HqD48s) server if you want to give this a shot! 94 | -------------------------------------------------------------------------------- /RELEASE_NOTES.md: -------------------------------------------------------------------------------- 1 | ## 4.3.3 2 | 3 | * Fix crashes related to `Dispose` and unloading of the control in general. (@Krugpelke, @NogginBops, @timsol, @4nonym0us) 4 | * Fixed issue where `GLWpfControl.Framebuffer` property stopped working. (@insel-maz, @NogginBops) 5 | * Hopefully fixed a few crashes related to MSAA not being supported. (@NogginBops) 6 | * Added `GLWpfControl.SupportsMSAA` property to check if MSAA will be supported. (@NogginBops) 7 | 8 | ## 4.3.2 9 | 10 | * Fixed AccessViolationException when disposing GLWpfControl. (@NogginBops) 11 | * Fixed issue where GLWpfControl would not work on integrated graphics cards. 12 | The current fix doesn't support using MSAA on these graphics cards and will throw a COMException. This is something we want to fix or be able to detect in the future. (@NogginBops) 13 | * Fixed issue where resizing control would leak GL objects due to wrong deletion order. (@NogginBops) 14 | 15 | ## 4.3.1 16 | 17 | Hotfix release to fix context handling in `4.3.0`. 18 | 19 | * Added documentation comments about OpenGL context handling. (@NogginBops) 20 | * Fixed issue where when multiple GLWpfControls only the last initialized controls OpenGL context would be current. (@NogginBops) 21 | 22 | ## 4.3.0 23 | 24 | * Made each `GLWpfControl` have it's own OpenGL context allowing different controls to have different context settings. (@NogginBops) 25 | * Enabled multisample anti-aliasing though `GLWpfControlSettings.Samples`. (@NogginBops) 26 | * Implemented `IDisposable` for `GLWpfControl` that allows native DirectX and OpenGL resources to be freed. (@NogginBops) 27 | * Made `GLWpfControl` have `Focusable` be `true` by default, solving a lot of the keyboard input event issues. (@NogginBops) 28 | * Deprecated `GLWpfControlSettings.GraphicsContextFlags` in favor of `GLWpfControlSettings.ContextFlags`. (@NogginBops) 29 | * Deprecated `GLWpfControlSettings.GraphicsProfile` in favor of `GLWpfControlSettings.Profile`. (@NogginBops) 30 | * Added `GLWpfControlSettings.SharedContext` to allow context sharing. (@NogginBops) 31 | * Deprecated `GLWpfControl.CanInvokeOnHandledEvents` and `GLWpfControl.RegisterToEventsDirectly`, updated readme to reflect this. (@NogginBops) 32 | * Fixed rounding issues related to DPI scaling. (@NogginBops, @5E-324) 33 | * Updated to depend on OpenTK 4.8.2. (@NogginBops, @softwareantics) 34 | * Fixed memory leak where DirectX resouces would never be freed. (@NogginBops) 35 | 36 | ## 4.2.3 37 | 38 | * Fix event issue, use `RegisterToEventsDirectly` and `CanInvokeOnHandledEvents` to customize event registering/handling. (@softwareantics) 39 | * Internal cleanup that fixed issue where setting `RenderContinuously = false` caused an extra call to render. (@francotiveron) 40 | 41 | ## 4.2.2 42 | 43 | * Fix issue where `4.2.1` was only compatible with `netcoreapp3.1-windows` and nothing else. 44 | 45 | ## 4.2.1 46 | 47 | * Fix broken nuget package in `4.2.0`. 48 | 49 | ## 4.2.0 50 | * Add ability to make the control transparent by setting `GLWpfControlSettings.TransparentBackground` to true. (@luiscuenca) 51 | * Change the dependency on OpenTK to be >= 4.3.0 < 5.0.0. (@NogginBops) 52 | * Add ability to pass a custom `IBindingsContext` in `GLWpfControlSettings`. (@Kaktusbot) 53 | * Add stencil buffer to the framebuffer. (@Svabik) 54 | * Fixed issue where remote desktop would fail due to having to use a software implementation of OpenGL. (@marcotod1410) 55 | * Fixed so that `KeyDownEvent` and `KeyUpEvent` properly work in the control. (@BBoldenow) 56 | 57 | ## 4.1.0 58 | * Add NonReloadingTabControl. 59 | * Add example with new NonReloadingTabControl. 60 | 61 | ## 4.0.0 62 | * Fix resizing 63 | * Unseal GLWpfControl 64 | * Fix crash on framebuffer access before inits 65 | 66 | ## 4.0.0-pre.12 67 | * Improved rendering performance by avoiding duplicate render calls (@marcotod1410) 68 | * Fix FrameBufferWidth property returning height incorrectly. 69 | * Fix resizing 70 | 71 | ## 4.0.0-pre.11 72 | * Fix for resource deallocation issue. 73 | 74 | ## 4.0.0-pre.10 75 | * Fix crash due to context mangling in tabbed views 76 | 77 | ## 4.0.0-pre.9 78 | * Fix crash for tabbed window 79 | * Total rewrite of the backend 80 | * All memory leaks removed 81 | * Faster loading 82 | * Faster resizing 83 | * Less memory usage 84 | * Reduced duplicate rendering 85 | * New design time preview 86 | * Simpler examples 87 | * Update to OpenTK 4.3.0 88 | 89 | ## 4.0.0-pre.8 90 | * Total rewrite of the backend 91 | * All memory leaks removed 92 | * Faster loading 93 | * Faster resizing 94 | * Less memory usage 95 | * Reduced duplicate rendering 96 | * New design time preview 97 | * Simpler examples 98 | * Update to OpenTK 4.3.0 99 | 100 | ## 4.0.0-pre.7 101 | * Fix design mode crash in Visual Studio. 102 | 103 | ## 4.0.0-pre.6 104 | * Update to OpenTK 4.3.0 105 | 106 | ## 4.0.0-pre.5 107 | * Fix for one-frame delay on startup (no more flashing screen) (@bezo97) 108 | 109 | ## 4.0.0-pre.4 110 | * Add support for DPI Scaling + optional config values to ignore this. (@marcotod1410) 111 | * Added Framebuffer Size to API. (@ marcotod1410) 112 | * Fix render initialization if not visible at the start (@marcotod1410) 113 | * Remove dependency on SharpDX and replace with custom bindings (@bezo97) 114 | 115 | ## 4.0.0-pre.3 116 | * Fix crash if control was to collapsed on startup. 117 | 118 | ## 4.0.0-pre.2 119 | * Fix Gamma/Linear color space issue (Thanks @Justin113D) 120 | 121 | ## 4.0.0-pre.1 122 | * Dotnet Core Support 123 | * Retarget to OpenTK 4.2.0 124 | 125 | ## 3.1.1 126 | * Backport of fix gamma/colour space issues (Thanks @Justin113D) 127 | 128 | ## 3.1.0 129 | * Add support for non-continuous event-based rendering via InvalidateVisual(). 130 | * Fix Incorrect minor version in OpenGL Settings. 131 | 132 | ## 3.0.1 133 | * Fix SharpDX.Direct3D9 dependency. 134 | 135 | ## 3.0.0 136 | * >10x performance increase via DirectX interop. Huge thanks to @Zcore. 137 | * Simplified API 138 | * Removed software render path 139 | * Added automatic context sharing by default 140 | 141 | ## 2.1.0 142 | * Allow support for external contexts across multiple controls. 143 | 144 | ## 2.0.3 145 | * Improve fix for event-ordering crash on some systems. 146 | 147 | ## 2.0.2 148 | * Possible fix for event-ordering crash on some systems. 149 | 150 | ## 2.0.1 151 | * Fix resize events not being raised. 152 | 153 | ## 2.0.0 154 | * Moved namespace to OpenTK.Wpf. 155 | * GLWpfControl now extends FrameworkElement instead of Control. 156 | * Moved to pure-code solution for greater simplicity. 157 | * Added some extra-paranoid null checking. 158 | 159 | ## 1.1.2 160 | * Possible fix for NPE on renderer access. 161 | 162 | ## 1.1.1 163 | * Automatically set the viewport for the user. 164 | 165 | ## 1.1.0 166 | * Use own HWND for improved performance (Thanks to @Eschryn) 167 | * Add time delta to the render event. 168 | * Better handling of resizing via delayed updates. 169 | * Remove slow-path detection (2x performance on low-end devices!) 170 | * Fix duplicate OpenGL resource unloading. 171 | 172 | ## 1.0.1 173 | * Add API to access the control's framebuffer. 174 | 175 | ## 1.0.0 176 | * Initial release 177 | 178 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | SET PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH% 4 | .paket\paket.bootstrapper.exe 5 | 6 | SET BuildTarget= 7 | if "%BuildRunner%" == "MyGet" ( 8 | SET BuildTarget=NuGet 9 | 10 | :: Replace the existing release notes file with one for this build only 11 | echo ### %PackageVersion% > RELEASE_NOTES.md 12 | echo * git build >> RELEASE_NOTES.md 13 | ) 14 | 15 | dotnet tool restore 16 | dotnet fake run build.fsx %* 17 | -------------------------------------------------------------------------------- /build.fsx: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------- 2 | // FAKE build script 3 | // -------------------------------------------------------------------------------------- 4 | open System 5 | open System.IO 6 | open System.Threading 7 | open System.Diagnostics 8 | open Fake.Core 9 | open Fake.DotNet 10 | open Fake.DotNet.NuGet 11 | open Fake.IO 12 | 13 | #r "paket: 14 | storage: packages 15 | nuget Fake.IO.FileSystem 16 | nuget Fake.DotNet.MSBuild 17 | nuget Fake.DotNet.Testing.XUnit2 18 | nuget Fake.DotNet.AssemblyInfoFile 19 | nuget Fake.DotNet.NuGet prerelease 20 | nuget Fake.DotNet.Paket 21 | nuget Fake.DotNet.Cli 22 | nuget Fake.Core.Target 23 | nuget Fake.Net.Http 24 | nuget Fake.Api.Github 25 | nuget xunit.runner.console 26 | nuget NuGet.CommandLine 27 | nuget Fake.Core.ReleaseNotes //" 28 | 29 | #load "./.fake/build.fsx/intellisense.fsx" 30 | 31 | open Fake.IO; 32 | open Fake.IO.FileSystemOperators 33 | open Fake.IO.Globbing.Operators 34 | 35 | // -------------------------------------------------------------------------------------- 36 | // project-specific details below 37 | // -------------------------------------------------------------------------------------- 38 | 39 | // Information about the project are used 40 | // - for version and project name in generated AssemblyInfo file 41 | // - by the generated NuGet package 42 | // - to run tests and to publish documentation on GitHub gh-pages 43 | // - for documentation, you also need to edit info in "docs/tools/generate.fsx" 44 | 45 | // The name of the project 46 | // (used by attributes in AssemblyInfo, name of a NuGet package and directory in 'src') 47 | let project = "OpenTK.GLWpfControl" 48 | 49 | // Short summary of the project 50 | // (used as description in AssemblyInfo and as a short summary for NuGet package) 51 | let summary = "A native WPF control for OpenTK 4.X." 52 | 53 | // Longer description of the project 54 | // (used as a description for NuGet package; line breaks are automatically cleaned up) 55 | let description = "" 56 | 57 | // List of author names (for NuGet package) 58 | let authors = [ "varon"; "NogginBops" ] 59 | 60 | // Tags for your project (for NuGet package) 61 | let tags = "WPF OpenTK OpenGL OpenGLES GLES OpenAL C# F# VB .NET Mono Vector Math Game Graphics Sound" 62 | 63 | let copyright = "Copyright (c) 2020 Team OpenTK." 64 | 65 | // File system information 66 | let solutionFile = "GLWpfControl.sln" 67 | 68 | let binDir = "./bin/" 69 | let buildDir = binDir "build" 70 | let nugetDir = binDir "nuget" 71 | let testDir = binDir "test" 72 | 73 | // Pattern specifying assemblies to be tested using NUnit 74 | let testAssemblies = "tests/**/bin/Release/*Tests*.dll" 75 | 76 | // Git configuration (used for publishing documentation in gh-pages branch) 77 | // The profile where the project is posted 78 | let gitOwner = "opentk" 79 | let gitHome = "https://github.com/" + gitOwner 80 | 81 | // The name of the project on GitHub 82 | let gitName = "GLWpfControl" 83 | 84 | // The url for the raw files hosted 85 | let gitRaw = Environment.environVarOrDefault "gitRaw" "https://raw.github.com/opentk" 86 | 87 | // -------------------------------------------------------------------------------------- 88 | // The rest of the file includes standard build steps 89 | // -------------------------------------------------------------------------------------- 90 | 91 | // Read additional information from the release notes document 92 | let release = ReleaseNotes.load "RELEASE_NOTES.md" 93 | 94 | // Helper active pattern for project types 95 | let (|Fsproj|Csproj|Vbproj|) (projFileName:string) = 96 | match projFileName with 97 | | f when f.EndsWith "fsproj" -> Fsproj 98 | | f when f.EndsWith "csproj" -> Csproj 99 | | f when f.EndsWith "vbproj" -> Vbproj 100 | | _ -> failwith (sprintf "Project file %s not supported. Unknown project type." projFileName) 101 | 102 | let activeProjects = 103 | !! "src/**/*.??proj" 104 | 105 | let releaseProjects = 106 | !! "src/**/*.??proj" 107 | -- "src/Example/**" 108 | 109 | let install = 110 | lazy 111 | (if (DotNet.getVersion id).StartsWith "6" then id 112 | else DotNet.install (fun options -> { options with Version = DotNet.Version "6.0.200" })) 113 | 114 | // Set general properties without arguments 115 | let inline dotnetSimple arg = DotNet.Options.lift install.Value arg 116 | 117 | // Generate assembly info files with the right version & up-to-date information 118 | Target.create "AssemblyInfo" (fun _ -> 119 | let getAssemblyInfoAttributes (projectName:string) = 120 | [ 121 | AssemblyInfo.Title (projectName) 122 | AssemblyInfo.Product project 123 | AssemblyInfo.Description summary 124 | AssemblyInfo.Version release.AssemblyVersion 125 | AssemblyInfo.FileVersion release.AssemblyVersion 126 | AssemblyInfo.CLSCompliant true 127 | AssemblyInfo.Copyright copyright 128 | ] 129 | 130 | let getProjectDetails projectPath = 131 | let projectName = Path.GetFileNameWithoutExtension((string)projectPath) 132 | ( projectPath, 133 | Path.GetDirectoryName((string)projectPath), 134 | (getAssemblyInfoAttributes projectName) 135 | ) 136 | 137 | activeProjects 138 | |> Seq.map getProjectDetails 139 | |> Seq.iter (fun (projFileName, folderName, attributes) -> 140 | match projFileName with 141 | | Fsproj -> AssemblyInfoFile.createFSharp (folderName @@ "AssemblyInfo.fs") attributes 142 | | Csproj -> AssemblyInfoFile.createCSharp ((folderName @@ "Properties") @@ "AssemblyInfo.cs") attributes 143 | | Vbproj -> AssemblyInfoFile.createVisualBasic ((folderName @@ "My Project") @@ "AssemblyInfo.vb") attributes 144 | ) 145 | ) 146 | 147 | // Copies binaries from default VS location to expected bin folder 148 | // But keeps a subdirectory structure for each project in the 149 | // src folder to support multiple project outputs 150 | Target.create "CopyBinaries" (fun _ -> 151 | activeProjects 152 | |> Seq.map (fun f -> ((System.IO.Path.GetDirectoryName f) @@ "bin/Release", "bin" @@ (System.IO.Path.GetFileNameWithoutExtension f))) 153 | |> Seq.iter (fun (fromDir, toDir) -> Shell.copyDir toDir fromDir (fun _ -> true)) 154 | ) 155 | 156 | // -------------------------------------------------------------------------------------- 157 | // Clean build results 158 | 159 | Target.create "Clean" (fun _ -> 160 | Shell.cleanDirs ["bin"; "temp"] 161 | ) 162 | 163 | Target.create "Restore" (fun _ -> DotNet.restore dotnetSimple "GLWpfControl.sln" |> ignore) 164 | 165 | // -------------------------------------------------------------------------------------- 166 | // Build library & test project 167 | 168 | Target.create "Build" (fun _ -> 169 | let setOptions a = 170 | let customParams = sprintf "/p:PackageVersion=%s /p:ProductVersion=%s" release.AssemblyVersion release.NugetVersion 171 | DotNet.Options.withCustomParams (Some customParams) (dotnetSimple a) 172 | 173 | for proj in activeProjects do 174 | DotNet.build setOptions proj 175 | 176 | ) 177 | 178 | // -------------------------------------------------------------------------------------- 179 | // Build a NuGet package 180 | 181 | Target.create "CreateNuGetPackage" (fun _ -> 182 | Directory.CreateDirectory nugetDir |> ignore 183 | let notes = release.Notes |> List.reduce (fun s1 s2 -> s1 + "\n" + s2) 184 | 185 | for proj in releaseProjects do 186 | Trace.logf "Creating nuget package for Project: %s\n" proj 187 | 188 | let dir = Path.GetDirectoryName proj 189 | let templatePath = Path.Combine(dir, "paket") 190 | let oldTemplateContent = File.ReadAllText templatePath 191 | let newTemplateContent = oldTemplateContent.Insert( 192 | oldTemplateContent.Length, 193 | sprintf "\nversion \n\t%s\nauthors \n\t%s\nowners \n\t%s\n" 194 | release.NugetVersion 195 | (authors |> List.reduce (fun s a -> s + " " + a)) 196 | (authors |> List.reduce (fun s a -> s + " " + a))).Replace( 197 | "#VERSION#", release.NugetVersion) 198 | File.WriteAllText(templatePath+".template", newTemplateContent); 199 | 200 | Trace.logf "Packing into folder: %s\n" (Path.GetFullPath(nugetDir)) 201 | 202 | let setParams (p:Paket.PaketPackParams) = 203 | { p with 204 | ReleaseNotes = notes 205 | OutputPath = Path.GetFullPath(nugetDir) 206 | WorkingDir = dir 207 | Version = release.NugetVersion 208 | } 209 | Paket.pack setParams 210 | ) 211 | 212 | 213 | Target.create "BuildPackage" ignore 214 | 215 | // --------- 216 | // Release Targets 217 | // --------- 218 | 219 | open Fake.Api 220 | 221 | Target.create "ReleaseOnGitHub" (fun _ -> 222 | let token = 223 | match Environment.environVarOrDefault "opentk_github_token" "" with 224 | | s when not (System.String.IsNullOrWhiteSpace s) -> s 225 | | _ -> 226 | failwith 227 | "please set the github_token environment variable to a github personal access token with repro access." 228 | 229 | let files = !!"bin/*" |> Seq.toList 230 | 231 | GitHub.createClientWithToken token 232 | |> GitHub.draftNewRelease gitOwner gitName release.NugetVersion (release.SemVer.PreRelease <> None) release.Notes 233 | //|> GitHub.uploadFiles files 234 | |> GitHub.publishDraft 235 | |> Async.RunSynchronously) 236 | 237 | Target.create "ReleaseOnNuGet" (fun _ -> 238 | let apiKey = 239 | match Environment.environVarOrDefault "opentk_nuget_api_key" "" with 240 | | s when not (System.String.IsNullOrWhiteSpace s) -> s 241 | | _ -> failwith "please set the nuget_api_key environment variable to a nuget access token." 242 | 243 | !! (nugetDir "*.nupkg") 244 | |> Seq.iter 245 | (DotNet.nugetPush (fun opts -> 246 | { opts with 247 | PushParams = 248 | { opts.PushParams with 249 | ApiKey = Some apiKey 250 | Source = Some "nuget.org" } }))) 251 | 252 | Target.create "ReleaseOnAll" ignore 253 | 254 | // -------------------------------------------------------------------------------------- 255 | // Run all targets by default. Invoke 'build ' to override 256 | 257 | open Fake.Core.TargetOperators 258 | 259 | Target.create "All" ignore 260 | 261 | "Clean" 262 | ==> "Restore" 263 | ==> "AssemblyInfo" 264 | ==> "Build" 265 | ==> "CopyBinaries" 266 | ==> "All" 267 | 268 | "All" 269 | ==> "CreateNuGetPackage" 270 | ==> "ReleaseOnNuGet" 271 | ==> "ReleaseOnGithub" 272 | ==> "ReleaseOnAll" 273 | 274 | Target.runOrDefault "All" 275 | -------------------------------------------------------------------------------- /build.fsx.lock: -------------------------------------------------------------------------------- 1 | STORAGE: PACKAGES 2 | RESTRICTION: == netstandard2.0 3 | NUGET 4 | remote: https://api.nuget.org/v3/index.json 5 | BlackFox.VsWhere (1.1) 6 | FSharp.Core (>= 4.2.3) 7 | Microsoft.Win32.Registry (>= 4.7) 8 | Fake.Api.GitHub (5.20.4) 9 | FSharp.Core (>= 4.7.2) 10 | Octokit (>= 0.48) 11 | Fake.Core.CommandLineParsing (5.20.4) 12 | FParsec (>= 1.1.1) 13 | FSharp.Core (>= 4.7.2) 14 | Fake.Core.Context (5.20.4) 15 | FSharp.Core (>= 4.7.2) 16 | Fake.Core.Environment (5.20.4) 17 | FSharp.Core (>= 4.7.2) 18 | Fake.Core.FakeVar (5.20.4) 19 | Fake.Core.Context (>= 5.20.4) 20 | FSharp.Core (>= 4.7.2) 21 | Fake.Core.Process (5.20.4) 22 | Fake.Core.Environment (>= 5.20.4) 23 | Fake.Core.FakeVar (>= 5.20.4) 24 | Fake.Core.String (>= 5.20.4) 25 | Fake.Core.Trace (>= 5.20.4) 26 | Fake.IO.FileSystem (>= 5.20.4) 27 | FSharp.Core (>= 4.7.2) 28 | System.Collections.Immutable (>= 1.7.1) 29 | Fake.Core.ReleaseNotes (5.20.4) 30 | Fake.Core.SemVer (>= 5.20.4) 31 | Fake.Core.String (>= 5.20.4) 32 | FSharp.Core (>= 4.7.2) 33 | Fake.Core.SemVer (5.20.4) 34 | FSharp.Core (>= 4.7.2) 35 | Fake.Core.String (5.20.4) 36 | FSharp.Core (>= 4.7.2) 37 | Fake.Core.Target (5.20.4) 38 | Fake.Core.CommandLineParsing (>= 5.20.4) 39 | Fake.Core.Context (>= 5.20.4) 40 | Fake.Core.Environment (>= 5.20.4) 41 | Fake.Core.FakeVar (>= 5.20.4) 42 | Fake.Core.Process (>= 5.20.4) 43 | Fake.Core.String (>= 5.20.4) 44 | Fake.Core.Trace (>= 5.20.4) 45 | FSharp.Control.Reactive (>= 4.4.2) 46 | FSharp.Core (>= 4.7.2) 47 | Fake.Core.Tasks (5.20.4) 48 | Fake.Core.Trace (>= 5.20.4) 49 | FSharp.Core (>= 4.7.2) 50 | Fake.Core.Trace (5.20.4) 51 | Fake.Core.Environment (>= 5.20.4) 52 | Fake.Core.FakeVar (>= 5.20.4) 53 | FSharp.Core (>= 4.7.2) 54 | Fake.Core.Xml (5.20.4) 55 | Fake.Core.String (>= 5.20.4) 56 | FSharp.Core (>= 4.7.2) 57 | Fake.DotNet.AssemblyInfoFile (5.20.4) 58 | Fake.Core.Environment (>= 5.20.4) 59 | Fake.Core.String (>= 5.20.4) 60 | Fake.Core.Trace (>= 5.20.4) 61 | Fake.IO.FileSystem (>= 5.20.4) 62 | FSharp.Core (>= 4.7.2) 63 | Fake.DotNet.Cli (5.20.4) 64 | Fake.Core.Environment (>= 5.20.4) 65 | Fake.Core.Process (>= 5.20.4) 66 | Fake.Core.String (>= 5.20.4) 67 | Fake.Core.Trace (>= 5.20.4) 68 | Fake.DotNet.MSBuild (>= 5.20.4) 69 | Fake.DotNet.NuGet (>= 5.20.4) 70 | Fake.IO.FileSystem (>= 5.20.4) 71 | FSharp.Core (>= 4.7.2) 72 | Mono.Posix.NETStandard (>= 1.0) 73 | Newtonsoft.Json (>= 12.0.3) 74 | Fake.DotNet.MSBuild (5.20.4) 75 | BlackFox.VsWhere (>= 1.1) 76 | Fake.Core.Environment (>= 5.20.4) 77 | Fake.Core.Process (>= 5.20.4) 78 | Fake.Core.String (>= 5.20.4) 79 | Fake.Core.Trace (>= 5.20.4) 80 | Fake.IO.FileSystem (>= 5.20.4) 81 | FSharp.Core (>= 4.7.2) 82 | MSBuild.StructuredLogger (>= 2.1.176) 83 | Fake.DotNet.NuGet (5.20.4) 84 | Fake.Core.Environment (>= 5.20.4) 85 | Fake.Core.Process (>= 5.20.4) 86 | Fake.Core.SemVer (>= 5.20.4) 87 | Fake.Core.String (>= 5.20.4) 88 | Fake.Core.Tasks (>= 5.20.4) 89 | Fake.Core.Trace (>= 5.20.4) 90 | Fake.Core.Xml (>= 5.20.4) 91 | Fake.IO.FileSystem (>= 5.20.4) 92 | Fake.Net.Http (>= 5.20.4) 93 | FSharp.Core (>= 4.7.2) 94 | Newtonsoft.Json (>= 12.0.3) 95 | NuGet.Protocol (>= 5.6) 96 | Fake.DotNet.Paket (5.20.4) 97 | Fake.Core.Process (>= 5.20.4) 98 | Fake.Core.String (>= 5.20.4) 99 | Fake.Core.Trace (>= 5.20.4) 100 | Fake.DotNet.Cli (>= 5.20.4) 101 | Fake.IO.FileSystem (>= 5.20.4) 102 | FSharp.Core (>= 4.7.2) 103 | Fake.DotNet.Testing.XUnit2 (5.20.4) 104 | Fake.Core.Process (>= 5.20.4) 105 | Fake.Core.String (>= 5.20.4) 106 | Fake.Core.Trace (>= 5.20.4) 107 | Fake.IO.FileSystem (>= 5.20.4) 108 | Fake.Testing.Common (>= 5.20.4) 109 | FSharp.Core (>= 4.7.2) 110 | Fake.IO.FileSystem (5.20.4) 111 | Fake.Core.String (>= 5.20.4) 112 | FSharp.Core (>= 4.7.2) 113 | Fake.Net.Http (5.20.4) 114 | Fake.Core.Trace (>= 5.20.4) 115 | FSharp.Core (>= 4.7.2) 116 | Fake.Testing.Common (5.20.4) 117 | Fake.Core.Trace (>= 5.20.4) 118 | FSharp.Core (>= 4.7.2) 119 | FParsec (1.1.1) 120 | FSharp.Core (>= 4.3.4) 121 | FSharp.Control.Reactive (5.0.2) 122 | FSharp.Core (>= 4.7.2) 123 | System.Reactive (>= 5.0) 124 | FSharp.Core (5.0.1) 125 | Microsoft.Bcl.AsyncInterfaces (6.0) 126 | System.Threading.Tasks.Extensions (>= 4.5.4) 127 | Microsoft.Build (17.0) 128 | Microsoft.Build.Framework (>= 17.0) 129 | Microsoft.NET.StringTools (>= 1.0) 130 | Microsoft.Win32.Registry (>= 4.3) 131 | System.Collections.Immutable (>= 5.0) 132 | System.Configuration.ConfigurationManager (>= 4.7) 133 | System.Reflection.Metadata (>= 1.6) 134 | System.Security.Principal.Windows (>= 4.7) 135 | System.Text.Encoding.CodePages (>= 4.0.1) 136 | System.Text.Json (>= 5.0.2) 137 | System.Threading.Tasks.Dataflow (>= 4.9) 138 | Microsoft.Build.Framework (17.0) 139 | System.Security.Permissions (>= 4.7) 140 | Microsoft.Build.Tasks.Core (17.0) 141 | Microsoft.Build.Framework (>= 17.0) 142 | Microsoft.Build.Utilities.Core (>= 17.0) 143 | Microsoft.NET.StringTools (>= 1.0) 144 | Microsoft.Win32.Registry (>= 4.3) 145 | System.CodeDom (>= 4.4) 146 | System.Collections.Immutable (>= 5.0) 147 | System.Reflection.Metadata (>= 1.6) 148 | System.Resources.Extensions (>= 4.6) 149 | System.Security.Cryptography.Pkcs (>= 4.7) 150 | System.Security.Cryptography.Xml (>= 4.7) 151 | System.Security.Permissions (>= 4.7) 152 | System.Threading.Tasks.Dataflow (>= 4.9) 153 | Microsoft.Build.Utilities.Core (17.0) 154 | Microsoft.Build.Framework (>= 17.0) 155 | Microsoft.NET.StringTools (>= 1.0) 156 | Microsoft.Win32.Registry (>= 4.3) 157 | System.Collections.Immutable (>= 5.0) 158 | System.Configuration.ConfigurationManager (>= 4.7) 159 | System.Security.Permissions (>= 4.7) 160 | System.Text.Encoding.CodePages (>= 4.0.1) 161 | Microsoft.NET.StringTools (1.0) 162 | System.Memory (>= 4.5.4) 163 | System.Runtime.CompilerServices.Unsafe (>= 5.0) 164 | Microsoft.NETCore.Platforms (6.0.1) 165 | Microsoft.NETCore.Targets (5.0) 166 | Microsoft.Win32.Registry (5.0) 167 | System.Buffers (>= 4.5.1) 168 | System.Memory (>= 4.5.4) 169 | System.Security.AccessControl (>= 5.0) 170 | System.Security.Principal.Windows (>= 5.0) 171 | Mono.Posix.NETStandard (1.0) 172 | MSBuild.StructuredLogger (2.1.545) 173 | Microsoft.Build (>= 16.10) 174 | Microsoft.Build.Framework (>= 16.10) 175 | Microsoft.Build.Tasks.Core (>= 16.10) 176 | Microsoft.Build.Utilities.Core (>= 16.10) 177 | Newtonsoft.Json (13.0.1) 178 | NuGet.CommandLine (6.0) 179 | NuGet.Common (6.0) 180 | NuGet.Frameworks (>= 6.0) 181 | NuGet.Configuration (6.0) 182 | NuGet.Common (>= 6.0) 183 | System.Security.Cryptography.ProtectedData (>= 4.4) 184 | NuGet.Frameworks (6.0) 185 | NuGet.Packaging (6.0) 186 | Newtonsoft.Json (>= 13.0.1) 187 | NuGet.Configuration (>= 6.0) 188 | NuGet.Versioning (>= 6.0) 189 | System.Security.Cryptography.Cng (>= 5.0) 190 | System.Security.Cryptography.Pkcs (>= 5.0) 191 | NuGet.Protocol (6.0) 192 | NuGet.Packaging (>= 6.0) 193 | NuGet.Versioning (6.0) 194 | Octokit (0.50) 195 | System.Buffers (4.5.1) 196 | System.CodeDom (6.0) 197 | System.Collections.Immutable (6.0) 198 | System.Memory (>= 4.5.4) 199 | System.Runtime.CompilerServices.Unsafe (>= 6.0) 200 | System.Configuration.ConfigurationManager (6.0) 201 | System.Security.Cryptography.ProtectedData (>= 6.0) 202 | System.Security.Permissions (>= 6.0) 203 | System.Formats.Asn1 (6.0) 204 | System.Buffers (>= 4.5.1) 205 | System.Memory (>= 4.5.4) 206 | System.Memory (4.5.4) 207 | System.Buffers (>= 4.5.1) 208 | System.Numerics.Vectors (>= 4.4) 209 | System.Runtime.CompilerServices.Unsafe (>= 4.5.3) 210 | System.Numerics.Vectors (4.5) 211 | System.Reactive (5.0) 212 | System.Runtime.InteropServices.WindowsRuntime (>= 4.3) 213 | System.Threading.Tasks.Extensions (>= 4.5.4) 214 | System.Reflection.Metadata (6.0) 215 | System.Collections.Immutable (>= 6.0) 216 | System.Resources.Extensions (6.0) 217 | System.Memory (>= 4.5.4) 218 | System.Runtime (4.3.1) 219 | Microsoft.NETCore.Platforms (>= 1.1.1) 220 | Microsoft.NETCore.Targets (>= 1.1.3) 221 | System.Runtime.CompilerServices.Unsafe (6.0) 222 | System.Runtime.InteropServices.WindowsRuntime (4.3) 223 | System.Runtime (>= 4.3) 224 | System.Security.AccessControl (6.0) 225 | System.Security.Principal.Windows (>= 5.0) 226 | System.Security.Cryptography.Cng (5.0) 227 | System.Security.Cryptography.Pkcs (6.0) 228 | System.Buffers (>= 4.5.1) 229 | System.Formats.Asn1 (>= 6.0) 230 | System.Memory (>= 4.5.4) 231 | System.Security.Cryptography.Cng (>= 5.0) 232 | System.Security.Cryptography.ProtectedData (6.0) 233 | System.Memory (>= 4.5.4) 234 | System.Security.Cryptography.Xml (6.0) 235 | System.Memory (>= 4.5.4) 236 | System.Security.AccessControl (>= 6.0) 237 | System.Security.Cryptography.Pkcs (>= 6.0) 238 | System.Security.Permissions (6.0) 239 | System.Security.AccessControl (>= 6.0) 240 | System.Security.Principal.Windows (5.0) 241 | System.Text.Encoding.CodePages (6.0) 242 | System.Memory (>= 4.5.4) 243 | System.Runtime.CompilerServices.Unsafe (>= 6.0) 244 | System.Text.Encodings.Web (6.0) 245 | System.Buffers (>= 4.5.1) 246 | System.Memory (>= 4.5.4) 247 | System.Runtime.CompilerServices.Unsafe (>= 6.0) 248 | System.Text.Json (6.0.1) 249 | Microsoft.Bcl.AsyncInterfaces (>= 6.0) 250 | System.Buffers (>= 4.5.1) 251 | System.Memory (>= 4.5.4) 252 | System.Numerics.Vectors (>= 4.5) 253 | System.Runtime.CompilerServices.Unsafe (>= 6.0) 254 | System.Text.Encodings.Web (>= 6.0) 255 | System.Threading.Tasks.Extensions (>= 4.5.4) 256 | System.Threading.Tasks.Dataflow (6.0) 257 | System.Threading.Tasks.Extensions (4.5.4) 258 | System.Runtime.CompilerServices.Unsafe (>= 4.5.3) 259 | xunit.runner.console (2.4.1) -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -o 4 | 5 | function version_compare() { 6 | ver1=(${1//./ }) 7 | ver2=(${2//./ }) 8 | 9 | len1=${#ver1[@]} 10 | len2=${#ver2[@]} 11 | 12 | vlen=$(($len1 < $len2 ? $len1 : $len2)) 13 | 14 | for ((i=0;i /dev/null) || EXIT_CODE=$? 28 | 29 | if (($EXIT_CODE == 0)) && version_compare "$MINIMAL_DOTNET_VERSION" "$CURRENT_DOTNET_VERSION"; then 30 | echo "dotnet command already installed" 31 | else 32 | # Install .NET Core (https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script) 33 | curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version 3.1.100 34 | 35 | PATH="~/.dotnet:$PATH" 36 | fi 37 | 38 | FSIARGS="" 39 | OS=${OS:-"unknown"} 40 | if [[ "$OS" != "Windows_NT" ]] 41 | then 42 | FSIARGS="--fsiargs -d:MONO" 43 | fi 44 | 45 | function run() { 46 | if [[ "$OS" != "Windows_NT" ]] 47 | then 48 | mono "$@" 49 | else 50 | "$@" 51 | fi 52 | } 53 | 54 | run .paket/paket.bootstrapper.exe 55 | 56 | if [[ "$OS" != "Windows_NT" ]] && 57 | [ ! -e ~/.config/.mono/certs ] 58 | then 59 | mozroots --import --sync --quiet 60 | fi 61 | 62 | dotnet tool restore 63 | dotnet fake run $FSIARGS build.fsx $@ -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://api.nuget.org/v3/index.json 2 | 3 | storage: none 4 | framework: netcoreapp3.1, netstandard2.0, netstandard2.1 -------------------------------------------------------------------------------- /paket.lock: -------------------------------------------------------------------------------- 1 | STORAGE: NONE 2 | RESTRICTION: || (== netcoreapp3.1) (== netstandard2.0) (== netstandard2.1) 3 | -------------------------------------------------------------------------------- /src/Example/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Example/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace Example { 4 | /// 5 | /// Interaction logic for App.xaml 6 | /// 7 | public partial class App : Application { } 8 | } -------------------------------------------------------------------------------- /src/Example/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 | )] -------------------------------------------------------------------------------- /src/Example/Example.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | WinExe 4 | netcoreapp3.1 5 | true 6 | false 7 | Example.App 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Example/ExampleScene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Runtime.CompilerServices; 4 | using OpenTK.Graphics.OpenGL; 5 | using OpenTK.Mathematics; 6 | 7 | namespace Example { 8 | /// Example class handling the rendering for OpenGL. 9 | public class ExampleScene { 10 | 11 | private static readonly Stopwatch _stopwatch = Stopwatch.StartNew(); 12 | 13 | private int Program; 14 | 15 | private int VAO; 16 | private int VBO; 17 | 18 | struct Vertex 19 | { 20 | public Vector2 Position; 21 | public Color4 Color; 22 | 23 | public Vertex(Vector2 position, Color4 color) 24 | { 25 | Position = position; 26 | Color = color; 27 | } 28 | } 29 | 30 | private static readonly Vertex[] vertices = 31 | { 32 | new Vertex((0.0f, 0.5f), Color4.Red), 33 | new Vertex((0.58f, -0.5f), Color4.Green), 34 | new Vertex((-0.58f, -0.5f), Color4.Blue), 35 | }; 36 | 37 | private static readonly string VertexShaderSource = 38 | @"#version 330 core 39 | 40 | in vec2 vPosition; 41 | in vec4 vColor; 42 | 43 | out vec4 fColor; 44 | 45 | void main() 46 | { 47 | gl_Position = vec4(vPosition, 0, 1); 48 | fColor = vColor; 49 | } 50 | "; 51 | 52 | private static readonly string FragmentShaderSource = 53 | @"#version 330 core 54 | 55 | in vec4 fColor; 56 | 57 | out vec4 oColor; 58 | 59 | void main() 60 | { 61 | oColor = fColor; 62 | } 63 | "; 64 | 65 | public void Initialize() 66 | { 67 | Program = GL.CreateProgram(); 68 | 69 | int vertexShader = GL.CreateShader(ShaderType.VertexShader); 70 | GL.ShaderSource(vertexShader, VertexShaderSource); 71 | GL.CompileShader(vertexShader); 72 | GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out int success); 73 | if (success == 0) 74 | { 75 | string log = GL.GetShaderInfoLog(vertexShader); 76 | Debug.WriteLine($"Vertex shader compile error: {log}"); 77 | } 78 | 79 | int fragmentShader = GL.CreateShader(ShaderType.FragmentShader); 80 | GL.ShaderSource(fragmentShader, FragmentShaderSource); 81 | GL.CompileShader(fragmentShader); 82 | GL.GetShader(fragmentShader, ShaderParameter.CompileStatus, out success); 83 | if (success == 0) 84 | { 85 | string log = GL.GetShaderInfoLog(fragmentShader); 86 | Debug.WriteLine($"Fragment shader compile error: {log}"); 87 | } 88 | 89 | GL.AttachShader(Program, vertexShader); 90 | GL.AttachShader(Program, fragmentShader); 91 | GL.LinkProgram(Program); 92 | GL.GetProgram(Program, GetProgramParameterName.LinkStatus, out success); 93 | if (success == 0) 94 | { 95 | string log = GL.GetProgramInfoLog(Program); 96 | Debug.WriteLine($"Program link error: {log}"); 97 | } 98 | 99 | GL.DetachShader(Program, vertexShader); 100 | GL.DetachShader(Program, fragmentShader); 101 | 102 | GL.DeleteShader(vertexShader); 103 | GL.DeleteShader(fragmentShader); 104 | 105 | int positionLocation = GL.GetAttribLocation(Program, "vPosition"); 106 | int colorLocation = GL.GetAttribLocation(Program, "vColor"); 107 | 108 | VAO = GL.GenVertexArray(); 109 | GL.BindVertexArray(VAO); 110 | 111 | VBO = GL.GenBuffer(); 112 | GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); 113 | GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * Unsafe.SizeOf(), vertices, BufferUsageHint.StaticDraw); 114 | 115 | GL.EnableVertexAttribArray(positionLocation); 116 | GL.VertexAttribPointer(positionLocation, 2, VertexAttribPointerType.Float, false, Unsafe.SizeOf(), 0); 117 | 118 | GL.EnableVertexAttribArray(colorLocation); 119 | GL.VertexAttribPointer(colorLocation, 4, VertexAttribPointerType.Float, false, Unsafe.SizeOf(), Unsafe.SizeOf()); 120 | } 121 | 122 | public void Render(float alpha = 1.0f) { 123 | var hue = (float) _stopwatch.Elapsed.TotalSeconds * 0.15f % 1; 124 | var c = Color4.FromHsv(new Vector4(alpha * hue, alpha * 0.75f, alpha * 0.75f, alpha)); 125 | GL.ClearColor(c); 126 | GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 127 | 128 | GL.UseProgram(Program); 129 | GL.DrawArrays(PrimitiveType.Triangles, 0, 3); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Example/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 29 | 35 | 43 |