diff options
author | Lauren Budorick <lauren@mapbox.com> | 2017-09-06 14:45:15 -0700 |
---|---|---|
committer | Lauren Budorick <lauren@mapbox.com> | 2017-09-07 13:55:52 -0700 |
commit | fb9c31607e2ada734bee69ed375b2d42f1ac612e (patch) | |
tree | 12fe43df7815d1f6f534214ebef7239c672dbaa8 | |
parent | f8a53234ffa6ff3fd1d8fc8e3aa8b10b16c815fd (diff) | |
download | qtlocation-mapboxgl-fb9c31607e2ada734bee69ed375b2d42f1ac612e.tar.gz |
Share single depth renderbuffer between fill-extrusion textures
-rw-r--r-- | src/mbgl/gl/context.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/gl/renderbuffer.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp | 193 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_parameters.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_parameters.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/render_pass.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/render_static_data.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 66 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.cpp | 33 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.hpp | 9 |
12 files changed, 183 insertions, 145 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index e18f1e0bcf..919d386ecd 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -454,15 +454,10 @@ Framebuffer Context::createFramebuffer(const Texture& color) { return { color.size, std::move(fbo) }; } -Framebuffer -Context::createFramebuffer(const Texture& color, - const Renderbuffer<RenderbufferType::DepthComponent>& depthTarget) { - auto fbo = createFramebuffer(); - bindFramebuffer = fbo; - MBGL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color.texture, 0)); +void +Context::attachRenderbuffer(const Renderbuffer<RenderbufferType::DepthComponent>& depthTarget) { MBGL_CHECK_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthTarget.renderbuffer)); checkFramebuffer(); - return { depthTarget.size, std::move(fbo) }; } UniqueTexture diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 9923567276..066dff4ab4 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -96,8 +96,8 @@ public: Framebuffer createFramebuffer(const Texture&, const Renderbuffer<RenderbufferType::DepthStencil>&); Framebuffer createFramebuffer(const Texture&); - Framebuffer createFramebuffer(const Texture&, - const Renderbuffer<RenderbufferType::DepthComponent>&); + + void attachRenderbuffer(const Renderbuffer<RenderbufferType::DepthComponent>&); template <typename Image, TextureFormat format = Image::channels == 4 ? TextureFormat::RGBA diff --git a/src/mbgl/gl/renderbuffer.hpp b/src/mbgl/gl/renderbuffer.hpp index cc8ff13268..23d6590bf5 100644 --- a/src/mbgl/gl/renderbuffer.hpp +++ b/src/mbgl/gl/renderbuffer.hpp @@ -12,6 +12,7 @@ public: using type = std::integral_constant<RenderbufferType, renderbufferType>; Size size; gl::UniqueRenderbuffer renderbuffer; + bool dirty = false; }; } // namespace gl diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 6295f62b21..9bcde2abc4 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -37,8 +37,9 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); - passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? RenderPass::Translucent - : RenderPass::None; + passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) + ? (RenderPass::Translucent | RenderPass::Pass3D) + : RenderPass::None; } bool RenderFillExtrusionLayer::hasTransition() const { @@ -50,113 +51,99 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* return; } - const auto size = parameters.context.viewport.getCurrentValue().size; + if (parameters.pass == RenderPass::Pass3D) { + const auto size = parameters.context.viewport.getCurrentValue().size; - if (!parameters.staticData.extrusionTexture || parameters.staticData.extrusionTexture->getSize() != size) { - parameters.staticData.extrusionTexture = OffscreenTexture(parameters.context, size, OffscreenTextureAttachment::Depth); - } - - parameters.staticData.extrusionTexture->bind(); - - parameters.context.setStencilMode(gl::StencilMode::disabled()); - parameters.context.setDepthMode(parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite)); - parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, 1.0f, {}); - - if (evaluated.get<FillExtrusionPattern>().from.empty()) { - for (const RenderTile& tile : renderTiles) { - assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl))); - FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); - - parameters.programs.fillExtrusion.get(evaluated).draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - FillExtrusionUniforms::values( - tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), - evaluated.get<FillExtrusionTranslateAnchor>(), - parameters.state), - parameters.state, - parameters.evaluatedLight - ), - *bucket.vertexBuffer, - *bucket.indexBuffer, - bucket.triangleSegments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), - getID()); + if (!renderTexture || renderTexture->getSize() != size) { + renderTexture = OffscreenTexture(parameters.context, size); } - } else { - optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from); - optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to); - if (!imagePosA || !imagePosB) { - return; + renderTexture->bind(); + renderTexture->attachRenderbuffer(*parameters.staticData.depthRenderbuffer); + + parameters.context.setStencilMode(gl::StencilMode::disabled()); + optional<float> depthClearValue = {}; + if (parameters.staticData.depthRenderbuffer->dirty) depthClearValue = 1.0; + parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); + parameters.staticData.depthRenderbuffer->dirty = false; + + if (evaluated.get<FillExtrusionPattern>().from.empty()) { + for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl))); + FillExtrusionBucket& bucket = + *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); + + parameters.programs.fillExtrusion.get(evaluated).draw( + parameters.context, gl::Triangles(), + parameters.depthModeFor3D(gl::DepthMode::ReadWrite), + gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + FillExtrusionUniforms::values( + tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), + evaluated.get<FillExtrusionTranslateAnchor>(), + parameters.state), + parameters.state, parameters.evaluatedLight), + *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments, + bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(), + getID()); + } + } else { + optional<ImagePosition> imagePosA = + parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from); + optional<ImagePosition> imagePosB = + parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to); + + if (!imagePosA || !imagePosB) { + return; + } + + parameters.imageManager.bind(parameters.context, 0); + + for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl))); + FillExtrusionBucket& bucket = + *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); + + parameters.programs.fillExtrusionPattern.get(evaluated).draw( + parameters.context, gl::Triangles(), + parameters.depthModeFor3D(gl::DepthMode::ReadWrite), + gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + FillExtrusionPatternUniforms::values( + tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), + evaluated.get<FillExtrusionTranslateAnchor>(), + parameters.state), + parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, + evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state, + -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, + parameters.evaluatedLight), + *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments, + bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(), + getID()); + } } - parameters.imageManager.bind(parameters.context, 0); - - for (const RenderTile& tile : renderTiles) { - assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl))); - FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); - - parameters.programs.fillExtrusionPattern.get(evaluated).draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadWrite), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - FillExtrusionPatternUniforms::values( - tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), - evaluated.get<FillExtrusionTranslateAnchor>(), - parameters.state), - parameters.imageManager.getPixelSize(), - *imagePosA, - *imagePosB, - evaluated.get<FillExtrusionPattern>(), - tile.id, - parameters.state, - -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, - parameters.evaluatedLight - ), - *bucket.vertexBuffer, - *bucket.indexBuffer, - bucket.triangleSegments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), - getID()); - } - } + } else if (parameters.pass == RenderPass::Translucent) { + parameters.context.bindTexture(renderTexture->getTexture()); - parameters.backend.bind(); - parameters.context.bindTexture(parameters.staticData.extrusionTexture->getTexture()); - - mat4 viewportMat; - matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); - - const Properties<>::PossiblyEvaluated properties; - - parameters.programs.extrusionTexture.draw( - parameters.context, - gl::Triangles(), - gl::DepthMode::disabled(), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), - ExtrusionTextureProgram::UniformValues{ - uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, - uniforms::u_image::Value{ 0 }, - uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } - }, - parameters.staticData.extrusionTextureVertexBuffer, - parameters.staticData.quadTriangleIndexBuffer, - parameters.staticData.extrusionTextureSegments, - ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, - properties, - parameters.state.getZoom(), - getID()); + const auto size = parameters.context.viewport.getCurrentValue().size; + + mat4 viewportMat; + matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); + + const Properties<>::PossiblyEvaluated properties; + + parameters.programs.extrusionTexture.draw( + parameters.context, gl::Triangles(), gl::DepthMode::disabled(), + gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + ExtrusionTextureProgram::UniformValues{ + uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, + uniforms::u_image::Value{ 0 }, + uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } }, + parameters.staticData.extrusionTextureVertexBuffer, + parameters.staticData.quadTriangleIndexBuffer, + parameters.staticData.extrusionTextureSegments, + ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, + parameters.state.getZoom(), getID()); + } } bool RenderFillExtrusionLayer::queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index a53e00ca6f..838494cf91 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -3,6 +3,8 @@ #include <mbgl/renderer/render_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> #include <mbgl/style/layers/fill_extrusion_layer_properties.hpp> +#include <mbgl/util/optional.hpp> +#include <mbgl/util/offscreen_texture.hpp> namespace mbgl { @@ -30,6 +32,8 @@ public: style::FillExtrusionPaintProperties::PossiblyEvaluated evaluated; const style::FillExtrusionLayer::Impl& impl() const; + + optional<OffscreenTexture> renderTexture; }; template <> diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index 584dcdf118..299db844bc 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -62,6 +62,10 @@ gl::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gl::DepthMode::Ma return gl::DepthMode { gl::DepthMode::LessEqual, mask, { nearDepth, farDepth } }; } +gl::DepthMode PaintParameters::depthModeFor3D(gl::DepthMode::Mask mask) const { + return gl::DepthMode { gl::DepthMode::LessEqual, mask, { 0.0, 1.0 } }; +} + gl::StencilMode PaintParameters::stencilModeForClipping(const ClipID& id) const { return gl::StencilMode { gl::StencilMode::Equal { static_cast<uint32_t>(id.mask.to_ulong()) }, diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index eb1ad73ad5..4a2c2c6f12 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -60,6 +60,7 @@ public: Programs& programs; gl::DepthMode depthModeForSublayer(uint8_t n, gl::DepthMode::Mask) const; + gl::DepthMode depthModeFor3D(gl::DepthMode::Mask) const; gl::StencilMode stencilModeForClipping(const ClipID&) const; gl::ColorMode colorModeForRenderPass() const; diff --git a/src/mbgl/renderer/render_pass.hpp b/src/mbgl/renderer/render_pass.hpp index ae2b923ba1..5d18304129 100644 --- a/src/mbgl/renderer/render_pass.hpp +++ b/src/mbgl/renderer/render_pass.hpp @@ -11,6 +11,7 @@ enum class RenderPass : uint8_t { None = 0, Opaque = 1 << 0, Translucent = 1 << 1, + Pass3D = 1 << 2, }; MBGL_CONSTEXPR RenderPass operator|(RenderPass a, RenderPass b) { diff --git a/src/mbgl/renderer/render_static_data.hpp b/src/mbgl/renderer/render_static_data.hpp index 07a47b4c8f..040c6bc524 100644 --- a/src/mbgl/renderer/render_static_data.hpp +++ b/src/mbgl/renderer/render_static_data.hpp @@ -4,7 +4,6 @@ #include <mbgl/gl/index_buffer.hpp> #include <mbgl/programs/programs.hpp> #include <mbgl/util/optional.hpp> -#include <mbgl/util/offscreen_texture.hpp> #include <string> @@ -26,7 +25,7 @@ public: SegmentVector<RasterAttributes> rasterSegments; SegmentVector<ExtrusionTextureAttributes> extrusionTextureSegments; - optional<OffscreenTexture> extrusionTexture; + optional<gl::Renderbuffer<gl::RenderbufferType::DepthComponent>> depthRenderbuffer; Programs programs; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 9894bdc12f..828a37f503 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -369,6 +369,63 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.frameHistory.upload(parameters.context, 0); } + // - PREPARE + CLIP ------------------------------------------------------------------------------ + { + MBGL_DEBUG_GROUP(parameters.context, "clip"); + + // Update all clipping IDs. + for (const auto& entry : renderSources) { + if (entry.second->isEnabled()) { + entry.second->startRender(parameters); + } + } + } + + // - 3D PASS ------------------------------------------------------------------------------------- + // Renders any 3D layers bottom-to-top to unique FBOs with texture attachments, but share the same + // depth rbo between them. + int indent = 0; + + if (debug::renderTree) { + Log::Info(Event::Render, "{"); + indent++; + } + + { + parameters.pass = RenderPass::Pass3D; + MBGL_DEBUG_GROUP(parameters.context, "3d"); + + if (debug::renderTree) { + Log::Info(Event::Render, "%*s%s {", indent++ * 4, "", "3D"); + } + + const auto size = parameters.context.viewport.getCurrentValue().size; + + if (!parameters.staticData.depthRenderbuffer || + parameters.staticData.depthRenderbuffer->size != size) { + parameters.staticData.depthRenderbuffer = + parameters.context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(size); + } + parameters.staticData.depthRenderbuffer->dirty = true; + + uint32_t i = static_cast<uint32_t>(order.size()) - 1; + for (auto it = order.begin(); it != order.end(); ++it, --i) { + parameters.currentLayer = i; + if (it->layer.hasRenderPass(parameters.pass)) { + MBGL_DEBUG_GROUP(parameters.context, it->layer.getID()); + it->layer.render(parameters, it->source); + } + } + + parameters.backend.bind(); + + if (debug::renderTree) { + Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}"); + } + } + + if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; } + // - CLEAR ------------------------------------------------------------------------------------- // Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any // tiles whatsoever. @@ -385,15 +442,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { // - CLIPPING MASKS ---------------------------------------------------------------------------- // Draws the clipping masks to the stencil buffer. { - MBGL_DEBUG_GROUP(parameters.context, "clip"); - - // Update all clipping IDs. - for (const auto& entry : renderSources) { - if (entry.second->isEnabled()) { - entry.second->startRender(parameters); - } - } - MBGL_DEBUG_GROUP(parameters.context, "clipping masks"); static const style::FillPaintProperties::PossiblyEvaluated properties {}; diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp index 77a1416e48..c0549a3f56 100644 --- a/src/mbgl/util/offscreen_texture.cpp +++ b/src/mbgl/util/offscreen_texture.cpp @@ -11,23 +11,15 @@ OffscreenTexture& OffscreenTexture::operator=(OffscreenTexture&&) = default; class OffscreenTexture::Impl { public: - Impl(gl::Context& context_, const Size size_, OffscreenTextureAttachment type_) - : context(context_), size(std::move(size_)), type(type_) { + Impl(gl::Context& context_, const Size size_) + : context(context_), size(std::move(size_)) { assert(!size.isEmpty()); } void bind() { if (!framebuffer) { texture = context.createTexture(size, gl::TextureFormat::RGBA); - - if (type == OffscreenTextureAttachment::Depth) { - gl::Renderbuffer<gl::RenderbufferType::DepthComponent> depth = - context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(size); - framebuffer = context.createFramebuffer(*texture, depth); - - } else { - framebuffer = context.createFramebuffer(*texture); - } + framebuffer = context.createFramebuffer(*texture); } else { context.bindFramebuffer = framebuffer->framebuffer; } @@ -37,6 +29,13 @@ public: context.viewport = { 0, 0, size }; } + void attachRenderbuffer(gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& renderbuffer) { + if (!attachedRenderbuffer || attachedRenderbuffer != &renderbuffer.renderbuffer) { + context.attachRenderbuffer(renderbuffer); + attachedRenderbuffer = &renderbuffer.renderbuffer; + } + } + PremultipliedImage readStillImage() { return context.readFramebuffer<PremultipliedImage>(size); } @@ -53,15 +52,14 @@ public: private: gl::Context& context; const Size size; - OffscreenTextureAttachment type; optional<gl::Framebuffer> framebuffer; optional<gl::Texture> texture; + gl::UniqueRenderbuffer* attachedRenderbuffer = nullptr; }; OffscreenTexture::OffscreenTexture(gl::Context& context, - const Size size, - OffscreenTextureAttachment type) - : impl(std::make_unique<Impl>(context, std::move(size), type)) { + const Size size) + : impl(std::make_unique<Impl>(context, std::move(size))) { assert(!size.isEmpty()); } @@ -71,6 +69,11 @@ void OffscreenTexture::bind() { impl->bind(); } +void OffscreenTexture::attachRenderbuffer( + gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& renderbuffer) { + impl->attachRenderbuffer(renderbuffer); +} + PremultipliedImage OffscreenTexture::readStillImage() { return impl->readStillImage(); } diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp index 0353f3f9c5..4031b5fdcf 100644 --- a/src/mbgl/util/offscreen_texture.hpp +++ b/src/mbgl/util/offscreen_texture.hpp @@ -9,21 +9,16 @@ class Context; class Texture; } // namespace gl -enum class OffscreenTextureAttachment { - None, - Depth, -}; - class OffscreenTexture { public: OffscreenTexture(gl::Context&, - Size size = { 256, 256 }, - OffscreenTextureAttachment type = OffscreenTextureAttachment::None); + Size size = { 256, 256 }); ~OffscreenTexture(); OffscreenTexture(OffscreenTexture&&); OffscreenTexture& operator=(OffscreenTexture&&); void bind(); + void attachRenderbuffer(gl::Renderbuffer<gl::RenderbufferType::DepthComponent>&); PremultipliedImage readStillImage(); |