picoe / Eto.OpenTK

Eto OpenGL viewport (C#)
MIT License
24 stars 41 forks source link

Compatibility with OpenTK 4.0.0 #40

Open shults-s opened 3 years ago

shults-s commented 3 years ago

When I trying to install the Eto.OpenTK 0.1.2 package in a .NET Core 3.1 Eto.Forms application, I get a NuGet warning NU1701 Package 'Eto.OpenTK 0.1.2' was restored using '.NETFramework, Version = v4.6.1, .NETFramework, Version = v4.6.2, .NETFramework, Version = v4.7, .NETFramework, Version = v4.7.1, .NETFramework, Version = v4.7.2, .NETFramework, Version = v4.8 'instead of the project target framework '.NETCoreApp, Version = v3.1'. This package may not be fully compatible with your project.

To eliminate this warning, as well as the application startup error (System.IO.FileNotFoundException: 'Could not load file or assembly' OpenTK, Version = 3.0.1.0, Culture = neutral, PublicKeyToken = ...') I tried to update OpenTK to version 4.0.0 in all of projects contained in this repository, having previously changed TargetFramework property in Eto.OpenTK, Eto.OpenTK.Gtk2, Eto.OpenTK.Mac64, Eto.OpenTK.WinForms, Eto.OpenTK.Wpf projects from net45 to netcoreapp3.1. After that, throughout the solution, I updated OpenTK to version 4.0.0.

It turned out that version 4.0.0 lacks the GraphicsMode class (used, for example, in WpfWinGLSurfaceHandler.cs), so the projects could not be rebuilt.

How difficult would it be to move from .NET Framework to .NET Core for this project and move from OpenTK 3.0.1 to 4.0.0 given changes in the new version?

Currently I use Eto.Forms 2.5.6, Eto.Platform.Wpf 2.5.6.

cwensley commented 3 years ago

Hey @shults-s, I really appreciate filing the issue. I had no idea that 4.0.0 was officially released (probably because it was ~7 hours ago).

Unfortunately, OpenTK 4.0 appears to only run on .NET Core as its libraries only target netstandard2.1 or netcoreapp3.1. It does not support .NET Framework. This is insane. It will make updating Eto.OpenTK a real pain to retain any sort of compatibility with .NET Framework based apps.. Talk about ripping off the band-aid.

Hopefully I can find a "graceful" upgrade path.. if not, well.. that sucks.

ItEndsWithTens commented 3 years ago

I wasn't aware of the problem with .NET Framework support, but keep in mind the other issue of context creation and management. As pointed out above, the GraphicsMode class is gone, but more than that, the entirety of OpenTK's platform-specific OpenGL context management code has been stripped out in favor of a dependency on GLFW.

That's fine for many users, who expect to create and work with windows only by way of OpenTK/GLFW, but it's a problem for those of us looking to embed hardware accelerated rendering in an existing UI toolkit like Eto, as GLFW doesn't currently allow creating a GL context from an existing native window handle.

I ran into this stuff myself when working on the Eto.Veldrid control: earlier in that project's development it depended on OpenTK for context creation, and beside the undesirable bloat and complexity of that, the biggest reason that approach was ultimately abandoned was the fact that sticking with OpenTK 3 would mean no .NET Core support, but upgrading to OpenTK 4 was impossible (or at least outrageously difficult) thanks to GLFW not letting you get a context from an existing handle.

Conceivably Eto.OpenTK could handle all rendering context creation and management itself, but I get the impression that's a sizeable task. I imagine it would consist of essentially ground-up rewriting all the platform-specific stuff OpenTK 3.x has...? I don't have the confidence to say for sure, so take that with a grain of salt.

A potentially better use of that hypothetical development effort might be a pull request for GLFW itself, since the glfw repository has an open issue regarding this very feature: glfw/glfw#25 I believe I've seen mention somewhere that the OpenTK team had maybe considered eventually coming up with a patch for GLFW to add the feature themselves, but I think most of their development discussions happen on Discord, and I'm not up on what they're planning with this, if anything.

shults-s commented 3 years ago

@cwensley @ItEndsWithTens

Thank you very much for your comprehensive explanations!

If I understand the situation correctly, due to the global breaking changes in OpenTK 4.0.0 (.NET Standard only, shifting responsibility of creating and managing the context to GLFW, ...), the problem of updating Eto.OpenTK to OpenTK 4.0.0 is almost impossible with such initial conditions and clearly not worth the effort that will have to be spent on it.

I will try to find out from the OpenTK developers how they see the future use of the library by those who want to embed it into existing GUI applications.

I am still very impressed with the ability to use MVVM (Bindings) in conjunction with a simple classic approach (UI through C# code). And all this is cross-platform and not memory-intensive... Thank you!

cwensley commented 3 years ago

One thing to consider given that OpenGL is deprecated on macOS (and could be removed entirely in a future version), is to use Eto.Veldrid instead. It uses Metal on macOS, OpenGL on Linux, and Direct3D on Windows. It already supports .NET Core, and is probably a better way forward than using OpenTK.

shults-s commented 3 years ago

@cwensley I think that in the context of portability to macOS, you are completely right. Regarding OpenTK, the developers say that everything is fine (#1155).

varon commented 3 years ago

@ItEndsWithTens

Just spotted this through a link to an issue on the OpenTK repo! Please fee free to '@' one of the maintainers if you guys ever need help in future. We'd also love to have you guys on the Discord if you want a super responsive link for Q&A.

To answer the question, in OpenTK 4.0, the graphics is totally decoupled from GLFW.

To use it with another framework or windowing system: 1) Implement IBindingsContext. 2) Call GL.LoadBindings(context)

In short, all that does is provide an interface to whatever GetProcAddress you want to use.

As an example implementation for GLFW:

public class GLFWBindingsContext : IBindingsContext
{
    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    public static extern IntPtr glfwGetProcAddress(string procName);

    public IntPtr GetProcAddress(string procName)
    {
        return glfwGetProcAddress(procName);
    }
}

Hope this helps.

varon commented 3 years ago

Also would be great if we can reopen this issue and work with you guys to support your use case.

ItEndsWithTens commented 3 years ago

@varon

Hi! Thanks for the info. Just to be clear up front, I'm not an Eto.Forms maintainer or anything, just a user, and although I've made a couple of contributions here and there, I can't speak for @cwensley in any official capacity as far as his plans for Eto.OpenTK.

That being said, to explain my own lack of @-ing anybody, I didn't mean to keep you guys out of the discussion or anything, I just assumed you wouldn't want to be bothered with something that would require a fair bit of hand holding. I did end up following the link to the connected issue over on the OpenTK repo, and it was there I first learned about IBindingsContext, but I still kept my mouth shut because I believe implementing that is no small task in this case.

Eto.Forms wraps a number of native platform GUI frameworks, including WinForms, WPF, MonoMac, Xamarin.Mac, and Gtk; if I'm not mistaken, implementing IBindingsContext would require context creation and management code for each of those. In the case of Gtk there's 'GLArea', which would certainly prove useful (and is what we did for Eto.Veldrid), but the other platforms aren't so lucky. From the look of the platform-specific context code for the OpenTK 3.x branch, and everything else I've read, it's non-trivial to get contexts up and running for even one platform, let alone four.

Speaking only for myself, that complexity is why I didn't bother getting in touch with any OpenTK devs; I've been toying with all this stuff for a couple years in a purely hobbyist capacity, and I'm not an experienced graphics developer, so you'd end up doing more than just offering the occasional suggestion or hint. I'd hate to ask anyone to babysit me through this sort of thing, especially in this case where someone else's project runs the risk of having my pedestrian questions associated with it. I'm not out to make anyone look bad.

cwensley commented 3 years ago

Hey @varon,

Thank you for reaching out! It is very appreciated. As @ItEndsWithTens mentioned I am the official maintainer as I've pulled it into the Eto.Forms fold, however it all started with @philstopford and @ItEndsWithTens excellent work getting this going. I too am not really well versed in OpenGL but I help facilitate the developers and organizations that need this functionality in their apps.

I appreciate the decoupling that your team has done with OpenTK to make it easier to integrate with more backends, but it does add a lot more work on our end to get it supported by setting up the GL context manually. This shouldn't be an issue with Gtk or Mac as they both provide ways to do this with GLArea and NSOpenGLView respectively. I haven't looked into what it takes to set up a GL context on windows, which would be the only major hurdle we would face. I am not overly concerned about this.

As for the .NET Standard 2.1 and netcoreapp3.1 requirement of the nuget packages, it makes things complicated as there are still many developers using Eto.Forms on .NET Framework, mono, and Xamarin.Mac. This basically means that anyone on those runtimes will not be able to take advantage of the new version of OpenTK. I'm sure you have not come to that decision lightly to drop support for these runtimes/platforms, but it is not something that we can do at this point or for probably a number of years. It would be ideal to have a .NET Standard 2.0 and/or .NET Framework 4.x target in the core NuGet packages to address this, but I understand if there aren't resources to maintain that or limit yourself to those API's.

So, it comes down to priorities. I would love to support OpenTK 4, but it will take some time to get that going. I also have to think about how to support both OpenTK v3 and v4 due to the issues above. This will also take effort and time. For now, since v3 works everywhere, there will not be a huge push to get v4 supported right away.

Perhaps when more people move away from .NET Framework and mono, and Xamarin.Mac runs on .NET (I believe MS are targeting for .NET 6 next year), then we can revisit this so we can drop our v3 support and go right to v4.

I hope this gives you some insight.

Cheers.

philstopford commented 3 years ago

Also would be great if we can reopen this issue and work with you guys to support your use case.

@varon : Would be interesting to get some insight into the cause of trouble with https://github.com/picoe/Eto.OpenTK/pull/41 when the non-simple viewports are enabled. They don't seem to draw anything. These were working with the earlier version of OpenTK. I guess something changed, and it's not clear what.

NogginBops commented 2 years ago

@philstopford Hi! It's been a while since this was active. I'm one of the active maintainers on OpenTK atm, it's likely that I can help answer this question. Should we discuss the issue and find a solution in the PR?

philstopford commented 2 years ago

@NogginBops : I think we'd welcome any and all help here. @cwensley made some responses earlier to @varon and I separately would like some help to restore the line drawing in the non-simple views. From reading around, it seems that the old approaches were deprecated and some kind of shader is now needed. I haven't been able to figure out what this should look like. My Linux test box is temporarily offline due to an OS update misfire that I'm trying to sort out at the moment.

If you're highly motivated, OpenTK is also used to provide OpenGL in this PR (https://github.com/picoe/Eto.Veldrid/pull/23) and I run into GLX failures on nVidia hardware under Linux. The debugger never traps this - the code just exits out to the command line; getting some expert assistance there would be amazing. Intel graphics does not yield this problem, nor does OpenGL inside Virtual Machines. The aim of the 'Eto.Veldrid' project was to try and give the developer/user the flexibility to choose the appropriate backend by choice or automatically at runtime.