Mercurial > fife-parpg
changeset 571:edc9efe969c2
This commit should fix the coloring overlay bug exposed by the commit in revision 3386. The InstanceRenderer was caching the overlays based on whether the current image had changed. The fix takes into account the current image as well as the overlay color to decide whether or not the overlay needs to be reproduced.
author | vtchill@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Tue, 29 Jun 2010 02:26:28 +0000 |
parents | 0e0a30f0eb20 |
children | da381ecca97d |
files | engine/core/view/renderers/instancerenderer.cpp engine/core/view/renderers/instancerenderer.h |
diffstat | 2 files changed, 49 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/engine/core/view/renderers/instancerenderer.cpp Mon Jun 28 21:28:44 2010 +0000 +++ b/engine/core/view/renderers/instancerenderer.cpp Tue Jun 29 02:26:28 2010 +0000 @@ -59,6 +59,7 @@ g(0), b(0), width(1), + dirty(false), outline(NULL), curimg(NULL) { } @@ -66,6 +67,7 @@ r(0), g(0), b(0), + dirty(false), overlay(NULL), curimg(NULL) { } @@ -161,7 +163,8 @@ } Image* InstanceRenderer::bindOutline(OutlineInfo& info, RenderItem& vc, Camera* cam) { - if (info.curimg == vc.image) { + if (!info.dirty && info.curimg == vc.image) { + // optimization for outline that has not changed return info.outline; } else { info.curimg = vc.image; @@ -222,19 +225,29 @@ // In case of OpenGL backend, SDLImage needs to be converted info.outline = m_renderbackend->createImage(img->detachSurface()); delete img; + + if (info.outline) { + // mark outline as not dirty since we created it here + info.dirty = false; + } + return info.outline; } Image* InstanceRenderer::bindColoring(ColoringInfo& info, RenderItem& vc, Camera* cam) { - if (info.curimg == vc.image) { + if (!info.dirty && info.curimg == vc.image) { + // optimization for coloring overlay that has not changed return info.overlay; - } else { + } + else { info.curimg = vc.image; } + if (info.overlay) { delete info.overlay; // delete old mask info.overlay = NULL; } + SDL_Surface* surface = vc.image->getSurface(); SDL_Surface* overlay_surface = SDL_ConvertSurface(surface, surface->format, surface->flags); @@ -255,6 +268,12 @@ // In case of OpenGL backend, SDLImage needs to be converted info.overlay = m_renderbackend->createImage(img->detachSurface()); delete img; + + if (info.overlay) { + // mark overlay coloring as not dirty since we created it here + info.dirty = false; + } + return info.overlay; } @@ -264,6 +283,7 @@ newinfo.g = g; newinfo.b = b; newinfo.width = width; + newinfo.dirty = true; // attempts to insert the element into the outline map // will return false in the second value of the pair if the instance already exists @@ -271,15 +291,20 @@ // existing data for the instance std::pair<InstanceToOutlines_t::iterator, bool> insertiter = m_instance_outlines.insert(std::make_pair(instance, newinfo)); - if (insertiter.second == false) - { + if (insertiter.second == false) { // the insertion did not happen because the instance // already exists in the map so lets just update its outline info OutlineInfo& info = insertiter.first->second; - info.r = r; - info.b = b; - info.g = g; - info.width = width; + + if (info.r != r || info.g != g || info.b != b || info.width != width) { + // only update the outline info if its changed since the last call + // flag the outline info as dirty so it will get processed during rendering + info.r = r; + info.b = b; + info.g = g; + info.width = width; + info.dirty = true; + } } } @@ -288,21 +313,27 @@ newinfo.r = r; newinfo.g = g; newinfo.b = b; - + newinfo.dirty = true; + // attempts to insert the element into the coloring map // will return false in the second value of the pair if the instance already exists // in the map and the first value of the pair will then be an iterator to the // existing data for the instance std::pair<InstanceToColoring_t::iterator, bool> insertiter = m_instance_colorings.insert(std::make_pair(instance, newinfo)); - if (insertiter.second == false) - { + if (insertiter.second == false) { // the insertion did not happen because the instance // already exists in the map so lets just update its coloring info ColoringInfo& info = insertiter.first->second; - info.r = r; - info.b = b; - info.g = g; + + if (info.r != r || info.g != g || info.b != b) { + // only update the coloring info if its changed since the last call + // flag the coloring info as dirty so it will get processed during rendering + info.r = r; + info.b = b; + info.g = g; + info.dirty = true; + } } }
--- a/engine/core/view/renderers/instancerenderer.h Mon Jun 28 21:28:44 2010 +0000 +++ b/engine/core/view/renderers/instancerenderer.h Tue Jun 29 02:26:28 2010 +0000 @@ -98,6 +98,7 @@ uint8_t g; uint8_t b; int width; + bool dirty; Image* outline; Image* curimg; OutlineInfo(); @@ -109,6 +110,7 @@ uint8_t r; uint8_t g; uint8_t b; + bool dirty; Image* overlay; Image* curimg; ColoringInfo(); @@ -116,6 +118,7 @@ }; typedef std::map<Instance*, OutlineInfo> InstanceToOutlines_t; typedef std::map<Instance*, ColoringInfo> InstanceToColoring_t; + //typedef std::map<int, ColoringInfo> InstanceToColoring_t; InstanceToOutlines_t m_instance_outlines; InstanceToColoring_t m_instance_colorings;