It just binds a layer of it to a framebuffer internally so no shader
changes or extra construction flags are needed. Originally I thought
about making the input an array as well, but ultimately that just
doesn't make sense -- the processing would need to be done slice by
slice anyway and you don't want to allocate the whole excessively sized
texture just for it to be used once, and only a part of it every time.
At first I was like "ugh this is BAD" and made the texture and output
framebuffer resident. Then I realized that for the upcoming array
variant I need to reattach the output texture every time, so having a
resident framebuffer was not that useful anymore, and then I realized
that having a resident texture but calling setImage() on it is not any
better than making a temporary one every time, and making the resident
texture significantly larger just to accomodate any size that could
possibly be processed was even worse. So, ultimately it's just these
comments.
Right now it didn't really matter as the only subclass making use of
this was DistanceFieldGlyphCacheGL in which the processed format was
always R8Unorm, nevertheless it's better this way, and makes it work
with 16-bit output and such that might get added in the future.
There's really no need to allocate 56 MB of image *and* texture data
just to verify the constructor is called. This makes the Emscripten test
OOM and there's really no need for that.
Was postponed in 8168a06bab because the
needed DebugTools::textureSubImage() was not there yet. Now I have (a
simplified version of) it done, so use it.
Wanted to add a proper variant that reads all layers at once into an
Image3D, but that requires the Image APIs to be made less crappy first.
So it's just this for noew because now I badly need it for
Text::DistanceFieldGlyphCacheArrayGL tests.
I fixed some minor English crimes in the method docs and then realized
this is all just bad and the utter uselessness and lack of information
led to way too many confused questions over the years. So let's do it
properly, finally, ugh.
Same approach as done e.g. in the Ui library -- taking advantage of the
base class already allocating an internal state struct, deriving from it
and putting the state there instead of either having it as a class
member (at the cost of extra header dependency) or as a separate state
struct (at the cost of extra allocation). The only downside is a virtual
destructor in the state struct, but compared to the alternatives that's
completely fine.
I think I tried this at least once in the past already, and failed the
same way. So just document that it's missing to prevent me from wasting
time on this again in the future.
The MAGNUM_GL_ABSTRACTSHADERPROGRAM_SUBCLASS_DRAW_IMPLEMENTATION() and
MAGNUM_GL_ABSTRACTSHADERPROGRAM_SUBCLASS_DISPATCH_IMPLEMENTATION() *is*
documented so that one stays not underscored.
One obvious use case is rendering a text that's just a bunch of \n
characters. With the current code, it would result in a completely empty
rectangle no matter how many newlines there would be, which isn't right
because -- even if nothing is actually visible -- it would break
anything that relies on the bounding rectangle for alignment and
positioning of other content.
Another case is for example the Ui library, which -- once ported to
use the new Renderer instead of the lower-level APIs -- wants to use the
bounding rectangle for cursor and selection positioning. And if it would
be empty for empty text, it'd mean empty input boxes would have
invisible cursor. Not good.
The old Renderer implementation seems to have handled this correctly --
but in f3d6ab4916, when porting to the new
APIs, I discarded that from the test, thinking it was some unnecessary
behavior. It wasn't, it was just never tested directly so I forgot it
was needed.
This was quite nasty, a multi-day effort to trim this down and then
increasingly growing disappointment as I discovered it was affecting
basically any use of the API.