Similarly to what's now done with NoInit tags for Containers::Array and
all math types such as Vector, there's now NoCreate tag for creating
wrappers without actually creating the underlying OpenGL object. The
instance is then equivalent to moved-from state. Useful to avoid
needless creation/deletion of OpenGL object in case you would overwrite
the instance later anyway:
Mesh mesh{NoCreate};
std::unique_ptr<Buffer> indices, vertices;
std::tie(mesh, indices, vertices) = MeshTools:compile(...);
Useful for squeezing out last bits of performance, e.g. in this case:
Vector3 a;
a[0] = something++;
a[1] = something++;
a[2] = something++;
In the code all elements are first zeroed out and then overwritten
later, thus it might be good to avoid the zero-initialization:
Vector3 a{Math::NoInit};
a[0] = something++;
a[1] = something++;
a[2] = something++;
This will of course be more useful in far larger data types and arrays
of these.
Previously only matrices allowed to be created either as an identity or
zero-initialized. Now all Math classes support that, including (dual)
complex numbers and quaternions.
Some classes are by default constructed zero-filled while other are set
to identity and the only way to to check this is to look into the
documentation. This changes the default constructor of all classes to
take an optional "tag" which acts as documentation about how the type is
constructed. Note that this result in no behavioral changes, just
ability to be more explicit when writing the code. Example:
// These two are equivalent
Quaternion q1;
Quaternion q2{Math::IdentityInit};
// These two are equivalent
Vector4 vec1;
Vector4 vec2{Math::ZeroInit};
Matrix4 a{Math::IdentityInit, 2}; // 2 on diagonal
Matrix4 b{Math::ZeroInit}; // all zero
This functionality was already present in some ugly form in Matrix,
Matrix3 and Matrix4 classes. It was long and ugly to write, so it is
now generalized into the new Math::IdentityInit and Math::ZeroInit tags,
the original Matrix::IdentityType, Matrix::Identity, Matrix::ZeroType
and Matrix::Zero are deprecated and will be removed in the future
release.
Math::Matrix<7, Int> m{Math::Matrix<7, Int>::Identity}; // before
Math::Matrix<7, Int> m{Math::IdentityInit}; // now
I wanted to preserve the parameter-less constructor of tests, but WINAPI
requires fairly ugly entagled set of functions, passing HWND around,
which required storing it in a global var and hoping it is properly
initialized when querying it for it to be passed to application
constructor.
When this was done, it was now fairly easy to support passing also
argv/argc to application constructor, which in the future will enable
selective disabling of extensions for even better test coverage.
This however needed slightly different main() function and thus we now
have MAGNUM_GL_TEST_MAIN() instead of CORRADE_TEST_MAIN(). Using the
latter will result in an assert inside std::optional.
In OpenGL ES 2.0 there is EXT_draw_buffers, which I overlooked somehow,
so I added it to extension list and included in the implementation. It
combines NV_draw_buffers and NV_fbo_color_attachments, so the
implementation now selects one of the two based on which extension is
supported, preferring the EXT one. Updated the documentation to be
less confusing, fixed extension links. Also the single-output
mapForDraw() is not handled separately on ES anymore and just calls
DrawBuffers implementation with single parameter, resulting in less
generated code.
EXT_draw_buffers can also be called on default framebuffer and
apparently in ES there is no way to map front framebuffer for drawing,
so I removed it from the DefaultFramebuffer::DrawAttachment enum.
This was a leftover from some not-well-thought-out design decision. The
function is now used exclusively for binding for draw, as all
framebuffer reading functions (blit(), read()) are doing the read
binding internally. Moreover it required the user to be extra careful on
ES2, because in many cases there are no separate binding points for
reading and drawing.
The function is now parameter-less and always bind the framebuffer for
drawing. The logic for internal binding was also simplified and on ES2
there are separate implementations for single/separate binding points.
For *Framebuffer::checkStatus() the documentation was updated to explain
the meaning of the parameter on ES2 implementation. Also removed the
need for FramebufferTarget::ReadDraw binding, as it was rather
confusing.
Old *Framebuffer::bind(FramebufferTarget) is now just an alias to the
parameter-less function, ignoring the parameter. Along with
FramebufferTarget::ReadDraw it is marked as deprecated and will be
removed in some future release.
Similar to Framebuffer::read(), it's now possible to get texture image
also in single statement:
Image2D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte});
in comparison to the previous way:
Image2D image{ColorFormat::RGBA, ColorType::UnsignedByte};
texture.image(0, image);
The previous way is still kept in the API and not deprecated, as it
might be more usable in some cases.
Had to rework the API a bit, the original one (everything through
DebugMessage) should be still available, but marked as deprecated (and
will be removed in some future release).
The whole cycle of reading up on a feature, understanding the feature,
understanding the bigger concept under the feature and then having
understood everything so thoroughly so I can document the functionality
is time consuming.