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."));
    if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>())
        CORRADE_SKIP(Extensions::GL::ARB::invalidate_subdata::string() + std::string(" is not available."));
    #elif defined(MAGNUM_TARGET_GLES2)
    if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::discard_framebuffer>())
        CORRADE_SKIP(Extensions::GL::EXT::discard_framebuffer::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

    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();
}
void FramebufferGLTest::invalidate() {
    #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::invalidate_subdata>())
        CORRADE_SKIP(Extensions::GL::ARB::invalidate_subdata::string() + std::string(" is not available."));
    #elif defined(MAGNUM_TARGET_GLES2)
    if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::discard_framebuffer>())
        CORRADE_SKIP(Extensions::GL::EXT::discard_framebuffer::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

    Renderbuffer stencil;
    stencil.setStorage(RenderbufferFormat::StencilIndex8, Vector2i(128));

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

    MAGNUM_VERIFY_NO_ERROR();

    framebuffer.invalidate({Framebuffer::InvalidationAttachment::Depth, Framebuffer::ColorAttachment(0)});

    MAGNUM_VERIFY_NO_ERROR();
}
Exemple #3
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
}
void SampleQueryGLTest::conditionalRender() {
    if(!Context::current()->isExtensionSupported<Extensions::GL::NV::conditional_render>())
        CORRADE_SKIP(Extensions::GL::NV::conditional_render::string() + std::string(" is not available."));

    Renderbuffer renderbuffer;
    renderbuffer.setStorage(RenderbufferFormat::RGBA8, Vector2i(32));

    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, Attribute<0, Vector2>{});

    MyShader shader;
    framebuffer.bind();

    MAGNUM_VERIFY_NO_ERROR();

    SampleQuery qYes{SampleQuery::Target::SamplesPassed},
        qNo{SampleQuery::Target::SamplesPassed},
        q{SampleQuery::Target::SamplesPassed};

    /* This should generate some samples */
    qYes.begin();
    mesh.draw(shader);
    qYes.end();

    /* Thus this should be rendered */
    qYes.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
    q.begin();
    mesh.draw(shader);
    q.end();
    qYes.endConditionalRender();

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_VERIFY(qYes.result<bool>());
    CORRADE_VERIFY(q.result<bool>());

    /* This shouldn't generate any samples */
    qNo.begin();
    qNo.end();

    /* Thus this should not be rendered */
    qNo.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
    q.begin();
    mesh.draw(shader);
    q.end();
    qNo.endConditionalRender();

    MAGNUM_VERIFY_NO_ERROR();
    CORRADE_VERIFY(!qNo.result<bool>());
    CORRADE_VERIFY(!q.result<bool>());
}
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);
}
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);
}
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);
    }