Browse Source

Support for layered texture attachments in Framebuffer.

I.e. rendering to a layer addressed by `gl_Layer` in geometry shader.
pull/126/head
Vladimír Vondruš 11 years ago
parent
commit
3d9d70f153
  1. 6
      doc/opengl-mapping.dox
  2. 2
      doc/opengl-support.dox
  3. 59
      src/Magnum/Framebuffer.cpp
  4. 84
      src/Magnum/Framebuffer.h
  5. 8
      src/Magnum/Implementation/FramebufferState.cpp
  6. 3
      src/Magnum/Implementation/FramebufferState.h
  7. 179
      src/Magnum/Test/FramebufferGLTest.cpp

6
doc/opengl-mapping.dox

@ -146,10 +146,10 @@ OpenGL function | Matching API
@fn_gl{FlushMappedBufferRange}, \n `glFlushMappedNamedBufferRange()`, \n @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access} | @ref Buffer::flushMappedRange()
@fn_gl2{FramebufferParameter,FramebufferParameteri}, \n `glNamedFramebufferParameter()`, \n @fn_gl_extension{NamedFramebufferParameter,EXT,direct_state_access} | |
@fn_gl{FramebufferRenderbuffer}, \n `glNamedFramebufferRenderbuffer()`, \n @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access} | @ref Framebuffer::attachRenderbuffer(), \n @ref Framebuffer::detach()
@fn_gl{FramebufferTexture}, \n `glNamedFramebufferTexture()`, \n @fn_gl_extension{NamedFramebufferTexture,EXT,direct_state_access} | not used, the functions below are used instead for compatibility reasons
@fn_gl2{FramebufferTexture1D,FramebufferTexture}, \n @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}, \n `glFramebufferTexture2D()`, \n `glNamedFramebufferTexture2DEXT()` | @ref Framebuffer::attachTexture()
@fn_gl{FramebufferTexture}, \n `glNamedFramebufferTexture()`, \n @fn_gl_extension{NamedFramebufferTexture,EXT,direct_state_access} | @ref Framebuffer::attachLayeredTexture()
@fn_gl2{FramebufferTexture1D,FramebufferTexture}, \n @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}, \n `glFramebufferTexture2D()`, \n `glNamedFramebufferTexture2DEXT()` | @ref Framebuffer::attachTexture(), \n @ref Framebuffer::attachCubeMapTexture()
@fn_gl2{FramebufferTexture3D,FramebufferTexture} | not used, @fn_gl{FramebufferTextureLayer} has more complete features
@fn_gl{FramebufferTextureLayer}, \n `glNamedFramebufferTextureLayer()`, \n @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access} | @ref Framebuffer::attachTextureLayer()
@fn_gl{FramebufferTextureLayer}, \n `glNamedFramebufferTextureLayer()`, \n @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access} | @ref Framebuffer::attachTextureLayer(), \n @ref Framebuffer::attachCubeMapTexture()
@fn_gl{FrontFace} | @ref Renderer::setFrontFace()
@subsection opengl-mapping-functions-g G

2
doc/opengl-support.dox

@ -90,7 +90,7 @@ GLSL 1.40 | done
Extension | Status
------------------------------------------- | ------
GLSL 1.50 | done
@extension{ARB,geometry_shader4} | missing layered attachments and some limit queries
@extension{ARB,geometry_shader4} | missing some limit queries
@extension{ARB,depth_clamp} | done
@extension{ARB,draw_elements_base_vertex} | done
@extension{ARB,fragment_coord_conventions} | done (shading language only)

59
src/Magnum/Framebuffer.cpp

@ -274,6 +274,40 @@ Framebuffer& Framebuffer::attachTextureLayer(const BufferAttachment attachment,
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, Texture3D& texture, const Int level) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), level);
return *this;
}
#ifndef MAGNUM_TARGET_GLES
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, Texture1DArray& texture, const Int level) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), level);
return *this;
}
#endif
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, Texture2DArray& texture, const Int level) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), level);
return *this;
}
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, CubeMapTexture& texture, const Int level) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), level);
return *this;
}
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, CubeMapTextureArray& texture, const Int level) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), level);
return *this;
}
Framebuffer& Framebuffer::attachLayeredTexture(const BufferAttachment attachment, MultisampleTexture2DArray& texture) {
(this->*Context::current()->state().framebuffer->textureImplementation)(attachment, texture.id(), 0);
return *this;
}
#endif
Framebuffer& Framebuffer::detach(const BufferAttachment attachment) {
(this->*Context::current()->state().framebuffer->renderbufferImplementation)(attachment, 0);
return *this;
@ -297,10 +331,6 @@ void Framebuffer::texture1DImplementationDefault(BufferAttachment attachment, GL
glFramebufferTexture1D(GLenum(bindInternal()), GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
}
void Framebuffer::texture1DImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel) {
glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel);
}
void Framebuffer::texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel) {
_flags |= ObjectFlag::Created;
glNamedFramebufferTexture1DEXT(_id, GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
@ -326,6 +356,27 @@ void Framebuffer::textureCubeMapImplementationDSA(const BufferAttachment attachm
}
#endif
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
void Framebuffer::textureImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint mipLevel) {
#ifndef MAGNUM_TARGET_GLES
glFramebufferTexture
#else
glFramebufferTextureEXT
#endif
(GLenum(bindInternal()), GLenum(attachment), textureId, mipLevel);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::textureImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel) {
glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel);
}
void Framebuffer::textureImplementationDSAEXT(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel) {
glNamedFramebufferTextureEXT(_id, GLenum(attachment), textureId, mipLevel);
}
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) {
#ifndef MAGNUM_TARGET_GLES2

84
src/Magnum/Framebuffer.h

@ -724,6 +724,81 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
Framebuffer& attachTextureLayer(BufferAttachment attachment, MultisampleTexture2DArray& texture, Int layer);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @brief Attach layered cube map texture to given buffer
* @param attachment Buffer attachment
* @param texture Texture
* @param level Mip level
* @return Reference to self (for method chaining)
*
* Attaches whole texture with all layers addressable using `gl_Layer`
* in geometry shader. If neither @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) nor @extension{EXT,direct_state_access} desktop
* extension is available, the framebuffer is bound before the
* operation (if not already).
* @see @ref detach(), @ref attachTexture(),
* @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{FramebufferTexture}
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, Texture3D& texture, Int level);
#ifndef MAGNUM_TARGET_GLES
/** @overload
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Only 2D array textures are available in OpenGL ES and
* WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, Texture1DArray& texture, Int level);
#endif
/** @overload
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, Texture2DArray& texture, Int level);
/**
* @overload
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, CubeMapTexture& texture, Int level);
/** @overload
* @requires_gl40 Extension @extension{ARB,texture_cube_map_array}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader} and
* @es_extension{EXT,texture_cube_map_array}
* @requires_gles Geometry shaders are not available in WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, CubeMapTextureArray& texture, Int level);
/** @overload
* @requires_gl32 Extension @extension{ARB,geometry_shader4} and
* @extension{ARB,texture_multisample}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader} and
* @es_extension{OES,texture_storage_multisample_2d_array}
* @requires_gles Geometry shaders are not available in WebGL.
*/
Framebuffer& attachLayeredTexture(BufferAttachment attachment, MultisampleTexture2DArray& texture);
#endif
/**
* @brief Detach any texture or renderbuffer bound to given buffer
* @param attachment Buffer attachment
@ -773,7 +848,6 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture1DImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level);
void MAGNUM_LOCAL texture1DImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level);
void MAGNUM_LOCAL texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level);
#endif
@ -784,6 +858,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
void MAGNUM_LOCAL textureCubeMapImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#endif
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
void MAGNUM_LOCAL textureImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL textureImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level);
void MAGNUM_LOCAL textureImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void MAGNUM_LOCAL textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#endif

8
src/Magnum/Implementation/FramebufferState.cpp

@ -73,10 +73,12 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA;
texture1DImplementation = &Framebuffer::texture1DImplementationDSA;
/* The 1D implementation uses the same function as the layered attachment */
texture1DImplementation = &Framebuffer::textureImplementationDSA;
/* DSA doesn't have texture target parameter so we need to use different
function to specify cube map face */
texture2DImplementation = &Framebuffer::texture2DImplementationDSA;
textureImplementation = &Framebuffer::textureImplementationDSA;
textureCubeMapImplementation = &Framebuffer::textureCubeMapImplementationDSA;
textureLayerImplementation = &Framebuffer::textureLayerImplementationDSA;
@ -94,6 +96,7 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
texture1DImplementation = &Framebuffer::texture1DImplementationDSAEXT;
/* The EXT_DSA implementation is the same for both 2D and cube map textures */
texture2DImplementation = &Framebuffer::texture2DImplementationDSAEXT;
textureImplementation = &Framebuffer::textureImplementationDSAEXT;
textureCubeMapImplementation = &Framebuffer::texture2DImplementationDSAEXT;
textureLayerImplementation = &Framebuffer::textureLayerImplementationDSAEXT;
@ -118,6 +121,9 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
#endif
/* The default implementation is the same for both 2D and cube map textures */
texture2DImplementation = &Framebuffer::texture2DImplementationDefault;
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
textureImplementation = &Framebuffer::textureImplementationDefault;
#endif
textureCubeMapImplementation = &Framebuffer::texture2DImplementationDefault;
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
textureLayerImplementation = &Framebuffer::textureLayerImplementationDefault;

3
src/Magnum/Implementation/FramebufferState.h

@ -78,6 +78,9 @@ struct FramebufferState {
#endif
void(Framebuffer::*texture2DImplementation)(Framebuffer::BufferAttachment, GLenum, GLuint, GLint);
void(Framebuffer::*textureCubeMapImplementation)(Framebuffer::BufferAttachment, GLenum, GLuint, GLint);
#if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2)
void(Framebuffer::*textureImplementation)(Framebuffer::BufferAttachment, GLuint, GLint);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(Framebuffer::*textureLayerImplementation)(Framebuffer::BufferAttachment, GLuint, GLint, GLint);
#endif

179
src/Magnum/Test/FramebufferGLTest.cpp

@ -86,6 +86,16 @@ struct FramebufferGLTest: AbstractOpenGLTester {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void attachCubeMapTextureArray();
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void attachLayeredTexture3D();
#ifndef MAGNUM_TARGET_GLES
void attachLayeredTexture1DArray();
#endif
void attachLayeredTexture2DArray();
void attachLayeredCubeMapTexture();
void attachLayeredCubeMapTextureArray();
void attachLayeredTexture2DMultisampleArray();
#endif
void detach();
void multipleColorOutputs();
@ -141,6 +151,16 @@ FramebufferGLTest::FramebufferGLTest() {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&FramebufferGLTest::attachCubeMapTextureArray,
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&FramebufferGLTest::attachLayeredTexture3D,
#ifndef MAGNUM_TARGET_GLES
&FramebufferGLTest::attachLayeredTexture1DArray,
#endif
&FramebufferGLTest::attachLayeredTexture2DArray,
&FramebufferGLTest::attachLayeredCubeMapTexture,
&FramebufferGLTest::attachLayeredCubeMapTextureArray,
&FramebufferGLTest::attachLayeredTexture2DMultisampleArray,
#endif
&FramebufferGLTest::detach,
&FramebufferGLTest::multipleColorOutputs,
@ -662,6 +682,165 @@ void FramebufferGLTest::attachCubeMapTextureArray() {
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void FramebufferGLTest::attachLayeredTexture3D() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
CORRADE_SKIP(Extensions::GL::EXT::geometry_shader::string() + std::string(" is not available."));
#endif
Texture3D color;
color.setStorage(1, TextureFormat::RGBA8, Vector3i{128});
Framebuffer framebuffer{{{}, Vector2i{128}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color, 0);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
#ifndef MAGNUM_TARGET_GLES
void FramebufferGLTest::attachLayeredTexture1DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
Texture1DArray color;
color.setStorage(1, TextureFormat::RGBA8, {128, 8});
Texture1DArray depthStencil;
depthStencil.setStorage(1, TextureFormat::Depth24Stencil8, {128, 8});
Framebuffer framebuffer{{{}, {128, 1}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color, 0)
.attachLayeredTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
#endif
void FramebufferGLTest::attachLayeredTexture2DArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
CORRADE_SKIP(Extensions::GL::EXT::geometry_shader::string() + std::string(" is not available."));
#endif
Texture2DArray color;
color.setStorage(1, TextureFormat::RGBA8, {128, 128, 8});
Texture2DArray depthStencil;
depthStencil.setStorage(1, TextureFormat::Depth24Stencil8, {128, 128, 8});
Framebuffer framebuffer{{{}, Vector2i{128}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color, 0)
.attachLayeredTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
void FramebufferGLTest::attachLayeredCubeMapTexture() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
CORRADE_SKIP(Extensions::GL::EXT::geometry_shader::string() + std::string(" is not available."));
#endif
CubeMapTexture color;
color.setStorage(1, TextureFormat::RGBA8, Vector2i{128});
CubeMapTexture depthStencil;
depthStencil.setStorage(1, TextureFormat::Depth24Stencil8, Vector2i{128});
Framebuffer framebuffer{{{}, Vector2i{128}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color, 0)
.attachLayeredTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
void FramebufferGLTest::attachLayeredCubeMapTextureArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not available."));
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
CORRADE_SKIP(Extensions::GL::EXT::geometry_shader::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_cube_map_array>())
CORRADE_SKIP(Extensions::GL::EXT::texture_cube_map_array::string() + std::string(" is not available."));
#endif
CubeMapTextureArray color;
color.setStorage(1, TextureFormat::RGBA8, {128, 128, 18});
CubeMapTextureArray depthStencil;
depthStencil.setStorage(1, TextureFormat::Depth24Stencil8, {128, 128, 18});
Framebuffer framebuffer{{{}, Vector2i{128}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color, 0)
.attachLayeredTexture(Framebuffer::BufferAttachment::DepthStencil, depthStencil, 0);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
void FramebufferGLTest::attachLayeredTexture2DMultisampleArray() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
CORRADE_SKIP(Extensions::GL::ARB::geometry_shader4::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not available."));
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
CORRADE_SKIP(Extensions::GL::EXT::geometry_shader::string() + std::string(" is not available."));
if(!Context::current()->isExtensionSupported<Extensions::GL::OES::texture_storage_multisample_2d_array>())
CORRADE_SKIP(Extensions::GL::OES::texture_storage_multisample_2d_array::string() + std::string(" is not available."));
#endif
MultisampleTexture2DArray color;
color.setStorage(4, TextureFormat::RGBA8, {128, 128, 8});
MultisampleTexture2DArray depthStencil;
depthStencil.setStorage(4, TextureFormat::Depth24Stencil8, {128, 128, 8});
Framebuffer framebuffer{{{}, Vector2i{128}}};
framebuffer.attachLayeredTexture(Framebuffer::ColorAttachment{0}, color)
.attachLayeredTexture(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);
}
#endif
void FramebufferGLTest::detach() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::framebuffer_object>())

Loading…
Cancel
Save