#pragma once #include #include #include #include namespace wowee { namespace pipeline { struct ADTTerrain; struct LiquidData; } namespace rendering { class Camera; class Shader; /** * Water surface for a single map chunk */ struct WaterSurface { glm::vec3 position; // World position float minHeight; // Minimum water height float maxHeight; // Maximum water height uint8_t liquidType; // 0=water, 1=ocean, 2=magma, 3=slime // Owning tile coordinates (for per-tile removal) int tileX = -1, tileY = -1; // Water layer dimensions within chunk (0-7 offset, 1-8 size) uint8_t xOffset = 0; uint8_t yOffset = 0; uint8_t width = 8; // Width in tiles (1-8) uint8_t height = 8; // Height in tiles (1-8) // Height map for water surface ((width+1) x (height+1) vertices) std::vector heights; // Render mask (which tiles have water) std::vector mask; // Render data uint32_t vao = 0; uint32_t vbo = 0; uint32_t ebo = 0; int indexCount = 0; bool hasHeightData() const { return !heights.empty(); } }; /** * Water renderer * * Renders water surfaces with transparency and animation. * Supports multiple liquid types (water, ocean, magma, slime). */ class WaterRenderer { public: WaterRenderer(); ~WaterRenderer(); bool initialize(); void shutdown(); /** * Load water surfaces from ADT terrain * @param terrain The ADT terrain data * @param append If true, add to existing water instead of replacing * @param tileX Tile X coordinate for tracking ownership (-1 = untracked) * @param tileY Tile Y coordinate for tracking ownership (-1 = untracked) */ void loadFromTerrain(const pipeline::ADTTerrain& terrain, bool append = false, int tileX = -1, int tileY = -1); /** * Remove all water surfaces belonging to a specific tile * @param tileX Tile X coordinate * @param tileY Tile Y coordinate */ void removeTile(int tileX, int tileY); /** * Clear all water surfaces */ void clear(); /** * Render all water surfaces */ void render(const Camera& camera, float time); /** * Enable/disable water rendering */ void setEnabled(bool enabled) { renderingEnabled = enabled; } bool isEnabled() const { return renderingEnabled; } /** * Query the water height at a given world position. * Returns the highest water surface height at that XY, or nullopt if no water. */ std::optional getWaterHeightAt(float glX, float glY) const; /** * Get water surface count */ int getSurfaceCount() const { return static_cast(surfaces.size()); } private: void createWaterMesh(WaterSurface& surface); void destroyWaterMesh(WaterSurface& surface); glm::vec4 getLiquidColor(uint8_t liquidType) const; float getLiquidAlpha(uint8_t liquidType) const; std::unique_ptr waterShader; std::vector surfaces; bool renderingEnabled = true; }; } // namespace rendering } // namespace wowee