summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-05-15 18:02:40 +0300
committerAndrei Karas <akaras@inbox.ru>2015-05-15 18:17:20 +0300
commit430f472b0e358ebb2cc7f2113c606f2ea03f7739 (patch)
treee0c5cca9455248b66ce86c2c32e45ab2192ccbbb
parentdfb43b30af56e9d7b00115e8a2a2f21a4f308227 (diff)
downloadplus-430f472b0e358ebb2cc7f2113c606f2ea03f7739.tar.gz
plus-430f472b0e358ebb2cc7f2113c606f2ea03f7739.tar.bz2
plus-430f472b0e358ebb2cc7f2113c606f2ea03f7739.tar.xz
plus-430f472b0e358ebb2cc7f2113c606f2ea03f7739.zip
Improve a bit map draw performance.
-rw-r--r--src/resources/map/map.cpp189
-rw-r--r--src/resources/map/map.h9
-rw-r--r--src/resources/mapreader.cpp2
3 files changed, 148 insertions, 52 deletions
diff --git a/src/resources/map/map.cpp b/src/resources/map/map.cpp
index 14465956e..9f4feb87b 100644
--- a/src/resources/map/map.cpp
+++ b/src/resources/map/map.cpp
@@ -87,6 +87,8 @@ Map::Map(const int width, const int height,
mMetaTiles(new MetaTile[mWidth * mHeight]),
mWalkLayer(nullptr),
mLayers(),
+ mDrawUnderLayers(),
+ mDrawOverLayers(),
mTilesets(),
mActors(),
mHasWarps(false),
@@ -131,7 +133,15 @@ Map::Map(const int width, const int height,
mHeights(nullptr),
mRedrawMap(true),
mBeingOpacity(false),
- mCustom(false)
+#ifdef USE_OPENGL
+ mCachedDraw(mOpenGL == RENDER_NORMAL_OPENGL
+ || mOpenGL == RENDER_GLES_OPENGL
+ || mOpenGL == RENDER_MODERN_OPENGL),
+#else
+ mCachedDraw(false),
+#endif
+ mCustom(false),
+ mDrawOnlyFringe(false)
{
const int size = mWidth * mHeight;
for (int i = 0; i < BlockType::NB_BLOCKTYPES; i++)
@@ -353,9 +363,7 @@ void Map::draw(Graphics *const graphics, int scrollX, int scrollY)
#ifdef USE_OPENGL
int updateFlag = 0;
- if (mOpenGL == RENDER_NORMAL_OPENGL
- || mOpenGL == RENDER_GLES_OPENGL
- || mOpenGL == RENDER_MODERN_OPENGL)
+ if (mCachedDraw)
{
if (mLastX != startX || mLastY != startY || mLastScrollX != scrollX
|| mLastScrollY != scrollY)
@@ -379,9 +387,7 @@ void Map::draw(Graphics *const graphics, int scrollX, int scrollY)
}
#endif
- if (mDrawLayersFlags == MapType::SPECIAL3
- || mDrawLayersFlags == MapType::SPECIAL4
- || mDrawLayersFlags == MapType::BLACKWHITE)
+ if (mDrawOnlyFringe)
{
if (mFringeLayer)
{
@@ -393,62 +399,77 @@ void Map::draw(Graphics *const graphics, int scrollX, int scrollY)
}
else
{
- bool overFringe = false;
-
- for (LayersCIter layeri = mLayers.begin(), layeri_end = mLayers.end();
- layeri != layeri_end && !overFringe; ++ layeri)
+ if (mCachedDraw)
{
- MapLayer *const layer = *layeri;
- if (!(layer->mMask & mMask))
- continue;
-
- if (layer->isFringeLayer())
+ FOR_EACH (Layers::iterator, it, mDrawUnderLayers)
{
- layer->setSpecialLayer(mSpecialLayer);
- layer->setTempLayer(mTempLayer);
- if (mDrawLayersFlags == MapType::SPECIAL2)
- overFringe = true;
+ MapLayer *const layer = *it;
+ if (updateFlag)
+ {
+ layer->updateOGL(graphics, startX, startY,
+ endX, endY, scrollX, scrollY, mDrawLayersFlags);
+ }
- layer->drawFringe(graphics, startX, startY, endX, endY,
- scrollX, scrollY, &mActors, mDrawLayersFlags, mActorFixY);
+ layer->drawOGL(graphics);
}
- else
+
+ if (mFringeLayer)
{
-#ifdef USE_OPENGL
- if (mOpenGL == RENDER_NORMAL_OPENGL
- || mOpenGL == RENDER_GLES_OPENGL
- || mOpenGL == RENDER_MODERN_OPENGL)
- {
- if (updateFlag)
- {
- layer->updateOGL(graphics, startX, startY,
- endX, endY, scrollX, scrollY, mDrawLayersFlags);
- }
+ mFringeLayer->setSpecialLayer(mSpecialLayer);
+ mFringeLayer->setTempLayer(mTempLayer);
+ mFringeLayer->drawFringe(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, &mActors, mDrawLayersFlags, mActorFixY);
+ }
- layer->drawOGL(graphics);
- }
- else
-#endif
+ FOR_EACH (Layers::iterator, it, mDrawOverLayers)
+ {
+ MapLayer *const layer = *it;
+ if (updateFlag)
{
- layer->draw(graphics, startX, startY, endX, endY,
- scrollX, scrollY, mDrawLayersFlags);
+ layer->updateOGL(graphics, startX, startY,
+ endX, endY, scrollX, scrollY, mDrawLayersFlags);
}
+
+ layer->drawOGL(graphics);
+ }
+ }
+ else
+ {
+ FOR_EACH (Layers::iterator, it, mDrawUnderLayers)
+ {
+ (*it)->draw(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, mDrawLayersFlags);
+ }
+
+ if (mFringeLayer)
+ {
+ mFringeLayer->setSpecialLayer(mSpecialLayer);
+ mFringeLayer->setTempLayer(mTempLayer);
+ mFringeLayer->drawFringe(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, &mActors, mDrawLayersFlags, mActorFixY);
+ }
+
+ FOR_EACH (Layers::iterator, it, mDrawOverLayers)
+ {
+ (*it)->draw(graphics, startX, startY, endX, endY,
+ scrollX, scrollY, mDrawLayersFlags);
}
}
}
// Don't draw if gui opacity == 1
- if (mBeingOpacity && mOpacity != 1.0F)
+ if (mBeingOpacity)
{
// Draws beings with a lower opacity to make them visible
// even when covered by a wall or some other elements...
ActorsCIter ai = mActors.begin();
const ActorsCIter ai_end = mActors.end();
- while (ai != ai_end)
+
+ if (mOpenGL == RENDER_SOFTWARE)
{
- if (Actor *const actor = *ai)
+ while (ai != ai_end)
{
- if (mOpenGL == RENDER_SOFTWARE)
+ if (Actor *const actor = *ai)
{
const int x = actor->getTileX();
const int y = actor->getTileY();
@@ -457,16 +478,33 @@ void Map::draw(Graphics *const graphics, int scrollX, int scrollY)
++ai;
continue;
}
+ // For now, just draw actors with only one layer.
+ if (actor->getNumberOfLayers() == 1)
+ {
+ actor->setAlpha(0.3F);
+ actor->draw(graphics, -scrollX, -scrollY);
+ actor->setAlpha(1.0F);
+ }
}
- // For now, just draw actors with only one layer.
- if (actor->getNumberOfLayers() == 1)
+ ++ai;
+ }
+ }
+ else
+ {
+ while (ai != ai_end)
+ {
+ if (Actor *const actor = *ai)
{
- actor->setAlpha(0.3F);
- actor->draw(graphics, -scrollX, -scrollY);
- actor->setAlpha(1.0F);
+ // For now, just draw actors with only one layer.
+ if (actor->getNumberOfLayers() == 1)
+ {
+ actor->setAlpha(0.3F);
+ actor->draw(graphics, -scrollX, -scrollY);
+ actor->setAlpha(1.0F);
+ }
}
+ ++ai;
}
- ++ai;
}
}
@@ -1207,7 +1245,7 @@ const TileAnimation *Map::getAnimationForGid(const int gid) const
if (mTileAnimations.empty())
return nullptr;
- TileAnimationMapCIter i = mTileAnimations.find(gid);
+ const TileAnimationMapCIter i = mTileAnimations.find(gid);
return (i == mTileAnimations.end()) ? nullptr : i->second;
}
@@ -1475,6 +1513,41 @@ uint8_t Map::getHeightOffset(const int x, const int y) const
return mHeights->getHeight(x, y);
}
+void Map::updateDrawLayersList()
+{
+ mDrawUnderLayers.clear();
+ mDrawOverLayers.clear();
+
+ if (mDrawOnlyFringe)
+ return;
+
+ LayersCIter layers = mLayers.begin();
+ const LayersCIter layers_end = mLayers.end();
+ for (; layers != layers_end; ++ layers)
+ {
+ MapLayer *const layer = *layers;
+ if (!(layer->mMask & mMask))
+ continue;
+
+ if (layer->isFringeLayer())
+ {
+ ++ layers;
+ break;
+ }
+
+ mDrawUnderLayers.push_back(layer);
+ }
+
+ for (; layers != layers_end; ++ layers)
+ {
+ MapLayer *const layer = *layers;
+ if (!(layer->mMask & mMask))
+ continue;
+
+ mDrawOverLayers.push_back(layer);
+ }
+}
+
void Map::setMask(const int mask)
{
if (mask != mMask)
@@ -1497,3 +1570,19 @@ void Map::addAnimation(const int gid, TileAnimation *const animation)
}
mTileAnimations[gid] = animation;
}
+
+void Map::setDrawLayersFlags(const MapType::MapType &n)
+{
+ mDrawLayersFlags = n;
+ if (mDrawLayersFlags == MapType::SPECIAL3
+ || mDrawLayersFlags == MapType::SPECIAL4
+ || mDrawLayersFlags == MapType::BLACKWHITE)
+ {
+ mDrawOnlyFringe = true;
+ }
+ else
+ {
+ mDrawOnlyFringe = false;
+ }
+ updateDrawLayersList();
+}
diff --git a/src/resources/map/map.h b/src/resources/map/map.h
index dc8c880b1..3afd6d8ef 100644
--- a/src/resources/map/map.h
+++ b/src/resources/map/map.h
@@ -216,8 +216,7 @@ class Map final : public Properties, public ConfigListener
*/
void addAnimation(const int gid, TileAnimation *const animation);
- void setDrawLayersFlags(const MapType::MapType &n)
- { mDrawLayersFlags = n; }
+ void setDrawLayersFlags(const MapType::MapType &n);
MapType::MapType getDrawLayersFlags() const A_WARN_UNUSED
{ return mDrawLayersFlags; }
@@ -327,6 +326,8 @@ class Map final : public Properties, public ConfigListener
void setMask(const int mask);
+ void updateDrawLayersList();
+
protected:
friend class Actor;
friend class Minimap;
@@ -377,6 +378,8 @@ class Map final : public Properties, public ConfigListener
MetaTile *const mMetaTiles;
WalkLayer *mWalkLayer;
Layers mLayers;
+ Layers mDrawUnderLayers;
+ Layers mDrawOverLayers;
Tilesets mTilesets;
Actors mActors;
bool mHasWarps;
@@ -452,7 +455,9 @@ class Map final : public Properties, public ConfigListener
const MapHeights *mHeights;
bool mRedrawMap;
bool mBeingOpacity;
+ bool mCachedDraw;
bool mCustom;
+ bool mDrawOnlyFringe;
};
#endif // RESOURCES_MAP_MAP_H
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 421915775..7b21cd1d0 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -462,6 +462,7 @@ Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path)
map->setWalkLayer(resman->getWalkLayer(fileName, map));
unloadTempLayers();
BLOCK_END("MapReader::readMap xml")
+ map->updateDrawLayersList();
return map;
}
@@ -1064,6 +1065,7 @@ Map *MapReader::createEmptyMap(const std::string &restrict filename,
map->addLayer(layer);
layer = new MapLayer(0, 0, 300, 300, true, 1);
map->addLayer(layer);
+ map->updateDrawLayersList();
return map;
}