depth_test LEQUAL;
lighting "Forest.lightn";
};
+step "blended" "shadow_map"
+{
+ depth_test
+ {
+ compare LEQUAL;
+ write false;
+ };
+ lighting "Forest.lightn";
+};
postprocessor
{
type ambient_occlusion;
depth_test LEQUAL;
lighting "Forest.lightn";
};
+step "blended" "content"
+{
+ depth_test
+ {
+ compare LEQUAL;
+ write false;
+ };
+ lighting "Forest.lightn";
+};
--- /dev/null
+import msp_interface;
+import shadow;
+
+uniform Rain
+{
+ vec4 rain_color;
+};
+
+uniform DynamicParams
+{
+ float time;
+};
+
+#pragma MSP stage(vertex)
+void main()
+{
+ vec4 vpos = vertex;
+ vpos.z = vpos.z-fract(time/2.5)*20.0;
+ if(vpos.z<0.0)
+ vpos.z += 20.0;
+ out vec4 world_vertex = world_obj_matrix*vpos;
+ gl_Position = clip_eye_matrix*eye_world_matrix*world_vertex;
+ passthrough;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+ float shadow = get_shadow_factor(0, world_vertex);
+ frag_color = rain_color*vec4(vec3(0.5+0.5*shadow), texcoord.x);
+}
--- /dev/null
+module "rain.glsl"
+{
+ specialize "use_shadow_map" true;
+};
--- /dev/null
+method "blended"
+{
+ shader "rain.shader";
+ uniforms
+ {
+ uniform "rain_color" 0.5 0.5 0.5 0.5;
+ };
+ blend SRC_ALPHA ONE_MINUS_SRC_ALPHA;
+};
resources(nullptr),
view(window),
camera(resources.get<GL::Camera>("Camera.camera")),
- water(resources.get<GL::Object>("Water.object"), resources, { resources.get<GL::Mesh>("Terrain.mesh"), -10.0f, -3.0f, 2.0f, 6.0f })
+ water(resources.get<GL::Object>("Water.object"), resources, { resources.get<GL::Mesh>("Terrain.mesh"), -10.0f, -3.0f, 2.0f, 6.0f }),
+ rain(resources, 3000, { -1.5f, -3.0f }, 10.0f)
{
window.set_title("Forest Pond");
window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &ForestPond::exit), 0));
content.add(resources.get<GL::Scene>("Forest.scene"));
content.add(*env_map);
+ content.add(rain);
water.set_matrix(GL::Matrix::translation(GL::Vector3(-3, 2, 0)));
view.set_content(sequence.get());
#include <msp/gl/windowview.h>
#include <msp/graphics/display.h>
#include <msp/graphics/window.h>
+#include "rain.h"
#include "water.h"
class ForestPond: public Msp::RegisteredApplication<ForestPond>
Msp::GL::OrderedScene content;
Water water;
+ Rain rain;
std::unique_ptr<Msp::GL::Sequence> env_seq;
std::unique_ptr<Msp::GL::EnvironmentMap> env_map;
--- /dev/null
+#include <msp/gl/meshbuilder.h>
+#include <msp/gl/renderer.h>
+#include "rain.h"
+
+using namespace Msp;
+
+Rain::Rain(DataFile::Collection &resources, unsigned count, const LinAl::Vector<float, 2> ¢er, float radius):
+ tech(resources.get<GL::Technique>("rain.tech")),
+ mesh((GL::VERTEX3, GL::TEXCOORD1))
+{
+ std::minstd_rand rng;
+ std::uniform_real_distribution<float> dist(0.0f, 1.0f);
+ GL::MeshBuilder bld(mesh);
+ bld.begin(GL::LINES);
+ for(unsigned i=0; i<count; ++i)
+ {
+ float r = sqrt(dist(rng))*radius;
+ Geometry::Angle<float> a = Geometry::Angle<float>::from_turns(dist(rng));
+ GL::Vector3 p = compose(center, 0.0f) + GL::Vector3(cos(a)*r, sin(a)*r, i*20.0f/count);
+ bld.texcoord(1.0f);
+ bld.vertex(p);
+ bld.texcoord(0.0f);
+ bld.vertex(p+GL::Vector3(0.0f, 0.0f, 0.2f));
+ }
+ bld.end();
+
+ shdata.uniform("time", 0.0f);
+}
+
+void Rain::setup_frame(GL::Renderer &)
+{
+ time += 0.016f;
+ shdata.uniform("time", time);
+}
+
+void Rain::render(GL::Renderer &renderer, GL::Tag tag) const
+{
+ const GL::RenderMethod *method = tech.find_method(tag);
+ if(!method)
+ return;
+
+ GL::Renderer::Push _push(renderer);
+
+ method->apply(renderer);
+ renderer.add_shader_data(shdata);
+ mesh.draw(renderer);
+}
--- /dev/null
+#ifndef RAIN_H_
+#define RAIN_H_
+
+#include <random>
+#include <msp/datafile/collection.h>
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderable.h>
+#include <msp/gl/technique.h>
+
+class Rain: public Msp::GL::Renderable
+{
+private:
+ const Msp::GL::Technique &tech;
+ Msp::GL::Mesh mesh;
+ Msp::GL::ProgramData shdata;
+ float time = 0.0f;
+
+public:
+ Rain(Msp::DataFile::Collection &, unsigned, const Msp::LinAl::Vector<float, 2> &, float);
+
+ void setup_frame(Msp::GL::Renderer &) override;
+ void render(Msp::GL::Renderer &, Msp::GL::Tag) const override;
+};
+
+#endif