Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Textures and skinning. #17
This is not really an issue, but more a suggestion about the library. I wanted to open the discussion with you before trying to implement something and send a PR. Let me know what you think!
I noticed the handy system to change colors per call using the PushStyleColor/PopStyleColor. That made me think about adding a PushTexCoords/PopTexCoords. If I'm correct every draw call that is not a text have texcoords that point to the upper-left corner of the font texture atlas, where a white pixel allow everything to get coloured correctly. Adding the pushpop methods I'm suggesting would allow to bypass this system and specify the texture coordinate of a custom skin. Allowing the library to render widgets with a much more customisable and complete style. At the same time it will continue to leverage the texture atlas and have only one texture binding for the whole batch of draw calls. The PushTexCoord would allow to specify the position of the skin in the atlas, and the PopTexCoord will at some point come back to the default notexture (0,0).
To be able to properly texture the different rectangles, I guess that it means that we will have to double the number of vertices per rectangles (to properly scale the texture at the corners). This can probably be done in the fragment shader without changing the number of vertices.
Except for this last bit, I think it would be a relatively easy and awesome feature to add to the library. Skinning is never totally required for a gui library but when well designed, it definitely push it to the next level.
So that was my random thoughts about your already really nice library!
I had some thought about the feature. My intuition is that if you go down the route of trying to skin the interface it will end up being more complicated than just passing a set of UV coordinates.
So while it is perfectly possible, at the moment I don't think it is in the best interest of the library to pursue this route. If you still want to give it a try in a fork I'm curious to hear about where you get it to, and I can provide some assistance. I'm not sure how a meaningful relooking can be performed with just a simple set of UV coordinates.
As a side thought. I think one of the value of ImGui is also to enable quick iterations and empower individual programmers who aren't usually excited by creating UI. Based on this idea my belief is that making the interface look too good may get in the way of supporting this goal. I want to allow people to add misaligned buttons and not feel bad about it. Similarly I decided against using icons because once you start expecting icons the lack of them becomes a blocker or suddently your interface feels odd and unfinished. But that is one way we use ImGui here and I'm sure there's other ways (we also write elaborate and sturdy tools but there are still pretty much all in "developer land").
PS: As you know it (based on your code) but some people may not, ImGui is already skinnable to some degree, that is, we can reconfigure colors and various sizes. I will try to provide screenshots of skinned versions to convey this information to newcomer. Additionally feel free to post screenshots of your tools if you have anything interesting to show!
On the other hand right after posting my first message, I quickly went to implement some very small additions just to assess what I was saying above.
You can find those small modifications on my fork here: https://github.com/simongeilfus/imgui/tree/skinning
Nothing fancy, just 2 uv's to grab the corner of a quad I added in the texture atlas. The colouring is made by your code and there's no scaling box or anything else. It's not even a proof of concept more a way for me to understand a bit better your rendering model.
True. But if I'm not wrong at the moment, most of them seem to be rectangle based and the circle based widgets should be easier to texture.
Maybe a really simple system could be enough to start and should work for both rectangles and circles. Here's an idea from the top of my head. Instead of storing the 8 texture coordinates (the dots in my drawing below), we could store only the opposite corners (red dots) and one extra float value for the distance to the inner corners (yellow dots). I guess most skin are probably going to be symmetrical and the center (between the doted lines) can probably be stretched in most cases.
That way we have only 4 Vec2 and 1 float to describe the texture mapping, we keep the 6 vertices that makes each quad and do the rest in the fragment shader (still have to think about a solution for this).
True! Having to deal with different states would complicate everything.
Indeed, that's always hard to define and I'm totally for not adding too much to the actual api. I actually love the fact that you don't have to size anything and that the layout options are very straightforward.
To be honest, the more I think about it, the more I think you're right in your first answer... I'll try to have a look at this a bit more this weekend and will let you know if I find anything interesting.
Thanks anyway for taking the time to think about it.
I'm closing this for now. Feel free to reopen later if you feel it's something you want to work on, but right now this would definitively be very low in the priority list.
However I'm happy to hear about skinning improvements, such as improving the Style system (I was thinking of using something with less parameters and relying on variance in HSV space, so e.g. button can be defined by their hue and the "hovered"/"active" colors are variants in HSV space).