Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 03:39
    xland commented #312
  • May 26 22:18
    mikke89 labeled #314
  • May 26 22:17
    mikke89 commented #314
  • May 26 17:15
    nimble0 commented #314
  • May 26 14:39
    Frenda starred mikke89/RmlUi
  • May 26 14:00
    Radagan starred mikke89/RmlUi
  • May 26 13:41

    mikke89 on master

    Update readme.md (compare)

  • May 26 12:13
    mikke89 commented #312
  • May 26 01:50
    xland commented #312
  • May 26 01:48
    xland commented #312
  • May 24 14:10
    mikke89 milestoned #220
  • May 24 13:12

    mikke89 on backends_refactor

    Update comments (compare)

  • May 24 12:03

    mikke89 on backends_refactor

    Move the global shortcut handle… (compare)

  • May 24 11:56

    mikke89 on backends_refactor

    Add DL libraries to CMake Format SFML Start refactoring SFML/GL2 back… and 2 more (compare)

  • May 24 10:27
    mikke89 labeled #318
  • May 24 10:27
    mikke89 labeled #318
  • May 24 10:27
    mikke89 commented #318
  • May 24 10:20
    mikke89 commented #317
  • May 24 10:19
    mikke89 closed #317
  • May 24 10:19
    mikke89 commented #317
bovacu
@bovacu
How did I miss that?? Thank you so much!!
Michael Barkholt
@barkholt
I have created a SDL_gpu backend if it of any use anywhere
bovacu
@bovacu
Yes send it to! I'd like to see it
bovacu
@bovacu
@mikke89 I just got the library integrated into my SDL engine, it works like a charm! Thank you so much for the help!
Michael R. P. Ragazzon
@mikke89
@barkholt Would be great to have a look. Is it open source? If so I'll happily add it to the thirdparty resources.
@bovacu Nice, very cool! Send us some screenshots when you have something to show :)
bovacu
@bovacu
yeah sure!
Michael Barkholt
@barkholt
@mikke89 @bovacu , I'll create a repository for it and notify you :)
Michael R. P. Ragazzon
@mikke89
Great, looking forward to having a look :)
Michael R. P. Ragazzon
@mikke89
Hi all. I made a post regarding the progress towards RmlUi 5.0: mikke89/RmlUi#307
Let me know whether you like the changes or have any other feedback :)
Paulo Coutinho
@paulocoutinhox
Hi. There is any port for Android/iOS?
Michael R. P. Ragazzon
@mikke89
@paulocoutinhox I don't know of any open source render backends for those platforms, you will have to make that yourself.
Paulo Coutinho
@paulocoutinhox
@mikke89 thanks
maybe you can transfer rmlui to a organization in github to make it more "standard", like librocket, ex: github.com/rmlui/rmlui
Michael R. P. Ragazzon
@mikke89
Hm, yeah, it's really just me maintaining the library right now so I don't see the point at this point in time. Maybe something to consider for later though, I appreciate the suggestion.
Jovan Batnožić
@jbatnozic
Hello everyone,
A few days ago I started learning RmlUi (I spent a lot of time researching GUI libraries for C++ and this far this one is the best I saw, congratulations!), and I had a question:
Since my main project is SFML-based, I followed the SFML-sample to integrate it all together, and it worked. However I saw that there was an option to also couple it all with GLEW. Now, my question is in what situation do I want GLEW? What does it do in RmlUi context? Does it make it run faster? Have more features? I couldn't find an answer to this anywhere.
Giulio Camuffo
@giulio.camuffo:matrix.org
[m]
glew is just a function loader for opengl
it's not going to make anything faster. if you don't need it don't think about it
Jovan Batnožić
@jbatnozic
Well I'm asking because in RendererInterfaceSFML class (in the sample) a lot of functions end up not implemented if you don't have GLEW, but I couldn't figure out if I needed them or not.
Michael R. P. Ragazzon
@mikke89
@jbatnozic As far as I can see the only difference is that with GLEW enabled the renderer also implements CompileGeometry. This shouldn't really make any functional difference, but may help with performance.
Thanks for appreciating the library, hope it works out well for you :)
I'd recommend that you also check out the backends branch, which will be merged to master soon: https://github.com/mikke89/RmlUi/tree/backends/Backends
In particular, some issues with the SFML backend has been fixed there, and it should hopefully be a bit better organized.
Jovan Batnožić
@jbatnozic
Wow, this "backends" branch looks great and really clears up some things :)
Thanks for the help!
Michael R. P. Ragazzon
@mikke89
Makes me happy hear that I'm on the right track with this approach, thanks!
Jovan Batnožić
@jbatnozic

Hello again, @mikke89
Last night I tried to use the code from backends branch for a few hours and here is my feedback on it (I understand it's not finished yet, but anyway):

  • First let me state that the things I tried were: The SFML platform/backend, the GL2 renderer and all was compiled on Windows with MSVC.
  • I liked (and understood) the idea of renderer/platform/backend separation and I think the Readme is well written.
  • However, I found the implementation lacking in several ways:
  • Compared to the "old" SFML sample, which is quite clear, both because it has a complete example to look at, and because the concept of implementing and registering a SystemInterface and RenderInterface is simple and straightforward, the new code was far too confusing. The interface implementations are unhelpfully intertwined with static/global functions and objects (I'll come back to this later). In the end I wasn't able to make a functional program loop.
  • Coming back to globals: There are far too many singletons. 1. They make the code difficult to understand (because tons of functions now access whatever object they want, instead of making it clear from the parameter list what they are supposed to access). 2. They make the code difficult to use. I didn't know which Initialize() functions to call, which not, and in what order. Everything is available everywhere but the dependencies are only implicit. Furthermore, as a user of RmlUi, I don't want the Backend and Platform layers to open and manage a window (or any other resource except the GUI itself) for me. I already have a runner, a Window and everything, I just want RmlUi to be 'plugged in' into my existing architecture and only draw the GUI onto a render target which I choose, when I tell it. The old SFML sample is great because it does exactly that.
  • Final point: The code isn't even correct. The SFML platform has a static sf::Window object. Apart from the fact that I want to use my own window (and even worse, what if I want 2?), the problem is that upon initialization this Window calls some OpenGL functions, which rely on other static objects. As we know from the C++ standard, the order of initialization of static objects is not defined (and is very unpredictable), and in my case the constructor of this Window crashed the program before it even got to main().

Conclusion: Currently I'm very inclined to stay with the code from the old SFML sample. The only significant difference (that I could see) was the renderer implementation (though I don't know enough about OpenGL to notice the practical difference, because the old one also seems to work fine). And apart from that it's just very understandable. Create the SFML system interface, create the SFML renderer, point them to your window, and you're good to go. There is currently no advantage to upgrading (for me at least).

Sorry for being harsh but I hope you find this useful :)

wh1t3lord
@wh1t3lord
I agree about singletons. It is better to not use antipatterns for developing, so it is better to remove all singletons.
Jovan Batnožić
@jbatnozic

It's not that singletons are an antipattern in and of themselves, but IMO they should only be used in two cases:

  • For constant data (we could argue that global const objects are singletons in some sense; this case isn't that interesting anyway).
  • For stuff where it doesn't even make sense to have 2 of them in the same process. For example, let's say you want to have a functionName -> function mapping. Well, by nature of C++, functions are global to the process, and unique (unique addresses at least), so a singleton would make sense here.

And whatever you do, don't make singletons depend on each other. There is no defined (de)initialization order. I learned this the hard way.

Michael R. P. Ragazzon
@mikke89

@jbatnozic Thanks a ton for the feedback. As far as I know you are the first one to take a solid look and trying to implement it into your own project. The fresh set of eyes is very valuable. Keep in mind though, I'm just trying my best here. Nothing is set in stone yet, and it's still early days with very few comments and documentation. I'm interested in taking this feedback and trying to figure out a constructive way forward.

  • Yeah, I understand there are too many initialization functions. Their order is not clear, and they generally result in hidden state changes (globals) which is not good. Some ideas to improve this:
    • Would it be better if we put most or all of the state in the interfaces? Then any initialization can happen in the constructor. Should we move all the renderer and platform functions to their respective interface as well?
    • I don't want to put too many details in the renderer and platform headers (ideally I'd like it to not require any platform or render-specific headers). We could use the pimpl-idiom, what do you think?
    • Some things are inherently singletons though, e.g. there is only one OpenGL state and we only need to call the loader for these functions once, and the unloader exactly once. How do we deal with this?
  • Currently there is an indirection to the backend which always goes through the shell. This is mostly just a feed-through, I realize this may make it harder to understand basic examples. Maybe we could rewrite the samples so that they call directly into the backend? And then the shell is reserved for more common functions specific to the samples.
  • Do you have suggestions for how to store the state of the backend?
  • The SFML backend in particular. I don't have too much experience with SFML, so getting outside help and feedback is appreciated. I'll certainly fix the sf::Window object, I didn't know that the window had any heavy initialization. The OpenWindow function was meant to be completely optional and mainly for something quick and easy to get going, and as a place to put common code needed for our samples. Maybe we want to move it entirely into the backend. I'll certainly add a way to hand a pointer to any user window, and I'll happily take any specific suggestions.

Thanks again for your feedback, and I want to say that I absolutely agree with your assessment: "I just want RmlUi to be 'plugged in' into my existing architecture". Yes! I'm totally on board with that, and that is my goal too. If you tried to copy out the GL shell and native platforms previously, that was a horrendous task. The SFML sample previously was in a different place because it was completely self-contained. This makes it a bit simpler, but it's obviously not sustainable to do this for every sample and backend combined. In some sense I want to be able to make all the other backends just as easy as the SFML sample was and if possible even more-so. And making it re-usable means we all benefit with improvements. I hope we can get there with more iterations and more feedback.

Jovan Batnožić
@jbatnozic

Keep in mind though, I'm just trying my best here

I know, and I'm not trying to bash, but to help :)

There are a lot of questions here but I'd like to start with this particular one:

Do you have suggestions for how to store the state of the backend?

I'd expect to be resposible for the lifetime of the backend myself. What I mean by that, is that I'd instantiate a Backend object of some kind, and then it would contain the System interface, Backend interface input converters etc.

Jovan Batnožić
@jbatnozic
Surely I'm missing some of the bigger picture and the problems you're coming across implementing all these various backends, BUT, here is my take from the user perspective:
  • The template given here (https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/main_loop.html) is basically what I expect from a library like this. I provide my own loop, window, input etc and in turn I tell the library when and where to render the GUI. That page offers good explanations so it's clear what goes where. (IIRC, Dear ImGui has a very similar model).
  • Is there a reason these backends can't be built on top of that idea? At the start of main() (in that example at least), You'd instantiate one of the Backend objects that you included in your project and compiled, and then it would provide something like getRenderer() and getSystemInterface() and probably a few more functions to set viewport and similar (not sure about this). You could provide some convenience functions together with it, like for converting between SFML events and RmlUi inputs and such operations, but IMO it's okay to leave them a little DIY. Instead of RmlUiSFML::HandleEvent(const sf::Event& event); you could have RmlUiSFML::HandleEvent(Rml::Context& context, const sf::Event& event); and since the user has their own loop and window etc. (but also provides his own Rml::Context) he should know when to call this.
  • Everything else, that you mentioned is optional and just for user quick start, IMO, should be separated. Not mixed with the "main" code and left for us to wonder what's crucial and what's optional.
Jovan Batnožić
@jbatnozic
On an unrelated note, this page (https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/documents.html) mentions an "instancer" a few times, so I wanted to ask, is it a typo and is meant to be an "instance" (which would make sense in those sentences), or is an "instancer" a real thing in RmlUi and I just missed what it is?
Michael R. P. Ragazzon
@mikke89

Thanks, that is some great feedback. I'm having many ideas based on your suggestions.

That main loop example is something I wrote on how I expect people to actually implement it in their own project. And you're right, this example would be nice to replicate in the samples. It's not trivial though since there is added complexity due to the necessary abstraction of all the different backends. But I do agree with you that we should be able to get closer to that example, I probably made some wrong abstraction levels here. I guess it's also okay to duplicate more code between the samples.

By the way, my initial idea was that the backend code (the actual glue code between renderer and platform) is something you would copy-and-paste into your own project, and sort of transform that into something like the main loop example. I see now that this backend code is a bit too fragmented to make that a trivial task, it takes more effort than say the old SFML sample. But perhaps if we make a better abstraction level we could have people re-use the backend as well.

I'll try to make some improvements and play around with the abstraction level. It would be great if we could follow up when I have more to show. Thanks again, your feedback is very much appreciated.

On an unrelated note, this page (https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/documents.html) mentions an "instancer" a few times, so I wanted to ask, is it a typo and is meant to be an "instance" (which would make sense in those sentences), or is an "instancer" a real thing in RmlUi and I just missed what it is?

Instancer is correct here, it is talking about element instancers for custom elements, you can read more about it here: https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/custom_elements.html#creating-a-custom-element-instancer

Jovan Batnožić
@jbatnozic

It would be great if we could follow up when I have more to show.

Don't worry, I'll stick around. I also need this to work for my own needs so I'll be glad to help.

It's a small market for C/C++ GUI libraries, and of those: some are archaic or not developed anymore at all, some are ugly and intended only for tools development, some have a hell of dependencies and are impossible to integrate, and some are simply too underdeveloped to be flexible enough. Noesis looks great but requires a licence, and ultimately RmlUi (What does Rml stand for anyway?) was the only one I found that had none of those problems. And as a bonus treat there was a Conan package for it as well so setting up took only minutes :D

Michael R. P. Ragazzon
@mikke89

Sounds good!

Yeah, it seems that this library hits this sweet spot for many people. I can resonate with that description of yours, I also ended up here after doing some research. At the time it was libRocket, which had already stopped being developed at the time so I started implementing my own fixes and desired features. Then the fork started gaining popularity and here we are. Rml stands for Rml Markup Language :P

Sygmei
@Sygmei

Hello there !

Saw this library a while ago and thought "hey, it's pretty interesting"
Realized today after reading this post https://www.reddit.com/r/cpp/comments/uv3cqd/is_there_any_mitbsd_licensed_ui_framework_for_c/ that RmlUi supports SFML and Lua integration, it's awesome !

https://tgui.eu/ is also a good solution for my needs but being able to leverage HTML for making an UI and scripting with Lua sure seems appealing :)
(It's for a game engine ui btw)

Michael R. P. Ragazzon
@mikke89
@Sygmei Hey, welcome! Always happy to see new people here. Feel free to try the library and let us know if we can be of any help :)
Jovan Batnožić
@jbatnozic

@mikke89
Ultimately I ended up making my own SFML backend, based on what I believe is a reasonable API for users. And because it was such a nice, small, self-contained example I put it up on GitHub so maybe it gives you some inspiration for your backends. <link>.

(note: "SPeMPE" is the name of a larger project where I plan to move this and that's the reason why everything is under that namespace.)

I couldn't get the geometry compiling in the renderer to work. (my OpenGL skills are zero)
Jovan Batnožić
@jbatnozic
I wasn't very generous with comments so if you're confused about something you can ask.
Michael R. P. Ragazzon
@mikke89
@jbatnozic Ah, that's great. Thanks for showing the code, that will be a nice reference to keep in mind. I'll try to find some time to work on the backends again soon.
Yeah, to enable geometry compilation you may need to load extra OpenGL functions, that's what GLEW is used for in the old SFML sample.
Sygmei
@Sygmei

Thanks @mikke89 :)

Quick question, did someone already tried to use RmlUi with CSS frameworks like Bootstrap or Bulma ?

Michael R. P. Ragazzon
@mikke89
Not that I know of, no.
Michael R. P. Ragazzon
@mikke89

Hey. I've made some efforts to cleanup the backend interface and in particular the SFML/GL2 backend. See the loaddocument sample, the backend interface, and the SFML/GL2 backend, plus the underlying renderer and platform.

Here are the main changes and rationale behind them:

  • I figured it's better to make a light-weight backend with a minimalistic set of functionality, just enough to make our own samples run. Users will most likely have their own specific needs. Rather than trying to make an interface suitable for everyone, which would always have reasons to expand and eventually lead to bloat, we make a light-weight interface which takes less effort to understand and modify.
  • Since the backend interface is not intended to be re-usable, I find it is better to be explicit about function calls (initialize/shutdown) rather than relying on a RAII wrapper around the backend resources. This does lead to some global state but this is now clearly tied directly to the lifetime of the backend, including the window which is created during initialization.
  • With that said, I've removed all global state from the renderer and platform layers, and moved them to their respective interfaces which again is now tied to the lifetime of the backend.
  • A new separation between sample code, backend and shell. The main loop is now actually located in main() :) Calls to the backend are now always done from the sample code, while the shell merely acts as common functionality for the built-in samples that is most likely not needed for other users.
    • Keep in mind that we obviously cannot move the SFML event handling directly to the sample code and main loop, as that needs to stay platform agnostic.
  • I cleaned up a lot of things and added a lot of comments to make usage and intentions clear. In particular, users can hopefully better understand what is optional, what is intended to be re-usable, and what is intended to be copied into their own application.

Let me know what you think about this direction :)

@jbatnozic