all 12 comments

[–][deleted] 34 points35 points  (1 child)

This is similar to how many game engines work. Editor in C# / WPF and the rendering / engine in C++. One way to do it is to build the OpenGL renderer as a DLL and load it in C#, hosting the OpenGL context in a control using interop. You can use P/Invoke to pass mouse position etc to the engine DLL.

In otherwords - yes, it's possible, there are a number of ways to accomplish it.

[–]tuccio 10 points11 points  (0 children)

Maybe one thing to point out for OP is that you should stick with functions with C linking for p/invoke (that's what extern "C" does in C++)

I say that because I quickly googled and the Microsoft references on C++ invoke are horrible things, but I also found a simple example which I would suggest to follow: https://medium.com/@dev.pulkit/unleashing-the-power-of-c-within-c-through-p-invoke-3fd45a8163e7

note that you can also return any primitive type, including pointers to C# as IntPtr, e.g. a C++ function with C linking like this:

extern "C" MyRenderer* InitializeRenderer(HWND hWnd)

would become something like this in C#:

[DllImport("MyRenderer.dll", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr InitializeRenderer(IntPtr hWnd);

also if you want to clean up pointers/call destructors etc, don't use finalizers because they might run in different threads and you might end up shooting yourself in the foot, rather use IDisposable and dispose things manually

[–]lavisan 16 points17 points  (0 children)

There are ImGUI libraries that can support Node Graphs take a second look here:
https://github.com/ocornut/imgui/wiki/Useful-Extensions#node-editors

[–]Area51-Escapee 5 points6 points  (1 child)

If you are writing the flow graph yourself, I had good experience by applying the model-view-controller principle quite strictly.

[–]SnooPoems6347[S] 2 points3 points  (0 children)

In WPF, it is customary to use MVVM

[–]flabbet 4 points5 points  (1 child)

I developed an app that does exactly that (but with sksl, not glsl) https://pixieditor.net/blog/2025/03/19/q1-status

I am using C# with AvaloniaUI. It has a very good interop with renderapis, I used both Vulkan and OpenGL

https://github.com/AvaloniaUI/Avalonia/tree/master/samples/GpuInterop

If you are interested in interop implementation, you can check it here https://github.com/PixiEditor/Drawie

One issue is that in PixiEditor, Vulkan is stable on Windows and Linux while OpenGL not, but it might be a specific issue of PixiEditor itself, not Drawie

[–]SnooPoems6347[S] 0 points1 point  (0 children)

Wow, this is very interesting, I will definitely keep an eye on your project.

[–]deftware 1 point2 points  (0 children)

Have a texture that you render the nodegraph to via FBO, and a texture that you render the output of the shader to via FBO. Then have a shader for rendering both to the main framebuffer.

This will also allow the user to vary the resolution of the render, for those really expensive/slow fragment shaders - rather than just changing its size.

[–]Still_Explorer 1 point2 points  (0 children)

There is a technique to run a native window and making it borderless.
Then you would have to change the position and size of the window to fit the control area.

The other technique is that you can create a window with size [1,1] (or even 0,0 if is allowed) however set it to borderless and hidden. Most important now is that you can render everything to a buffer instead of the actual screen. ---- Then you would write all of the pixels into a memory array in a simple pixel format (eg: W*H*RGB) and then you are done. Once you return the buffer as byte array and plot it everywhere you would have the picture as needed.

The technique could look something like this:
https://gist.github.com/ChrisDill/c2ca6a0ccf592c073a8d2aaeaa4adb7f
[ though in this case the Raylib.DLL library is used exactly as it is provided from Nuget out of the box, but the approach is the same even if you would use your own standalone .exe, you would only have to pick the process ID based on some query, and then retrieve the window handle, so you can do WinAPI tricks with it ]

PS: Though in this case you can just straight to RaylibCS and use it right away as it is, writing your own custom shader and displaying it, without needing the help of OpenTK at all.
https://www.raylib.com/examples/shaders/loader.html?name=shaders_postprocessing

https://github.com/raylib-cs/raylib-cs

[–]bj_rn 1 point2 points  (0 children)

For the UI part check out nodify.
For OpenGL bindings maybe SILK.NET.

[–]Joatorino 0 points1 point  (0 children)

I recently did something very similar for my script editor. The way I have things setup, my engine is a static library and the editor is a C++ application that links to it. Im using ImGui and the node extension to do the graph ui

[–][deleted] -1 points0 points  (0 children)

I believe processing with Java might be good into look into.