From e9998dd427e1de038e05bba6950bef99416f8001 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 22 Sep 2024 03:23:14 +0200 Subject: [PATCH] Fix grid rendering -- it rendered original obs, not trimmed obs (black border poking out left/right in some cases) Also avoid unnecessary recomputation in some cases. --- Aquaria/Game.cpp | 29 +++++++++++++++++++---------- Aquaria/Game.h | 2 +- Aquaria/GridRender.cpp | 17 ++++++++++++++--- Aquaria/SceneEditor.cpp | 15 ++++++++------- Aquaria/ScriptInterface.cpp | 2 +- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 646cb1a..e5d8177 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -323,8 +323,11 @@ void Game::transitionToScene(std::string scene) void Game::addObsRow(unsigned tx, unsigned ty, unsigned len) { - ObsRow obsRow(tx, ty, len); - obsRows.push_back(obsRow); + if(len) + { + ObsRow obsRow(tx, ty, len); + obsRows.push_back(obsRow); + } } void Game::clearObsRows() @@ -550,7 +553,7 @@ void Game::reconstructEntityGrid() // TODO: ideally this would be split into two functions, one that reconstructs blackness // and is called on map load or by the editor, and another one that just reconstructs // the dynamic parts of the grid. -void Game::reconstructGrid(bool force) +void Game::reconstructGrid(bool force, bool updateDraw) { if (!force && isSceneEditorActive()) return; @@ -584,8 +587,11 @@ void Game::reconstructGrid(bool force) trimGrid(); - // Must update OT_BLACK after trimGrid() - updateGridRender(OT_MASK_ALL); + if(updateDraw) + { + // Must update OT_BLACK after trimGrid() + updateGridRender(OT_MASK_ALL); + } } void Game::trimGrid() @@ -1771,7 +1777,7 @@ next_SE: if(!tilesDefs.empty()) dsq->tilemgr.createTiles(&tilesDefs[0], tilesDefs.size()); - this->reconstructGrid(true); + this->reconstructGrid(true, false); std::vector toSpawn; @@ -1800,7 +1806,7 @@ next_SE: findMaxCameraValues(); - this->reconstructGrid(true); + this->reconstructGrid(true, true); return true; } @@ -1808,9 +1814,8 @@ next_SE: void Game::handleEditorMapGridUpdate() { - reconstructGrid(true); findMaxCameraValues(); - updateGridRender(OT_MASK_BLACK); + reconstructGrid(true, true); } void Game::spawnEntities(const EntitySaveData *sav, size_t n) @@ -4068,7 +4073,11 @@ void Game::updateGridRender(ObsType obs) // Keeping it here possibly for future mod compat. // It's also always shown, so we can immediately rebuild it if(obs & OT_BLACK) - blackRender->rebuildBuffers(this->obsRows); + { + // Don't pass this->obsRows here (which is the raw data)! + // Need the changes done by trimGrid() -> need to collect rows anew. + blackRender->rebuildBuffers(); + } } Vector Game::getCameraPositionFor(const Vector &pos) diff --git a/Aquaria/Game.h b/Aquaria/Game.h index ff841c6..283b8e7 100644 --- a/Aquaria/Game.h +++ b/Aquaria/Game.h @@ -148,7 +148,7 @@ public: void updateParticlePause(); - void reconstructGrid(bool force=false); + void reconstructGrid(bool force, bool updateDraw); void reconstructEntityGrid(); void registerSporeDrop(const Vector &pos, int t); diff --git a/Aquaria/GridRender.cpp b/Aquaria/GridRender.cpp index b59f4ce..03a507d 100644 --- a/Aquaria/GridRender.cpp +++ b/Aquaria/GridRender.cpp @@ -49,13 +49,19 @@ static void collectRows(std::vector& rows, ObsType obs) if(on) { // previous tile is the last one, so -1 - rows.push_back(ObsRow(startx, y, x - startx)); + size_t len = x - startx; + assert(len); + rows.push_back(ObsRow(startx, y, len)); on = false; } } } if(on) - rows.push_back(ObsRow(startx, y, endX - startx)); + { + size_t len = endX - startx; + assert(len); + rows.push_back(ObsRow(startx, y, len)); + } } } @@ -131,6 +137,7 @@ void GridRender::rebuildBuffers(const std::vector& rows) for(size_t i = 0; i < N; ++i) { const ObsRow& row = rows[i]; + assert(row.len); // Don't bother to transform to float. The GPU can do that better. // The scale factor of a GridRender is set to TILE_SIZE, that pre-bakes the @@ -183,13 +190,17 @@ void GridRender::onRender(const RenderState& rs) const if(!primsToDraw) return; + const int H = (int)primIndexInLine.size(); + if(!H) + return; + const float vh = core->getVirtualHeight(); const float voy = core->getVirtualOffY(); const float vox = core->getVirtualOffX(); const Vector topleft = core->getTopLeftCornerInWorldCoords(); const TileVector ct(topleft); - const int H = (int)primIndexInLine.size(); + int startY = ct.y; // Note that it's possible that the scale factor is negative (mods can use this), diff --git a/Aquaria/SceneEditor.cpp b/Aquaria/SceneEditor.cpp index c7c9176..200d7af 100644 --- a/Aquaria/SceneEditor.cpp +++ b/Aquaria/SceneEditor.cpp @@ -455,7 +455,7 @@ void SceneEditor::executeButtonID(int bid) break; case 103: // regen collision - game->reconstructGrid(true); + game->reconstructGrid(true, true); break; case 104: generateLevel(); @@ -1067,7 +1067,7 @@ void SceneEditor::deleteSelected() TileStorage& ts = getCurrentLayerTiles(); ts.deleteSome(&selectedTiles[0], n); selectedTiles.clear(); - game->reconstructGrid(); + game->reconstructGrid(true, true); } } else if (editType == ET_ENTITIES) @@ -1116,7 +1116,7 @@ void SceneEditor::checkForRebuild() { if(ts.tiles[i].flags & TILEFLAG_SOLID) { - game->reconstructGrid(); + game->reconstructGrid(true, true); break; } } @@ -1271,7 +1271,7 @@ void SceneEditor::toggleElementSolid() TileData& t = ts.tiles[selectedTiles[i]]; t.flags = TileMgr::GetTileFlags(nextSolidEF(TileMgr::GetElementFlag((TileFlags)t.flags))); } - game->reconstructGrid(true); + game->reconstructGrid(true, true); } } @@ -1288,7 +1288,7 @@ void SceneEditor::toggleElementHurt() else ts.changeFlags(0, TILEFLAG_SOLID | TILEFLAG_HURT | TILEFLAG_SOLID_IN | TILEFLAG_TRIM, &selectedTiles[0], n); - game->reconstructGrid(true); + game->reconstructGrid(true, true); } } @@ -1361,6 +1361,7 @@ void SceneEditor::mouseButtonLeft() void SceneEditor::mouseButtonRight() { if (multiSelecting || state != ES_SELECTING || core->mouse.buttons.left) return; + if (editType == ET_ENTITIES) { if (editingEntity) @@ -2135,7 +2136,7 @@ void SceneEditor::nextElement() if (core->getAltState()) { debugLog("rebuilding level!"); - game->reconstructGrid(true); + game->reconstructGrid(true, true); return; } @@ -2293,7 +2294,7 @@ void SceneEditor::cloneSelectedElement() } if(allflags & TILEFLAG_SOLID) - game->reconstructGrid(true); + game->reconstructGrid(true, true); } } else if (editType == ET_ENTITIES) diff --git a/Aquaria/ScriptInterface.cpp b/Aquaria/ScriptInterface.cpp index ea0afa2..5a04b37 100644 --- a/Aquaria/ScriptInterface.cpp +++ b/Aquaria/ScriptInterface.cpp @@ -3347,7 +3347,7 @@ luaFunc(errorLog) luaFunc(reconstructGrid) { - game->reconstructGrid(true); + game->reconstructGrid(true, true); luaReturnNil(); }