Premise: I render "sprites" based on a constant vertex buffer and use UBO data to position and size the quads on-the-fly in the vertex shader. This approach is separate from text rendering and not feasible for text strings because of reasons I try to explain below.
I'm using a glyph texture and one quad per character to render variable-width text (this is a full tutorial on bitmap fonts).
To render a whole line, I have to position the quads appropriately, and this means I have to set vertices accordingly. The problem here is that the n-th character position depends on all preceding characters in the string. Because of this, I've abandoned the idea to use a constant vertex buffer and position/size quad information with an UBO. This approach would just move the problem from the vertex buffer to the uniform buffer without much gain but needless additional complexity.
The vertex buffer contains the quads for all strings and has a maximum total size (say, 1024 characters/quads). With
vkCmdDrawIndexedIndirect I can then render just the right number of characters/quads.
The problem now is that the vertex buffer as a whole changes every time a single string (or even a character in a string) changes.
Say the vertex buffer contains quads for these 3 strings:
You have 10 hit points.Press left arrow to move camera left.This door is locked.
If I now loose a hit point, I want to change quads to render these 3 strings:
You have 9 hit points.Press left arrow to move camera left.This door is locked.
10 becoming a
9 causes all vertices to shift, and requires an upload of the whole vertex buffer.
Now consider that generally, many strings will change often if not every frame, and thus I'll end up with a vertex buffer that is transferred from host memory to device local memory every frame.
I've read in several questions/answers here on SO and other sources, that updating vertex buffers every frame is not really very smart, so... what other choices are there?
Even something like
vkCmdUpdateBuffer wouldn't help, I'd still have to update on the average 50% of the buffer.
Should I maybe have two types of labels? Like "static labels" that change not very often (maybe once per second) and a smaller set of "dynamic labels" which are supposed to change every frame and are managed on a completely separate basis? Maybe this "semantic" separation is necessary? Or is there a source (tutorial, document, whatever) that explains better how bitmap fonts should be used?
Or, maybe, is there a way to use a constant vertex buffer and an UBO that is organized somehow in a special way that I'm not aware of (e.G. keeping dynamic strings towards the end)?
I could add a C++ function that measures/estimates how static/dynamic the strings are, or even add a "dynamicity hint" to string rendering like this:
renderText("fontname", "string", x, y, MEDIUM_DYNAMICITY);
Do these ideas lead to feasible/senseful implementations? Or do I risk spending days implementing something that won't yield much fruitfulness?