Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/rendering/StarTilePainter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/rendering/StarTilePainter.hpp')
-rw-r--r--source/rendering/StarTilePainter.hpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/source/rendering/StarTilePainter.hpp b/source/rendering/StarTilePainter.hpp
new file mode 100644
index 0000000..9e21850
--- /dev/null
+++ b/source/rendering/StarTilePainter.hpp
@@ -0,0 +1,140 @@
+#ifndef STAR_NEW_TILE_PAINTER_HPP
+#define STAR_NEW_TILE_PAINTER_HPP
+
+#include "StarTtlCache.hpp"
+#include "StarWorldRenderData.hpp"
+#include "StarMaterialRenderProfile.hpp"
+#include "StarRenderer.hpp"
+#include "StarWorldCamera.hpp"
+
+namespace Star {
+
+STAR_CLASS(Assets);
+STAR_CLASS(MaterialDatabase);
+STAR_CLASS(TilePainter);
+
+class TilePainter {
+public:
+ // The rendered tiles are split and cached in chunks of RenderChunkSize x
+ // RenderChunkSize. This means that, around the border, there may be as many
+ // as RenderChunkSize - 1 tiles rendered outside of the viewing area from
+ // chunk alignment. In addition to this, there is also a region around each
+ // tile that is used for neighbor based rendering rules which has a max of
+ // MaterialRenderProfileMaxNeighborDistance. If the given tile data does not
+ // extend RenderChunkSize + MaterialRenderProfileMaxNeighborDistance - 1
+ // around the viewing area, then border chunks can continuously change hash,
+ // and will be recomputed too often.
+ static unsigned const RenderChunkSize = 16;
+ static unsigned const BorderTileSize = RenderChunkSize + MaterialRenderProfileMaxNeighborDistance - 1;
+
+ TilePainter(RendererPtr renderer);
+
+ // Adjusts lighting levels for liquids.
+ void adjustLighting(WorldRenderData& renderData) const;
+
+ // Sets up chunk data for every chunk that intersects the rendering region
+ // and prepares it for rendering. Do not call cleanup in between calling
+ // setup and each render method.
+ void setup(WorldCamera const& camera, WorldRenderData& renderData);
+
+ void renderBackground(WorldCamera const& camera);
+ void renderMidground(WorldCamera const& camera);
+ void renderLiquid(WorldCamera const& camera);
+ void renderForeground(WorldCamera const& camera);
+
+ // Clears any render data, as well as cleaning up old cached textures and
+ // chunks.
+ void cleanup();
+
+private:
+ typedef uint64_t QuadZLevel;
+ typedef uint64_t ChunkHash;
+
+ enum class TerrainLayer { Background, Midground, Foreground };
+
+ struct LiquidInfo {
+ TexturePtr texture;
+ Vec4B color;
+ Vec3F bottomLightMix;
+ float textureMovementFactor;
+ };
+
+ typedef HashMap<TerrainLayer, HashMap<QuadZLevel, RenderBufferPtr>> TerrainChunk;
+ typedef HashMap<LiquidId, RenderBufferPtr> LiquidChunk;
+
+ typedef size_t MaterialRenderPieceIndex;
+ typedef tuple<MaterialId, MaterialRenderPieceIndex, MaterialHue, bool> MaterialPieceTextureKey;
+ typedef String AssetTextureKey;
+ typedef Variant<MaterialPieceTextureKey, AssetTextureKey> TextureKey;
+
+ typedef List<pair<MaterialRenderPieceConstPtr, Vec2F>> MaterialPieceResultList;
+
+ struct TextureKeyHash {
+ size_t operator()(TextureKey const& key) const;
+ };
+
+ // chunkIndex here is the index of the render chunk such that chunkIndex *
+ // RenderChunkSize results in the coordinate of the lower left most tile in
+ // the render chunk.
+
+ static ChunkHash terrainChunkHash(WorldRenderData& renderData, Vec2I chunkIndex);
+ static ChunkHash liquidChunkHash(WorldRenderData& renderData, Vec2I chunkIndex);
+
+ static QuadZLevel materialZLevel(uint32_t zLevel, MaterialId material, MaterialHue hue, MaterialColorVariant colorVariant);
+ static QuadZLevel modZLevel(uint32_t zLevel, ModId mod, MaterialHue hue, MaterialColorVariant colorVariant);
+ static QuadZLevel damageZLevel();
+
+ static RenderTile const& getRenderTile(WorldRenderData const& renderData, Vec2I const& worldPos);
+
+ template <typename Function>
+ static void forEachRenderTile(WorldRenderData const& renderData, RectI const& worldCoordRange, Function&& function);
+
+ void renderTerrainChunks(WorldCamera const& camera, TerrainLayer terrainLayer);
+
+ shared_ptr<TerrainChunk const> getTerrainChunk(WorldRenderData& renderData, Vec2I chunkIndex);
+ shared_ptr<LiquidChunk const> getLiquidChunk(WorldRenderData& renderData, Vec2I chunkIndex);
+
+ bool produceTerrainPrimitives(HashMap<QuadZLevel, List<RenderPrimitive>>& primitives,
+ TerrainLayer terrainLayer, Vec2I const& pos, WorldRenderData const& renderData);
+ void produceLiquidPrimitives(HashMap<LiquidId, List<RenderPrimitive>>& primitives, Vec2I const& pos, WorldRenderData const& renderData);
+
+ bool determineMatchingPieces(MaterialPieceResultList& resultList, bool* occlude, MaterialDatabaseConstPtr const& materialDb, MaterialRenderMatchList const& matchList,
+ WorldRenderData const& renderData, Vec2I const& basePos, TileLayer layer, bool isMod);
+
+ float liquidDrawLevel(float liquidLevel) const;
+
+ List<LiquidInfo> m_liquids;
+
+ Vec4B m_backgroundLayerColor;
+ Vec4B m_foregroundLayerColor;
+ Vec2F m_liquidDrawLevels;
+
+ RendererPtr m_renderer;
+ TextureGroupPtr m_textureGroup;
+
+ HashTtlCache<TextureKey, TexturePtr, TextureKeyHash> m_textureCache;
+ HashTtlCache<pair<Vec2I, ChunkHash>, shared_ptr<TerrainChunk const>> m_terrainChunkCache;
+ HashTtlCache<pair<Vec2I, ChunkHash>, shared_ptr<LiquidChunk const>> m_liquidChunkCache;
+
+ List<shared_ptr<TerrainChunk const>> m_pendingTerrainChunks;
+ List<shared_ptr<LiquidChunk const>> m_pendingLiquidChunks;
+
+ Maybe<Vec2F> m_lastCameraCenter;
+ Vec2F m_cameraPan;
+};
+
+template <typename Function>
+void TilePainter::forEachRenderTile(WorldRenderData const& renderData, RectI const& worldCoordRange, Function&& function) {
+ RectI indexRect = RectI::withSize(renderData.geometry.diff(worldCoordRange.min(), renderData.tileMinPosition), worldCoordRange.size());
+ indexRect.limit(RectI::withSize(Vec2I(0, 0), Vec2I(renderData.tiles.size())));
+
+ if (!indexRect.isEmpty()) {
+ renderData.tiles.forEach(Array2S(indexRect.min()), Array2S(indexRect.size()), [&](Array2S const& index, RenderTile const& tile) {
+ return function(worldCoordRange.min() + (Vec2I(index) - indexRect.min()), tile);
+ });
+ }
+}
+
+}
+
+#endif