#pragma once #include #include #include #include #include #include #include namespace wowee { namespace pipeline { struct ADTTerrain; struct LiquidData; struct WMOLiquid; } namespace rendering { class Camera; class VkContext; /** * Water surface for a single map chunk */ struct WaterSurface { glm::vec3 position; glm::vec3 origin; glm::vec3 stepX; glm::vec3 stepY; float minHeight; float maxHeight; uint16_t liquidType; int tileX = -1, tileY = -1; uint32_t wmoId = 0; uint8_t xOffset = 0; uint8_t yOffset = 0; uint8_t width = 8; uint8_t height = 8; std::vector heights; std::vector mask; // Vulkan render data ::VkBuffer vertexBuffer = VK_NULL_HANDLE; VmaAllocation vertexAlloc = VK_NULL_HANDLE; ::VkBuffer indexBuffer = VK_NULL_HANDLE; VmaAllocation indexAlloc = VK_NULL_HANDLE; int indexCount = 0; // Per-surface material UBO ::VkBuffer materialUBO = VK_NULL_HANDLE; VmaAllocation materialAlloc = VK_NULL_HANDLE; // Material descriptor set (set 1) VkDescriptorSet materialSet = VK_NULL_HANDLE; bool hasHeightData() const { return !heights.empty(); } }; /** * Water renderer (Vulkan) */ class WaterRenderer { public: WaterRenderer(); ~WaterRenderer(); bool initialize(VkContext* ctx, VkDescriptorSetLayout perFrameLayout); void shutdown(); void loadFromTerrain(const pipeline::ADTTerrain& terrain, bool append = false, int tileX = -1, int tileY = -1); void loadFromWMO(const pipeline::WMOLiquid& liquid, const glm::mat4& modelMatrix, uint32_t wmoId); void removeWMO(uint32_t wmoId); void removeTile(int tileX, int tileY); void clear(); void render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera, float time); void setEnabled(bool enabled) { renderingEnabled = enabled; } bool isEnabled() const { return renderingEnabled; } std::optional getWaterHeightAt(float glX, float glY) const; std::optional getWaterTypeAt(float glX, float glY) const; int getSurfaceCount() const { return static_cast(surfaces.size()); } private: void createWaterMesh(WaterSurface& surface); void destroyWaterMesh(WaterSurface& surface); glm::vec4 getLiquidColor(uint16_t liquidType) const; float getLiquidAlpha(uint16_t liquidType) const; void updateMaterialUBO(WaterSurface& surface); VkDescriptorSet allocateMaterialSet(); VkContext* vkCtx = nullptr; // Pipeline VkPipeline waterPipeline = VK_NULL_HANDLE; VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; VkDescriptorSetLayout materialSetLayout = VK_NULL_HANDLE; VkDescriptorPool materialDescPool = VK_NULL_HANDLE; static constexpr uint32_t MAX_WATER_SETS = 2048; std::vector surfaces; bool renderingEnabled = true; }; } // namespace rendering } // namespace wowee