diff options
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/context.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/gl/offscreen_texture.cpp | 87 | ||||
-rw-r--r-- | src/mbgl/gl/offscreen_texture.hpp | 26 |
4 files changed, 132 insertions, 0 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index f4e565c766..d33ae067f6 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -6,6 +6,7 @@ #include <mbgl/gl/renderbuffer_resource.hpp> #include <mbgl/gl/draw_scope_resource.hpp> #include <mbgl/gl/texture.hpp> +#include <mbgl/gl/offscreen_texture.hpp> #include <mbgl/gl/command_encoder.hpp> #include <mbgl/gl/debugging_extension.hpp> #include <mbgl/gl/vertex_array_extension.hpp> @@ -553,6 +554,17 @@ void Context::updateTextureResourceSub(gfx::TextureResource& resource, Enum<gfx::TextureChannelDataType>::to(type), data)); } +std::unique_ptr<gfx::OffscreenTexture> +Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) { + return std::make_unique<gl::OffscreenTexture>(*this, size, type); +} + +std::unique_ptr<gfx::OffscreenTexture> +Context::createOffscreenTexture(const Size size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth, + gfx::TextureChannelDataType type) { + return std::make_unique<gl::OffscreenTexture>(*this, size, depth, type); +} std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() { return std::make_unique<gl::DrawScopeResource>(createVertexArray()); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 530ff1c73f..2fb1d242ce 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -201,6 +201,13 @@ private: void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, + gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override; diff --git a/src/mbgl/gl/offscreen_texture.cpp b/src/mbgl/gl/offscreen_texture.cpp new file mode 100644 index 0000000000..96d8b7e4c4 --- /dev/null +++ b/src/mbgl/gl/offscreen_texture.cpp @@ -0,0 +1,87 @@ +#include <mbgl/gl/offscreen_texture.hpp> +#include <mbgl/gl/renderable_resource.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/framebuffer.hpp> + +namespace mbgl { +namespace gl { + +class OffscreenTextureResource final : public gl::RenderableResource { +public: + OffscreenTextureResource(gl::Context& context_, + const Size size_, + const gfx::TextureChannelDataType type_) + : context(context_), size(size_), type(type_) { + assert(!size.isEmpty()); + } + + OffscreenTextureResource(gl::Context& context_, + const Size size_, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth_, + const gfx::TextureChannelDataType type_) + : context(context_), size(size_), depth(&depth_), type(type_) { + assert(!size.isEmpty()); + } + + void bind() override { + if (!framebuffer) { + texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type); + if (depth) { + framebuffer = context.createFramebuffer(*texture, *depth); + } else { + framebuffer = context.createFramebuffer(*texture); + } + } else { + context.bindFramebuffer = framebuffer->framebuffer; + } + + context.activeTextureUnit = 0; + context.scissorTest = false; + context.viewport = { 0, 0, size }; + } + + PremultipliedImage readStillImage() { + assert(framebuffer); + context.bindFramebuffer = framebuffer->framebuffer; + return context.readFramebuffer<PremultipliedImage>(size); + } + + gfx::Texture& getTexture() { + assert(texture); + return *texture; + } + +private: + gl::Context& context; + const Size size; + optional<gfx::Texture> texture; + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>* depth = nullptr; + const gfx::TextureChannelDataType type; + optional<gl::Framebuffer> framebuffer; +}; + +OffscreenTexture::OffscreenTexture(gl::Context& context, + const Size size_, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type)) { +} + +OffscreenTexture::OffscreenTexture( + gl::Context& context, + const Size size_, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& renderbuffer, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture( + size, std::make_unique<OffscreenTextureResource>(context, size_, renderbuffer, type)) { +} + +PremultipliedImage OffscreenTexture::readStillImage() { + return getResource<OffscreenTextureResource>().readStillImage(); +} + +gfx::Texture& OffscreenTexture::getTexture() { + return getResource<OffscreenTextureResource>().getTexture(); +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/offscreen_texture.hpp b/src/mbgl/gl/offscreen_texture.hpp new file mode 100644 index 0000000000..5b211df505 --- /dev/null +++ b/src/mbgl/gl/offscreen_texture.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <mbgl/gfx/offscreen_texture.hpp> +#include <mbgl/gfx/renderbuffer.hpp> + +namespace mbgl { +namespace gl { + +class Context; + +class OffscreenTexture final : public gfx::OffscreenTexture { +public: + OffscreenTexture(gl::Context&, + Size size, + gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); + OffscreenTexture(gl::Context&, + Size size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, + gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); + + PremultipliedImage readStillImage() override; + gfx::Texture& getTexture() override; +}; + +} // namespace gl +} // namespace mbgl |