// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getStencilBuffer()
{
	Renderbuffer *stencilbuffer = mStencilbufferPointer;

	if(stencilbuffer)
	{
		return stencilbuffer->getRenderTarget();
	}

	return nullptr;
}
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getDepthBuffer()
{
	Renderbuffer *depthbuffer = mDepthbufferPointer;

	if(depthbuffer)
	{
		return depthbuffer->getRenderTarget();
	}

	return nullptr;
}
unsigned int Framebuffer::getRenderTargetSerial()
{
    Renderbuffer *colorbuffer = mColorbufferPointer.get();

    if (colorbuffer)
    {
        return colorbuffer->getSerial();
    }

    return 0;
}
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getRenderTarget()
{
	Renderbuffer *colorbuffer = mColorbufferPointer;

	if(colorbuffer)
	{
		return colorbuffer->getRenderTarget();
	}

	return nullptr;
}
Beispiel #5
0
static void init_multisample(unsigned samples, unsigned width, unsigned height)
{
   if (samples <= 1)
      samples = 0;

   Framebuffer::set_back_buffer(0);
   ms_color.init(GL_RGBA8, width, height, samples);
   ms_depth_stencil.init(GL_DEPTH24_STENCIL8, width, height, samples);
   ms_fbo.set_attachments({}, {{ &ms_color }, { &ms_depth_stencil }});
   multisample = samples;
}
Beispiel #6
0
void SampleQueryGLTest::querySamplesPassed() {
    #ifdef MAGNUM_TARGET_GLES2
    if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::occlusion_query_boolean>())
        CORRADE_SKIP(Extensions::GL::EXT::occlusion_query_boolean::string() + std::string(" is not available."));
    #endif

    Renderbuffer renderbuffer;
    #ifndef MAGNUM_TARGET_GLES2
    renderbuffer.setStorage(RenderbufferFormat::RGBA8, Vector2i(32));
    #else
    renderbuffer.setStorage(RenderbufferFormat::RGBA4, Vector2i(32));
    #endif

    Framebuffer framebuffer({{}, Vector2i(32)});
    framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), renderbuffer);

    Buffer buffer;
    constexpr Vector2 triangle[] = {{-1.0f, 1.0f}, {-1.0f, -3.0f}, {3.0f, 1.0f}};
    buffer.setData(triangle, BufferUsage::StaticDraw);

    Mesh mesh;
    mesh.setPrimitive(MeshPrimitive::Triangles)
        .setCount(3)
        .addVertexBuffer(buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>());

    MyShader shader;

    MAGNUM_VERIFY_NO_ERROR();

    SampleQuery q;
    #ifndef MAGNUM_TARGET_GLES
    q.begin(SampleQuery::Target::SamplesPassed);
    #else
    q.begin(SampleQuery::Target::AnySamplesPassed);
    #endif

    framebuffer.bind(FramebufferTarget::ReadDraw);
    mesh.draw(shader);

    q.end();
    const bool availableBefore = q.resultAvailable();
    const UnsignedInt count = q.result<UnsignedInt>();
    const bool availableAfter = q.resultAvailable();

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_VERIFY(!availableBefore);
    CORRADE_VERIFY(availableAfter);
    #ifndef MAGNUM_TARGET_GLES
    CORRADE_COMPARE(count, 32*32);
    #else
    CORRADE_VERIFY(count > 0);
    #endif
}
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
	mColorbufferPointer = new Renderbuffer(0, colorbuffer);

	Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
	mDepthbufferPointer = depthStencilRenderbuffer;
	mStencilbufferPointer = depthStencilRenderbuffer;

	mColorbufferType = GL_RENDERBUFFER_OES;
	mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER_OES : GL_NONE_OES;
	mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER_OES : GL_NONE_OES;
}
Beispiel #8
0
unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
{
    ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);

    Renderbuffer *colorbuffer = mColorbufferPointers[colorAttachment].get();

    if (colorbuffer)
    {
        return colorbuffer->getSerial();
    }

    return 0;
}
DepthStencilbuffer *Framebuffer::getStencilbuffer()
{
    Renderbuffer *rb = mStencilbufferPointer.get();

    if (rb != NULL && rb->isStencilbuffer())
    {
        return static_cast<DepthStencilbuffer*>(rb->getStorage());
    }
    else
    {
        return NULL;
    }
}
Beispiel #10
0
Colorbuffer *Framebuffer::getColorbuffer()
{
    Renderbuffer *rb = mColorbufferPointer.get();

    if (rb != NULL && rb->isColorbuffer())
    {
        return static_cast<Colorbuffer*>(rb->getStorage());
    }
    else
    {
        return NULL;
    }
}
Beispiel #11
0
bool Framebuffer::hasStencil()
{
	if(mStencilbufferType != GL_NONE_OES)
	{
		Renderbuffer *stencilbufferObject = getStencilbuffer();

		if(stencilbufferObject)
		{
			return stencilbufferObject->getStencilSize() > 0;
		}
	}

	return false;
}
Beispiel #12
0
	void ResizeLightMask(GLuint width, GLuint height)
	{
		Texture::Active(light_tex_unit);
		Texture::Target tex_tgt = Texture::Target::Rectangle;
		light_mask.Bind(tex_tgt);
		Texture::Image2D(
			tex_tgt,
			0,
			PixelDataInternalFormat::Red,
			width, height,
			0,
			PixelDataFormat::Red,
			PixelDataType::UnsignedByte,
			nullptr
		);

		Renderbuffer::Target rbo_tgt = Renderbuffer::Target::Renderbuffer;
		light_rbo.Bind(rbo_tgt);
		Renderbuffer::Storage(
			rbo_tgt,
			PixelDataInternalFormat::DepthComponent,
			width,
			height
		);

	}
Beispiel #13
0
DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
    : Framebuffer(0)
{
    Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
    mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);

    Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);

    // Make a new attachment objects to ensure we do not double-delete
    // See angle issue 686
    mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
    mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);

    mDrawBufferStates[0] = GL_BACK;
    mReadBufferState = GL_BACK;
}
Beispiel #14
0
IDirect3DSurface9 *Framebuffer::getDepthStencil()
{
    Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
    
    if (!depthstencilbuffer)
    {
        depthstencilbuffer = mStencilbufferPointer.get();
    }

    if (depthstencilbuffer)
    {
        return depthstencilbuffer->getDepthStencil();
    }

    return NULL;
}
Beispiel #15
0
DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
    : Framebuffer(renderer)
{
    mColorbufferPointers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer));

    Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
    mDepthbufferPointer.set(depthStencilRenderbuffer);
    mStencilbufferPointer.set(depthStencilRenderbuffer);

    mColorbufferTypes[0] = GL_RENDERBUFFER;
    mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
    mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;

    mDrawBufferStates[0] = GL_BACK;
    mReadBufferState = GL_BACK;
}
Beispiel #16
0
void FramebufferGLTest::multipleColorOutputs() {
    #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."));
    #elif defined(MAGNUM_TARGET_GLES2)
    if(!Context::current()->isExtensionSupported<Extensions::GL::NV::draw_buffers>())
        CORRADE_SKIP(Extensions::GL::NV::draw_buffers::string() + std::string(" is not available."));
    #endif

    Texture2D color1;
    #ifndef MAGNUM_TARGET_GLES2
    color1.setStorage(1, TextureFormat::RGBA8, Vector2i(128));
    #else
    color1.setStorage(1, TextureFormat::RGBA, Vector2i(128));
    #endif

    Texture2D color2;
    #ifndef MAGNUM_TARGET_GLES2
    color2.setStorage(1, TextureFormat::RGBA8, Vector2i(128));
    #else
    color2.setStorage(1, TextureFormat::RGBA, Vector2i(128));
    #endif

    Renderbuffer depth;
    depth.setStorage(RenderbufferFormat::DepthComponent16, Vector2i(128));

    Framebuffer framebuffer({{}, Vector2i(128)});
    framebuffer.attachTexture(Framebuffer::ColorAttachment(0), color1, 0)
               .attachTexture(Framebuffer::ColorAttachment(1), color2, 0)
               .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, depth)
               .mapForDraw({{0, Framebuffer::ColorAttachment(1)},
                            {1, Framebuffer::ColorAttachment(0)}});

    #ifdef MAGNUM_TARGET_GLES2
    if(Context::current()->isExtensionSupported<Extensions::GL::NV::read_buffer>())
    #endif
    {
        #ifdef MAGNUM_TARGET_GLES2
        Debug() << "Using" << Extensions::GL::NV::read_buffer::string();
        #endif
        framebuffer.mapForRead(Framebuffer::ColorAttachment(1));
    }

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete);
}
Beispiel #17
0
void Framebuffer::AttachRenderbuffer(GLenum attachment, const Renderbuffer &rb)
{
	GLint bind_draw = 0, bind_read = 0;
	glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &bind_draw);
	glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &bind_read);
	Bind();
	glFramebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, rb.GetId());
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, bind_draw);
	glBindFramebuffer(GL_READ_FRAMEBUFFER, bind_read);
}
Beispiel #18
0
GLenum Framebuffer::getImplementationColorReadType()
{
	Renderbuffer *colorbuffer = mColorbufferPointer;

	if(colorbuffer)
	{
		switch(colorbuffer->getInternalFormat())
		{
		case sw::FORMAT_A8R8G8B8:      return GL_UNSIGNED_BYTE;
		case sw::FORMAT_A8B8G8R8:      return GL_UNSIGNED_BYTE;
		case sw::FORMAT_X8R8G8B8:      return GL_UNSIGNED_BYTE;
		case sw::FORMAT_X8B8G8R8:      return GL_UNSIGNED_BYTE;
		case sw::FORMAT_A1R5G5B5:      return GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
		case sw::FORMAT_R5G6B5:        return GL_UNSIGNED_SHORT_5_6_5;
		default:
			UNREACHABLE(colorbuffer->getInternalFormat());
		}
	}

	return GL_UNSIGNED_BYTE;
}
Beispiel #19
0
void Framebuffer::attachRenderbuffer(const Renderbuffer &renderbuffer, Attachment attachment)
{
	GLuint bound = (_boundTo == ReadFramebuffer) ? _boundRead : _boundDraw;

	if (bound != _id)
		glBindFramebuffer(_boundTo, _id);

	glFramebufferRenderbuffer(_boundTo, attachment, GL_RENDERBUFFER, renderbuffer.getId());

	if (bound != _id)
		glBindFramebuffer(_boundTo, bound);
}
Beispiel #20
0
void Framebuffer::set_color_attachment(unsigned index, Renderbuffer &renderbuffer)
{
  GL_ERROR_GUARD;
  assert(index < 16); // momentalne je podporovanych len 16 attachmentov
                      // dobre by bolo zistit max pocet cez glGet
//  assert(texture.type() == TextureType::TEXTURE_2D);
  my_vs.bind_write_framebuffer(*this, false);
  GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
  glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, attachment, GL_RENDERBUFFER,
    renderbuffer.gl_renderbuffer());
  my_color_attachments |= 1 << index;
}
Beispiel #21
0
GLenum Framebuffer::getImplementationColorReadFormat()
{
	Renderbuffer *colorbuffer = mColorbufferPointer;

	if(colorbuffer)
	{
		// Don't return GL_RGBA since that's always supported. Provide a second option here.
		switch(colorbuffer->getInternalFormat())
		{
		case sw::FORMAT_A8R8G8B8:      return GL_BGRA_EXT;
		case sw::FORMAT_A8B8G8R8:      return GL_BGRA_EXT;
		case sw::FORMAT_X8R8G8B8:      return 0x80E0;   // GL_BGR_EXT
		case sw::FORMAT_X8B8G8R8:      return 0x80E0;   // GL_BGR_EXT
		case sw::FORMAT_A1R5G5B5:      return GL_BGRA_EXT;
		case sw::FORMAT_R5G6B5:        return 0x80E0;   // GL_BGR_EXT
		default:
			UNREACHABLE(colorbuffer->getInternalFormat());
		}
	}

	return GL_RGBA;
}
void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
    EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
        target, samples, internalformat, width, height);

    Context *context = GetValidGlobalContext();
    if (context)
    {
        if (!ValidateRenderbufferStorageParametersANGLE(context, target, samples, internalformat,
            width, height))
        {
            return;
        }

        Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
        Error error = renderbuffer->setStorageMultisample(samples, internalformat, width, height);
        if (error.isError())
        {
            context->recordError(error);
            return;
        }
    }
}
Beispiel #23
0
void FramebufferGLTest::invalidateSub() {
    #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."));
    #endif

    Renderbuffer color;
    color.setStorage(RenderbufferFormat::RGBA8, Vector2i(128));

    Renderbuffer depth;
    depth.setStorage(RenderbufferFormat::DepthComponent16, Vector2i(128));

    Framebuffer framebuffer({{}, Vector2i(128)});
    framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), color)
               .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, depth);

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete);

    framebuffer.invalidate({Framebuffer::InvalidationAttachment::Depth, Framebuffer::ColorAttachment(0)},
                           {{32, 16}, {79, 64}});

    MAGNUM_VERIFY_NO_ERROR();
}
ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target,
                                                                   GLeglImageOES image)
{
    EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);

    Context *context = GetValidGlobalContext();
    if (context)
    {
        egl::Display *display   = egl::GetGlobalDisplay();
        egl::Image *imageObject = reinterpret_cast<egl::Image *>(image);
        if (!ValidateEGLImageTargetRenderbufferStorageOES(context, display, target, imageObject))
        {
            return;
        }

        Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
        Error error = renderbuffer->setStorageEGLImageTarget(imageObject);
        if (error.isError())
        {
            context->recordError(error);
            return;
        }
    }
}
Beispiel #25
0
	void SetupLightMask(void)
	{
		Texture::Active(light_tex_unit);
		Texture::Target tex_tgt = Texture::Target::Rectangle;
		light_mask.Bind(tex_tgt);

		draw_prog.Use();
		UniformSampler(draw_prog, "LightMap").Set(GLuint(light_tex_unit));

		Texture::MinFilter(tex_tgt, TextureMinFilter::Linear);
		Texture::MagFilter(tex_tgt, TextureMagFilter::Linear);
		Texture::WrapS(tex_tgt, TextureWrap::ClampToEdge);
		Texture::WrapT(tex_tgt, TextureWrap::ClampToEdge);

		Framebuffer::Target fbo_tgt = Framebuffer::Target::Draw;
		light_fbo.Bind(fbo_tgt);
		Framebuffer::AttachTexture(fbo_tgt, FramebufferAttachment::Color, light_mask, 0);

		Renderbuffer::Target rbo_tgt = Renderbuffer::Target::Renderbuffer;
		light_rbo.Bind(rbo_tgt);
		Framebuffer::AttachRenderbuffer(fbo_tgt, FramebufferAttachment::Depth, light_rbo);
	}
void FramebufferGLTest::attachRenderbuffer() {
    #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."));
    #endif

    Renderbuffer color;
    #ifndef MAGNUM_TARGET_GLES2
    color.setStorage(RenderbufferFormat::RGBA8, Vector2i(128));
    #else
    color.setStorage(RenderbufferFormat::RGBA4, Vector2i(128));
    #endif

    /* 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;
    #ifdef MAGNUM_TARGET_GLES2
    if(Context::current()->isExtensionSupported<Extensions::GL::OES::packed_depth_stencil>())
    #endif
    {
        #ifdef MAGNUM_TARGET_GLES2
        Debug() << "Using" << Extensions::GL::OES::packed_depth_stencil::string();
        #endif
        depthStencil.setStorage(RenderbufferFormat::Depth24Stencil8, Vector2i(128));
    }
    #ifdef MAGNUM_TARGET_GLES2
    else depthStencil.setStorage(RenderbufferFormat::DepthComponent16, Vector2i(128));
    #endif

    Framebuffer framebuffer({{}, Vector2i(128)});
    framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), color)
               .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, depthStencil);

    #ifdef MAGNUM_TARGET_GLES2
    if(Context::current()->isExtensionSupported<Extensions::GL::OES::packed_depth_stencil>())
    #endif
    {
        framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment::Stencil, depthStencil);
    }

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Read), Framebuffer::Status::Complete);
    CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::Draw), Framebuffer::Status::Complete);
}
Beispiel #27
0
	void attach(Renderbuffer const& b, GLenum attachment_point){
		moggle::gl::framebuffer_renderbuffer(GL_FRAMEBUFFER, attachment_point, GL_RENDERBUFFER, b.get_id());
	}
Beispiel #28
0
void FramebufferGLTest::read() {
    #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."));
    #endif

    Renderbuffer color;
    #ifndef MAGNUM_TARGET_GLES2
    color.setStorage(RenderbufferFormat::RGBA8, Vector2i(128));
    #else
    color.setStorage(RenderbufferFormat::RGBA4, Vector2i(128));
    #endif

    /* 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;
    #ifdef MAGNUM_TARGET_GLES2
    if(Context::current()->isExtensionSupported<Extensions::GL::OES::packed_depth_stencil>())
    #endif
    {
        #ifdef MAGNUM_TARGET_GLES2
        Debug() << "Using" << Extensions::GL::OES::packed_depth_stencil::string();
        #endif
        depthStencil.setStorage(RenderbufferFormat::Depth24Stencil8, Vector2i(128));
    }
    #ifdef MAGNUM_TARGET_GLES2
    else depthStencil.setStorage(RenderbufferFormat::DepthComponent16, Vector2i(128));
    #endif

    Framebuffer framebuffer({{}, Vector2i(128)});
    framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), color)
               .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, depthStencil);

    #ifdef MAGNUM_TARGET_GLES2
    if(Context::current()->isExtensionSupported<Extensions::GL::OES::packed_depth_stencil>())
    #endif
    {
        framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment::Stencil, depthStencil);
    }

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(framebuffer.checkStatus(FramebufferTarget::ReadDraw), Framebuffer::Status::Complete);

    Renderer::setClearColor(Math::normalize<Color4>(Color4ub(128, 64, 32, 17)));
    Renderer::setClearDepth(Math::normalize<Float, UnsignedShort>(48352));
    Renderer::setClearStencil(67);
    framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil);

    Image2D colorImage(ColorFormat::RGBA, ColorType::UnsignedByte);
    framebuffer.read({16, 8}, {8, 16}, colorImage);
    CORRADE_COMPARE(colorImage.size(), Vector2i(8, 16));

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_COMPARE(colorImage.data<Color4ub>()[0], Color4ub(128, 64, 32, 17));

    #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(ColorFormat::DepthComponent, ColorType::UnsignedShort);
        framebuffer.read({}, Vector2i(1), depthImage);

        MAGNUM_VERIFY_NO_ERROR();
        CORRADE_COMPARE(depthImage.data<UnsignedShort>()[0], 48352);
    }

    #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(ColorFormat::StencilIndex, ColorType::UnsignedByte);
        framebuffer.read({}, Vector2i(1), stencilImage);

        MAGNUM_VERIFY_NO_ERROR();
        CORRADE_COMPARE(stencilImage.data<UnsignedByte>()[0], 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(ColorFormat::DepthStencil, ColorType::UnsignedInt248);
        framebuffer.read({}, Vector2i(1), depthStencilImage);

        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);
    }
 void Framebuffer::attachDepthBuffer(const Renderbuffer& rb)
 {
     bind();
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb.getHandle());
     _depth = true;
 }
 void Framebuffer::attachColorBuffer(const Renderbuffer& rb)
 {
     bind();
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb.getHandle());
     _color = true;
 }