Files
Vibe-HD-2D/engine/include/hd2d/Water.h
Gabrieal Jimmy 2c99305fb0 init
2026-10-02 12:42:00 -05:00

51 lines
1.9 KiB
C++

#pragma once
#include "hd2d/GL.h"
#include <glm/glm.hpp>
namespace hd2d {
class Terrain;
// Planar water body: reflective, refractive, depth-absorbing surface with
// procedural waves, sun glints and shoreline foam. Rendered at full
// resolution (not pixelated) on purpose, like HD-2D's water.
class Water {
public:
~Water();
// Builds a tessellated grid covering [minXZ, maxXZ] at height `level`.
void build(glm::vec2 minXZ, glm::vec2 maxXZ, float level, float cellSize = 0.25f);
// Distance-to-shore field (world units) over the water bounds, from every
// terrain tile whose top is above the water. Drives foam and ripples.
void buildShoreField(const Terrain& terrain, int texelsPerUnit = 8);
void draw() const;
float level() const { return level_; }
GLuint shoreTexture() const { return shoreTex_; }
// (minX, minZ, 1/sizeX, 1/sizeZ): maps world xz to shore texture uv.
glm::vec4 shoreRect() const { return {min_.x, min_.y, 1.0f / (max_.x - min_.x), 1.0f / (max_.y - min_.y)}; }
// Look parameters (tweakable at runtime).
glm::vec3 shallowColor{0.03f, 0.40f, 0.62f};
glm::vec3 deepColor{0.005f, 0.10f, 0.30f};
glm::vec3 absorption{1.6f, 0.5f, 0.22f}; // per unit of light path, per channel
float clarity = 0.5f; // how much of the bottom stays visible
float waveScale = 0.9f;
float waveStrength = 1.2f;
float waveSpeed = 0.35f;
float refraction = 0.035f;
float reflectionDistort = 0.05f;
float specular = 6.0f;
float glitter = 1.0f; // twinkling point sparkles
float foamWidth = 0.45f; // world units from the shore
float foamIntensity = 0.85f;
float causticsIntensity = 1.4f;
private:
GLuint vao_ = 0, vbo_ = 0, ibo_ = 0, shoreTex_ = 0;
GLsizei indexCount_ = 0;
float level_ = 0.0f;
glm::vec2 min_{0.0f}, max_{1.0f};
};
} // namespace hd2d