# HG changeset patch # User vtchill@33b003aa-7bff-0310-803a-e67f0ece8222 # Date 1277778388 0 # Node ID edc9efe969c2a5bce2a128a92ac24e74de7540fa # Parent 0e0a30f0eb20521d55c21a99e9034308a3afb34f 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. diff -r 0e0a30f0eb20 -r edc9efe969c2 engine/core/view/renderers/instancerenderer.cpp --- 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 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 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; + } } } diff -r 0e0a30f0eb20 -r edc9efe969c2 engine/core/view/renderers/instancerenderer.h --- 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 InstanceToOutlines_t; typedef std::map InstanceToColoring_t; + //typedef std::map InstanceToColoring_t; InstanceToOutlines_t m_instance_outlines; InstanceToColoring_t m_instance_colorings;