--- /dev/null
+#ifndef WATER_H_
+#define WATER_H_
+
+#include <random>
+#include <msp/gl/objectinstance.h>
+#include <msp/gl/texture2d.h>
+
+class Water: public Msp::GL::ObjectInstance
+{
+public:
+ struct Region
+ {
+ const Msp::GL::Mesh &terrain;
+ float left;
+ float bottom;
+ float right;
+ float top;
+ };
+
+private:
+ struct State
+ {
+ Msp::GL::Texture2D surface;
+ Msp::GL::Texture2D velocity;
+ Msp::GL::Texture2D clamping;
+ };
+
+ unsigned width;
+ unsigned height;
+ State state[2];
+ State *current;
+ State *next;
+ float time = 0.0f;
+ float stepsize = 0.001f;
+ std::minstd_rand rng;
+ Msp::GL::Texture2D bottom;
+ Msp::GL::Texture2D normals;
+ Msp::GL::Texture2D variance_x;
+ Msp::GL::Texture2D variance_y;
+ const Msp::GL::Sampler &sampler;
+ const Msp::GL::Program &sim_integrate;
+ const Msp::GL::Program &sim_velocity;
+ const Msp::GL::Program &sim_clamp;
+ const Msp::GL::Program &normals_shader;
+ const Msp::GL::Program &variance_x_shader;
+ const Msp::GL::Program &variance_y_shader;
+ Msp::GL::ProgramData sim_shdata;
+ Msp::GL::ProgramData shdata;
+ bool simulated = false;
+
+public:
+ Water(const Msp::GL::Object &, Msp::DataFile::Collection &, const Region &);
+
+public:
+ void setup_frame(Msp::GL::Renderer &) override;
+ void finish_frame() override;
+
+ void setup_render(Msp::GL::Renderer &, Msp::GL::Tag) const override;
+};
+
+#endif