From 6ae0b71bbbf10d42b2b2b89685fbee78ac16297f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Thu, 22 May 2014 14:15:51 +0200 Subject: [PATCH] fix framebuffer drawing on ios --- include/llmr/map/transform_state.hpp | 1 + include/llmr/renderer/painter.hpp | 1 + src/map/map.cpp | 22 +++++++++++----------- src/map/transform_state.cpp | 4 ++++ src/renderer/painter_composite.cpp | 2 +- src/renderer/painter_framebuffers.cpp | 14 +++++++++++++- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/include/llmr/map/transform_state.hpp b/include/llmr/map/transform_state.hpp index a6c69cae3..29d0f59c4 100644 --- a/include/llmr/map/transform_state.hpp +++ b/include/llmr/map/transform_state.hpp @@ -19,6 +19,7 @@ public: box cornersToBox(uint32_t z) const; // Dimensions + bool hasSize() const; uint16_t getWidth() const; uint16_t getHeight() const; uint16_t getFramebufferWidth() const; diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 4f5646db6..a1db116b6 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -103,6 +103,7 @@ public: void bindFramebuffer(); void pushFramebuffer(); GLuint popFramebuffer(); + void discardFramebuffers(); void drawComposite(GLuint texture, const CompositeProperties &properties); bool needsAnimation() const; diff --git a/src/map/map.cpp b/src/map/map.cpp index ec47c6292..9df6ecb4b 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -134,15 +134,17 @@ void Map::render(uv_async_t *async) { map->prepare(); - if (map->is_rendered.test_and_set() == false) { - if (map->is_clean.test_and_set() == false) { - map->render(); - map->is_swapped.clear(); - map->view.swap(); - } else { - // We set the rendered flag in the test above, so we have to reset it - // now that we're not actually rendering because the map is clean. - map->is_rendered.clear(); + if (map->state.hasSize()) { + if (map->is_rendered.test_and_set() == false) { + if (map->is_clean.test_and_set() == false) { + map->render(); + map->is_swapped.clear(); + map->view.swap(); + } else { + // We set the rendered flag in the test above, so we have to reset it + // now that we're not actually rendering because the map is clean. + map->is_rendered.clear(); + } } } } @@ -556,8 +558,6 @@ void Map::renderLayers(const std::vector& layers) { if (debug::renderTree) { std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; } - - glFlush(); } template diff --git a/src/map/transform_state.cpp b/src/map/transform_state.cpp index b6a4e5bb2..c22678a4e 100644 --- a/src/map/transform_state.cpp +++ b/src/map/transform_state.cpp @@ -59,6 +59,10 @@ box TransformState::cornersToBox(uint32_t z) const { #pragma mark - Dimensions +bool TransformState::hasSize() const { + return width && height; +} + uint16_t TransformState::getWidth() const { return width; } diff --git a/src/renderer/painter_composite.cpp b/src/renderer/painter_composite.cpp index ac73bc80c..9ff5de108 100644 --- a/src/renderer/painter_composite.cpp +++ b/src/renderer/painter_composite.cpp @@ -11,7 +11,7 @@ void Painter::drawComposite(GLuint texture, const CompositeProperties &propertie // Normally, we're using premultiplied alpha, but the resulting image we've // just drawn is non-premultiplied. That means when blending, we have to make // sure that we account for that. - glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); useProgram(compositeShader->program); compositeShader->setMatrix(nativeMatrix); diff --git a/src/renderer/painter_framebuffers.cpp b/src/renderer/painter_framebuffers.cpp index e627c21b3..83a8e29ca 100644 --- a/src/renderer/painter_framebuffers.cpp +++ b/src/renderer/painter_framebuffers.cpp @@ -7,7 +7,11 @@ using namespace llmr; void Painter::clearFramebuffers() { +#ifdef TARGET_OS_IPHONE + glBindFramebuffer(GL_FRAMEBUFFER, 1); +#else glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif // Delete any framebuffers that we might have allocated glDeleteTextures((int)fbos_color.size(), fbos.data()); @@ -24,10 +28,18 @@ void Painter::clearFramebuffers() { void Painter::bindFramebuffer() { if (fbo_level < 0) { +#ifdef TARGET_OS_IPHONE + glBindFramebuffer(GL_FRAMEBUFFER, 1); +#else glBindFramebuffer(GL_FRAMEBUFFER, 0); - } else if (fbos.size() > (size_t)fbo_level) { +#endif + } else if (fbos.size() > (size_t) fbo_level) { GLuint fbo = fbos[fbo_level]; glBindFramebuffer(GL_FRAMEBUFFER, fbo); +#if GL_EXT_discard_framebuffer + const GLenum discards[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards); +#endif } else { // TODO: Convert this to textures so we can composite them and use them in blend operations