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.
`char*` is now the default type for byte arrays. Results in shorter
code, less annoyances and more convenient testing. As is the case with
Corrade, I'm not doing any compatibility/deprecation layer, as most of
these functions is not widely used anyway.
Not sure why I chose to have offset and size in these two function, but
that's probably because I never used them in real code. The original
overloads taking pair of Vector2i are now marked as deprecated and will
be removed in future release.
ARB_DSA is now preferred in single-bind cases, as it is easier to use
than passing pointers to ARB_multi_bind. ARB_multi_bind was preferred
for single-bind previously simply because EXT_DSA was not in core.
Because there is a lot to say about feature selection for each function,
I took this as a opportunity to remove redundant documentation blocks,
just refer to Texture documentation from everywhere and add extension
requirements and deprecation where needed, so it's clear for each class
what needs what.
ARB_DSA also took the opportunity to finally remove all target enum
values from function calls and because of that the CubeMapTexture has to
handle a bunch of special cases. In order:
- CubeMapTexture::imageSize() now doesn't take face parameter and
returns one value for all faces. I'm thus now also assuming that the
user is sane and called either setStorage() or setImage() with the
same size for all faces. In non-ARB_DSA path I'm thus querying only
size of +X face and returning it as size for all faces. The old
imageSize(Coordinate, Int) overload is still present, but ignores
the first parameter and calls imageSize(Int). It is marked as
deprecated and will be removed in some future release.
- CubeMapTexture::image() now needs to call glTextureSubImage() in
ARB_DSA path to make it possible to extract single face. Other code
paths (EXT_DSA, Robustness and "default") remain the same.
- CubeMapTexture::setSubImage() calls glTextureSubImage3D() in
ARB_DSA, because it is not possible to specify face index in
glTextureSubImage2D(). Other code paths (EXT_DSA and "default")
remain the same.
Implementation of these special cases is extracted into CubeMapTexture
class to avoid pollution of AbstractTexture with incompatible nonsense.
Full support for EXT_transform_feedback, transform feedback objects
from ARB_transform_feedback2 and equivalent OpenGL ES 3.0 functionality.
Example usage is in src/Magnum/Test/TransformFeedbackGLTest.cpp, I'll
add some example later.
No backward compatibility issues should exist, as the class is in most
(if not all) cases used with unscoped name:
class MyShader: public AbstractShaderProgram {
public:
typedef Attribute<0, Vector3> Position;
// ...
};
With DSA there is slightly different (but completely understandable)
usage -- it's needed to specify the target upon creation, not deferring
it to begin() call. Timestamp queries (TimeQuery::timestamp()) must now
also be created with new TimeQuery::Target::Timestamp target.
The old way (parameterless constructor and begin(Target)) is still
supported, but is marked as deprecated and will be removed in future
release. Also, using the old way the DSA function is simply not used.
Also fixed SampleQuery test to account for cases where the driver might
not support ARB_occlusion_query2.
According to reports on delphigl.de this extension is far more supported
in comparison to the NV version (and also there's much less FF cruft in
the specification).
The indexed binding is allowed for only some types (atomic counters,
uniforms, shader storage and transform feedback), thus we need separate
enum for that. Because the bind() function will be used far more often
than setTargetHint(), the original Target enum is now renamed to
TargetHint and the new Target enum contains (in non-deprecated build)
only three values.
For backwards compatibility, though, we need to have all original Target
values, thus the new Target enum contains also all other values from
TargetHint, but they are marked as deprecated and (at least) run-time
checked in bind() so they aren't accidentaly used for indexed binding.
Similarly there are also deprecated Target overloads of Buffer() and
setTargetHint(). It's ugly, but hopefully will suffice for now. This mess
will be removed as soon as possible in some upcoming version.