summaryrefslogtreecommitdiff
path: root/src/mbgl/gl/offscreen_texture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/gl/offscreen_texture.cpp')
-rw-r--r--src/mbgl/gl/offscreen_texture.cpp87
1 files changed, 87 insertions, 0 deletions
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