Kelsidavis-WoWee/include/rendering/water_renderer.hpp
Kelsi e12141a673 Add configurable MSAA anti-aliasing, update auth screen and terrain shader
- MSAA: conditional 2-att (off) vs 3-att (on) render pass with auto-resolve
- MSAA: multisampled color+depth images, query max supported sample count
- MSAA: .setMultisample() on all 25+ main-pass pipelines across 17 renderers
- MSAA: recreatePipelines() on every sub-renderer for runtime MSAA changes
- MSAA: Renderer::setMsaaSamples() orchestrates swapchain+pipeline+ImGui rebuild
- MSAA: Anti-Aliasing combo (Off/2x/4x/8x) in Video settings, persisted
- Update auth screen assets and terrain fragment shader
2026-02-22 02:59:24 -08:00

118 lines
3 KiB
C++

#pragma once
#include <vector>
#include <memory>
#include <optional>
#include <cstdint>
#include <vulkan/vulkan.h>
#include <vk_mem_alloc.h>
#include <glm/glm.hpp>
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<float> heights;
std::vector<uint8_t> 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 recreatePipelines();
void render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera, float time);
void setEnabled(bool enabled) { renderingEnabled = enabled; }
bool isEnabled() const { return renderingEnabled; }
std::optional<float> getWaterHeightAt(float glX, float glY) const;
std::optional<uint16_t> getWaterTypeAt(float glX, float glY) const;
int getSurfaceCount() const { return static_cast<int>(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<WaterSurface> surfaces;
bool renderingEnabled = true;
};
} // namespace rendering
} // namespace wowee