From 9550029ac128b6aa00f188d667007ac78a1ebf22 Mon Sep 17 00:00:00 2001 From: helios2000 Date: Tue, 7 Nov 2017 18:22:40 +0100 Subject: [PATCH 1/6] Inital commit. Refs #1029 Added RenderCache interface and adapted RenderBase. Also introduced a very simple method to detect LayerCache updates. --- engine/core/video/rendercache.h | 64 +++++++++++++++++++++++++++++++ engine/core/view/camera.cpp | 14 ++++++- engine/core/view/camera.h | 5 +++ engine/core/view/layercache.cpp | 15 ++++++-- engine/core/view/layercache.h | 4 +- engine/core/view/rendererbase.cpp | 45 ++++++++++++++++++++++ engine/core/view/rendererbase.h | 16 ++++++-- 7 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 engine/core/video/rendercache.h diff --git a/engine/core/video/rendercache.h b/engine/core/video/rendercache.h new file mode 100644 index 000000000..6b08a9cfe --- /dev/null +++ b/engine/core/video/rendercache.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIDEO_RENDERCACHE_H +#define FIFE_VIDEO_RENDERCACHE_H + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "renderbackend.h" + +namespace FIFE { + + /** Abstract interface for all the rendercaches. */ + class RenderCache { + public: + /** Constructor. + */ + RenderCache() {}; + + /** Destructor. + */ + virtual ~RenderCache() {}; + + virtual void clear() = 0; + + /** Render + */ + virtual void render() = 0; + + virtual void addLine(const Point& p1, const Point& p2, const Color& color) = 0; + + virtual void addLines(const std::vector& points, const Color& color) = 0; + + virtual void updateLines(uint32_t position, const std::vector& points, const Color& color) = 0; + }; +} + +#endif diff --git a/engine/core/view/camera.cpp b/engine/core/view/camera.cpp index 88155b776..ff165a4f0 100644 --- a/engine/core/view/camera.cpp +++ b/engine/core/view/camera.cpp @@ -745,10 +745,12 @@ namespace FIFE { m_cache[layer] = new LayerCache(this); m_cache[layer]->setLayer(layer); m_layerToInstances[layer] = RenderList(); + m_cacheUpdates[m_cache[layer]] = true; refresh(); } void Camera::removeLayer(Layer* layer) { + m_cacheUpdates.erase(m_cache[layer]); delete m_cache[layer]; m_cache.erase(layer); m_layerToInstances.erase(layer); @@ -970,11 +972,21 @@ namespace FIFE { if ((*layer_it)->isStatic() && m_transform == NoneTransform) { continue; } - cache->update(m_transform, instancesToRender); + bool update = cache->update(m_transform, instancesToRender); + m_cacheUpdates[cache] = update; } resetUpdates(); } + bool Camera::isLayerCacheUpdated(Layer* layer) { + LayerCache* cache = m_cache[layer]; + if (!cache) { + FL_ERR(_log, LMsg("Layer Cache miss! (This shouldn't happen!)") << layer->getId()); + return false; + } + return m_cacheUpdates[cache]; + } + void Camera::render() { updateRenderLists(); diff --git a/engine/core/view/camera.h b/engine/core/view/camera.h index 5592d2f66..8228cb28e 100644 --- a/engine/core/view/camera.h +++ b/engine/core/view/camera.h @@ -407,6 +407,10 @@ namespace FIFE { */ void render(); + /** Returns true if the LayerCache had to be recalculated, otherwise false. + */ + bool isLayerCacheUpdated(Layer* layer); + private: friend class MapObserver; void addLayer(Layer* layer); @@ -493,6 +497,7 @@ namespace FIFE { t_layer_to_instances m_layerToInstances; std::map m_cache; + std::map m_cacheUpdates; MapObserver* m_map_observer; // is lighting enable diff --git a/engine/core/view/layercache.cpp b/engine/core/view/layercache.cpp index f1e8377b3..2f68d57bc 100644 --- a/engine/core/view/layercache.cpp +++ b/engine/core/view/layercache.cpp @@ -366,7 +366,7 @@ namespace FIFE { } } - void LayerCache::update(Camera::Transform transform, RenderList& renderlist) { + bool LayerCache::update(Camera::Transform transform, RenderList& renderlist) { // this is only a bit faster, but works without this block too. if(!m_layer->areInstancesVisible()) { FL_DBG(_log, "Layer instances hidden"); @@ -378,13 +378,13 @@ namespace FIFE { } m_entriesToUpdate.clear(); renderlist.clear(); - return; + return true; } // if transform is none then we have only to update the instances with an update info. if (transform == Camera::NoneTransform) { if (!m_entriesToUpdate.empty()) { std::set entryToRemove; - updateEntries(entryToRemove, renderlist); + bool update = updateEntries(entryToRemove, renderlist); //std::cout << "update entries: " << int32_t(m_entriesToUpdate.size()) << " remove entries: " << int32_t(entryToRemove.size()) <<"\n"; if (!entryToRemove.empty()) { std::set::iterator entry_it = entryToRemove.begin(); @@ -392,7 +392,9 @@ namespace FIFE { m_entriesToUpdate.erase(*entry_it); } } + return update; } + return false; } else { m_zoom = m_camera->getZoom(); m_zoomed = !Mathd::Equal(m_zoom, 1.0); @@ -455,6 +457,7 @@ namespace FIFE { sortRenderList(renderlist); } } + return true; } void LayerCache::fullUpdate(Camera::Transform transform) { @@ -500,7 +503,8 @@ namespace FIFE { } } - void LayerCache::updateEntries(std::set& removes, RenderList& renderlist) { + bool LayerCache::updateEntries(std::set& removes, RenderList& renderlist) { + bool update = false; RenderList needSorting; Rect viewport = m_camera->getViewPort(); std::set::const_iterator entry_it = m_entriesToUpdate.begin(); @@ -531,6 +535,7 @@ namespace FIFE { // remove from renderlist for (RenderList::iterator it = renderlist.begin(); it != renderlist.end(); ++it) { if ((*it)->instance == item->instance) { + update = true; renderlist.erase(it); break; } @@ -551,12 +556,14 @@ namespace FIFE { } if (!needSorting.empty()) { + update = true; if (m_needSorting) { sortRenderList(renderlist); } else { sortRenderList(needSorting); } } + return update; } bool LayerCache::updateVisual(Entry* entry) { diff --git a/engine/core/view/layercache.h b/engine/core/view/layercache.h index 8df613cc9..35f45ff31 100644 --- a/engine/core/view/layercache.h +++ b/engine/core/view/layercache.h @@ -55,7 +55,7 @@ namespace FIFE { void setLayer(Layer* layer); - void update(Camera::Transform transform, RenderList& renderlist); + bool update(Camera::Transform transform, RenderList& renderlist); void addInstance(Instance* instance); void removeInstance(Instance* instance); @@ -92,7 +92,7 @@ namespace FIFE { void reset(); void fullUpdate(Camera::Transform transform); void fullCoordinateUpdate(Camera::Transform transform); - void updateEntries(std::set& removes, RenderList& renderlist); + bool updateEntries(std::set& removes, RenderList& renderlist); bool updateVisual(Entry* entry); void updatePosition(Entry* entry); void updateScreenCoordinate(RenderItem* item, bool changedZoom = true); diff --git a/engine/core/view/rendererbase.cpp b/engine/core/view/rendererbase.cpp index f67cd1826..67f13082b 100644 --- a/engine/core/view/rendererbase.cpp +++ b/engine/core/view/rendererbase.cpp @@ -30,6 +30,7 @@ #include "model/structures/layer.h" #include "model/structures/map.h" #include "util/log/logger.h" +#include "video/rendercache.h" #include "rendererbase.h" namespace FIFE { @@ -61,6 +62,10 @@ namespace FIFE { m_listener(NULL) { } + RendererBase::~RendererBase() { + deleteRenderCaches(); + } + void RendererBase::setPipelinePosition(int32_t position) { if (position !=m_pipeline_position) { m_pipeline_position = position; @@ -76,6 +81,9 @@ namespace FIFE { if (m_listener) { m_listener->onRendererEnabledChanged(this); } + if (!enabled) { + deleteRenderCaches(); + } } } @@ -87,10 +95,12 @@ namespace FIFE { void RendererBase::removeActiveLayer(Layer* layer) { m_active_layers.remove(layer); + deleteRenderCache(layer); } void RendererBase::clearActiveLayers() { m_active_layers.clear(); + deleteRenderCaches(); } bool RendererBase::isActivedLayer(Layer* layer) { @@ -107,4 +117,39 @@ namespace FIFE { } } + RenderCache* RendererBase::createRenderCache(Layer* layer) { + RenderCache* cache = getRenderCache(layer); + if (cache) { + FL_WARN(_log, "RenderCache already created! Instead of a new one, the existing is returned"); + } else { + cache = m_renderbackend->createRenderCache(); + m_layerCaches.insert(std::pair(layer, cache)); + } + return cache; + } + + RenderCache* RendererBase::getRenderCache(Layer* layer) { + RenderCache* cache = NULL; + std::map::iterator it = m_layerCaches.find(layer); + if (it != m_layerCaches.end()) { + cache = it->second; + } + return cache; + } + + void RendererBase::deleteRenderCaches() { + std::map::iterator it = m_layerCaches.begin(); + for (; it != m_layerCaches.end(); ++it) { + delete it->second; + } + m_layerCaches.clear(); + } + + void RendererBase::deleteRenderCache(Layer* layer) { + std::map::iterator it = m_layerCaches.find(layer); + if (it != m_layerCaches.end()) { + delete it->second; + m_layerCaches.erase(it); + } + } } diff --git a/engine/core/view/rendererbase.h b/engine/core/view/rendererbase.h index 9b5c84f98..fe0fb6332 100644 --- a/engine/core/view/rendererbase.h +++ b/engine/core/view/rendererbase.h @@ -24,6 +24,7 @@ // Standard C++ library includes #include +#include #include // 3rd party library includes @@ -41,6 +42,7 @@ namespace FIFE { class Map; class Instance; class RenderBackend; + class RenderCache; class RendererBase; /** RendererListener allows reaction to changes in renderer @@ -93,7 +95,7 @@ namespace FIFE { /** Destructor */ - virtual ~RendererBase() {}; + virtual ~RendererBase(); /** This method is called by the view to ask renderer to draw its rendering aspect based on * given parameters. Renderers receive non-clipped instance stack since there is no @@ -151,9 +153,9 @@ namespace FIFE { */ void clearActiveLayers(); - /** Activates all layers from given elevation + /** Activates all layers for given map */ - void activateAllLayers(Map* elevation); + void activateAllLayers(Map* map); /** Returns if given layer is currently activated */ @@ -163,11 +165,19 @@ namespace FIFE { */ std::list getActiveLayers() const {return m_active_layers;} + RenderCache* createRenderCache(Layer* layer); + + RenderCache* getRenderCache(Layer* layer); + + void deleteRenderCaches(); + + void deleteRenderCache(Layer* layer); protected: RendererBase(); std::list m_active_layers; + std::map m_layerCaches; RenderBackend* m_renderbackend; private: From 8b0a3df713230517fcd6e510ae8eb21b6f4c80cd Mon Sep 17 00:00:00 2001 From: helios2000 Date: Tue, 7 Nov 2017 18:31:56 +0100 Subject: [PATCH 2/6] Added SDL and OpenGL RenderCaches and BufferObjects. Backends handle the creation. Refs #1029 --- CMakeLists.txt | 9 ++ engine/core/video/opengl/glbufferobject.cpp | 141 ++++++++++++++++++ engine/core/video/opengl/glbufferobject.h | 81 ++++++++++ engine/core/video/opengl/glrendercache.cpp | 82 ++++++++++ engine/core/video/opengl/glrendercache.h | 67 +++++++++ .../core/video/opengl/renderbackendopengl.cpp | 26 ++++ .../core/video/opengl/renderbackendopengl.h | 4 + engine/core/video/renderbackend.h | 4 + engine/core/video/sdl/renderbackendsdl.cpp | 6 + engine/core/video/sdl/renderbackendsdl.h | 2 + engine/core/video/sdl/sdlbufferobject.cpp | 69 +++++++++ engine/core/video/sdl/sdlbufferobject.h | 74 +++++++++ engine/core/video/sdl/sdlrendercache.cpp | 67 +++++++++ engine/core/video/sdl/sdlrendercache.h | 69 +++++++++ engine/core/view/camera.i | 1 + 15 files changed, 702 insertions(+) create mode 100644 engine/core/video/opengl/glbufferobject.cpp create mode 100644 engine/core/video/opengl/glbufferobject.h create mode 100644 engine/core/video/opengl/glrendercache.cpp create mode 100644 engine/core/video/opengl/glrendercache.h create mode 100644 engine/core/video/sdl/sdlbufferobject.cpp create mode 100644 engine/core/video/sdl/sdlbufferobject.h create mode 100644 engine/core/video/sdl/sdlrendercache.cpp create mode 100644 engine/core/video/sdl/sdlrendercache.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b97786ba..6debc4727 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,11 +318,15 @@ set(FIFE_CORE_SRC ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/subimagefont.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/textrenderpool.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/truetypefont.cpp + ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glbufferobject.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glimage.cpp + ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glrendercache.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/renderbackendopengl.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/renderbackendsdl.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlblendingfunctions.cpp + ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlbufferobject.cpp ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlimage.cpp + ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlrendercache.cpp ${PROJECT_SOURCE_DIR}/engine/core/view/camera.cpp ${PROJECT_SOURCE_DIR}/engine/core/view/layercache.cpp ${PROJECT_SOURCE_DIR}/engine/core/view/rendererbase.cpp @@ -536,6 +540,7 @@ set(FIFE_CORE_HDR ${PROJECT_SOURCE_DIR}/engine/core/video/image.h ${PROJECT_SOURCE_DIR}/engine/core/video/imagemanager.h ${PROJECT_SOURCE_DIR}/engine/core/video/renderbackend.h + ${PROJECT_SOURCE_DIR}/engine/core/video/rendercache.h ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/fontbase.h ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/ifont.h ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/imagefontbase.h @@ -543,11 +548,15 @@ set(FIFE_CORE_HDR ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/textrenderpool.h ${PROJECT_SOURCE_DIR}/engine/core/video/fonts/truetypefont.h ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/fife_opengl.h + ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glbufferobject.h ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glimage.h + ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/glrendercache.h ${PROJECT_SOURCE_DIR}/engine/core/video/opengl/renderbackendopengl.h ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/renderbackendsdl.h ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlblendingfunctions.h + ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlbufferobject.h ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlimage.h + ${PROJECT_SOURCE_DIR}/engine/core/video/sdl/sdlrendercache.h ${PROJECT_SOURCE_DIR}/engine/core/view/camera.h ${PROJECT_SOURCE_DIR}/engine/core/view/layercache.h ${PROJECT_SOURCE_DIR}/engine/core/view/rendererbase.h diff --git a/engine/core/video/opengl/glbufferobject.cpp b/engine/core/video/opengl/glbufferobject.cpp new file mode 100644 index 000000000..8fe025e69 --- /dev/null +++ b/engine/core/video/opengl/glbufferobject.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder + +#include "renderbackendopengl.h" +#include "glbufferobject.h" + + +namespace FIFE { + + OpenGLBufferLinesObject::OpenGLBufferLinesObject() { + m_final = false; + m_vboId = 0; + m_vboIndicesId = 0; + m_oldFinalSize = 0; + } + + OpenGLBufferLinesObject::~OpenGLBufferLinesObject() { + glDeleteBuffers(1, &m_vboId); + glDeleteBuffers(1, &m_vboIndicesId); + } + + void OpenGLBufferLinesObject::add(const std::vector& points, const Color& color) { + if (points.size() < 2) { + return; + } + m_final = false; + std::vector::const_iterator it = points.begin(); + renderDataP rd; + rd.vertex[0] = static_cast((*it).x) + 0.375; + rd.vertex[1] = static_cast((*it).y) + 0.375; + rd.color[0] = color.getR(); + rd.color[1] = color.getG(); + rd.color[2] = color.getB(); + rd.color[3] = color.getAlpha(); + m_data.push_back(rd); + ++it; + uint32_t indice = m_indices.empty() ? 0 : m_indices.back() + 1; + for (; it != points.end(); ++it) { + rd.vertex[0] = static_cast((*it).x) + 0.375; + rd.vertex[1] = static_cast((*it).y) + 0.375; + m_data.push_back(rd); + m_indices.push_back(indice++); + m_indices.push_back(indice); + + } + } + + void OpenGLBufferLinesObject::clear() { + m_data.clear(); + m_indices.clear(); + /*if (m_vboId != 0) { + glDeleteBuffers(1, &m_vboId); + glDeleteBuffers(1, &m_vboIndicesId); + m_vboId = 0; + m_vboIndicesId = 0; + }*/ + m_final = false; + } + + void OpenGLBufferLinesObject::update(uint32_t position, const std::vector& points, const Color& color) { + uint32_t elements = points.size(); + for (uint32_t i = 0; i < elements; ++i) { + renderDataP& rd = m_data[position + i]; + rd.vertex[0] = static_cast(points[i].x) + 0.375; + rd.vertex[1] = static_cast(points[i].y) + 0.375; + } + + if (!m_final) { + finalize(); + } else { + //std::cout << "4 \n"; + glBindBuffer(GL_ARRAY_BUFFER, m_vboId); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(renderDataP) * position, sizeof(renderDataP) * elements, &m_data[position].vertex); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + + void OpenGLBufferLinesObject::finalize() { + if (m_vboId == 0) { + //std::cout << "1 \n"; + glGenBuffers(1, &m_vboId); + glGenBuffers(1, &m_vboIndicesId); + } + + if (m_oldFinalSize != m_indices.size()) { + //std::cout << "2 \n"; + glBindBuffer(GL_ARRAY_BUFFER, m_vboId); + glBufferData(GL_ARRAY_BUFFER, sizeof(renderDataP) * m_data.size(), &m_data[0].vertex, GL_STREAM_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndicesId); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * m_indices.size(), &m_indices[0], GL_STREAM_DRAW); + m_oldFinalSize = m_indices.size(); + } else { + //std::cout << "3 \n"; + glBindBuffer(GL_ARRAY_BUFFER, m_vboId); + glBufferData(GL_ARRAY_BUFFER, sizeof(renderDataP) * m_data.size(), NULL, GL_STREAM_DRAW); + GLvoid* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + memcpy(ptr, &m_data[0].vertex, sizeof(renderDataP) * m_data.size()); + glUnmapBuffer(GL_ARRAY_BUFFER); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + m_final = true; + } + + void OpenGLBufferLinesObject::render() { + if (m_data.empty()) { + return; + } + if (!m_final) { + finalize(); + } + static_cast(RenderBackend::instance())->renderVboBuffers(m_indices.size(), m_vboId, m_vboIndicesId); + } +} diff --git a/engine/core/video/opengl/glbufferobject.h b/engine/core/video/opengl/glbufferobject.h new file mode 100644 index 000000000..19542bde6 --- /dev/null +++ b/engine/core/video/opengl/glbufferobject.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIDEO_OPENGL_BUFFEROBJECT_H +#define FIFE_VIDEO_OPENGL_BUFFEROBJECT_H + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "util/structures/point.h" +#include "video/color.h" + +#include "fife_opengl.h" + +namespace FIFE { + + /** Abstract interface for all the opengl buffer objects. */ + class OpenGLBufferObject { + public: + /** Destructor + */ + virtual ~OpenGLBufferObject() {} + + /** Render + */ + virtual void render() = 0; + + }; + + // for regular primitives with color and alpha + struct renderDataP { + GLfloat vertex[2]; + GLubyte color[4]; + }; + + + class OpenGLBufferLinesObject : public OpenGLBufferObject { + public: + OpenGLBufferLinesObject(); + virtual ~OpenGLBufferLinesObject(); + void add(const std::vector& points, const Color& color); + void update(uint32_t position, const std::vector& points, const Color& color); + void clear(); + void finalize(); + void render(); + private: + bool m_final; + uint32_t m_oldFinalSize; + GLuint m_vboId; + GLuint m_vboIndicesId; + std::vector m_data; + std::vector m_indices; + }; +} + +#endif diff --git a/engine/core/video/opengl/glrendercache.cpp b/engine/core/video/opengl/glrendercache.cpp new file mode 100644 index 000000000..51fc60cb9 --- /dev/null +++ b/engine/core/video/opengl/glrendercache.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "renderbackendopengl.h" +#include "glbufferobject.h" +#include "glrendercache.h" + +#define BUFFER_OFFSET(i) ((void*)(i)) + +namespace FIFE { + GLRenderCache::GLRenderCache(): + RenderCache() { + + m_buffer = NULL; + } + + GLRenderCache::~GLRenderCache() { + delete m_buffer; + } + + void GLRenderCache::clear() { + if (m_buffer) { + static_cast(m_buffer)->clear(); + } + + } + + void GLRenderCache::render() { + if (m_buffer) { + m_buffer->render(); + } + } + + void GLRenderCache::addLine(const Point& p1, const Point& p2, const Color& color) { + } + + void GLRenderCache::addLines(const std::vector& points, const Color& color) { + if (points.size() < 2) { + return; + } + if (!m_buffer) { + m_buffer = new OpenGLBufferLinesObject(); + } + static_cast(m_buffer)->add(points, color); + } + + void GLRenderCache::updateLines(uint32_t position, const std::vector& points, const Color& color) { + if (points.size() < 2) { + return; + } + if (!m_buffer) { + return; + } + static_cast(m_buffer)->update(position, points, color); + } +} diff --git a/engine/core/video/opengl/glrendercache.h b/engine/core/video/opengl/glrendercache.h new file mode 100644 index 000000000..c87c8d3b4 --- /dev/null +++ b/engine/core/video/opengl/glrendercache.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIDEO_OPENGL_RENDERCACHE_H +#define FIFE_VIDEO_OPENGL_RENDERCACHE_H + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "video/rendercache.h" + +namespace FIFE { + class OpenGLBufferObject; + + class GLRenderCache : public RenderCache { + public: + /** Constructor. + */ + GLRenderCache(); + + /** Destructor. + */ + virtual ~GLRenderCache(); + + virtual void clear(); + + /** Render + */ + virtual void render(); + + virtual void addLine(const Point& p1, const Point& p2, const Color& color); + + virtual void addLines(const std::vector& points, const Color& color); + virtual void updateLines(uint32_t position, const std::vector& points, const Color& color); + + private: + + OpenGLBufferObject* m_buffer; + }; +} + +#endif diff --git a/engine/core/video/opengl/renderbackendopengl.cpp b/engine/core/video/opengl/renderbackendopengl.cpp index 9b95e9bc3..872949b26 100644 --- a/engine/core/video/opengl/renderbackendopengl.cpp +++ b/engine/core/video/opengl/renderbackendopengl.cpp @@ -32,9 +32,11 @@ #include "video/devicecaps.h" #include "glimage.h" +#include "glrendercache.h" #include "renderbackendopengl.h" #include "SDL_image.h" +#define BUFFER_OFFSET(i) ((GLvoid*)(i)) namespace FIFE { /** Logger to use for this source file. @@ -2700,4 +2702,28 @@ namespace FIFE { glPopMatrix(); } + + RenderCache* RenderBackendOpenGL::createRenderCache() { + RenderCache* cache = new GLRenderCache(); + return cache; + } + + void RenderBackendOpenGL::renderVboBuffers(uint32_t elements, GLuint vbo, GLuint indice) { + enableColorArray(); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indice); + // VBO starting point + setVertexPointer(2, sizeof(renderDataP), BUFFER_OFFSET(0)); + // Color starting point in VBO + setColorPointer(sizeof(renderDataP), BUFFER_OFFSET(8)); + // IBO starting point + glDrawElements(GL_LINES, elements, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // stupid shit :P + setVertexPointer(2, 0, 0); + setColorPointer(0, 0); + } } diff --git a/engine/core/video/opengl/renderbackendopengl.h b/engine/core/video/opengl/renderbackendopengl.h index b49688f1b..0d46d5bb0 100644 --- a/engine/core/video/opengl/renderbackendopengl.h +++ b/engine/core/video/opengl/renderbackendopengl.h @@ -102,11 +102,15 @@ namespace FIFE { virtual void renderGuiGeometry(const std::vector& vertices, const std::vector& indices, const DoublePoint& translation, ImagePtr texture); + virtual RenderCache* createRenderCache(); + void enableTextures(uint32_t texUnit); void disableTextures(uint32_t texUnit); void bindTexture(uint32_t texUnit, GLuint texId); void bindTexture(GLuint textId); + void renderVboBuffers(uint32_t elements, GLuint vbo, GLuint indice); + protected: virtual void setClipArea(const Rect& cliparea, bool clear); diff --git a/engine/core/video/renderbackend.h b/engine/core/video/renderbackend.h index a7cf6afa0..d09a11e69 100644 --- a/engine/core/video/renderbackend.h +++ b/engine/core/video/renderbackend.h @@ -52,6 +52,7 @@ namespace FIFE { class Image; + class RenderCache; #ifdef HAVE_OPENGL enum GLConstants { @@ -497,6 +498,8 @@ namespace FIFE { */ void addControlPoints(const std::vector& points, std::vector& newPoints); + virtual RenderCache* createRenderCache() = 0; + protected: /** Sets given clip area into image @@ -547,6 +550,7 @@ namespace FIFE { std::stack m_clipstack; ClipInfo m_guiClip; + private: bool m_isframelimit; uint32_t m_frame_start; diff --git a/engine/core/video/sdl/renderbackendsdl.cpp b/engine/core/video/sdl/renderbackendsdl.cpp index b68b2d853..53b27f6ef 100644 --- a/engine/core/video/sdl/renderbackendsdl.cpp +++ b/engine/core/video/sdl/renderbackendsdl.cpp @@ -35,6 +35,7 @@ #include "renderbackendsdl.h" #include "sdlimage.h" +#include "sdlrendercache.h" #include "SDL_image.h" namespace FIFE { @@ -687,4 +688,9 @@ namespace FIFE { void RenderBackendSDL::renderGuiGeometry(const std::vector& vertices, const std::vector& indices, const DoublePoint& translation, ImagePtr texture) { } + + RenderCache* RenderBackendSDL::createRenderCache() { + RenderCache* cache = new SDLRenderCache(); + return cache; + } } diff --git a/engine/core/video/sdl/renderbackendsdl.h b/engine/core/video/sdl/renderbackendsdl.h index 8c2067eb8..5cb0a31eb 100644 --- a/engine/core/video/sdl/renderbackendsdl.h +++ b/engine/core/video/sdl/renderbackendsdl.h @@ -96,6 +96,8 @@ namespace FIFE { virtual void renderGuiGeometry(const std::vector& vertices, const std::vector& indices, const DoublePoint& translation, ImagePtr texture); + virtual RenderCache* createRenderCache(); + SDL_Renderer* getRenderer() { return m_renderer; } protected: diff --git a/engine/core/video/sdl/sdlbufferobject.cpp b/engine/core/video/sdl/sdlbufferobject.cpp new file mode 100644 index 000000000..b3e609cec --- /dev/null +++ b/engine/core/video/sdl/sdlbufferobject.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "sdlbufferobject.h" + +namespace FIFE { + SDLBufferLineObject::SDLBufferLineObject(const Point& p1, const Point& p2, const Color& color) { + m_p1 = p1; + m_p2 = p2; + m_color = color; + } + + SDLBufferLineObject::~SDLBufferLineObject() { + } + + void SDLBufferLineObject::render() { + SDL_Renderer* renderer = static_cast(RenderBackend::instance())->getRenderer(); + SDL_SetRenderDrawColor(renderer, m_color.getR(), m_color.getG(), m_color.getB(), m_color.getAlpha()); + SDL_RenderDrawLine(renderer, m_p1.x, m_p1.y, m_p2.x, m_p2.y); + } + + + SDLBufferLinesObject::SDLBufferLinesObject(const std::vector& points, const Color& color) { + m_count = points.size(); + m_color = color; + m_points = new SDL_Point[m_count]; + uint32_t index = 0; + for (; index < m_count; index++) { + m_points[index].x = points[index].x; + m_points[index].y = points[index].y; + } + } + + SDLBufferLinesObject::~SDLBufferLinesObject() { + delete[] m_points; + } + + void SDLBufferLinesObject::render() { + SDL_Renderer* renderer = static_cast(RenderBackend::instance())->getRenderer(); + SDL_SetRenderDrawColor(renderer, m_color.getR(), m_color.getG(), m_color.getB(), m_color.getAlpha()); + SDL_RenderDrawLines(renderer, m_points, m_count); + } +} diff --git a/engine/core/video/sdl/sdlbufferobject.h b/engine/core/video/sdl/sdlbufferobject.h new file mode 100644 index 000000000..2fb92cde0 --- /dev/null +++ b/engine/core/video/sdl/sdlbufferobject.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIDEO_SDL_BUFFEROBJECT_H +#define FIFE_VIDEO_SDL_BUFFEROBJECT_H + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "renderbackendsdl.h" + +namespace FIFE { + /** Abstract interface for all the sdl buffer objects. */ + class SDLBufferObject { + public: + /** Destructor + */ + virtual ~SDLBufferObject() {} + + /** Render + */ + virtual void render() = 0; + }; + + + class SDLBufferLineObject : public SDLBufferObject { + public: + SDLBufferLineObject(const Point& p1, const Point& p2, const Color& color); + virtual ~SDLBufferLineObject(); + void render(); + private: + Point m_p1; + Point m_p2; + Color m_color; + }; + + class SDLBufferLinesObject : public SDLBufferObject { + public: + SDLBufferLinesObject(const std::vector& points, const Color& color); + virtual ~SDLBufferLinesObject(); + void render(); + private: + SDL_Point* m_points; + Color m_color; + int32_t m_count; + }; +} + +#endif diff --git a/engine/core/video/sdl/sdlrendercache.cpp b/engine/core/video/sdl/sdlrendercache.cpp new file mode 100644 index 000000000..e8046ef10 --- /dev/null +++ b/engine/core/video/sdl/sdlrendercache.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "sdlbufferobject.h" + +#include "sdlrendercache.h" + +namespace FIFE { + SDLRenderCache::SDLRenderCache(): + RenderCache() { + } + + SDLRenderCache::~SDLRenderCache() { + clear(); + } + + void SDLRenderCache::clear() { + std::vector::iterator it = m_objects.begin(); + for (; it != m_objects.end(); it++) { + delete *it; + } + m_objects.clear(); + } + + void SDLRenderCache::render() { + std::vector::iterator it = m_objects.begin(); + for (; it != m_objects.end(); it++) { + (*it)->render(); + } + } + + void SDLRenderCache::addLine(const Point& p1, const Point& p2, const Color& color) { + SDLBufferObject* lines = new SDLBufferLineObject(p1, p2, color); + m_objects.push_back(lines); + } + + void SDLRenderCache::addLines(const std::vector& points, const Color& color) { + SDLBufferObject* lines = new SDLBufferLinesObject(points, color); + m_objects.push_back(lines); + } +} diff --git a/engine/core/video/sdl/sdlrendercache.h b/engine/core/video/sdl/sdlrendercache.h new file mode 100644 index 000000000..9c85fc153 --- /dev/null +++ b/engine/core/video/sdl/sdlrendercache.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2005-2017 by the FIFE team * + * http://www.fifengine.net * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIDEO_SDL_RENDERCACHE_H +#define FIFE_VIDEO_SDL_RENDERCACHE_H + +// Standard C++ library includes + +// Platform specific includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "video/rendercache.h" + +namespace FIFE { + class SDLBufferObject; + + class SDLRenderCache : public RenderCache { + public: + /** Constructor. + */ + SDLRenderCache(); + + /** Destructor. + */ + virtual ~SDLRenderCache(); + + + virtual void clear(); + + /** Render + */ + virtual void render(); + + virtual void addLine(const Point& p1, const Point& p2, const Color& color); + + virtual void addLines(const std::vector& points, const Color& color); + + virtual void updateLines(uint32_t position, const std::vector& points, const Color& color) {}; + + private: + std::vector m_objects; + + }; +} + +#endif diff --git a/engine/core/view/camera.i b/engine/core/view/camera.i index 242d44f1e..a91594983 100644 --- a/engine/core/view/camera.i +++ b/engine/core/view/camera.i @@ -36,6 +36,7 @@ namespace FIFE { public: ~Camera(); const std::string& getId() const; + Map* getMap(); void setId(const std::string& id); void setTilt(double tilt); double getTilt() const; From 770f0eb035c5d65ce1eec09634513eaf0f7d8fa7 Mon Sep 17 00:00:00 2001 From: helios2000 Date: Tue, 7 Nov 2017 18:34:08 +0100 Subject: [PATCH 3/6] Rewrite BlockingInfoRenderer. Refs #1029 --- .../view/renderers/blockinginforenderer.cpp | 153 +++++++++++------- .../view/renderers/blockinginforenderer.h | 9 +- 2 files changed, 103 insertions(+), 59 deletions(-) diff --git a/engine/core/view/renderers/blockinginforenderer.cpp b/engine/core/view/renderers/blockinginforenderer.cpp index 81a6fda18..6d3c9793e 100644 --- a/engine/core/view/renderers/blockinginforenderer.cpp +++ b/engine/core/view/renderers/blockinginforenderer.cpp @@ -28,6 +28,7 @@ // First block: files included from the FIFE root src directory // Second block: files included from the same folder #include "video/renderbackend.h" +#include "video/rendercache.h" #include "util/math/fife_math.h" #include "util/log/logger.h" #include "model/metamodel/grids/cellgrid.h" @@ -48,7 +49,8 @@ namespace FIFE { static Logger _log(LM_VIEWVIEW); BlockingInfoRenderer::BlockingInfoRenderer(RenderBackend* renderbackend, int32_t position): - RendererBase(renderbackend, position) { + RendererBase(renderbackend, position), + m_updated(true) { setEnabled(false); m_color.r = 0; m_color.g = 255; @@ -57,6 +59,7 @@ namespace FIFE { BlockingInfoRenderer::BlockingInfoRenderer(const BlockingInfoRenderer& old): RendererBase(old), + m_updated(true), m_color(old.m_color) { setEnabled(false); } @@ -75,85 +78,121 @@ namespace FIFE { void BlockingInfoRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { - FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); + FL_WARN(_log, "No cellgrid assigned to layer, can not draw blocking info"); return; } - Rect cv = cam->getViewPort(); + RenderCache* renderCache = getRenderCache(layer); + // Only render if nothing has changed. + if (renderCache && !cam->isUpdated() && cam->isLayerCacheUpdated(layer)) { + bool found = false; + // Only test code + for (RenderList::iterator it = instances.begin(); it != instances.end(); ++it) { + if ((*it)->instance->getId() == "NPC:girl") { + std::map::iterator it2 = m_test.find((*it)->instance->getFifeId()); + if (it2 == m_test.end()) continue; + uint32_t pos = it2->second; + uint32_t cellSideCount = cg->getCellSideCount(); + const uint32_t halfCell = cellSideCount / 2; + std::vector data(cellSideCount + 2); + Color color(m_color.r, m_color.g, m_color.b, 255); + + std::vector vertices; + cg->getVertices(vertices, (*it)->instance->getLocationRef().getLayerCoordinates()); + for (uint32_t i = 0; i < cellSideCount; ++i) { + ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); + data[i].x = pts.x; + data[i].y = pts.y; + } + data[cellSideCount] = data[0]; + data[cellSideCount + 1] = data[halfCell]; + renderCache->updateLines(pos*6, data, color); + found = true; + break; + } + } + if (found) { + renderCache->render(); + return; + } + + } + //if (!cam->isUpdated() && !cam->isLayerCacheUpdated(layer) && !m_updated) { + if (!cam->isUpdated() && !m_updated) { + if (renderCache) { + renderCache->render(); + return; + } + } + + if (!renderCache) { + renderCache = createRenderCache(layer); + } + renderCache->clear(); + m_test.clear(); + uint32_t pos = 0; + uint32_t cellSideCount = cg->getCellSideCount(); + const uint32_t halfCell = cellSideCount / 2; + std::vector data(cellSideCount + 2); + Color color(m_color.r, m_color.g, m_color.b, 255); CellCache* cache = layer->getCellCache(); if (cache) { - const std::vector >& cells = cache->getCells(); - std::vector >::const_iterator it = cells.begin(); - for (; it != cells.end(); ++it) { - std::vector::const_iterator cit = (*it).begin(); - for (; cit != (*it).end(); ++cit) { - ExactModelCoordinate emc = FIFE::intPt2doublePt((*cit)->getLayerCoordinates()); - ScreenPoint sp = cam->toScreenCoordinates(cg->toMapCoordinates(emc)); - // if it is not in cameras view continue - if (sp.x < cv.x || sp.x > cv.x + cv.w || - sp.y < cv.y || sp.y > cv.y + cv.h) { - continue; - } - if ((*cit)->getCellType() != CTYPE_NO_BLOCKER) { - std::vector vertices; - cg->getVertices(vertices, (*cit)->getLayerCoordinates()); - std::vector::const_iterator it = vertices.begin(); - int32_t halfind = vertices.size() / 2; - ScreenPoint firstpt = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); - Point pt1(firstpt.x, firstpt.y); - Point pt2; - ++it; - for (; it != vertices.end(); it++) { - ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); - pt2.x = pts.x; - pt2.y = pts.y; - m_renderbackend->drawLine(pt1, pt2, m_color.r, m_color.g, m_color.b); - pt1 = pt2; - } - m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), m_color.r, m_color.g, m_color.b); - ScreenPoint spt1 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[0])); - Point pt3(spt1.x, spt1.y); - ScreenPoint spt2 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[halfind])); - Point pt4(spt2.x, spt2.y); - m_renderbackend->drawLine(pt3, pt4, m_color.r, m_color.g, m_color.b); - } + // fill render cache with cell data + Rect layerView = cam->getLayerViewPort(layer); + std::vector cells = cache->getCellsInRect(layerView); + std::vector::iterator cit = cells.begin(); + for (; cit != cells.end(); ++cit) { + if ((*cit)->getCellType() == CTYPE_NO_BLOCKER) { + continue; + } + const std::set& instances2 = (*cit)->getInstances(); + for (std::set::const_iterator it = instances2.begin(); it != instances2.end(); ++it) { + m_test[(*it)->getFifeId()] = pos; + } + std::vector vertices; + cg->getVertices(vertices, (*cit)->getLayerCoordinates()); + for (uint32_t i = 0; i < cellSideCount; ++i) { + ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); + data[i].x = pts.x; + data[i].y = pts.y; } + data[cellSideCount] = data[0]; + data[cellSideCount+1] = data[halfCell]; + renderCache->addLines(data, color); + ++pos; } } else { + // fill render cache with instance data RenderList::const_iterator instance_it = instances.begin(); - for (;instance_it != instances.end(); ++instance_it) { + for (; instance_it != instances.end(); ++instance_it) { Instance* instance = (*instance_it)->instance; if (!instance->getObject()->isBlocking() || !instance->isBlocking()) { continue; } + /*if (instance->getId() == "NPC:girl") { + std::cout << "found " << instance->getFifeId() << "\n"; + }*/ std::vector vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); - std::vector::const_iterator it = vertices.begin(); - int32_t halfind = vertices.size() / 2; - ScreenPoint firstpt = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); - Point pt1(firstpt.x, firstpt.y); - Point pt2; - ++it; - for (; it != vertices.end(); it++) { - ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(*it)); - pt2.x = pts.x; - pt2.y = pts.y; - m_renderbackend->drawLine(pt1, pt2, m_color.r, m_color.g, m_color.b); - pt1 = pt2; + for (uint32_t i = 0; i < cellSideCount; ++i) { + ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); + data[i].x = pts.x; + data[i].y = pts.y; } - m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), m_color.r, m_color.g, m_color.b); - ScreenPoint spt1 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[0])); - Point pt3(spt1.x, spt1.y); - ScreenPoint spt2 = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[halfind])); - Point pt4(spt2.x, spt2.y); - m_renderbackend->drawLine(pt3, pt4, m_color.r, m_color.g, m_color.b); + data[cellSideCount] = data[0]; + data[cellSideCount + 1] = data[halfCell]; + renderCache->addLines(data, color); } } + m_updated = false; + // render + renderCache->render(); } void BlockingInfoRenderer::setColor(uint8_t r, uint8_t g, uint8_t b) { m_color.r = r; m_color.g = g; m_color.b = b; + m_updated = true; } } diff --git a/engine/core/view/renderers/blockinginforenderer.h b/engine/core/view/renderers/blockinginforenderer.h index 27bf017f3..49018c622 100644 --- a/engine/core/view/renderers/blockinginforenderer.h +++ b/engine/core/view/renderers/blockinginforenderer.h @@ -35,7 +35,7 @@ namespace FIFE { class RenderBackend; - class BlockingInfoRenderer: public RendererBase { + class BlockingInfoRenderer : public RendererBase { public: /** Constructor. * @@ -63,7 +63,7 @@ namespace FIFE { */ std::string getName() { return "BlockingInfoRenderer"; } - /** This method is called by the view to ask renderer to draw its rendering aspect based on + /** This method is called by the camera to ask renderer to draw its rendering aspect based on * given parameters. * * @param cam Camera view to draw @@ -85,6 +85,11 @@ namespace FIFE { static BlockingInfoRenderer* getInstance(IRendererContainer* cnt); private: + std::map m_test; + + //! indicates updates + bool m_updated; + //! currently used color SDL_Color m_color; }; From c4900cc64c425f26e941dee2d9d70380cef5fb3a Mon Sep 17 00:00:00 2001 From: helios2000 Date: Thu, 9 Nov 2017 19:22:28 +0100 Subject: [PATCH 4/6] Removed dirty test code and added an better update mechanism to LayerCache. Refs #1029 --- engine/core/model/structures/cellcache.cpp | 19 ++++ engine/core/model/structures/cellcache.h | 6 + engine/core/view/camera.cpp | 30 +++-- engine/core/view/camera.h | 4 +- engine/core/view/layercache.cpp | 31 ++++-- engine/core/view/layercache.h | 11 +- .../view/renderers/blockinginforenderer.cpp | 105 +++++++++--------- .../view/renderers/blockinginforenderer.h | 6 +- 8 files changed, 131 insertions(+), 81 deletions(-) diff --git a/engine/core/model/structures/cellcache.cpp b/engine/core/model/structures/cellcache.cpp index 4b61df89c..2fa6fc27f 100644 --- a/engine/core/model/structures/cellcache.cpp +++ b/engine/core/model/structures/cellcache.cpp @@ -882,6 +882,7 @@ namespace FIFE { std::vector CellCache::getCellsInRect(const Rect& rec) { std::vector cells; + cells.reserve(rec.w * rec.h); ModelCoordinate current(rec.x, rec.y); ModelCoordinate target(rec.x+rec.w, rec.y+rec.h); @@ -897,6 +898,24 @@ namespace FIFE { return cells; } + std::vector CellCache::getBlockingCellsInRect(const Rect& rec) { + std::vector cells; + cells.reserve(rec.w * rec.h); + + ModelCoordinate current(rec.x, rec.y); + ModelCoordinate target(rec.x + rec.w, rec.y + rec.h); + for (; current.y < target.y; ++current.y) { + current.x = rec.x; + for (; current.x < target.x; ++current.x) { + Cell* c = getCell(current); + if (c && c->getCellType() != CTYPE_NO_BLOCKER) { + cells.push_back(c); + } + } + } + return cells; + } + std::vector CellCache::getCellsInCircle(const ModelCoordinate& center, uint16_t radius) { std::vector cells; //radius power 2 diff --git a/engine/core/model/structures/cellcache.h b/engine/core/model/structures/cellcache.h index 3aaf890c0..4d85aec94 100644 --- a/engine/core/model/structures/cellcache.h +++ b/engine/core/model/structures/cellcache.h @@ -269,6 +269,12 @@ namespace FIFE { */ std::vector getCellsInRect(const Rect& rec); + /** Returns all blocking cells in the rect. + * @param rec A const reference to the Rect which specifies the size. + * @return A vector that contain the cells. + */ + std::vector getBlockingCellsInRect(const Rect& rec); + /** Returns all cells in the circle. * @param center A const reference to the ModelCoordinate where the center of the circle is. * @param radius A unsigned integer, radius of the circle. diff --git a/engine/core/view/camera.cpp b/engine/core/view/camera.cpp index ff165a4f0..d04770292 100644 --- a/engine/core/view/camera.cpp +++ b/engine/core/view/camera.cpp @@ -745,12 +745,10 @@ namespace FIFE { m_cache[layer] = new LayerCache(this); m_cache[layer]->setLayer(layer); m_layerToInstances[layer] = RenderList(); - m_cacheUpdates[m_cache[layer]] = true; refresh(); } void Camera::removeLayer(Layer* layer) { - m_cacheUpdates.erase(m_cache[layer]); delete m_cache[layer]; m_cache.erase(layer); m_layerToInstances.erase(layer); @@ -954,11 +952,6 @@ namespace FIFE { } void Camera::updateRenderLists() { - if (!m_map) { - FL_ERR(_log, "No map for camera found"); - return; - } - const std::list& layers = m_map->getLayers(); std::list::const_iterator layer_it = layers.begin(); for (;layer_it != layers.end(); ++layer_it) { @@ -972,8 +965,7 @@ namespace FIFE { if ((*layer_it)->isStatic() && m_transform == NoneTransform) { continue; } - bool update = cache->update(m_transform, instancesToRender); - m_cacheUpdates[cache] = update; + cache->update(m_transform, instancesToRender); } resetUpdates(); } @@ -984,15 +976,28 @@ namespace FIFE { FL_ERR(_log, LMsg("Layer Cache miss! (This shouldn't happen!)") << layer->getId()); return false; } - return m_cacheUpdates[cache]; + if (!cache->getUpdatedInstances().empty() || !cache->getRemovedInstances().empty()) { + return true; + } + return false; } - void Camera::render() { - updateRenderLists(); + const std::set& Camera::getUpdatedInstances(Layer* layer) { + LayerCache* cache = m_cache[layer]; + return cache->getUpdatedInstances(); + } + + const std::set& Camera::getRemovedInstances(Layer* layer) { + LayerCache* cache = m_cache[layer]; + return cache->getRemovedInstances(); + } + void Camera::render() { if (!m_map) { + FL_ERR(_log, "No map for camera found"); return; } + updateRenderLists(); uint32_t lm = m_renderbackend->getLightingModel(); if (lm != 0) { @@ -1048,6 +1053,7 @@ namespace FIFE { } } } + m_cache[*layer_it]->resetCachedInstances(); } renderOverlay(); diff --git a/engine/core/view/camera.h b/engine/core/view/camera.h index 8228cb28e..db529bbcd 100644 --- a/engine/core/view/camera.h +++ b/engine/core/view/camera.h @@ -411,6 +411,9 @@ namespace FIFE { */ bool isLayerCacheUpdated(Layer* layer); + const std::set& getUpdatedInstances(Layer* layer); + const std::set& getRemovedInstances(Layer* layer); + private: friend class MapObserver; void addLayer(Layer* layer); @@ -497,7 +500,6 @@ namespace FIFE { t_layer_to_instances m_layerToInstances; std::map m_cache; - std::map m_cacheUpdates; MapObserver* m_map_observer; // is lighting enable diff --git a/engine/core/view/layercache.cpp b/engine/core/view/layercache.cpp index 2f68d57bc..253330d22 100644 --- a/engine/core/view/layercache.cpp +++ b/engine/core/view/layercache.cpp @@ -302,6 +302,7 @@ namespace FIFE { for (RenderList::iterator it = renderList.begin(); it != renderList.end(); ++it) { if ((*it)->instance == instance) { renderList.erase(it); + m_removedInstances.insert(instance->getFifeId()); break; } } @@ -366,7 +367,7 @@ namespace FIFE { } } - bool LayerCache::update(Camera::Transform transform, RenderList& renderlist) { + void LayerCache::update(Camera::Transform transform, RenderList& renderlist) { // this is only a bit faster, but works without this block too. if(!m_layer->areInstancesVisible()) { FL_DBG(_log, "Layer instances hidden"); @@ -378,13 +379,12 @@ namespace FIFE { } m_entriesToUpdate.clear(); renderlist.clear(); - return true; } // if transform is none then we have only to update the instances with an update info. if (transform == Camera::NoneTransform) { if (!m_entriesToUpdate.empty()) { std::set entryToRemove; - bool update = updateEntries(entryToRemove, renderlist); + updateEntries(entryToRemove, renderlist); //std::cout << "update entries: " << int32_t(m_entriesToUpdate.size()) << " remove entries: " << int32_t(entryToRemove.size()) <<"\n"; if (!entryToRemove.empty()) { std::set::iterator entry_it = entryToRemove.begin(); @@ -392,9 +392,7 @@ namespace FIFE { m_entriesToUpdate.erase(*entry_it); } } - return update; } - return false; } else { m_zoom = m_camera->getZoom(); m_zoomed = !Mathd::Equal(m_zoom, 1.0); @@ -457,7 +455,6 @@ namespace FIFE { sortRenderList(renderlist); } } - return true; } void LayerCache::fullUpdate(Camera::Transform transform) { @@ -503,8 +500,7 @@ namespace FIFE { } } - bool LayerCache::updateEntries(std::set& removes, RenderList& renderlist) { - bool update = false; + void LayerCache::updateEntries(std::set& removes, RenderList& renderlist) { RenderList needSorting; Rect viewport = m_camera->getViewPort(); std::set::const_iterator entry_it = m_entriesToUpdate.begin(); @@ -531,12 +527,13 @@ namespace FIFE { // add to renderlist and sort renderlist.push_back(item); needSorting.push_back(item); + m_updatedInstances.insert(item->instance); } else { // remove from renderlist for (RenderList::iterator it = renderlist.begin(); it != renderlist.end(); ++it) { if ((*it)->instance == item->instance) { - update = true; renderlist.erase(it); + m_removedInstances.insert(item->instance->getFifeId()); break; } } @@ -544,6 +541,7 @@ namespace FIFE { } else if (onScreenA && onScreenB && positionUpdate) { // sort needSorting.push_back(item); + m_updatedInstances.insert(item->instance); } if (!entry->forceUpdate) { @@ -556,14 +554,12 @@ namespace FIFE { } if (!needSorting.empty()) { - update = true; if (m_needSorting) { sortRenderList(renderlist); } else { sortRenderList(needSorting); } } - return update; } bool LayerCache::updateVisual(Entry* entry) { @@ -817,4 +813,17 @@ namespace FIFE { void LayerCache::setCacheImage(ImagePtr image) { m_cacheImage = image; } + + void LayerCache::resetCachedInstances() { + m_updatedInstances.clear(); + m_removedInstances.clear(); + } + + const std::set& LayerCache::getUpdatedInstances() { + return m_updatedInstances; + } + + const std::set& LayerCache::getRemovedInstances() { + return m_removedInstances; + } } diff --git a/engine/core/view/layercache.h b/engine/core/view/layercache.h index 35f45ff31..6e514b856 100644 --- a/engine/core/view/layercache.h +++ b/engine/core/view/layercache.h @@ -55,7 +55,7 @@ namespace FIFE { void setLayer(Layer* layer); - bool update(Camera::Transform transform, RenderList& renderlist); + void update(Camera::Transform transform, RenderList& renderlist); void addInstance(Instance* instance); void removeInstance(Instance* instance); @@ -64,6 +64,10 @@ namespace FIFE { ImagePtr getCacheImage(); void setCacheImage(ImagePtr image); + void resetCachedInstances(); + const std::set& getUpdatedInstances(); + const std::set& getRemovedInstances(); + private: enum RenderEntryUpdateType { EntryNoneUpdate = 0x00, @@ -92,7 +96,7 @@ namespace FIFE { void reset(); void fullUpdate(Camera::Transform transform); void fullCoordinateUpdate(Camera::Transform transform); - bool updateEntries(std::set& removes, RenderList& renderlist); + void updateEntries(std::set& removes, RenderList& renderlist); bool updateVisual(Entry* entry); void updatePosition(Entry* entry); void updateScreenCoordinate(RenderItem* item, bool changedZoom = true); @@ -110,6 +114,9 @@ namespace FIFE { std::set m_entriesToUpdate; std::deque m_freeEntries; + std::set m_updatedInstances; + std::set m_removedInstances; + bool m_needSorting; double m_zMin; double m_zMax; diff --git a/engine/core/view/renderers/blockinginforenderer.cpp b/engine/core/view/renderers/blockinginforenderer.cpp index 6d3c9793e..d19571d88 100644 --- a/engine/core/view/renderers/blockinginforenderer.cpp +++ b/engine/core/view/renderers/blockinginforenderer.cpp @@ -83,53 +83,26 @@ namespace FIFE { } RenderCache* renderCache = getRenderCache(layer); - // Only render if nothing has changed. - if (renderCache && !cam->isUpdated() && cam->isLayerCacheUpdated(layer)) { - bool found = false; - // Only test code - for (RenderList::iterator it = instances.begin(); it != instances.end(); ++it) { - if ((*it)->instance->getId() == "NPC:girl") { - std::map::iterator it2 = m_test.find((*it)->instance->getFifeId()); - if (it2 == m_test.end()) continue; - uint32_t pos = it2->second; - uint32_t cellSideCount = cg->getCellSideCount(); - const uint32_t halfCell = cellSideCount / 2; - std::vector data(cellSideCount + 2); - Color color(m_color.r, m_color.g, m_color.b, 255); - - std::vector vertices; - cg->getVertices(vertices, (*it)->instance->getLocationRef().getLayerCoordinates()); - for (uint32_t i = 0; i < cellSideCount; ++i) { - ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); - data[i].x = pts.x; - data[i].y = pts.y; - } - data[cellSideCount] = data[0]; - data[cellSideCount + 1] = data[halfCell]; - renderCache->updateLines(pos*6, data, color); - found = true; - break; - } - } - if (found) { - renderCache->render(); - return; - } - - } - //if (!cam->isUpdated() && !cam->isLayerCacheUpdated(layer) && !m_updated) { - if (!cam->isUpdated() && !m_updated) { - if (renderCache) { - renderCache->render(); - return; + // full update on start, camera change or color change + if (!renderCache || cam->isUpdated() || m_updated) { + if (!renderCache) { + renderCache = createRenderCache(layer); } + fullUpdate(cam, layer, instances, renderCache); + } else if (cam->isLayerCacheUpdated(layer)) { + // update data on Instance changes + update(cam, layer, renderCache); } - if (!renderCache) { - renderCache = createRenderCache(layer); - } + // render + renderCache->render(); + } + + void BlockingInfoRenderer::fullUpdate(Camera* cam, Layer* layer, RenderList& instances, RenderCache* renderCache) { + CellGrid* cg = layer->getCellGrid(); + renderCache->clear(); - m_test.clear(); + m_fifeIdToBufferId.clear(); uint32_t pos = 0; uint32_t cellSideCount = cg->getCellSideCount(); const uint32_t halfCell = cellSideCount / 2; @@ -139,15 +112,13 @@ namespace FIFE { if (cache) { // fill render cache with cell data Rect layerView = cam->getLayerViewPort(layer); - std::vector cells = cache->getCellsInRect(layerView); + std::vector cells = cache->getBlockingCellsInRect(layerView); std::vector::iterator cit = cells.begin(); for (; cit != cells.end(); ++cit) { - if ((*cit)->getCellType() == CTYPE_NO_BLOCKER) { - continue; - } + // get Instances on Cell const std::set& instances2 = (*cit)->getInstances(); for (std::set::const_iterator it = instances2.begin(); it != instances2.end(); ++it) { - m_test[(*it)->getFifeId()] = pos; + m_fifeIdToBufferId[(*it)->getFifeId()] = pos; } std::vector vertices; cg->getVertices(vertices, (*cit)->getLayerCoordinates()); @@ -157,7 +128,7 @@ namespace FIFE { data[i].y = pts.y; } data[cellSideCount] = data[0]; - data[cellSideCount+1] = data[halfCell]; + data[cellSideCount + 1] = data[halfCell]; renderCache->addLines(data, color); ++pos; } @@ -169,9 +140,7 @@ namespace FIFE { if (!instance->getObject()->isBlocking() || !instance->isBlocking()) { continue; } - /*if (instance->getId() == "NPC:girl") { - std::cout << "found " << instance->getFifeId() << "\n"; - }*/ + m_fifeIdToBufferId[instance->getFifeId()] = pos; std::vector vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); for (uint32_t i = 0; i < cellSideCount; ++i) { @@ -182,11 +151,39 @@ namespace FIFE { data[cellSideCount] = data[0]; data[cellSideCount + 1] = data[halfCell]; renderCache->addLines(data, color); + ++pos; } } m_updated = false; - // render - renderCache->render(); + } + + void BlockingInfoRenderer::update(Camera* cam, Layer* layer, RenderCache* renderCache) { + CellGrid* cg = layer->getCellGrid(); + Color color(m_color.r, m_color.g, m_color.b, 255); + uint32_t cellSideCount = cg->getCellSideCount(); + const uint32_t halfCell = cellSideCount / 2; + const uint32_t elements = cellSideCount + 2; + std::vector data(elements); + // TODO: Add code for cam->getRemovedInstances(layer) + // update Instance data + const std::set& updatedInstances = cam->getUpdatedInstances(layer); + std::set::const_iterator it = updatedInstances.begin(); + for (; it != updatedInstances.end(); ++it) { + std::map::iterator it2 = m_fifeIdToBufferId.find((*it)->getFifeId()); + if (it2 == m_fifeIdToBufferId.end()) continue; + uint32_t pos = it2->second; + + std::vector vertices; + cg->getVertices(vertices, (*it)->getLocationRef().getLayerCoordinates()); + for (uint32_t i = 0; i < cellSideCount; ++i) { + ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); + data[i].x = pts.x; + data[i].y = pts.y; + } + data[cellSideCount] = data[0]; + data[cellSideCount + 1] = data[halfCell]; + renderCache->updateLines(pos * elements, data, color); + } } void BlockingInfoRenderer::setColor(uint8_t r, uint8_t g, uint8_t b) { diff --git a/engine/core/view/renderers/blockinginforenderer.h b/engine/core/view/renderers/blockinginforenderer.h index 49018c622..893352f2f 100644 --- a/engine/core/view/renderers/blockinginforenderer.h +++ b/engine/core/view/renderers/blockinginforenderer.h @@ -85,7 +85,11 @@ namespace FIFE { static BlockingInfoRenderer* getInstance(IRendererContainer* cnt); private: - std::map m_test; + void fullUpdate(Camera* cam, Layer* layer, RenderList& instances, RenderCache* renderCache); + + void update(Camera* cam, Layer* layer, RenderCache* renderCache); + + std::map m_fifeIdToBufferId; //! indicates updates bool m_updated; From 23f5bbe35534537192f7681dac95236c0330e74d Mon Sep 17 00:00:00 2001 From: helios2000 Date: Fri, 10 Nov 2017 18:52:06 +0100 Subject: [PATCH 5/6] Implemented add() for SDLBufferLinesObject. Refs #1029 --- engine/core/video/sdl/sdlbufferobject.cpp | 14 ++++++++++++++ engine/core/video/sdl/sdlbufferobject.h | 2 ++ engine/core/video/sdl/sdlrendercache.cpp | 12 ++++++++++++ engine/core/video/sdl/sdlrendercache.h | 11 +++++++++-- engine/core/view/layercache.cpp | 1 + .../core/view/renderers/blockinginforenderer.cpp | 4 ++-- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/engine/core/video/sdl/sdlbufferobject.cpp b/engine/core/video/sdl/sdlbufferobject.cpp index b3e609cec..2765c5830 100644 --- a/engine/core/video/sdl/sdlbufferobject.cpp +++ b/engine/core/video/sdl/sdlbufferobject.cpp @@ -61,6 +61,20 @@ namespace FIFE { delete[] m_points; } + void SDLBufferLinesObject::add(const std::vector& points, const Color& color) { + if (m_count != points.size()) { + delete[] m_points; + m_count = points.size(); + m_points = new SDL_Point[m_count]; + } + m_color = color; + uint32_t index = 0; + for (; index < m_count; index++) { + m_points[index].x = points[index].x; + m_points[index].y = points[index].y; + } + } + void SDLBufferLinesObject::render() { SDL_Renderer* renderer = static_cast(RenderBackend::instance())->getRenderer(); SDL_SetRenderDrawColor(renderer, m_color.getR(), m_color.getG(), m_color.getB(), m_color.getAlpha()); diff --git a/engine/core/video/sdl/sdlbufferobject.h b/engine/core/video/sdl/sdlbufferobject.h index 2fb92cde0..d808016ea 100644 --- a/engine/core/video/sdl/sdlbufferobject.h +++ b/engine/core/video/sdl/sdlbufferobject.h @@ -38,6 +38,7 @@ namespace FIFE { /** Abstract interface for all the sdl buffer objects. */ class SDLBufferObject { public: + /** Destructor */ virtual ~SDLBufferObject() {} @@ -63,6 +64,7 @@ namespace FIFE { public: SDLBufferLinesObject(const std::vector& points, const Color& color); virtual ~SDLBufferLinesObject(); + void add(const std::vector& points, const Color& color); void render(); private: SDL_Point* m_points; diff --git a/engine/core/video/sdl/sdlrendercache.cpp b/engine/core/video/sdl/sdlrendercache.cpp index e8046ef10..4d8383218 100644 --- a/engine/core/video/sdl/sdlrendercache.cpp +++ b/engine/core/video/sdl/sdlrendercache.cpp @@ -46,6 +46,7 @@ namespace FIFE { delete *it; } m_objects.clear(); + m_typeBuffers.clear(); } void SDLRenderCache::render() { @@ -58,10 +59,21 @@ namespace FIFE { void SDLRenderCache::addLine(const Point& p1, const Point& p2, const Color& color) { SDLBufferObject* lines = new SDLBufferLineObject(p1, p2, color); m_objects.push_back(lines); + std::vector& lineBuffers = m_typeBuffers[LineBufferObject]; + lineBuffers.push_back(lines); } void SDLRenderCache::addLines(const std::vector& points, const Color& color) { SDLBufferObject* lines = new SDLBufferLinesObject(points, color); m_objects.push_back(lines); + std::vector& linesBuffers = m_typeBuffers[LinesBufferObject]; + linesBuffers.push_back(lines); + } + + void SDLRenderCache::updateLines(uint32_t position, const std::vector& points, const Color& color) { + std::vector& linesBuffers = m_typeBuffers[LinesBufferObject]; + // Position calculation is too hacky + SDLBufferLinesObject* object = static_cast(linesBuffers[position / points.size()]); + object->add(points, color); } } diff --git a/engine/core/video/sdl/sdlrendercache.h b/engine/core/video/sdl/sdlrendercache.h index 9c85fc153..250c9d83e 100644 --- a/engine/core/video/sdl/sdlrendercache.h +++ b/engine/core/video/sdl/sdlrendercache.h @@ -23,6 +23,7 @@ #define FIFE_VIDEO_SDL_RENDERCACHE_H // Standard C++ library includes +#include // Platform specific includes @@ -39,6 +40,12 @@ namespace FIFE { class SDLRenderCache : public RenderCache { public: + enum BufferObjectType { + LineBufferObject = 0, + LinesBufferObject = 1, + TrianglesBufferObject = 2 + }; + /** Constructor. */ SDLRenderCache(); @@ -58,11 +65,11 @@ namespace FIFE { virtual void addLines(const std::vector& points, const Color& color); - virtual void updateLines(uint32_t position, const std::vector& points, const Color& color) {}; + virtual void updateLines(uint32_t position, const std::vector& points, const Color& color); private: std::vector m_objects; - + std::map > m_typeBuffers; }; } diff --git a/engine/core/view/layercache.cpp b/engine/core/view/layercache.cpp index 253330d22..289f7a71d 100644 --- a/engine/core/view/layercache.cpp +++ b/engine/core/view/layercache.cpp @@ -379,6 +379,7 @@ namespace FIFE { } m_entriesToUpdate.clear(); renderlist.clear(); + return; } // if transform is none then we have only to update the instances with an update info. if (transform == Camera::NoneTransform) { diff --git a/engine/core/view/renderers/blockinginforenderer.cpp b/engine/core/view/renderers/blockinginforenderer.cpp index d19571d88..c563e4254 100644 --- a/engine/core/view/renderers/blockinginforenderer.cpp +++ b/engine/core/view/renderers/blockinginforenderer.cpp @@ -104,7 +104,7 @@ namespace FIFE { renderCache->clear(); m_fifeIdToBufferId.clear(); uint32_t pos = 0; - uint32_t cellSideCount = cg->getCellSideCount(); + const uint32_t cellSideCount = cg->getCellSideCount(); const uint32_t halfCell = cellSideCount / 2; std::vector data(cellSideCount + 2); Color color(m_color.r, m_color.g, m_color.b, 255); @@ -160,7 +160,7 @@ namespace FIFE { void BlockingInfoRenderer::update(Camera* cam, Layer* layer, RenderCache* renderCache) { CellGrid* cg = layer->getCellGrid(); Color color(m_color.r, m_color.g, m_color.b, 255); - uint32_t cellSideCount = cg->getCellSideCount(); + const uint32_t cellSideCount = cg->getCellSideCount(); const uint32_t halfCell = cellSideCount / 2; const uint32_t elements = cellSideCount + 2; std::vector data(elements); From 4a7c57887a7233d331a930f5811cb3dd036e8b6e Mon Sep 17 00:00:00 2001 From: helios2000 Date: Sun, 20 May 2018 17:46:17 +0200 Subject: [PATCH 6/6] More work on RenderCache --- engine/core/video/opengl/glbufferobject.cpp | 5 -- engine/core/video/opengl/glrendercache.cpp | 8 +- engine/core/video/opengl/glrendercache.h | 1 + engine/core/video/rendercache.h | 10 +-- engine/core/video/sdl/sdlbufferobject.cpp | 80 +++++++++++-------- engine/core/video/sdl/sdlbufferobject.h | 40 ++++++---- engine/core/video/sdl/sdlrendercache.cpp | 47 +++++++---- engine/core/video/sdl/sdlrendercache.h | 9 ++- .../view/renderers/blockinginforenderer.cpp | 55 ++++++++----- .../view/renderers/blockinginforenderer.h | 3 +- 10 files changed, 152 insertions(+), 106 deletions(-) diff --git a/engine/core/video/opengl/glbufferobject.cpp b/engine/core/video/opengl/glbufferobject.cpp index 8fe025e69..11803585c 100644 --- a/engine/core/video/opengl/glbufferobject.cpp +++ b/engine/core/video/opengl/glbufferobject.cpp @@ -68,7 +68,6 @@ namespace FIFE { m_data.push_back(rd); m_indices.push_back(indice++); m_indices.push_back(indice); - } } @@ -95,7 +94,6 @@ namespace FIFE { if (!m_final) { finalize(); } else { - //std::cout << "4 \n"; glBindBuffer(GL_ARRAY_BUFFER, m_vboId); glBufferSubData(GL_ARRAY_BUFFER, sizeof(renderDataP) * position, sizeof(renderDataP) * elements, &m_data[position].vertex); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -104,20 +102,17 @@ namespace FIFE { void OpenGLBufferLinesObject::finalize() { if (m_vboId == 0) { - //std::cout << "1 \n"; glGenBuffers(1, &m_vboId); glGenBuffers(1, &m_vboIndicesId); } if (m_oldFinalSize != m_indices.size()) { - //std::cout << "2 \n"; glBindBuffer(GL_ARRAY_BUFFER, m_vboId); glBufferData(GL_ARRAY_BUFFER, sizeof(renderDataP) * m_data.size(), &m_data[0].vertex, GL_STREAM_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndicesId); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * m_indices.size(), &m_indices[0], GL_STREAM_DRAW); m_oldFinalSize = m_indices.size(); } else { - //std::cout << "3 \n"; glBindBuffer(GL_ARRAY_BUFFER, m_vboId); glBufferData(GL_ARRAY_BUFFER, sizeof(renderDataP) * m_data.size(), NULL, GL_STREAM_DRAW); GLvoid* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); diff --git a/engine/core/video/opengl/glrendercache.cpp b/engine/core/video/opengl/glrendercache.cpp index 51fc60cb9..aa4dfbcd1 100644 --- a/engine/core/video/opengl/glrendercache.cpp +++ b/engine/core/video/opengl/glrendercache.cpp @@ -34,9 +34,7 @@ #define BUFFER_OFFSET(i) ((void*)(i)) namespace FIFE { - GLRenderCache::GLRenderCache(): - RenderCache() { - + GLRenderCache::GLRenderCache() { m_buffer = NULL; } @@ -79,4 +77,8 @@ namespace FIFE { } static_cast(m_buffer)->update(position, points, color); } + + void GLRenderCache::removeLines(uint32_t position, uint32_t elements) { + + } } diff --git a/engine/core/video/opengl/glrendercache.h b/engine/core/video/opengl/glrendercache.h index c87c8d3b4..e18423231 100644 --- a/engine/core/video/opengl/glrendercache.h +++ b/engine/core/video/opengl/glrendercache.h @@ -57,6 +57,7 @@ namespace FIFE { virtual void addLines(const std::vector& points, const Color& color); virtual void updateLines(uint32_t position, const std::vector& points, const Color& color); + virtual void removeLines(uint32_t position, uint32_t elements); private: diff --git a/engine/core/video/rendercache.h b/engine/core/video/rendercache.h index 6b08a9cfe..ae4775ca7 100644 --- a/engine/core/video/rendercache.h +++ b/engine/core/video/rendercache.h @@ -39,14 +39,10 @@ namespace FIFE { /** Abstract interface for all the rendercaches. */ class RenderCache { public: - /** Constructor. - */ - RenderCache() {}; - - /** Destructor. - */ virtual ~RenderCache() {}; + /** Clear + */ virtual void clear() = 0; /** Render @@ -58,6 +54,8 @@ namespace FIFE { virtual void addLines(const std::vector& points, const Color& color) = 0; virtual void updateLines(uint32_t position, const std::vector& points, const Color& color) = 0; + + virtual void removeLines(uint32_t position, uint32_t elements) = 0; }; } diff --git a/engine/core/video/sdl/sdlbufferobject.cpp b/engine/core/video/sdl/sdlbufferobject.cpp index 2765c5830..ee014dc43 100644 --- a/engine/core/video/sdl/sdlbufferobject.cpp +++ b/engine/core/video/sdl/sdlbufferobject.cpp @@ -30,54 +30,64 @@ #include "sdlbufferobject.h" namespace FIFE { - SDLBufferLineObject::SDLBufferLineObject(const Point& p1, const Point& p2, const Color& color) { - m_p1 = p1; - m_p2 = p2; - m_color = color; + SDLBufferPrimitiveObject::SDLBufferPrimitiveObject(RenderType type, const std::vector& points, const Color& color) { + add(type, points, color); } - SDLBufferLineObject::~SDLBufferLineObject() { - } + SDLBufferPrimitiveObject::~SDLBufferPrimitiveObject() { - void SDLBufferLineObject::render() { - SDL_Renderer* renderer = static_cast(RenderBackend::instance())->getRenderer(); - SDL_SetRenderDrawColor(renderer, m_color.getR(), m_color.getG(), m_color.getB(), m_color.getAlpha()); - SDL_RenderDrawLine(renderer, m_p1.x, m_p1.y, m_p2.x, m_p2.y); } + void SDLBufferPrimitiveObject::add(RenderType type, const std::vector& points, const Color& color) { + uint32_t index = m_points.size(); + uint32_t elements = points.size(); + BufferDescriptor bc = { type, index, elements, color }; - SDLBufferLinesObject::SDLBufferLinesObject(const std::vector& points, const Color& color) { - m_count = points.size(); - m_color = color; - m_points = new SDL_Point[m_count]; - uint32_t index = 0; - for (; index < m_count; index++) { - m_points[index].x = points[index].x; - m_points[index].y = points[index].y; + m_points.resize(index + elements); + for (uint32_t i = 0; i < elements; ++i) { + m_points[index + i].x = points[i].x; + m_points[index + i].y = points[i].y; } - } - SDLBufferLinesObject::~SDLBufferLinesObject() { - delete[] m_points; + m_descriptors.push_back(bc); + m_descriptorPosition[index] = m_descriptors.size() - 1; } - void SDLBufferLinesObject::add(const std::vector& points, const Color& color) { - if (m_count != points.size()) { - delete[] m_points; - m_count = points.size(); - m_points = new SDL_Point[m_count]; - } - m_color = color; - uint32_t index = 0; - for (; index < m_count; index++) { - m_points[index].x = points[index].x; - m_points[index].y = points[index].y; + void SDLBufferPrimitiveObject::update(uint32_t position, const std::vector& points, const Color& color) { + BufferDescriptor& bd = m_descriptors[m_descriptorPosition[position]]; + bd.color = color; + uint32_t index = bd.position; + uint32_t elements = points.size(); + for (uint32_t i = 0; i < elements; ++i) { + m_points[index + i].x = points[i].x; + m_points[index + i].y = points[i].y; } } - void SDLBufferLinesObject::render() { + void SDLBufferPrimitiveObject::remove(uint32_t position, uint32_t elements) { + BufferDescriptor& bd = m_descriptors[m_descriptorPosition[position]]; + bd.count = 0; + } + + void SDLBufferPrimitiveObject::render() { + if (m_descriptors.empty()) return; + SDL_Point* point = NULL; SDL_Renderer* renderer = static_cast(RenderBackend::instance())->getRenderer(); - SDL_SetRenderDrawColor(renderer, m_color.getR(), m_color.getG(), m_color.getB(), m_color.getAlpha()); - SDL_RenderDrawLines(renderer, m_points, m_count); + std::vector::iterator it = m_descriptors.begin(); + for (; it != m_descriptors.end(); ++it) { + const BufferDescriptor& bd = *it; + SDL_SetRenderDrawColor(renderer, bd.color.getR(), bd.color.getG(), bd.color.getB(), bd.color.getAlpha()); + point = &m_points[bd.position]; + switch (bd.type) { + case Render_Point: + case Render_Points: + SDL_RenderDrawPoints(renderer, point, bd.count); + break; + case Render_Line: + case Render_Lines: + SDL_RenderDrawLines(renderer, point, bd.count); + break; + } + } } } diff --git a/engine/core/video/sdl/sdlbufferobject.h b/engine/core/video/sdl/sdlbufferobject.h index d808016ea..037ec2f79 100644 --- a/engine/core/video/sdl/sdlbufferobject.h +++ b/engine/core/video/sdl/sdlbufferobject.h @@ -23,7 +23,7 @@ #define FIFE_VIDEO_SDL_BUFFEROBJECT_H // Standard C++ library includes - +#include // Platform specific includes // 3rd party library includes @@ -48,28 +48,34 @@ namespace FIFE { virtual void render() = 0; }; + enum RenderType { + Render_Point, + Render_Points, + Render_Line, + Render_Lines, + Render_Rect, + Render_Rects + }; - class SDLBufferLineObject : public SDLBufferObject { - public: - SDLBufferLineObject(const Point& p1, const Point& p2, const Color& color); - virtual ~SDLBufferLineObject(); - void render(); - private: - Point m_p1; - Point m_p2; - Color m_color; + struct BufferDescriptor { + RenderType type; + uint32_t position; + uint32_t count; + Color color; }; - class SDLBufferLinesObject : public SDLBufferObject { + class SDLBufferPrimitiveObject : public SDLBufferObject { public: - SDLBufferLinesObject(const std::vector& points, const Color& color); - virtual ~SDLBufferLinesObject(); - void add(const std::vector& points, const Color& color); + SDLBufferPrimitiveObject(RenderType type, const std::vector& points, const Color& color); + virtual ~SDLBufferPrimitiveObject(); + void add(RenderType type, const std::vector& points, const Color& color); + void update(uint32_t position, const std::vector& points, const Color& color); + void remove(uint32_t position, uint32_t elements); void render(); private: - SDL_Point* m_points; - Color m_color; - int32_t m_count; + std::vector m_points; + std::vector m_descriptors; + std::unordered_map m_descriptorPosition; }; } diff --git a/engine/core/video/sdl/sdlrendercache.cpp b/engine/core/video/sdl/sdlrendercache.cpp index 4d8383218..3a7df6580 100644 --- a/engine/core/video/sdl/sdlrendercache.cpp +++ b/engine/core/video/sdl/sdlrendercache.cpp @@ -32,8 +32,7 @@ #include "sdlrendercache.h" namespace FIFE { - SDLRenderCache::SDLRenderCache(): - RenderCache() { + SDLRenderCache::SDLRenderCache() { } SDLRenderCache::~SDLRenderCache() { @@ -57,23 +56,43 @@ namespace FIFE { } void SDLRenderCache::addLine(const Point& p1, const Point& p2, const Color& color) { - SDLBufferObject* lines = new SDLBufferLineObject(p1, p2, color); - m_objects.push_back(lines); - std::vector& lineBuffers = m_typeBuffers[LineBufferObject]; - lineBuffers.push_back(lines); + std::vector points(2); + points[0] = p1; + points[1] = p2; + SDLBufferObject* buffer = m_typeBuffers[PrimitiveBufferObject]; + if (!buffer) { + buffer = new SDLBufferPrimitiveObject(RenderType::Render_Line, points, color); + m_typeBuffers[PrimitiveBufferObject] = buffer; + m_objects.push_back(buffer); + } else { + static_cast(buffer)->add(RenderType::Render_Line, points, color); + } } void SDLRenderCache::addLines(const std::vector& points, const Color& color) { - SDLBufferObject* lines = new SDLBufferLinesObject(points, color); - m_objects.push_back(lines); - std::vector& linesBuffers = m_typeBuffers[LinesBufferObject]; - linesBuffers.push_back(lines); + SDLBufferObject* buffer = m_typeBuffers[PrimitiveBufferObject]; + if (!buffer) { + buffer = new SDLBufferPrimitiveObject(FIFE::RenderType::Render_Lines, points, color); + m_typeBuffers[PrimitiveBufferObject] = buffer; + m_objects.push_back(buffer); + } else { + static_cast(buffer)->add(RenderType::Render_Lines, points, color); + } } void SDLRenderCache::updateLines(uint32_t position, const std::vector& points, const Color& color) { - std::vector& linesBuffers = m_typeBuffers[LinesBufferObject]; - // Position calculation is too hacky - SDLBufferLinesObject* object = static_cast(linesBuffers[position / points.size()]); - object->add(points, color); + SDLBufferObject* buffer = m_typeBuffers[PrimitiveBufferObject]; + if (!buffer) { + return; + } + static_cast(buffer)->update(position, points, color); + } + + void SDLRenderCache::removeLines(uint32_t position, uint32_t elements) { + SDLBufferObject* buffer = m_typeBuffers[PrimitiveBufferObject]; + if (!buffer) { + return; + } + static_cast(buffer)->remove(position, elements); } } diff --git a/engine/core/video/sdl/sdlrendercache.h b/engine/core/video/sdl/sdlrendercache.h index 250c9d83e..071ebe02d 100644 --- a/engine/core/video/sdl/sdlrendercache.h +++ b/engine/core/video/sdl/sdlrendercache.h @@ -24,6 +24,7 @@ // Standard C++ library includes #include +#include // Platform specific includes @@ -41,9 +42,7 @@ namespace FIFE { class SDLRenderCache : public RenderCache { public: enum BufferObjectType { - LineBufferObject = 0, - LinesBufferObject = 1, - TrianglesBufferObject = 2 + PrimitiveBufferObject = 0 }; /** Constructor. @@ -67,9 +66,11 @@ namespace FIFE { virtual void updateLines(uint32_t position, const std::vector& points, const Color& color); + virtual void removeLines(uint32_t position, uint32_t elements); + private: std::vector m_objects; - std::map > m_typeBuffers; + std::map m_typeBuffers; }; } diff --git a/engine/core/view/renderers/blockinginforenderer.cpp b/engine/core/view/renderers/blockinginforenderer.cpp index c563e4254..22244d4d8 100644 --- a/engine/core/view/renderers/blockinginforenderer.cpp +++ b/engine/core/view/renderers/blockinginforenderer.cpp @@ -106,7 +106,8 @@ namespace FIFE { uint32_t pos = 0; const uint32_t cellSideCount = cg->getCellSideCount(); const uint32_t halfCell = cellSideCount / 2; - std::vector data(cellSideCount + 2); + const uint32_t elements = cellSideCount + 2; + std::vector data(elements); Color color(m_color.r, m_color.g, m_color.b, 255); CellCache* cache = layer->getCellCache(); if (cache) { @@ -118,7 +119,7 @@ namespace FIFE { // get Instances on Cell const std::set& instances2 = (*cit)->getInstances(); for (std::set::const_iterator it = instances2.begin(); it != instances2.end(); ++it) { - m_fifeIdToBufferId[(*it)->getFifeId()] = pos; + m_fifeIdToBufferId[(*it)->getFifeId()] = pos * elements; } std::vector vertices; cg->getVertices(vertices, (*cit)->getLayerCoordinates()); @@ -140,7 +141,7 @@ namespace FIFE { if (!instance->getObject()->isBlocking() || !instance->isBlocking()) { continue; } - m_fifeIdToBufferId[instance->getFifeId()] = pos; + m_fifeIdToBufferId[instance->getFifeId()] = pos * elements; std::vector vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); for (uint32_t i = 0; i < cellSideCount; ++i) { @@ -159,30 +160,42 @@ namespace FIFE { void BlockingInfoRenderer::update(Camera* cam, Layer* layer, RenderCache* renderCache) { CellGrid* cg = layer->getCellGrid(); - Color color(m_color.r, m_color.g, m_color.b, 255); const uint32_t cellSideCount = cg->getCellSideCount(); const uint32_t halfCell = cellSideCount / 2; const uint32_t elements = cellSideCount + 2; - std::vector data(elements); - // TODO: Add code for cam->getRemovedInstances(layer) + + // remove data + const std::set& removedInstances = cam->getRemovedInstances(layer); + std::set::const_iterator rit = removedInstances.begin(); + for (; rit != removedInstances.end(); ++rit) { + std::unordered_map::iterator rit2 = m_fifeIdToBufferId.find(*rit); + if (rit2 == m_fifeIdToBufferId.end()) continue; + uint32_t pos = rit2->second; + renderCache->removeLines(pos, elements); + } + // update Instance data const std::set& updatedInstances = cam->getUpdatedInstances(layer); - std::set::const_iterator it = updatedInstances.begin(); - for (; it != updatedInstances.end(); ++it) { - std::map::iterator it2 = m_fifeIdToBufferId.find((*it)->getFifeId()); - if (it2 == m_fifeIdToBufferId.end()) continue; - uint32_t pos = it2->second; - - std::vector vertices; - cg->getVertices(vertices, (*it)->getLocationRef().getLayerCoordinates()); - for (uint32_t i = 0; i < cellSideCount; ++i) { - ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); - data[i].x = pts.x; - data[i].y = pts.y; + if (!updatedInstances.empty()) { + Color color(m_color.r, m_color.g, m_color.b, 255); + std::vector data(elements); + std::set::const_iterator it = updatedInstances.begin(); + for (; it != updatedInstances.end(); ++it) { + std::unordered_map::iterator it2 = m_fifeIdToBufferId.find((*it)->getFifeId()); + if (it2 == m_fifeIdToBufferId.end()) continue; + uint32_t pos = it2->second; + + std::vector vertices; + cg->getVertices(vertices, (*it)->getLocationRef().getLayerCoordinates()); + for (uint32_t i = 0; i < cellSideCount; ++i) { + ScreenPoint pts = cam->toScreenCoordinates(cg->toMapCoordinates(vertices[i])); + data[i].x = pts.x; + data[i].y = pts.y; + } + data[cellSideCount] = data[0]; + data[cellSideCount + 1] = data[halfCell]; + renderCache->updateLines(pos, data, color); } - data[cellSideCount] = data[0]; - data[cellSideCount + 1] = data[halfCell]; - renderCache->updateLines(pos * elements, data, color); } } diff --git a/engine/core/view/renderers/blockinginforenderer.h b/engine/core/view/renderers/blockinginforenderer.h index 893352f2f..57c3ec5fa 100644 --- a/engine/core/view/renderers/blockinginforenderer.h +++ b/engine/core/view/renderers/blockinginforenderer.h @@ -23,6 +23,7 @@ #define FIFE_BLOCKINGINFORENDERER_H // Standard C++ library includes +#include // 3rd party library includes @@ -89,7 +90,7 @@ namespace FIFE { void update(Camera* cam, Layer* layer, RenderCache* renderCache); - std::map m_fifeIdToBufferId; + std::unordered_map m_fifeIdToBufferId; //! indicates updates bool m_updated;