From 3ac706f1b697c7851ff734e9315f11c6b28792a0 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Tue, 18 Jul 2023 18:57:54 +0200 Subject: [PATCH] Fix support for vertically flipped tiles Turns out there was another renderer bug that would effectively ignore the vertical flip if a Quad had an active ElementEffect that used a grid (effects on numpad keys 1,2,3,5,6). --- Aquaria/SceneEditor.cpp | 1 + Aquaria/TileMgr.cpp | 7 +++--- BBGE/Tile.h | 3 ++- BBGE/TileRender.cpp | 50 +++++++++++++++++++++++++++++++---------- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index 6abcdf0..c369b7b 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -2342,6 +2342,7 @@ void SceneEditor::updateText() os << " efx: " << (t.eff ? (t.eff->efxidx + 1) : 0); // +1 so that it resembles the layout on numpad os << " tag: " << t.tag; os << " gfx: " << t.et->gfx; + os << " F:" << ((t.flags & TILEFLAG_FH) ? "H" : "") << ((t.flags & TILEFLAG_FV) ? "V" : ""); } break; case ET_ENTITIES: diff --git a/Aquaria/TileMgr.cpp b/Aquaria/TileMgr.cpp index c94c609..f41ad36 100644 --- a/Aquaria/TileMgr.cpp +++ b/Aquaria/TileMgr.cpp @@ -122,11 +122,11 @@ void TileMgr::createTiles(const TileDef* defs, size_t n) if(d.fh) t->flags |= TILEFLAG_FH; + if(d.fv) + t->flags |= TILEFLAG_FV; if(d.repeat) t->setRepeatOn(d.rsx, d.rsy); - // FIXME: handle fv - t->rotation = d.rot; t->tag = d.tag; t->scalex = d.sx; @@ -152,6 +152,7 @@ void TileMgr::exportGridFillers(std::vector& fillers) const { GridFiller gf; gf.fh = !!(t.flags & TILEFLAG_FH); + //gf.fv = !!(t.flags & TILEFLAG_FV); // doesn't exist; vertical flip is never considered for grid collision gf.position = Vector(t.x, t.y); gf.rotation = t.rotation; gf.scale = Vector(t.scalex, t.scaley); @@ -263,7 +264,7 @@ TileDef::TileDef(unsigned lr) TileDef::TileDef(unsigned lr, const TileData& t) : layer(lr), idx((unsigned)t.et->idx), x(t.x), y(t.y), rot(t.rotation) , fh(!!(t.flags & TILEFLAG_FH)) - , fv(false) // FIXME + , fv(!!(t.flags & TILEFLAG_FV)) , ef(TileMgr::GetElementFlag((TileFlags)t.flags)) , efxIdx(t.eff ? t.eff->efxidx : -1) , repeat(!!(t.flags & TILEFLAG_REPEAT)) diff --git a/BBGE/Tile.h b/BBGE/Tile.h index fc9ee56..f30b990 100644 --- a/BBGE/Tile.h +++ b/BBGE/Tile.h @@ -95,7 +95,8 @@ enum TileFlags TILEFLAG_HIDDEN = 0x80, // don't render tile TILEFLAG_SELECTED = 0x100, // ephemeral: selected in editor TILEFLAG_EDITOR_HIDDEN = 0x200, // tile is hidden for editor reasons. temporarily set when multi-selecting and moving. doesn't count as hidden externally and is only for rendering. - TILEFLAG_OWN_REPEAT = 0x400 // owns TileRepeatData, may update, must delete + TILEFLAG_OWN_REPEAT = 0x400, // owns TileRepeatData, may update, must delete + TILEFLAG_FV = 0x800, // flipped vertically }; struct TileData; diff --git a/BBGE/TileRender.cpp b/BBGE/TileRender.cpp index 146b783..f84572e 100644 --- a/BBGE/TileRender.cpp +++ b/BBGE/TileRender.cpp @@ -121,18 +121,6 @@ void TileRender::onRender(const RenderState& rs) const glBindTexture(GL_TEXTURE_2D, 0); // unlikely } - glPushMatrix(); - glTranslatef(pos.x, pos.y, pos.z); - - glRotatef(tile.rotation, 0, 0, 1); - if(tile.flags & TILEFLAG_FH) - glRotatef(180, 0, 1, 0); - - // this is only relevant in editor mode and is always 0 otherwise - //glTranslatef(tile.beforeScaleOffsetX, tile.beforeScaleOffsetY, 0); - - glScalef(sw, sh, 1); - float alpha = rs.alpha; const TileEffectData * const eff = tile.eff; if(eff != prevEff) // effects between tiles are often shared so this works not only for NULL @@ -153,6 +141,44 @@ void TileRender::onRender(const RenderState& rs) const glColor4f(rs.color.x, rs.color.y, rs.color.z, alpha); } + glPushMatrix(); + glTranslatef(pos.x, pos.y, pos.z); + + // HACK: Due to a renderer bug in older versions, vertical flip is ignored + // when a grid-based tile effect is applied. + // Maps were designed with the bug present so we need to replicate it, + // otherwise things won't look correct. + unsigned effflag = tile.flags; + if(grid) + effflag &= ~TILEFLAG_FV; + + float effrot = tile.rotation; + + // both set? that's effectively a rotation by 180° + if ((effflag & (TILEFLAG_FH | TILEFLAG_FV)) == (TILEFLAG_FH | TILEFLAG_FV)) + effrot += 180; + + glRotatef(effrot, 0, 0, 1); + + switch(effflag & (TILEFLAG_FH | TILEFLAG_FV)) + { + case TILEFLAG_FH: + glRotatef(180, 0, 1, 0); + break; + + case TILEFLAG_FV: + glRotatef(180, 1, 0, 0); + break; + + default: ; // both or none set, nothing to do + } + + // this is only relevant in editor mode and is always 0 otherwise + //glTranslatef(tile.beforeScaleOffsetX, tile.beforeScaleOffsetY, 0); + + glScalef(sw, sh, 1); + + if(!grid) { const float *tcbuf = (tile.flags & TILEFLAG_REPEAT)