Closed tjpalmer closed 2 months ago
For example, I added extra dbg and get printouts like this on each frame:
[native/src/text.rs:137:9] text = "Score: 800"
[native/src/text.rs:137:9] &align_x = Left
[native/src/text.rs:137:9] &align_y = Top
[native/src/text.rs:137:9] left = 10.0
[native/src/text.rs:137:9] top = 10.0
[native/src/text.rs:137:9] size = PhysicalSize {
width: 800,
height: 600,
}
[native/src/text.rs:137:9] text = "Time: 600"
[native/src/text.rs:137:9] &align_x = Right
[native/src/text.rs:137:9] &align_y = Top
[native/src/text.rs:137:9] left = 639.67773
[native/src/text.rs:137:9] top = 10.0
[native/src/text.rs:137:9] size = PhysicalSize {
width: 800,
height: 600,
}
And if I change the order and draw the right-side text first then the left-side, I no longer see the right-side text, but the left-side looks fine.
What's probably happening is that prepare
is overwriting the previous prepare
'd text before it's actually submitted to the GPU.
The way prepare
and render
are meant to work together is roughly something like this:
prepare
to give it a chance to upload any GPU resources needed for rendering laterSo normally you'd only call a renderer's prepare
once per frame, and ideally before you start a render pass. Then once you start a render pass, you'd call render
once.
Obviously there are some trade-offs there though. For example, sometimes it's more convenient to use multiple renderers so you can call prepare
on each of them with their own lists of text areas to draw. You could check this by having two text renderers.
Thanks much for the thoughts! Is caching separate per renderer?
I might also try just separate passes for each text draw. I'm not expert on gpu things, so I don't know all the pros and cons.
Is caching separate per renderer?
The caches are shared between renderers (e.g., TextAtlas
and SwashCache
are passed to prepare
), but assuming they're being updated every frame sometimes it can be slightly more efficient to have one text renderer instead of two. If it's only a handful of text renderers I probably wouldn't worry about having one renderer vs multiple - you could just do whichever is more convenient.
I might also try just separate passes for each text draw. I'm not expert on gpu things, so I don't know all the pros and cons.
A few passes could be fine but generally you should try to keep your rendering to as few passes as possible. You can follow the same rough structure for everything you want to render:
prepare
at this pointrender
For the first gather step, sometimes people like to queue objects to be drawn, or query them all somehow. The important point is that you're trying to prepare all GPU resources before you start the render pass. This page on the wgpu wiki https://github.com/gfx-rs/wgpu/wiki/Encapsulating-Graphics-Work might also be a good reference.
Thanks much for the additional advice! I'll think about better structuring. Meanwhile, looks like using multiple renderers does do the trick. (And multiple passes doesn't change the described behavior.) Thanks again.
Thanks so much for the great work on glyphon! I have an issue in this code where I use the same text renderer in the same frame to draw in multiple places. The calls are driven from a separate app, and here's the code where the multiple draws originate. The left-aligned "Score" text is clipped off:
But if I comment out the second draw and keep only the first, it seems to render correctly:
Also, if I print out numbers (such as with
dbg!
in the Rust code), they look as expected. Any guesses what I'm doing wrong here or how to troubleshoot?