The class now supports incremental filling, multiple fonts, texture
arrays, removes all reliance on STL containers and is finally properly
documented.
To avoid complete breakage of every use, as much as possible was kept as
deprecated APIs -- in particular the reserve() with the nasty
std::vectors, the insert() that assumes a 2D cache and a single font
and textureSize() that returns a 2D vector. Those behave the same as
before, but will assert if the cache is an array or contains more than
one font.
On the other hand, begin() / end() access with std::unordered_map iterators
(ew!) was removed as the internals simply aren't a hashmap anymore. The
image() that returned an Image2D is now used to fill the glyph cache
instead of querying its potentially processed contents, and returns a
MutableImageView3D. I considered keeping it and adding sourceImage()
instead, but such naming turned out to be too inconsistent. For querying
processed image data (such as with the distance field cache) there's a
new processedImage() query, guarded by new GlyphCacheFeature bits -- if
both ImageProcessing and ProcessedImageDownload is set, it can be used
to retrieve the processed image (so, similar as ImageDownload was
before), and if neither is set, the cache contents are queryable
directly through image(), without needing any special support from
the GPU API.
Existing code is updated only in the minimal way possible to ensure that
no serious breakage was introduced by reimplementing the deprecated APIs
on top of the new backend. Porting away from deprecated APIs will be
done in next commits. The GlyphCache and DistanceFieldGlyphCache have
their public API kept intact for now, as a similar rework will be needed
for them as well.
Additionally, the MagnumFont and MagnumFontConverter plugins aren't
compiling yet as they require substantial changes to deal with the new
glyph cache features. That is not the case with other plugins in the
magnum-plugins repository tho, for those the backwards compatibility
"just works". On the other hand, since layout of the AbstractGlyphChange
changed, I'm bumping the AbstractFont plugin interface version to
force-trigger a rebuild of dependent projects. Because I ran a stale
magnum-player binary, it worked without crashing or GL errors but just
didn't show ANY text whatsoever due to ABI differences, and I wasted
some precious minutes before realizing that a simple rebuild would fix
it.
Not that C++ STL and exceptions would be anything to take inspiration
from, but there's std::out_of_range. Python IndexError is also specified
as "index out of range", not "bounds".
About time this got done. This also has an XFAIL for the case where a
distance field image is processed with an offset, have to fix the
underlying issue in TextureTools first.
Also added a range assertion for the distance field image setter to
match what the abstract base does, together with a corresponding getter.
Allows the Font and FontConverter plugins be built without TARGET_GL
enabled. That was the last piece missing for making the magnum-plugins
repo completely GL-free.
103% of use cases use the returned value directly without checking, so
we might as well do the check ourselves. Added new function hasCurrent()
and added deprecated backward-compatibility conversion and -> operators.
Wow, that creeped to a lot of places.
Last dinosaur from the pointer age.
Yeah, sorry, I know, the enums are renamed for second or third time in a
row, first they were Image::Format, then ImageFormat, then ColorFormat
and now PixelFormat. But this time it's final and last time they are
renamed and now everything is finally consistent:
* ColorFormat::DepthComponent -- depth is not a color, thus
PixelFormat::DepthComponent makes a lot more sense.
* There will be PixelStorage classes, which will be stored in images
alonside PixelFormat/PixelType enums, making everything nicely
aligned.
* The GL documentation about glTexImage2D() etc. denotes the <format>
and <type> parameters as format and type of *pixel* data, so now we
are _finally_ consistent with the official naming.
I wonder why did I not choose PixelFormat originally. Anyway, the old
<Magnum/ColorFormat.h> header, ColorFormat, ColorType and
CompressedColorFormat types are now aliases to the new ones, are marked
as deprecated and will be removed in some future release (as always, I'm
waiting at least six months before removing the deprecated
functionality).
With pixel pack/unpack support it will be possible to create views onto
sub-images, renamed the class to reflect that.
The old Magnum/ImageReference.h and ImageReference types are now aliases
to ImageView.h and ImageView types, are marked as deprecated and will be
removed in future release.
The only places where they aren't absolute are:
- when header is included from corresponding source file
- when including headers which are not part of final installation (e.g.
test-specific configuration, headers from Implementation/)
Everything what was in src/ is now in src/Corrade, everything from
src/Plugins is now in src/MagnumPlugins, everything from external/ is in
src/MagnumExternal. Added new CMakeLists.txt file and updated the other
ones for the moves, no other change was made. If MAGNUM_BUILD_DEPRECATED
is set, everything compiles and installs like previously except for the
plugins, which are now in MagnumPlugins and not in Magnum/Plugins.
There will be many places (e.g. all
Platform::*Application::Configuration classes) where Version will be
used without Context (and all GL stuff brought with it).
Encourages vectorization and generic usage even more. Some functions
were rewritten to make use of the new features, resulting in shorter and
more readable code. This also fixes the annoying naming collision with
WINAPI Rectangle() function.
The old Rectangle is now subclass of Range2D, is marked as deprecated
and will be removed in future release.
Operators that are part of Vector are operating only with the same type
as Vector itself, operators for multiplying/dividing integral vectors
with floating-point numbers and vectors are now out-of-class and enabled
only for integer vectors. It allows better control (e.g. multiplying
integer and floating-point vector will _always_ result in floating-point
one). Thoroughly tested integer/FP operations and also reworked and
tested operator and funciton reimplementations in subclasses, both for
value correctness and result type correctness.
The testing is now slightly more sloppy due to inability to not pass any
Font or GlyphCache object. But it is actually better from user point of
view, as it is now impossible to do that by accident.
Makes some cases less consistent (and some convenience shortcuts
impossible), but goes well with the attitude "don't use pointer when it
can't be null".
Avoids some nullptr-related errors and leads to simpler implementation,
as we need to only handle ImageReference and BufferImage types. All
other Image classes are implicitly convertible to ImageReference and
implicit conversion works only with references, not with pointers. The
usage might be clumsy at this point, as Trade::*Importer classes return
pointer to Trade::ImageData which then needs to be dereferenced.
Hopefully introducing C++14's std::optional (or equivalent) might help
solve that issue.
Also removed "convenience" overloads for setting e.g. 2D subdata of 3D
texture. The convenience overload doesn't cover all subdata cases (only
XY plane, not YZ or XZ ones) and overly complicates the implementation.
This can be done in the future in Image classes themselves.
* Not requiring ARB_texture_storage, as Texture::setStorage() has
already implemented fallback.
* Not requiring EXT_texture_rg for single-channel texture on ES2, as
this extension might not be available everywhere (unlike in ES3
desktop OpenGL, where Mesa 8/9 with OpenGL 2.1 supports it), fallback
to Luminance in GlyphCache and RGB in DistanceFieldGlyphCache,
because Luminance might not be renderable everywhere.
* Re-enabled building of Text library in all ES PKGBUILDs.
* Older GLSL doesn't have texelFetch() and related things, working
around it by using classical texture() and normalized floating-point
coordinates. But that needs to have Texture::imageSize() passed,
which is not available in OpenGL ES, thus the user must specify it
explicitly there. On desktop OpenGL that parameter is ignored.
* Older GLSL doesn't have gl_VertexID, thus vertex buffer must be
created and vertex data passed expliticly.
* GLSL ES 2.0 doesn't have one-component texture format and
TextureFormat::Luminance probably isn't renderable anywhere, thus
TextureFormat::RGB should be used, although it is inefficient.
* Checking for framebuffer completeness, if not complete, nothing is
done.
* Re-eabled building of TextureTools library in all ES PKGBUILDs.
Solves another trivial choice (similar to the one with TextureFormat
etc. in 7de45c98b1), less typing and also
preparation for ARB_sampler_objects extension.
Advantages:
* The enums were large (600-800 lines) and they polluted the header,
now they are in separate files (except for BufferTexture, which has
the enum small enough to be left in the same file).
* Image classes now don't need to include OpenGL headers, as they were
needed only for the enum values. With advantage of C++11's forward
enum declarations there is no need to include the enum headers
anywhere in implementation, only when particular values are needed.
* The values are now less verbose:
AbstractTexture::InternalFormat::RGB8 // before
TextureFormat::RGB8 // now
* Resolved another "trivial choice" problem (thanks @JanDupal for
introducing this term to me): how to specify the format if there are
ten ways to do it (some being massively confusing):
Image2D::Format f = AbstractImage::Format::RGB; // too long...
Image2D::Format f = Image3D::Format::RGBA; // why 3D? this works?
Image2D::Format f = BufferImage1D::Format::RGBA; // wat?
It is even worse (and more verbose) with textures:
Texture2D::InternalFormat f =
CubeMapTextureArray::InternalFormat::RGB8; // this is allowed?
To have consistent naming this change was done also with
BufferTexture::InternalFormat (now BufferTextureFormat), although there
were no trivial choice issues and the enum isn't too large. But at least
it is now less typing.