Browse Source

Implemented glClearBuffer() APIs from GL 3.0 / GLES 3.0.

According to my browser, glClear() can't be used to clear integer
framebuffers, so this APIs are needed.
pull/218/head
Vladimír Vondruš 9 years ago
parent
commit
32613a592a
  1. 2
      doc/opengl-mapping.dox
  2. 1
      doc/opengl-support.dox
  3. 61
      src/Magnum/AbstractFramebuffer.cpp
  4. 68
      src/Magnum/AbstractFramebuffer.h
  5. 20
      src/Magnum/DefaultFramebuffer.cpp
  6. 36
      src/Magnum/DefaultFramebuffer.h
  7. 20
      src/Magnum/Framebuffer.cpp
  8. 37
      src/Magnum/Framebuffer.h
  9. 21
      src/Magnum/Implementation/FramebufferState.cpp
  10. 8
      src/Magnum/Implementation/FramebufferState.h
  11. 28
      src/Magnum/Renderer.h
  12. 220
      src/Magnum/Test/FramebufferGLTest.cpp

2
doc/opengl-mapping.dox

@ -85,7 +85,7 @@ OpenGL function | Matching API
@fn_gl{CheckFramebufferStatus}, \n `glCheckNamedFramebufferStatus()`, \n @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} | @ref DefaultFramebuffer::checkStatus(), \n @ref Framebuffer::checkStatus()
@fn_gl{ClampColor} | |
@fn_gl{Clear} | @ref AbstractFramebuffer::clear()
@fn_gl{ClearBuffer}, \n `glClearNamedFramebuffer()` | |
@fn_gl{ClearBuffer}, \n `glClearNamedFramebuffer()` | @ref AbstractFramebuffer::clearDepth(), @ref AbstractFramebuffer::clearStencil(), @ref AbstractFramebuffer::clearDepthStencil(), @ref DefaultFramebuffer::clearColor(), @ref Framebuffer::clearColor()
@fn_gl{ClearBufferData}, \n `glClearNamedBufferData()`, \n @fn_gl_extension{ClearNamedBufferData,EXT,direct_state_access} | |
@fn_gl{ClearBufferSubData}, \n `glClearNamedBufferSubData()`, \n @fn_gl_extension{ClearNamedBufferSubData,EXT,direct_state_access} | |
@fn_gl{ClearColor} | @ref Renderer::setClearColor()

1
doc/opengl-support.dox

@ -50,6 +50,7 @@ following:
Extension | Status
------------------------------------------- | ------
GLSL 1.30 | done
@fn_gl{ClearBuffer} functions | done
@extension{ARB,map_buffer_range} | done
@extension{ARB,color_buffer_float} | |
@extension{ARB,half_float_pixel} | done

61
src/Magnum/AbstractFramebuffer.cpp

@ -278,6 +278,23 @@ AbstractFramebuffer& AbstractFramebuffer::clear(const FramebufferClearMask mask)
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
AbstractFramebuffer& AbstractFramebuffer::clearDepth(const Float depth) {
(this->*Context::current().state().framebuffer->clearFImplementation)(GL_DEPTH, 0, &depth);
return *this;
}
AbstractFramebuffer& AbstractFramebuffer::clearStencil(const Int stencil) {
(this->*Context::current().state().framebuffer->clearIImplementation)(GL_STENCIL, 0, &stencil);
return *this;
}
AbstractFramebuffer& AbstractFramebuffer::clearDepthStencil(const Float depth, const Int stencil) {
(this->*Context::current().state().framebuffer->clearFIImplementation)(GL_DEPTH_STENCIL, depth, stencil);
return *this;
}
#endif
void AbstractFramebuffer::read(const Range2Di& rectangle, Image2D& image) {
bindInternal(FramebufferTarget::Read);
@ -473,6 +490,50 @@ GLenum AbstractFramebuffer::checkStatusImplementationDSAEXT(const FramebufferTar
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::clearImplementationDefault(const GLenum buffer, const GLint drawbuffer, const GLint* const value) {
bindInternal(FramebufferTarget::Draw);
glClearBufferiv(buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDefault(const GLenum buffer, const GLint drawbuffer, const GLuint* const value) {
bindInternal(FramebufferTarget::Draw);
glClearBufferuiv(buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDefault(const GLenum buffer, const GLint drawbuffer, const GLfloat* const value) {
bindInternal(FramebufferTarget::Draw);
glClearBufferfv(buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDefault(const GLenum buffer, const GLfloat depth, const GLint stencil) {
bindInternal(FramebufferTarget::Draw);
glClearBufferfi(buffer, 0, depth, stencil);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::clearImplementationDSA(const GLenum buffer, const GLint drawbuffer, const GLint* const value) {
bindInternal(FramebufferTarget::Draw);
glClearNamedFramebufferiv(_id, buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDSA(const GLenum buffer, const GLint drawbuffer, const GLuint* const value) {
bindInternal(FramebufferTarget::Draw);
glClearNamedFramebufferuiv(_id, buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDSA(const GLenum buffer, const GLint drawbuffer, const GLfloat* const value) {
bindInternal(FramebufferTarget::Draw);
glClearNamedFramebufferfv(_id, buffer, drawbuffer, value);
}
void AbstractFramebuffer::clearImplementationDSA(const GLenum buffer, const GLfloat depth, const GLint stencil) {
bindInternal(FramebufferTarget::Draw);
glClearNamedFramebufferfi(_id, buffer, 0, depth, stencil);
}
#endif
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers) {
bindInternal(FramebufferTarget::Draw);

68
src/Magnum/AbstractFramebuffer.h

@ -166,8 +166,9 @@ in repeated @fn_gl{Get} calls. See also @ref Context::resetState() and
@ref Context::State::Framebuffers.
If extension @extension{ARB,direct_state_access} (part of OpenGL 4.5) is
available, @ref blit() function uses DSA to avoid unnecessary call to
@fn_gl{BindFramebuffer}. See its documentation for more information.
available, @ref blit(), @ref clearDepth(), @ref clearStencil() and
@ref clearDepthStencil() functions use DSA to avoid unnecessary call to
@fn_gl{BindFramebuffer}. See their documentation for more information.
If @extension{ARB,robustness} is available, @ref read() operations are
protected from buffer overflow.
@ -303,9 +304,59 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @see @ref Renderer::setClearColor(), @ref Renderer::setClearDepth(),
* @ref Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
* @fn_gl{Clear}
* @deprecated_gl Prefer to use @ref Framebuffer::clearColor() "*Framebuffer::clearColor()"
* / @ref clearDepth() / @ref clearDepthStencil() instead of
* @ref Renderer::setClearColor() / @ref Renderer::setClearDepth()
* / @ref Renderer::setClearStencil() and @ref clear() as it leads
* to less state changes.
*/
AbstractFramebuffer& clear(FramebufferClearMask mask);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Clear depth buffer to specified value
* @param depth Value to clear with
* @return Reference to self (for method chaining)
*
* @see @ref clear(), @fn_gl{ClearNamedFramebuffer}, eventually
* @fn_gl{BindFramebuffer}, then @fn_gl{ClearBuffer}
* @requires_gl30 Direct framebuffer clearing is not available in
* OpenGL 2.1.
* @requires_gles30 Direct framebuffer clearing is not available in
* OpenGL ES 2.0 or WebGL 1.0.
*/
AbstractFramebuffer& clearDepth(Float depth);
/**
* @brief Clear stencil buffer to specified value
* @param stencil Value to clear with
* @return Reference to self (for method chaining)
*
* @see @ref clear(), @fn_gl{ClearNamedFramebuffer}, eventually
* @fn_gl{BindFramebuffer}, then @fn_gl{ClearBuffer}
* @requires_gl30 Direct framebuffer clearing is not available in
* OpenGL 2.1.
* @requires_gles30 Direct framebuffer clearing is not available in
* OpenGL ES 2.0 or WebGL 1.0.
*/
AbstractFramebuffer& clearStencil(Int stencil);
/**
* @brief Clear depth and stencil buffer to specified value
* @param depth Depth value to clear with
* @param stencil Stencil value to clear with
* @return Reference to self (for method chaining)
*
* @see @ref clear(), @fn_gl{ClearNamedFramebuffer}, eventually
* @fn_gl{BindFramebuffer}, then @fn_gl{ClearBuffer}
* @requires_gl30 Direct framebuffer clearing is not available in
* OpenGL 2.1.
* @requires_gles30 Direct framebuffer clearing is not available in
* OpenGL ES 2.0 or WebGL 1.0.
*/
AbstractFramebuffer& clearDepthStencil(Float depth, Int stencil);
#endif
/**
* @brief Read block of pixels from framebuffer to image
* @param rectangle Framebuffer rectangle to read
@ -729,6 +780,19 @@ class MAGNUM_EXPORT AbstractFramebuffer {
GLenum MAGNUM_LOCAL checkStatusImplementationDSAEXT(FramebufferTarget target);
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL clearImplementationDefault(GLenum buffer, GLint drawbuffer, const GLint* value);
void MAGNUM_LOCAL clearImplementationDefault(GLenum buffer, GLint drawbuffer, const GLuint* value);
void MAGNUM_LOCAL clearImplementationDefault(GLenum buffer, GLint drawbuffer, const GLfloat* value);
void MAGNUM_LOCAL clearImplementationDefault(GLenum buffer, GLfloat depth, GLint stencil);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL clearImplementationDSA(GLenum buffer, GLint drawbuffer, const GLint* value);
void MAGNUM_LOCAL clearImplementationDSA(GLenum buffer, GLint drawbuffer, const GLuint* value);
void MAGNUM_LOCAL clearImplementationDSA(GLenum buffer, GLint drawbuffer, const GLfloat* value);
void MAGNUM_LOCAL clearImplementationDSA(GLenum buffer, GLfloat depth, GLint stencil);
#endif
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers);
#ifndef MAGNUM_TARGET_GLES

20
src/Magnum/DefaultFramebuffer.cpp

@ -31,6 +31,9 @@
#include "Magnum/Extensions.h"
#include "Magnum/Implementation/State.h"
#include "Magnum/Implementation/FramebufferState.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/Math/Color.h"
#endif
namespace Magnum {
@ -45,6 +48,23 @@ DefaultFramebuffer::Status DefaultFramebuffer::checkStatus(const FramebufferTarg
return Status((this->*Context::current().state().framebuffer->checkStatusImplementation)(target));
}
#ifndef MAGNUM_TARGET_GLES2
DefaultFramebuffer& DefaultFramebuffer::clearColor(const Color4& color) {
(this->*Context::current().state().framebuffer->clearFImplementation)(GL_COLOR, 0, color.data());
return *this;
}
DefaultFramebuffer& DefaultFramebuffer::clearColor(const Vector4i& color) {
(this->*Context::current().state().framebuffer->clearIImplementation)(GL_COLOR, 0, color.data());
return *this;
}
DefaultFramebuffer& DefaultFramebuffer::clearColor(const Vector4ui& color) {
(this->*Context::current().state().framebuffer->clearUIImplementation)(GL_COLOR, 0, color.data());
return *this;
}
#endif
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;

36
src/Magnum/DefaultFramebuffer.h

@ -343,6 +343,28 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
*/
Status checkStatus(FramebufferTarget target);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Clear color buffer to specified value
* @param color Value to clear with
* @return Reference to self (for method chaining)
*
* @see @ref clear(), @fn_gl{ClearNamedFramebuffer}, eventually
* @fn_gl{BindFramebuffer}, then @fn_gl{ClearBuffer}
* @requires_gl30 Direct framebuffer clearing is not available in
* OpenGL 2.1.
* @requires_gles30 Direct framebuffer clearing is not available in
* OpenGL ES 2.0 or WebGL 1.0.
*/
DefaultFramebuffer& clearColor(const Color4& color);
/** @overload */
DefaultFramebuffer& clearColor(const Vector4i& color);
/** @overload */
DefaultFramebuffer& clearColor(const Vector4ui& color);
#endif
/**
* @brief Map shader outputs to buffer attachment
* @return Reference to self (for method chaining)
@ -466,6 +488,20 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
AbstractFramebuffer::clear(mask);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
DefaultFramebuffer& clearDepth(Float depth) {
AbstractFramebuffer::clearDepth(depth);
return *this;
}
DefaultFramebuffer& clearStencil(Int stencil) {
AbstractFramebuffer::clearStencil(stencil);
return *this;
}
DefaultFramebuffer& clearDepthStencil(Float depth, Int stencil) {
AbstractFramebuffer::clearDepthStencil(depth, stencil);
return *this;
}
#endif
#endif
private:

20
src/Magnum/Framebuffer.cpp

@ -34,6 +34,9 @@
#include "Magnum/Image.h"
#include "Magnum/Renderbuffer.h"
#include "Magnum/Texture.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/Math/Color.h"
#endif
#ifndef MAGNUM_TARGET_GLES2
#include "Magnum/BufferImage.h"
@ -153,6 +156,23 @@ Framebuffer::Status Framebuffer::checkStatus(const FramebufferTarget target) {
return Status((this->*Context::current().state().framebuffer->checkStatusImplementation)(target));
}
#ifndef MAGNUM_TARGET_GLES2
Framebuffer& Framebuffer::clearColor(const Int attachment, const Color4& color) {
(this->*Context::current().state().framebuffer->clearFImplementation)(GL_COLOR, attachment, color.data());
return *this;
}
Framebuffer& Framebuffer::clearColor(const Int attachment, const Vector4i& color) {
(this->*Context::current().state().framebuffer->clearIImplementation)(GL_COLOR, attachment, color.data());
return *this;
}
Framebuffer& Framebuffer::clearColor(const Int attachment, const Vector4ui& color) {
(this->*Context::current().state().framebuffer->clearUIImplementation)(GL_COLOR, attachment, color.data());
return *this;
}
#endif
Framebuffer& Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;

37
src/Magnum/Framebuffer.h

@ -454,6 +454,29 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
*/
Status checkStatus(FramebufferTarget target);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Clear color buffer to specified value
* @param attachment Color attachment index
* @param color Value to clear with
* @return Reference to self (for method chaining)
*
* @see @ref clear(), @fn_gl{ClearNamedFramebuffer}, eventually
* @fn_gl{BindFramebuffer}, then @fn_gl{ClearBuffer}
* @requires_gl30 Direct framebuffer clearing is not available in
* OpenGL 2.1.
* @requires_gles30 Direct framebuffer clearing is not available in
* OpenGL ES 2.0 or WebGL 1.0.
*/
Framebuffer& clearColor(Int attachment, const Color4& color);
/** @overload */
Framebuffer& clearColor(Int attachment, const Vector4i& color);
/** @overload */
Framebuffer& clearColor(Int attachment, const Vector4ui& color);
#endif
/**
* @brief Map shader output to attachments
* @return Reference to self (for method chaining)
@ -841,6 +864,20 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
AbstractFramebuffer::clear(mask);
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
Framebuffer& clearDepth(Float depth) {
AbstractFramebuffer::clearDepth(depth);
return *this;
}
Framebuffer& clearStencil(Int stencil) {
AbstractFramebuffer::clearStencil(stencil);
return *this;
}
Framebuffer& clearDepthStencil(Float depth, Int stencil) {
AbstractFramebuffer::clearDepthStencil(depth, stencil);
return *this;
}
#endif
#endif
private:

21
src/Magnum/Implementation/FramebufferState.cpp

@ -64,6 +64,12 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Extension added above */
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA;
clearIImplementation = &AbstractFramebuffer::clearImplementationDSA;
clearUIImplementation = &AbstractFramebuffer::clearImplementationDSA;
clearFImplementation = &AbstractFramebuffer::clearImplementationDSA;
clearFIImplementation = &AbstractFramebuffer::clearImplementationDSA;
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSA;
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
@ -89,6 +95,13 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
extensions.emplace_back(Extensions::GL::EXT::direct_state_access::string());
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSAEXT;
/* I don't bother with EXT_DSA anymore */
clearIImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearUIImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearFImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearFIImplementation = &AbstractFramebuffer::clearImplementationDefault;
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSAEXT;
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSAEXT;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSAEXT;
@ -111,6 +124,14 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#endif
{
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDefault;
#ifndef MAGNUM_TARGET_GLES2
clearIImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearUIImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearFImplementation = &AbstractFramebuffer::clearImplementationDefault;
clearFIImplementation = &AbstractFramebuffer::clearImplementationDefault;
#endif
#ifndef MAGNUM_TARGET_GLES2
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDefault;
#endif

8
src/Magnum/Implementation/FramebufferState.h

@ -50,6 +50,14 @@ struct FramebufferState {
void(*blitImplementation)(AbstractFramebuffer&, AbstractFramebuffer&, const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter);
#endif
GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget);
#ifndef MAGNUM_TARGET_GLES2
void(AbstractFramebuffer::*clearIImplementation)(GLenum, GLint, const GLint*);
void(AbstractFramebuffer::*clearUIImplementation)(GLenum, GLint, const GLuint*);
void(AbstractFramebuffer::*clearFImplementation)(GLenum, GLint, const GLfloat*);
void(AbstractFramebuffer::*clearFIImplementation)(GLenum, GLfloat, GLint);
#endif
void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*);
#ifndef MAGNUM_TARGET_GLES
void(AbstractFramebuffer::*drawBufferImplementation)(GLenum);

28
src/Magnum/Renderer.h

@ -358,7 +358,12 @@ class MAGNUM_EXPORT Renderer {
* @brief Set clear color
*
* Initial value is `{0.125f, 0.125f, 0.125f, 1.0f}`.
* @see @fn_gl{ClearColor}
* @see @ref Framebuffer::clearColor() "*Framebuffer::clearColor()",
* @fn_gl{ClearColor}
* @deprecated_gl Prefer to use @ref Framebuffer::clearColor() "*Framebuffer::clearColor()"
* instead of @ref setClearColor() and
* @ref AbstractFramebuffer::clear() as it leads to less state
* changes.
*/
static void setClearColor(const Color4& color);
@ -367,9 +372,14 @@ class MAGNUM_EXPORT Renderer {
* @brief Set clear depth
*
* Initial value is `1.0`.
* @see @ref Feature::DepthTest, @fn_gl{ClearDepth}
* @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(),
* @ref AbstractFramebuffer::clearDepthStencil(), @fn_gl{ClearDepth}
* @requires_gl See @ref setClearDepth(Float), which is available in
* OpenGL ES and WebGL.
* @deprecated_gl Prefer to use @ref AbstractFramebuffer::clearDepth()
* / @ref AbstractFramebuffer::clearDepthStencil() instead of
* @ref setClearDepth() and @ref AbstractFramebuffer::clear() as
* it leads to less state changes.
*/
static void setClearDepth(Double depth);
#endif
@ -380,7 +390,12 @@ class MAGNUM_EXPORT Renderer {
* If OpenGL ES, OpenGL 4.1 or extension @extension{ARB,ES2_compatibility}
* is not available, this function behaves exactly as
* @ref setClearDepth(Double).
* @see @ref Feature::DepthTest, @fn_gl{ClearDepth}
* @see @ref Feature::DepthTest, @ref AbstractFramebuffer::clearDepth(),
* @ref AbstractFramebuffer::clearDepthStencil(), @fn_gl{ClearDepth}
* @deprecated_gl Prefer to use @ref AbstractFramebuffer::clearDepth()
* / @ref AbstractFramebuffer::clearDepthStencil() instead of
* @ref setClearDepth() and @ref AbstractFramebuffer::clear() as
* it leads to less state changes.
*/
static void setClearDepth(Float depth);
@ -388,7 +403,12 @@ class MAGNUM_EXPORT Renderer {
* @brief Set clear stencil
*
* Initial value is `0`.
* @see @ref Feature::StencilTest, @fn_gl{ClearStencil}
* @see @ref Feature::StencilTest, @ref AbstractFramebuffer::clearStencil(),
* @ref AbstractFramebuffer::clearDepthStencil(), @fn_gl{ClearStencil}
* @deprecated_gl Prefer to use @ref AbstractFramebuffer::clearStencil()
* / @ref AbstractFramebuffer::clearDepthStencil() instead of
* @ref setClearStencil() and @ref AbstractFramebuffer::clear() as
* it leads to less state changes.
*/
static void setClearStencil(Int stencil);

220
src/Magnum/Test/FramebufferGLTest.cpp

@ -102,6 +102,14 @@ struct FramebufferGLTest: OpenGLTester {
void multipleColorOutputs();
void clear();
#ifndef MAGNUM_TARGET_GLES2
void clearColorI();
void clearColorUI();
void clearColorF();
void clearDepth();
void clearStencil();
void clearDepthStencil();
#endif
void invalidate();
#ifndef MAGNUM_TARGET_GLES2
void invalidateSub();
@ -195,6 +203,14 @@ FramebufferGLTest::FramebufferGLTest() {
&FramebufferGLTest::multipleColorOutputs,
&FramebufferGLTest::clear,
#ifndef MAGNUM_TARGET_GLES2
&FramebufferGLTest::clearColorI,
&FramebufferGLTest::clearColorUI,
&FramebufferGLTest::clearColorF,
&FramebufferGLTest::clearDepth,
&FramebufferGLTest::clearStencil,
&FramebufferGLTest::clearDepthStencil,
#endif
&FramebufferGLTest::invalidate,
#ifndef MAGNUM_TARGET_GLES2
&FramebufferGLTest::invalidateSub,
@ -1014,6 +1030,210 @@ void FramebufferGLTest::clear() {
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES2
void FramebufferGLTest::clearColorI() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8I, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearColor(0, Vector4i{-124, 67, 37, 17});
MAGNUM_VERIFY_NO_ERROR();
Image2D colorImage = framebuffer.read({{}, Vector2i{1}},
{PixelFormat::RGBAInteger, PixelType::Int});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(colorImage.data<Vector4i>()[0], (Vector4i{-124, 67, 37, 17}));
}
void FramebufferGLTest::clearColorUI() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8UI, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearColor(0, Vector4ui{240, 67, 37, 17});
MAGNUM_VERIFY_NO_ERROR();
Image2D colorImage = framebuffer.read({{}, Vector2i{1}},
{PixelFormat::RGBAInteger, PixelType::UnsignedInt});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(colorImage.data<Vector4ui>()[0], (Vector4ui{240, 67, 37, 17}));
}
void FramebufferGLTest::clearColorF() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearColor(0, Math::unpack<Color4>(Color4ub{128, 64, 32, 17}));
MAGNUM_VERIFY_NO_ERROR();
Image2D colorImage = framebuffer.read({{}, Vector2i{1}},
{PixelFormat::RGBA, PixelType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(colorImage.data<Color4ub>()[0], (Color4ub{128, 64, 32, 17}));
}
void FramebufferGLTest::clearDepth() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8, Vector2i{16});
/* Separate depth and stencil renderbuffers are not supported (or at least
on my NVidia, thus we need to do this juggling with one renderbuffer */
Renderbuffer depthStencil;
depthStencil.setStorage(RenderbufferFormat::Depth24Stencil8, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color)
.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearDepth(Math::unpack<Float, UnsignedShort>(48352));
MAGNUM_VERIFY_NO_ERROR();
#ifdef MAGNUM_TARGET_GLES
if(Context::current().isExtensionSupported<Extensions::GL::NV::read_depth>())
#endif
{
#ifdef MAGNUM_TARGET_GLES
Debug() << "Using" << Extensions::GL::NV::read_depth::string();
#endif
Image2D depthImage = framebuffer.read({{}, Vector2i{1}}, {PixelFormat::DepthComponent, PixelType::UnsignedShort});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(depthImage.data<UnsignedShort>()[0], 48352);
}
}
void FramebufferGLTest::clearStencil() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8, Vector2i{16});
Renderbuffer depthStencil;
depthStencil.setStorage(RenderbufferFormat::Depth24Stencil8, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color)
.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearStencil(67);
MAGNUM_VERIFY_NO_ERROR();
#ifdef MAGNUM_TARGET_GLES
if(Context::current().isExtensionSupported<Extensions::GL::NV::read_stencil>())
#endif
{
#ifdef MAGNUM_TARGET_GLES
Debug() << "Using" << Extensions::GL::NV::read_stencil::string();
#endif
Image2D stencilImage = framebuffer.read({{}, Vector2i{1}}, {PixelFormat::StencilIndex, PixelType::UnsignedByte});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(stencilImage.data<UnsignedByte>()[0], 67);
}
}
void FramebufferGLTest::clearDepthStencil() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isVersionSupported(Version::GL300))
CORRADE_SKIP("GL 3.0 is not available.");
#endif
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8, Vector2i{16});
/* Separate depth and stencil renderbuffers are not supported (or at least
on my NVidia, thus we need to do this juggling with one renderbuffer */
Renderbuffer depthStencil;
depthStencil.setStorage(RenderbufferFormat::Depth24Stencil8, Vector2i{16});
Framebuffer framebuffer({{}, Vector2i{16}});
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color)
.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
framebuffer.clearDepthStencil(Math::unpack<Float, UnsignedShort>(48352), 67);
#ifdef MAGNUM_TARGET_GLES
if(Context::current().isExtensionSupported<Extensions::GL::NV::read_depth_stencil>())
#endif
{
#ifdef MAGNUM_TARGET_GLES
Debug() << "Using" << Extensions::GL::NV::read_depth_stencil::string();
#endif
Image2D depthStencilImage = framebuffer.read({{}, Vector2i{1}}, {PixelFormat::DepthStencil, PixelType::UnsignedInt248});
MAGNUM_VERIFY_NO_ERROR();
/** @todo This will probably fail on different systems */
CORRADE_COMPARE(depthStencilImage.data<UnsignedInt>()[0] >> 8, 12378300);
CORRADE_COMPARE(depthStencilImage.data<UnsignedByte>()[0], 67);
}
}
#endif
void FramebufferGLTest::invalidate() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())

Loading…
Cancel
Save