Hey guys, question for everyone who's making a des...
# thinking-together
m
Hey guys, question for everyone who's making a desktop visual lang: what do you use for rendering and why?
🤔 1
c
Do you mean Qt vs GL vs DX vs GUI, etc.?
m
@Chris Maughan yep
c
My tool is designed as a shader authoring tool (in part), so my plan is to support rendering using GL, DX12, Vulkan. This is for the shaders/graphics the user creates. GL because it is a guaranteed lowest common denominator. DX12/Vulkan because they are the cutting edge. I don't want to use Metal if I can help it. For GUI elements I have 2 approaches: • ImGui. This sits on top of the API's I just mentioned and does buttons/checkboxes/windows, etc. • NanoVg. This is a vector drawing library along a similar vain to ImGui. It has slightly better support for pattern rendering, and is a bit simpler to use for basic primitives. It also uses GL, etc. for the bottom level of drawing. In this image, ImGui is drawing the left hand text editor, the sequencer along the bottom. NanoVg is drawing the Nodegraph UI inside the top right window. And everything sits on top of OpenGL in this example. My choices are based on ease of use and cross platform. Using custom GUI code for each platform is out of the question. I have a version of the text editor in the image that runs on Qt. Qt is a good cross platform choice for 2D/UI frameworks, but it is my least favourite API to work with (I do it for a day job too, so I am proficient at using it). Qt is powerful, but can be very frustrating. On the other hand, using it as a way to get a QPainter and draw shapes would be an easy cross platform method. I use SDL to do the heavy lifting of creating OS specific windows for drawing in. SDL is a great way to get a window on screen. ImGui integrates will with it. So my pathway is SDL->OpenGL/DX->ImGui OR NanoVg
m
@Chris Maughan Thank you! I already knew about imgui, my question was more targeted at rendering stuff like dataflow graphs, but nanovg might be what I'm looking for. I'll look into it:)
c
Something I am unable to use but would like to is the Slug library for text: https://sluglibrary.com/ As far as I can see this is the gold standard for rendering text on a 3D Device; it looks far better than what I have come up with so far (on a par with OS/GUI font rendering). Unfortunately it is commercial, though the author has hinted that he'd love some company to buy it and make it free.
ImGui is quite capable of drawing shapes for you. You can drop into a lower level and draw anything you like using the drawing code. Many people do that for custom GUI
This is an orientation gizmo I did; it renders entirely with ImGui (I think I ported this from somewhere, but I've forgotten... 🙂 Ah, yes, it was from 'AntTweakBar'.
m
Found this in the readme of nanovg, idk if it should but this kinda scare me away from using something...
This project is not actively maintained.
c
So you see, you can even draw triangles in ImGui if you want to.
Yeah, NanoVg isn't maintained any more. I've had no problem using it 😉 If you are getting started, I'd use ImGui.
Have a look at this thread ^ it contains custom node editors written using ImGui
m
Thank you!
c
I'm using NanoVG (which is OpenGL based) ... I know it's no longer actively supported, but it's in plain C and a lot simpler (IMHO) than imGUI.
p
I'd love to see more answers to this! I'm unhappy how state is managed in every OOP framework and every framework that uses a VDOM. I think neither mutability with objects nor mutability on another layer (vdom) works well. Building something else has been hard for me. Text rendering especially. Building something cross platform makes it 100x harder. Using the web platform doesn't work, when you try to build on a lower level: You can't even measure text dimensions easily. I've tried building up my own cross-platform solution based on WebGL, WASM (Rust), but failed at font layout. Compiling harfbuzz to wasm just didn't work for me, despite some people claiming to have done that. So, I'm considering non-web solutions again. Basically, I'm really interested what others have to say. Also, adding a reference to Raph Levien's work here, as I think he's also interested in this space: https://raphlinus.github.io/
👍 1
m
@Philipp Krüger I'd actually be really interested in giving a rust-based solution a try :D
p
@Matei Adriel There's rust stuff happening here: https://github.com/linebender and also some relevant stuff (for me mostly) here: https://github.com/RazrFalcon/rustybuzz But it's very experimental. Hard to say what these projects are going to become, in what direction they'll evolve, and in what time they'd be viable. 🙂
c
Fonts are always hard, especially for smaller text. An HD display helps a lot - the problem is lessened on a 4K screen 🙂 As I said, the Slug library is probably an easy solution if you don't mind paying or just want a prototype. I've used Direct2D on windows before; that is nice renderer. Qt is very nice for fonts as long as you are happy to bite into that huge apple. Another approach is to use an OS specific renderer to draw your specific text onto a texture and then apply it in the engine; that gives you the best of both worlds, but you need to write custom bits. I've heard good things about HarfBuzz; I really should get around to building it.
p
I'm pretty sure harfbuzz itself is very mature, this is from their wiki:
The current HarfBuzz tree, used to be also known as harfbuzz-ng, is under active development and is what is directly used in Firefox, Chrome, LibreOffice, XeTeX, Minikin/Android/Flutter, PlayStation, Qt/KDE, GTK+/Gnome, Java, Emacs and Unreal Engine among many other places directly or indirectly.
c
Yeah, it's just big/complex.
s
WebKit direct DOM manipulation via Javascript
s
I was playing around with a shader editor and built on a similar stack as @Chris Maughan
if you're not used to or wanting to specifically interact with low level GPU APIs I wouldn't recommend it though
I specifically wanted to play around with raytracing, wave instrinics, and maybe in the future mesh shaders
as well as gain some more knowledge of how things are done in the DX12 API. I'd done some hello triangle stuff in Vulkan and done a lot of DX11 work for various jobs and side projects, but hadn't officially touched DX12
IMGUI is really nice though
d
I use Vulkan and imgui in my own project, Onex. And, to echo comments above, I also use lines and triangles in imgui to draw arrows. 😊 I had to remember some school maths. 😧
s
If I was working on a higher level tool I'd either do it with something browser based, or using a game engine
d
I tried browsers and game engines. Never again
👍 2
s
why not?
d
Way way too much baggage. It's liberating starting from the metal (no pun intended)
👍 2
Not sure it's more work: fighting incompatible models Vs writing more code..
Basically you're up against decades of assumptions around The Web and The Game, resp
s
fair enough, I think it depends on what you're working on
d
If you start with Sascha Willem's example code, it's pretty easy to get going
s
you can also go higher level than Vulkan + IMGUI and lower level than Unity or Unreal 🙂
like using sokol, or bgfx or something of that nature
even wgpu
I'd argue that for all of the FOC projects I've seen Vulkan is overkill
and GL would be fine, or DX11
d
OK. True nuff. Just wanted to be ahead of the curve 😊
Basing on imgui means I can always switch
But not when I start doing the serious 3D stuff obviously.
Which is a while away. 2D will keep me busy for a bit
s
if you're using subgroups in vulkan, or some fancy usage of descriptor sets or resource binding, etc. The thing about Vulkan is using it naively will give you worse performance in many cases than using GL or DX11 naively
but that doesn't actually matter for many use cases
i
+1 to imgui for rendering for something more complex like a fullblown editor, you'll need some statemanagement & databinding solution
i'm personally biased towards the immutable + unidirectional flow model and have my own library to handle it
but if you're in C++ and have a tolerance for templates, lager is a good library for that: https://sinusoid.es/lager/#contents
@Chris Maughan curious why are you using nanovg at all given your usse of imgui? (ps thx for zep, it's my code editor widget still)
😄 1
s
@ikrima thanks for the link to lager btw, I wasn't aware of an Elm style library for C++
it uses std::variant and actually uses the words "stringly typed actions" (although discourages usage), so maybe not great for high performance run time but completely reasonable for most things
i
👍 the author's pretty great and I use his immutable persistent data structures library. honestly the biggest reason i had to roll my own was bc it's heavy template usage (and it links boost.hana)
s
yeah...
i
(more of a criticism of C++ vss. the lib; i'm not sure there's a way to do it in C++ otherwise. case in point, my version eschews type safety + uses C++ JIT codegen)
@Scott Anderson re: elm - have you seen a library in the general ecosystem that has a good approach to UI databinding?
imho, WPF has been the gold standard but not familiar with elm + broader landscape
m
I already made a demo-ish visual fp lang using purescript (which runs in the browser) which was rendered to a html5 canvas
But I'm trying to switch to desktop dev
Since IMO the js tooling is shit
d
The thing about Vulkan is using it naively will give you worse performance in many cases than using GL or DX11 naively
Doesn't everyone use Vulkan naively? There are probably 3 people who actually know what they're doing, it's so insanely complicated. I rely on Sascha to be my code chef and sprinkle some of my own seasonings on!
m
Im comfotable in rust + a bunch of fp langs (f#, haskell, purescript, a few more)
It seems like all the stuff you guys recommend is c++ based
I did some c++ for school a while back but I'm by all means a beginner at it
d
I'd stick to C if you can, then. 😊
imgui is annoyingly C++ but doesn't really benefit from it
All basic graphics techs are in C
And God codes in C apparently
i
also just in case it was implied, i'd like to clarify that i do not recommend C++ but if you are forced in C++, here's some stuff. imgui i believe has a cimgui binding (used in sokol)
relevant maybe?
I actually want to use Rust, but for side projects I decided learning Rust (which I don't know well) + learning DX12 or Vulkan + actually making a somewhat useful toy application for prototyping was too much
and it wouldn't be learning idiomatic safe Rust, it'd be learning unsafe Rust in order to interface with a low level API
also, no not everyone uses Vulkan naively, professional game developers with performant Vulkan engines don't use it naively, my (maybe long winded) point was that using Vulkan is probably overkill for hobby projects and doesn't give you anything that OpenGL wouldn't, and might actually be measurably worse
👍🏼 1
but if the goal is to learn Vulkan or use features that only exist in Vulkan (mesh shading, ray tracing, etc.) then definitely use Vulkan!
in any side project I've done with Vulkan or DX12 I've used it super naively though hah
d
re: Godot: I went all-out with Godot but hit the issues I mentioned above
👍 2
re: Vulkan: like I said, I /naively/ (!) thought I was being all leading edge 😄
I am considering going back to my old friend OpenGL|ES 2, or 3
s
if Vulkan is working for you no need to switch
and Vulkan could unlock some great things
i
@Scott Anderson hot damn, thanks for that godot link!
d
Godot is the best OS game engine, don't get me wrong
just too much of an impedance mismatch to my C code!
d
For rendering my UI, what I want is a cross platform, high level, GPU-accelerated graphics UI that goes far beyond the postscript/SVG 2D graphics model. It should support hybrid 2D/3D, and it should be extensible using procedurally defined graphics primitives (signed distance functions) as seen on shadertoy.com. So there are no limits to what a UI can look like. You aren't boxed in by the SVG 2D rendering model or by what HTML/CSS can render. Shadertoy code has performance cliffs. To make this efficient, it should use an extended version of Raph Linus's GPU accelerated rendering architecture: https://raphlinus.github.io/rust/graphics/gpu/2020/06/13/fast-2d-rendering.html Briefly, there is a display list of primitives loaded on the GPU, the viewport is partitioned into tiles, and each tile renders only primitives visible in that tile. Cross platform means Linux, Windows, MacOS, Android, iOS and web via WASM and WebGPU. Anybody want to help build this?
c
@ikrima I'm using NanoVg for 2 reasons; firstly it is simpler than ImGui for rendering basic primitives, secondly it has better gradient pattern support (last time I looked); and I'm using that for subtle effects here and there. NanoVg needs only a few lines of code to draw stuff, ImGui needs significantly more for custom. Glad to hear you are using Zep; I haven't given it enough love lately; but I will shortly be doing another round of bug fixes. If you have a screenshot of it in-situ, would love to see.
I heard out 'Lager' just yesterday, sounds like an interesting project.
m
So your guys recommendations are to learn more C?
c
There are language wrappers around all this stuff (maybe not much for shader code which is very c-like). So it's not essential; but I'd imagine a low level 3D coder would have an easier time with C/C++.
d
I personally use C++, since I'm doing low level coding, and all of the graphics libraries that I need to use are written in C++. There is also a graphics programming community using Rust, and they are doing some cool things, but it's tiny compared to C++.
s
If you're doing low level graphics programming C or C++, followed by Rust, followed by C# are probably your best options just in terms of ecosystems, platforms you can target, examples available, etc.
you can do other languages of course
js is probably better than most, but the lowest level you can go with js is WebGL\WebGPU
p
Hi! I've got an updated answer to an old, but interesting question: I'm thinking of running skia in the browser (that's the stack figma uses). It's quite accessible via their 'canvaskit': https://skia.org/user/modules/canvaskit
👍 5
c
This looks great, very keen to stress test it
m
does it provide some extra functionality not exposed by browser's canvas? because afaik browsers use skia for the canvas implementation?
p
Yes! @Mariano Guerra . One critical thing that I've been missing is way more control over text rendering. You can measure the text size, find the position at which to place underlines, get the caret index for clicks, etc.
👍🏽 1
Those things haven't been standardized for canvas, yet. All there is for canvas is measuring text width (but not height), and optionally giving a desired maximum width for text layout, but no control over whether to justify text, left or right align it, etc.
(why do all my sentences end with etc.?)
j
Actual text flow within a canvas-like API with real multilingual text shaping (using Harfbuzz) is a pretty big extra. It's also interesting that if one uses Skia in the browser, the API is then the same for native, allowing code reuse. Lastly, there's this quite cool idea to serialize Skia API calls on a remote server for display on a local machine (sort of like a vector version of what X's network transparency).