25 #include <boost/bind.hpp>
31 #include "video/renderbackend.h"
32 #include "video/image.h"
33 #include "video/imagemanager.h"
34 #include "video/sdl/sdlimage.h"
35 #include "video/animation.h"
36 #include "util/math/fife_math.h"
37 #include "util/log/logger.h"
38 #include "util/time/timemanager.h"
39 #include "model/metamodel/grids/cellgrid.h"
40 #include "model/metamodel/action.h"
41 #include "model/structures/instance.h"
42 #include "model/structures/layer.h"
43 #include "model/structures/location.h"
44 #include "model/structures/map.h"
45 #include "video/opengl/fife_opengl.h"
47 #include "view/camera.h"
48 #include "view/visual.h"
49 #include "instancerenderer.h"
51 #include "video/opengle/gleimage.h"
55 uint32_t scale(uint32_t val,
double factor) {
56 return static_cast<uint32_t
>(ceil(static_cast<double>(val) * factor));
61 static Logger _log(LM_VIEWVIEW);
63 class InstanceRendererDeleteListener :
public InstanceDeleteListener {
65 InstanceRendererDeleteListener(InstanceRenderer* r) {
68 virtual ~InstanceRendererDeleteListener() {}
70 virtual void onInstanceDeleted(Instance* instance) {
71 m_renderer->removeInstance(instance);
75 InstanceRenderer* m_renderer;
78 InstanceRenderer::OutlineInfo::OutlineInfo(InstanceRenderer* r):
87 InstanceRenderer::ColoringInfo::ColoringInfo(InstanceRenderer* r):
96 InstanceRenderer::AreaInfo::AreaInfo():
106 InstanceRenderer::OutlineInfo::~OutlineInfo() {
107 renderer->addToCheck(outline);
110 InstanceRenderer::ColoringInfo::~ColoringInfo() {
111 if (renderer->needColorBinding()) {
112 renderer->addToCheck(overlay);
116 InstanceRenderer::AreaInfo::~AreaInfo() {
119 InstanceRenderer* InstanceRenderer::getInstance(IRendererContainer* cnt) {
120 return dynamic_cast<InstanceRenderer*
>(cnt->getRenderer(
"InstanceRenderer"));
123 InstanceRenderer::InstanceRenderer(RenderBackend* renderbackend, int32_t position):
124 RendererBase(renderbackend, position),
127 m_timer_enabled(false) {
129 if(m_renderbackend->
getName() ==
"OpenGLe") {
130 m_need_sorting =
false;
132 m_need_sorting =
true;
133 if(m_renderbackend->
getName() ==
"SDL") {
134 m_need_bind_coloring =
true;
136 m_need_bind_coloring =
false;
140 m_timer.setInterval(m_interval);
141 m_timer.setCallback(boost::bind(&InstanceRenderer::check,
this));
143 m_delete_listener =
new InstanceRendererDeleteListener(
this);
146 InstanceRenderer::InstanceRenderer(
const InstanceRenderer& old):
149 m_interval(old.m_interval),
150 m_timer_enabled(false) {
152 if(m_renderbackend->
getName() ==
"OpenGLe") {
153 m_need_sorting =
false;
155 m_need_sorting =
true;
156 if(m_renderbackend->
getName() ==
"SDL") {
157 m_need_bind_coloring =
true;
159 m_need_bind_coloring =
false;
163 m_timer.setInterval(m_interval);
164 m_timer.setCallback(boost::bind(&InstanceRenderer::check,
this));
166 m_delete_listener =
new InstanceRendererDeleteListener(
this);
169 RendererBase* InstanceRenderer::clone() {
170 return new InstanceRenderer(*
this);
173 InstanceRenderer::~InstanceRenderer() {
175 if (!m_assigned_instances.empty()) {
179 delete m_delete_listener;
182 void InstanceRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
184 CellGrid* cg = layer->getCellGrid();
186 FL_WARN(_log,
"No cellgrid assigned to layer, cannot draw instances");
191 renderAlreadySorted(cam, layer, instances);
193 renderUnsorted(cam, layer, instances);
197 void InstanceRenderer::renderUnsorted(Camera* cam, Layer* layer, RenderList& instances)
200 const bool any_effects = !(m_instance_outlines.empty() && m_instance_colorings.empty());
201 const bool unlit = !m_unlit_groups.empty();
202 uint32_t lm = m_renderbackend->getLightingModel();
205 Map* parent = layer->getMap();
206 int num_layers = parent->getLayerCount();
208 const std::list<Layer*>& layers = parent->getLayers();
209 std::list<Layer*>::const_iterator iter = layers.begin();
210 for (; iter != layers.end(); ++iter, ++this_layer) {
211 if (*iter == layer) {
217 static const double global_z_min = -100.0;
218 static const double global_z_max = 100.0;
220 static const double depth_range = fabs(global_z_min - global_z_max);
229 double layer_depth_range = depth_range /
static_cast<double>(num_layers);
231 double layer_z_offset = global_z_min +
232 layer_depth_range *
static_cast<double>(this_layer) -
233 layer_depth_range * 0.5;
237 double layer_z_offset = global_z_max - (num_layers - (this_layer - 1)) * 20;
240 std::multimap<float, RenderItem*> transparentInstances;
242 RenderList::iterator instance_it = instances.begin();
243 for (;instance_it != instances.end(); ++instance_it) {
245 Instance* instance = (*instance_it)->instance;
246 RenderItem& vc = **instance_it;
247 float vertexZ =
static_cast<float>(layer_z_offset + vc.screenpoint.z);
250 if(vc.transparency == 255) {
252 InstanceToOutlines_t::iterator outline_it = m_instance_outlines.find(instance);
253 const bool outline = outline_it != m_instance_outlines.end();
255 Image* outline = bindOutline(outline_it->second, vc, cam);
256 outline->renderZ(vc.dimensions, vertexZ, 255, lm != 0 ?
true :
false);
257 vc.image->renderZ(vc.dimensions, vertexZ, 255);
260 InstanceToColoring_t::iterator coloring_it = m_instance_colorings.find(instance);
261 const bool coloring = coloring_it != m_instance_colorings.end();
263 uint8_t rgb[3] = { coloring_it->second.r, coloring_it->second.g, coloring_it->second.b };
264 vc.image->renderZ(vc.dimensions, vertexZ, 255,
false, rgb);
267 if (outline || coloring) {
273 if(lm != 0 && unlit) {
275 std::string lit_name = instance->getObject()->getNamespace();
276 std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
277 for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
278 if(lit_name.find(*unlit_it) != std::string::npos) {
284 vc.image->renderZ(vc.dimensions, vertexZ, 255, found ?
true :
false);
288 vc.image->renderZ(vc.dimensions, vertexZ, 255);
290 transparentInstances.insert(std::pair<float, RenderItem*>(vertexZ, &vc));
295 if(!transparentInstances.empty()) {
296 std::multimap<float, RenderItem*>::iterator it = transparentInstances.begin();
297 for( ; it != transparentInstances.end(); ++it) {
298 RenderItem& vc = *(it->second);
299 uint8_t alpha = vc.transparency;
300 float vertexZ = it->first;
303 InstanceToOutlines_t::iterator outline_it = m_instance_outlines.find(vc.instance);
304 const bool outline = outline_it != m_instance_outlines.end();
306 Image* outline = bindOutline(outline_it->second, vc, cam);
307 outline->renderZ(vc.dimensions, vertexZ, alpha, lm != 0 ?
true :
false);
308 vc.image->renderZ(vc.dimensions, vertexZ, alpha);
311 InstanceToColoring_t::iterator coloring_it = m_instance_colorings.find(vc.instance);
312 const bool coloring = coloring_it != m_instance_colorings.end();
314 uint8_t rgb[3] = { coloring_it->second.r, coloring_it->second.g, coloring_it->second.b };
315 vc.image->renderZ(vc.dimensions, vertexZ, alpha,
false, rgb);
318 if (outline || coloring) {
324 if(lm != 0 && unlit) {
326 std::string lit_name = vc.instance->getObject()->getNamespace();
327 std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
328 for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
329 if(lit_name.find(*unlit_it) != std::string::npos) {
335 vc.image->renderZ(vc.dimensions, vertexZ, alpha, found ?
true :
false);
339 vc.image->renderZ(vc.dimensions, vertexZ, alpha);
344 void InstanceRenderer::renderAlreadySorted(Camera* cam, Layer* layer, RenderList& instances) {
345 const bool any_effects = !(m_instance_outlines.empty() && m_instance_colorings.empty());
346 const bool unlit = !m_unlit_groups.empty();
347 uint32_t lm = m_renderbackend->getLightingModel();
349 m_area_layer =
false;
350 if(!m_instance_areas.empty()) {
351 InstanceToAreas_t::iterator area_it = m_instance_areas.begin();
352 for(;area_it != m_instance_areas.end(); area_it++) {
353 AreaInfo& info = area_it->second;
354 if(info.instance->getLocation().getLayer() == layer) {
356 DoublePoint3D instance_posv = cam->toVirtualScreenCoordinates(info.instance->getLocation().getMapCoordinates());
357 info.z = instance_posv.z;
364 RenderList::iterator instance_it = instances.begin();
365 for (;instance_it != instances.end(); ++instance_it) {
367 Instance* instance = (*instance_it)->instance;
368 RenderItem& vc = **instance_it;
371 InstanceToAreas_t::iterator areas_it = m_instance_areas.begin();
372 for(;areas_it != m_instance_areas.end(); areas_it++) {
373 AreaInfo& infoa = areas_it->second;
375 if(infoa.z >= vc.screenpoint.z) {
380 std::string str_name = instance->getObject()->getNamespace();
381 std::list<std::string>::iterator group_it = infoa.groups.begin();
382 for(;group_it != infoa.groups.end(); ++group_it) {
383 if(str_name.find((*group_it)) != std::string::npos) {
386 p = cam->toScreenCoordinates(infoa.instance->getLocation().getMapCoordinates());
387 rec.
x = p.x - infoa.w / 2;
388 rec.y = p.y - infoa.h / 2;
391 if(infoa.instance != instance && vc.dimensions.intersects(rec)) {
392 vc.transparency = 255 - infoa.trans;
402 InstanceToOutlines_t::iterator outline_it = m_instance_outlines.find(instance);
403 const bool outline = outline_it != m_instance_outlines.end();
408 vc.image->render(vc.dimensions, vc.transparency);
409 bindOutline(outline_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
410 m_renderbackend->changeRenderInfos(1, 4, 5,
false,
true, 255, REPLACE, ALWAYS);
412 bindOutline(outline_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
413 vc.image->render(vc.dimensions, vc.transparency);
417 InstanceToColoring_t::iterator coloring_it = m_instance_colorings.find(instance);
418 const bool coloring = coloring_it != m_instance_colorings.end();
420 if(m_need_bind_coloring) {
421 bindColoring(coloring_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
422 m_renderbackend->changeRenderInfos(1, 4, 5,
true,
false, 0, KEEP, ALWAYS);
424 uint8_t rgb[3] = { coloring_it->second.r, coloring_it->second.g, coloring_it->second.b };
425 vc.image->render(vc.dimensions, vc.transparency, rgb);
426 m_renderbackend->changeRenderInfos(1, 4, 5,
true,
false, 0, KEEP, ALWAYS);
430 if (outline || coloring) {
437 std::string lit_name = instance->getObject()->getNamespace();
438 std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
439 for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
440 if(lit_name.find(*unlit_it) != std::string::npos) {
445 vc.image->render(vc.dimensions, vc.transparency);
447 m_renderbackend->changeRenderInfos(1, 4, 5,
true,
true, 255, REPLACE, ALWAYS);
449 m_renderbackend->changeRenderInfos(1, 4, 5,
true,
true, 0, ZERO, ALWAYS);
454 vc.image->render(vc.dimensions, vc.transparency);
459 inline bool aboveThreshold(int32_t threshold, int32_t alpha, int32_t prev_alpha) {
462 if (((alpha - threshold) >= 0 || (prev_alpha - threshold) >= 0) && (alpha != prev_alpha)) {
469 if((alpha == 0 || prev_alpha == 0) && (alpha != prev_alpha)) {
477 Image* InstanceRenderer::bindOutline(OutlineInfo& info, RenderItem& vc, Camera* cam) {
478 bool valid = isValidImage(info.outline);
479 if (!info.dirty && info.curimg == vc.image.get() && valid) {
480 removeFromCheck(info.outline);
482 return info.outline.get();
484 info.curimg = vc.image.get();
489 addToCheck(info.outline);
498 std::stringstream sts;
499 sts << vc.image.get()->getName() <<
"," <<
static_cast<uint32_t
>(info.r) <<
"," <<
500 static_cast<uint32_t>(info.g) <<
"," <<
static_cast<uint32_t
>(info.b) <<
"," << info.width;
502 if (ImageManager::instance()->exists(sts.str())) {
503 info.outline = ImageManager::instance()->getPtr(sts.str());
504 if (isValidImage(info.outline)) {
505 removeFromCheck(info.outline);
508 return info.outline.get();
516 if(vc.image->isSharedImage()) {
517 vc.image->forceLoadInternal();
520 SDL_Surface* surface = vc.image->getSurface();
521 SDL_Surface* outline_surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA,
522 vc.image->getWidth(), vc.image->getHeight(), 32,
523 RMASK, GMASK, BMASK, AMASK);
526 uint8_t r, g, b, a = 0;
529 for (int32_t x = 0; x < outline_surface->w; x ++) {
531 for (int32_t y = 0; y < outline_surface->h; y ++) {
532 vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
533 if (aboveThreshold(info.threshold, static_cast<int32_t>(a), prev_a)) {
535 for (int32_t yy = y; yy < y + info.width; yy++) {
536 Image::putPixel(outline_surface, x, yy, info.r, info.g, info.b);
539 for (int32_t yy = y - info.width; yy < y; yy++) {
540 Image::putPixel(outline_surface, x, yy, info.r, info.g, info.b);
548 for (int32_t y = 0; y < outline_surface->h; y ++) {
550 for (int32_t x = 0; x < outline_surface->w; x ++) {
551 vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
552 if (aboveThreshold(info.threshold, static_cast<int32_t>(a), prev_a)) {
554 for (int32_t xx = x; xx < x + info.width; xx++) {
555 Image::putPixel(outline_surface, xx, y, info.r, info.g, info.b);
558 for (int32_t xx = x - info.width; xx < x; xx++) {
559 Image::putPixel(outline_surface, xx, y, info.r, info.g, info.b);
568 Image* img = m_renderbackend->createImage(sts.str(), outline_surface);
569 img->setState(IResource::RES_LOADED);
573 removeFromCheck(info.outline);
575 info.outline.get()->copySubimage(0, 0, temp);
576 info.outline.get()->setState(IResource::RES_LOADED);
579 info.outline = ImageManager::instance()->add(img);
584 return info.outline.get();
587 Image* InstanceRenderer::bindColoring(ColoringInfo& info, RenderItem& vc, Camera* cam) {
588 bool valid = isValidImage(info.overlay);
589 if (!info.dirty && info.curimg == vc.image.get() && valid) {
590 removeFromCheck(info.overlay);
592 return info.overlay.get();
594 info.curimg = vc.image.get();
599 addToCheck(info.overlay);
604 std::stringstream sts;
605 sts << vc.image.get()->getName() <<
"," <<
static_cast<uint32_t
>(info.r) <<
"," <<
606 static_cast<uint32_t>(info.g) <<
"," <<
static_cast<uint32_t
>(info.b);
608 if (ImageManager::instance()->exists(sts.str())) {
609 info.overlay = ImageManager::instance()->getPtr(sts.str());
610 valid = isValidImage(info.overlay);
612 removeFromCheck(info.overlay);
615 return info.overlay.get();
622 if(vc.image->isSharedImage()) {
623 vc.image->forceLoadInternal();
627 SDL_Surface* surface = vc.image->getSurface();
628 SDL_Surface* overlay_surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA,
629 vc.image->getWidth(), vc.image->getHeight(), 32,
630 RMASK, GMASK, BMASK, AMASK);
632 uint8_t r, g, b, a = 0;
634 for (int32_t x = 0; x < overlay_surface->w; x ++) {
635 for (int32_t y = 0; y < overlay_surface->h; y ++) {
636 vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
638 Image::putPixel(overlay_surface, x, y, (r + info.r) >> 1, (g + info.g) >> 1, (b + info.b) >> 1, a);
644 Image* img = m_renderbackend->createImage(sts.str(), overlay_surface);
648 removeFromCheck(info.overlay);
650 info.overlay.get()->copySubimage(0, 0, temp);
651 info.overlay.get()->setState(IResource::RES_LOADED);
654 img->setState(IResource::RES_LOADED);
655 info.overlay = ImageManager::instance()->add(img);
660 return info.overlay.get();
663 void InstanceRenderer::addOutlined(Instance* instance, int32_t r, int32_t g, int32_t b, int32_t width, int32_t threshold) {
664 OutlineInfo newinfo(
this);
668 newinfo.threshold = threshold;
669 newinfo.width = width;
670 newinfo.dirty =
true;
676 std::pair<InstanceToOutlines_t::iterator, bool> insertiter = m_instance_outlines.insert(std::make_pair(instance, newinfo));
678 if (insertiter.second ==
false) {
681 OutlineInfo& info = insertiter.first->second;
683 if (info.r != r || info.g != g || info.b != b || info.width != width) {
690 info.threshold = threshold;
694 std::pair<InstanceToEffects_t::iterator, bool> iter = m_assigned_instances.insert(std::make_pair(instance, OUTLINE));
696 instance->addDeleteListener(m_delete_listener);
698 Effect& effect = iter.first->second;
699 if ((effect & OUTLINE) != OUTLINE) {
706 void InstanceRenderer::addColored(Instance* instance, int32_t r, int32_t g, int32_t b) {
707 ColoringInfo newinfo(
this);
711 newinfo.dirty =
true;
717 std::pair<InstanceToColoring_t::iterator, bool> insertiter = m_instance_colorings.insert(std::make_pair(instance, newinfo));
719 if (insertiter.second ==
false) {
722 ColoringInfo& info = insertiter.first->second;
724 if (info.r != r || info.g != g || info.b != b) {
732 std::pair<InstanceToEffects_t::iterator, bool> iter = m_assigned_instances.insert(std::make_pair(instance, COLOR));
734 instance->addDeleteListener(m_delete_listener);
736 Effect& effect = iter.first->second;
737 if ((effect & COLOR) != COLOR) {
744 void InstanceRenderer::addTransparentArea(Instance* instance,
const std::list<std::string> &groups, uint32_t w, uint32_t h, uint8_t trans,
bool front) {
746 newinfo.instance = instance;
747 newinfo.groups = groups;
751 newinfo.trans = trans;
752 newinfo.front = front;
759 std::pair<InstanceToAreas_t::iterator, bool> insertiter = m_instance_areas.insert(std::make_pair(instance, newinfo));
761 if (insertiter.second ==
false) {
764 AreaInfo& info = insertiter.first->second;
766 std::pair<InstanceToEffects_t::iterator, bool> iter = m_assigned_instances.insert(std::make_pair(instance, AREA));
768 instance->addDeleteListener(m_delete_listener);
770 Effect& effect = iter.first->second;
771 if ((effect & AREA) != AREA) {
778 void InstanceRenderer::removeOutlined(Instance* instance) {
779 InstanceToEffects_t::iterator it = m_assigned_instances.find(instance);
780 if (it != m_assigned_instances.end()) {
781 if (it->second == OUTLINE) {
782 instance->removeDeleteListener(m_delete_listener);
783 m_instance_outlines.erase(instance);
784 m_assigned_instances.erase(it);
785 }
else if ((it->second & OUTLINE) == OUTLINE) {
786 it->second -= OUTLINE;
787 m_instance_outlines.erase(instance);
792 void InstanceRenderer::removeColored(Instance* instance) {
793 InstanceToEffects_t::iterator it = m_assigned_instances.find(instance);
794 if (it != m_assigned_instances.end()) {
795 if (it->second == COLOR) {
796 instance->removeDeleteListener(m_delete_listener);
797 m_instance_colorings.erase(instance);
798 m_assigned_instances.erase(it);
799 }
else if ((it->second & COLOR) == COLOR) {
801 m_instance_colorings.erase(instance);
806 void InstanceRenderer::removeTransparentArea(Instance* instance) {
807 InstanceToEffects_t::iterator it = m_assigned_instances.find(instance);
808 if (it != m_assigned_instances.end()) {
809 if (it->second == AREA) {
810 instance->removeDeleteListener(m_delete_listener);
811 m_instance_areas.erase(instance);
812 m_assigned_instances.erase(it);
813 }
else if ((it->second & AREA) == AREA) {
815 m_instance_areas.erase(instance);
820 void InstanceRenderer::removeAllOutlines() {
821 if (!m_instance_outlines.empty()) {
822 InstanceToOutlines_t::iterator outline_it = m_instance_outlines.begin();
823 for (; outline_it != m_instance_outlines.end(); ++outline_it) {
824 InstanceToEffects_t::iterator it = m_assigned_instances.find((*outline_it).first);
825 if (it != m_assigned_instances.end()) {
826 if (it->second == OUTLINE) {
827 (*outline_it).first->removeDeleteListener(m_delete_listener);
828 m_assigned_instances.erase(it);
829 }
else if ((it->second & OUTLINE) == OUTLINE) {
830 it->second -= OUTLINE;
834 m_instance_outlines.clear();
838 void InstanceRenderer::removeAllColored() {
839 if (!m_instance_colorings.empty()) {
840 InstanceToColoring_t::iterator color_it = m_instance_colorings.begin();
841 for (; color_it != m_instance_colorings.end(); ++color_it) {
842 InstanceToEffects_t::iterator it = m_assigned_instances.find((*color_it).first);
843 if (it != m_assigned_instances.end()) {
844 if (it->second == COLOR) {
845 (*color_it).first->removeDeleteListener(m_delete_listener);
846 m_assigned_instances.erase(it);
847 }
else if ((it->second & COLOR) == COLOR) {
852 m_instance_colorings.clear();
856 void InstanceRenderer::removeAllTransparentAreas() {
857 if (!m_instance_areas.empty()) {
858 InstanceToAreas_t::iterator area_it = m_instance_areas.begin();
859 for (; area_it != m_instance_areas.end(); ++area_it) {
860 InstanceToEffects_t::iterator it = m_assigned_instances.find((*area_it).first);
861 if (it != m_assigned_instances.end()) {
862 if (it->second == AREA) {
863 (*area_it).first->removeDeleteListener(m_delete_listener);
864 m_assigned_instances.erase(it);
865 }
else if ((it->second & AREA) == AREA) {
870 m_instance_areas.clear();
874 void InstanceRenderer::addIgnoreLight(
const std::list<std::string> &groups) {
875 std::list<std::string>::const_iterator group_it = groups.begin();
876 for(;group_it != groups.end(); ++group_it) {
877 m_unlit_groups.push_back(*group_it);
879 m_unlit_groups.sort();
880 m_unlit_groups.unique();
883 void InstanceRenderer::removeIgnoreLight(
const std::list<std::string> &groups) {
884 std::list<std::string>::const_iterator group_it = groups.begin();
885 for(;group_it != groups.end(); ++group_it) {
886 std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
887 for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
888 if((*group_it).find(*unlit_it) != std::string::npos) {
889 m_unlit_groups.remove(*unlit_it);
896 void InstanceRenderer::removeAllIgnoreLight() {
897 m_unlit_groups.clear();
900 void InstanceRenderer::reset() {
902 if (m_timer_enabled) {
908 removeAllTransparentAreas();
909 removeAllIgnoreLight();
911 m_check_images.clear();
914 void InstanceRenderer::setRemoveInterval(uint32_t interval) {
915 if (m_interval != interval*1000) {
916 m_interval = interval*1000;
917 m_timer.setInterval(m_interval);
921 uint32_t InstanceRenderer::getRemoveInterval()
const {
922 return m_interval/1000;
925 void InstanceRenderer::addToCheck(
const ImagePtr& image) {
926 if (isValidImage(image)) {
928 ImagesToCheck_t::iterator it = m_check_images.begin();
929 for (; it != m_check_images.end(); ++it) {
930 if (it->image.get()->getName() == image.get()->getName()) {
936 entry.timestamp = TimeManager::instance()->getTime();
937 m_check_images.push_front(entry);
939 if (!m_timer_enabled) {
940 m_timer_enabled =
true;
946 void InstanceRenderer::check() {
947 uint32_t now = TimeManager::instance()->getTime();
948 ImagesToCheck_t::iterator it = m_check_images.begin();
950 while (it != m_check_images.end()) {
951 if (now - it->timestamp > m_interval) {
952 if (isValidImage(it->image)) {
953 ImageManager::instance()->free(it->image.get()->getName());
955 it = m_check_images.erase(it);
961 if (m_check_images.empty() && m_timer_enabled) {
962 m_timer_enabled =
false;
967 void InstanceRenderer::removeFromCheck(
const ImagePtr& image) {
968 if (isValidImage(image)) {
970 ImagesToCheck_t::iterator it = m_check_images.begin();
971 for (; it != m_check_images.end(); ++it) {
972 if (it->image.get()->getName() == image.get()->getName()) {
973 m_check_images.erase(it);
978 if (m_check_images.empty() && m_timer_enabled) {
979 m_timer_enabled =
false;
985 void InstanceRenderer::removeInstance(Instance* instance) {
986 InstanceToEffects_t::iterator it = m_assigned_instances.find(instance);
987 if (it != m_assigned_instances.end()) {
988 m_instance_outlines.erase(instance);
989 m_instance_colorings.erase(instance);
990 m_instance_areas.erase(instance);
991 instance->removeDeleteListener(m_delete_listener);
992 m_assigned_instances.erase(it);
996 bool InstanceRenderer::isValidImage(
const ImagePtr& image) {
998 if (image.get()->getState() == IResource::RES_LOADED) {