From 029f753bbf193eea2fcbe8a62c0b26f28929ebfa Mon Sep 17 00:00:00 2001 From: Teo-CD Date: Mon, 29 Jan 2024 00:25:54 +0000 Subject: [PATCH] World: Re-use RectangleShapes for rendering sf::RectangleShapes were created brand new each frame, which takes a lot of time. Instead, keep an array of them available and update them instead of creating new ones. This also allows a nice optimization of only updating them if needed, by checking their previous value. Update the available number of rects when the window resizes. --- World.cpp | 22 ++++++++++++++++------ World.h | 6 ++++-- main.cpp | 3 +++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/World.cpp b/World.cpp index b8a8eb6..a7f7bf1 100644 --- a/World.cpp +++ b/World.cpp @@ -27,6 +27,12 @@ int World::getH() const return h; } +void World::resizeWindow(const sf::FloatRect& resizedView) { + sf::RectangleShape defaultRectangle(sf::Vector2f(1,2)); + defaultRectangle.setFillColor(Colors::Wall); + renderColumns.resize(static_cast(resizedView.width), defaultRectangle); +} + BlockType World::getBlock(int x, int y) const { return map[x + w*y]; @@ -212,18 +218,22 @@ float World::castRay(float originX, float originY, float orientation) const } void World::fillColumn(sf::RenderWindow& window, unsigned int column, - float scale, sf::Color fillColor) const + float scale, sf::Color fillColor) { float columnHeight = static_cast(window.getSize().y)*scale; - sf::RectangleShape pixelColumn(sf::Vector2f(1,columnHeight)); - pixelColumn.setPosition(static_cast(column), - (static_cast(window.getSize().y)-columnHeight)/2.0f); - pixelColumn.setFillColor(fillColor); + sf::RectangleShape& pixelColumn = renderColumns[column]; + if (pixelColumn.getSize().y != columnHeight) { + pixelColumn.setSize({1, columnHeight}); + pixelColumn.setPosition(static_cast(column), + (static_cast(window.getSize().y) - columnHeight) / 2.0f); + } + if (pixelColumn.getFillColor() != fillColor) + pixelColumn.setFillColor(fillColor); window.draw(pixelColumn); } -void World::render(sf::RenderWindow& window) const +void World::render(sf::RenderWindow& window) { float windowX = static_cast(window.getSize().x); float windowY = static_cast(window.getSize().y); diff --git a/World.h b/World.h index 43b4b1e..7b24d70 100644 --- a/World.h +++ b/World.h @@ -30,12 +30,13 @@ public: std::vector worldMap = {}); int getW() const; int getH() const; + void resizeWindow(const sf::FloatRect& resizedView); inline BlockType getBlock(int x, int y) const; inline BlockType getBlock(float x, float y) const; void setBlock(BlockType block, int x, int y, int width = 1, int height = 1); - void render(sf::RenderWindow&) const; + void render(sf::RenderWindow&); /** * Move the world one step forward. @@ -47,13 +48,14 @@ public: private: int w; int h; + std::vector renderColumns; std::vector map; sf::Color groundColor; sf::Color ceilingColor; void fillColumn(sf::RenderWindow&, unsigned int column, float scale, - sf::Color fillColor = Colors::Wall) const; + sf::Color fillColor = Colors::Wall); /** * Cast a ray from a given position and return its distance to the origin. * @param originX Ray X origin, strictly positive diff --git a/main.cpp b/main.cpp index 0aedcd7..83ef919 100644 --- a/main.cpp +++ b/main.cpp @@ -15,10 +15,12 @@ int main() World world(32,32); world.setBlock(BlockType::AIR,1,1,30,30); world.setBlock(BlockType::WALL,4,4,2,2); + world.setBlock(BlockType::WALL, 4, 6, 1, 10); world.player.move(2,2); std::cout << world << std::endl; sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting"); + world.resizeWindow(sf::FloatRect(0,0, 1000, 1000)); #ifdef IMGUI if (!ImGui::SFML::Init(window)) { std::cout << "Failed to init Dear ImGui SFML" << std::endl; @@ -47,6 +49,7 @@ int main() static_cast(event.size.width), static_cast(event.size.height)); window.setView(sf::View(newView)); + world.resizeWindow(newView); continue; } #ifdef IMGUI