add bar healthbars.
This PR is mainly to create discussion on the future of Zero-k healthbars.
I am starting to understand this I need a lot more time. I have no background on GL shaders, so this is new to me. How do we profile this to compare it with jK healthbars? I would assume bar healthbars would run faster as the rendering should be parallelized on the gpu.
There is some sort of "Widget Profiler" widget available via Alt+F11, it is vrey flawed though. The shader approach may be an order of magnitude faster and visible there anyway, hard to tell.
For proper, accurate profiling there's Tracy https://beyond-all-reason.github.io/spring/development/profiling-with-tracy but that one requires adding tracy scope points all over gameside code (it's free perf-wise in non-tracy engine builds but clutters up the code a bit) which looks like this https://github.com/search?q=repo%3Abeyond-all-reason%2FBeyond-All-Reason%20tracy&type=code
Tracy is a good subproject, one that probably wants to be done before any large profiling efforts. I didn't know it required manual scoping though, that sounds like a lot of legwork. So perfect for a PR.
On GL4 healthbars, I think we can safely assume that they are much faster than jK bars. The tricky part will be using the tech to make something that fits ZK.
Editing the lua should be easy. Just copy the kj "getters" into the bar health bars, though it does handle them differently, keeping track of the status, similarly to how we do morph. I was thinking of doing something similar so units that are no longer in Los can have outdated health bars. That is a separate feature.
@GoogleFrog Do you want me to work towards replacing the jk health bars and experimental gui_healthbars with bar healthbars?
Yes, that would be good. The existing widget shouldn't be touched, unless perhaps you want to make a shared config file that controls both widgets. We'll probably want to use the existing widget as a shaderless fallback. The unused shader widget looks removable.
Data is passed to to the shaders using struct SUniformsBuffer{...vec4[4] userDefined;}. What I understand, each unit receives their own SUniformsBuffer, meaning we can only pass 17 data points (4 for each vec4 + health which is passed in a different field of the buffer).
currently we have 22 bars, so we need to share some channels. This is what I propose:
(*) health (different field in the buffer)
(0) morph, reclaim
(1) building, resurrect
(2) paralyze
(3) disarm
(4) slow
(5) reload
(6) dgun (currently dgun and reload are the same. I want to separate them.)
(7) teleport, heat, speed, reammo, jump, goo, capture_reload, ability, stockpile, capture_reload, shield
(8) teleport_pw?
(9) capture
(don't import) water_tank
Any issues with using the proposed channels? I overloaded slot 7 with unit specific bar, which I believe no unit shares. Any known collisions (current or future) with this proposal?
I may swap the numbers around and what gets paired with reclaim/resurrect.
Some notes:
- campaign commander can have jump and shield at the same time IIRC.
- modders can add any combination from channel 7 (up to all of them)
- Perhaps fallback to old style bars when this is the case?
- Could reserve say 2-3 bars and draw the first 2-3 found abilities, though see below
- Or ask engine to provide more room.
- remember some channels will need to be reserved for migrating various other rendering to GL4:
- whether a unit is selected (for selection shapes)
- cloak shader
- construction shader?
- tint, glow?
- others?
I didn't realize that the uniform was shared between all shaders. That makes things much harder. If this is the case, I feel we should have a widget that caches and updates the uniform for all unit status. Other widgets can read the cache directly (for non shaders) or relay on the widget to update the uniform for their shaders. Once I get all the bars working, I can split this widget. Current working bars: health, shields, paralyze (percent and duration both work).
Perhaps what we need is a uniform that tells the shader which bars are being drawn (via a bitmask?), and then four or five uniforms that contain the data to draw in each case.
I think we can wait until we are closer to running out of channels before we resort to a bitmap of what the values are. We are using just over half. I think other shaders will need the status provided anyway. Most of the other shaders Sprung mentioned can easily use the status provided by the bar, or overload one already in use. If we want to flash bars based on unit selection and command, that info will also need to be sent.
Connected more bars. The remaining bars to connect are: Morph, Reload, Dgun, Teleport, Ability, Stockpile.
I've been thinking there should be a stable before Christmas, but after the tournament tomorrow. This PR is too large and late to get into that stable, but I should be able to look at it shortly after. We will want some sort of solid handling of which healthbars are enabled. Eg, setting the default to be disabled for the old bars won't disable them for existing players.
I think there should be a setting for which bar the player wants enabled, and a fallback that enables the old bars if the player has insufficient shader support. The new setting should be a strong enough source of truth to disable the old bars for existing players.
I agree, this is too large to be ready in a few days.
I do plan on adding a bar style selection option. When I do this, I plan on making a plain shader less option. With this option, we can remove the jk bar widget.
I have grand plans for the bars. The difficulty is deciding what is mvp.
MVP IMO:
- Connect all bars.Remaining:
- Morph (done just not commited)
- Reload
- Dgun
- Teleport
- Ability
- Stockpile.
- some options
- style
- basic bars (shaderless)
- bars (current shaders)
- size/position
- when to hide
- style
- artwork or at least color for all bars so you can tell them apart.
- Bug fixes
- 100% text is drawn as 0%
- 0% shows a bar the size of both round corners. (Probably just hide the bar for mvp, and deal with it later)
- Resolve shader licences or rewrite them.
So there is still a lot to work on before this is ready.