From c90a55959980f9ef9678a45b9c9ded906d637b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 4 Nov 2016 17:39:14 +0100 Subject: [core] move framebuffer reading to gl::Context --- src/mbgl/gl/context.cpp | 26 ++++++++++++++++++++++++++ src/mbgl/gl/context.hpp | 10 ++++++++++ src/mbgl/gl/types.hpp | 4 ++++ 3 files changed, 40 insertions(+) (limited to 'src/mbgl/gl') diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 1cd546f407..811a038caf 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -92,6 +92,32 @@ UniqueRenderbuffer Context::createRenderbuffer(const RenderbufferType type, cons return renderbuffer; } +std::unique_ptr Context::readFramebuffer(const Size size, const TextureFormat format, const bool flip) { + const size_t stride = size.width * (format == TextureFormat::RGBA ? 4 : 1); + auto data = std::make_unique(stride * size.height); + +#if not MBGL_USE_GLES2 + // When reading data from the framebuffer, make sure that we are storing the values + // tightly packed into the buffer to avoid buffer overruns. + pixelStorePack = { 1 }; +#endif // MBGL_USE_GLES2 + + MBGL_CHECK_ERROR(glReadPixels(0, 0, size.width, size.height, static_cast(format), + GL_UNSIGNED_BYTE, data.get())); + + if (flip) { + auto tmp = std::make_unique(stride); + uint8_t* rgba = data.get(); + for (int i = 0, j = size.height - 1; i < j; i++, j--) { + std::memcpy(tmp.get(), rgba + i * stride, stride); + std::memcpy(rgba + i * stride, rgba + j * stride, stride); + std::memcpy(rgba + j * stride, tmp.get(), stride); + } + } + + return data; +} + namespace { void checkFramebuffer() { diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 9bfa54fa55..169aa5566e 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -62,6 +62,15 @@ public: const Renderbuffer&); Framebuffer createFramebuffer(const Texture&); + template + Image readFramebuffer(const Size size, bool flip = true) { + static_assert(Image::channels == (format == TextureFormat::RGBA ? 4 : 1), + "image format mismatch"); + return { size, readFramebuffer(size, format, flip) }; + } + // Create a texture from an image with data. template Texture createTexture(const Image& image, TextureUnit unit = 0) { @@ -167,6 +176,7 @@ private: void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit); UniqueFramebuffer createFramebuffer(); UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size); + std::unique_ptr readFramebuffer(Size, TextureFormat, bool flip); PrimitiveType operator()(const Points&); PrimitiveType operator()(const Lines&); diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 6e1bc5f8e1..1697656469 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -50,6 +50,10 @@ enum class TextureWrap : bool { Clamp, Repeat }; enum class TextureFormat : uint32_t { RGBA = 0x1908, Alpha = 0x1906, +#if not MBGL_USE_GLES2 + Stencil = 0x1901, + Depth = 0x1902, +#endif // MBGL_USE_GLES2 }; enum class PrimitiveType { -- cgit v1.2.1