From 12c92d6dd04ed208963605faa533f2fda5ef5c07 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Fri, 27 Sep 2013 04:42:22 +0200 Subject: [PATCH] Fix Tilemap's scanrow z sorting for good Also make it a tad faster. --- src/scene.cpp | 10 ++++++++++ src/scene.h | 3 +++ src/tilemap.cpp | 46 +++++++++++++++++++++++++++++----------------- src/viewport.cpp | 4 ++++ src/viewport.h | 1 + 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/scene.cpp b/src/scene.cpp index 8384fa2..ef42bd4 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -88,6 +88,16 @@ SceneElement::SceneElement(Scene &scene, int z) scene.insert(*this); } +SceneElement::SceneElement(Scene &scene, int z, unsigned int cStamp) + : link(this), + creationStamp(cStamp), + z(z), + visible(true), + scene(&scene) +{ + scene.insert(*this); +} + SceneElement::~SceneElement() { unlink(); diff --git a/src/scene.h b/src/scene.h index 0e2ed0f..bbc9b2e 100644 --- a/src/scene.h +++ b/src/scene.h @@ -30,6 +30,7 @@ class SceneElement; class Viewport; class Window; +class ScanRow; class Scene { @@ -60,12 +61,14 @@ protected: friend class SceneElement; friend class Window; + friend class ScanRow; }; class SceneElement { public: SceneElement(Scene &scene, int z = 0); + SceneElement(Scene &scene, int z, unsigned int cStamp); virtual ~SceneElement(); void setScene(Scene &scene); diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 65a52b1..52b52f4 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -217,7 +217,8 @@ struct ScanRow : public ViewportElement void draw(); void drawInt(); - void updateZ(); + void initUpdateZ(); + void finiUpdateZ(); }; struct TilemapPrivate @@ -236,9 +237,6 @@ struct TilemapPrivate Vec2i dispPos; - /* For updating scanrow z */ - int tileYOffset; - /* Tile atlas */ struct { TEXFBO gl; @@ -299,6 +297,14 @@ struct TilemapPrivate QVector scanrows; Scene::Geometry sceneGeo; Vec2i sceneOffset; + + /* The ground and scanrow elements' creationStamp + * should be aquired once (at Tilemap construction) + * instead of regenerated everytime the elements are + * (re)created. Scanrows can share one stamp because + * their z always differs anway */ + unsigned int groundStamp; + unsigned int scanrowStamp; } elem; /* Replica bitmask */ @@ -338,7 +344,6 @@ struct TilemapPrivate flashData(0), priorities(0), visible(true), - tileYOffset(0), mapWidth(0), mapHeight(0), replicas(Normal), @@ -398,6 +403,9 @@ struct TilemapPrivate elem.ground = 0; + elem.groundStamp = gState->genTimeStamp(); + elem.scanrowStamp = gState->genTimeStamp(); + prepareCon = gState->prepareDraw.connect (sigc::mem_fun(this, &TilemapPrivate::prepare)); } @@ -974,7 +982,10 @@ struct TilemapPrivate void updateZOrder() { for (int i = 0; i < elem.scanrows.count(); ++i) - elem.scanrows[i]->updateZ(); + elem.scanrows[i]->initUpdateZ(); + + for (int i = 0; i < elem.scanrows.count(); ++i) + elem.scanrows[i]->finiUpdateZ(); } void prepare() @@ -1024,7 +1035,7 @@ struct TilemapPrivate }; GroundLayer::GroundLayer(TilemapPrivate *p, Viewport *viewport) - : ViewportElement(viewport), + : ViewportElement(viewport, 0, p->elem.groundStamp), p(p) { vboCount = p->scanrowBases[0] * 6; @@ -1105,7 +1116,7 @@ void GroundLayer::onGeometryChange(const Scene::Geometry &geo) } ScanRow::ScanRow(TilemapPrivate *p, Viewport *viewport, int index) - : ViewportElement(viewport, 32 + index*32), + : ViewportElement(viewport, 32 + index*32, p->elem.scanrowStamp), index(index), p(p) { @@ -1146,10 +1157,16 @@ void ScanRow::drawInt() GL_UNSIGNED_INT, (GLvoid*) (vboOffset + p->tiles.frameIdx * p->tiles.bufferFrameSize)); } -void ScanRow::updateZ() +void ScanRow::initUpdateZ() { - int y = (p->offset.y > 0) ? -p->offset.y : 0; - setZ(32 + (((y) / 32) + index) * 32); + unlink(); +} + +void ScanRow::finiUpdateZ() +{ + z = 32 * (index+1) - p->offset.y; + + scene->insert(*this); } void Tilemap::Autotiles::set(int i, Bitmap *bitmap) @@ -1362,12 +1379,7 @@ void Tilemap::setOY(int value) p->updatePosition(); p->updateReplicas(); - int tileYOffset = value / 32; - if (tileYOffset != p->tileYOffset) - { - p->tileYOffset = tileYOffset; - p->zOrderDirty = true; - } + p->zOrderDirty = true; } diff --git a/src/viewport.cpp b/src/viewport.cpp index bc180e5..04b3416 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -231,6 +231,10 @@ ViewportElement::ViewportElement(Viewport *viewport, int z) m_viewport(viewport) {} +ViewportElement::ViewportElement(Viewport *viewport, int z, unsigned int cStamp) + : SceneElement(viewport ? *viewport : *gState->screen(), z, cStamp) +{} + Viewport *ViewportElement::getViewport() const { return m_viewport; diff --git a/src/viewport.h b/src/viewport.h index 3a5e3a0..54e0141 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -65,6 +65,7 @@ class ViewportElement : public SceneElement { public: ViewportElement(Viewport *viewport = 0, int z = 0); + ViewportElement(Viewport *viewport, int z, unsigned int cStamp); Viewport *getViewport() const;