]> git.tdb.fi Git - libs/demoscene.git/blobdiff - source/vignette.cpp
Add a vignette postprocessor
[libs/demoscene.git] / source / vignette.cpp
diff --git a/source/vignette.cpp b/source/vignette.cpp
new file mode 100644 (file)
index 0000000..e4d7de8
--- /dev/null
@@ -0,0 +1,76 @@
+#include <algorithm>
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderer.h>
+#include <msp/gl/texture2d.h>
+#include "resources.h"
+#include "vignette.h"
+
+using namespace std;
+
+namespace Msp {
+namespace DemoScene {
+
+Vignette::Vignette(float aspect):
+       mesh(get_fullscreen_quad()),
+       shprog(Resources::get_builtins().get<GL::Program>("vignette.glsl"))
+{
+       shdata.uniform("coord_scale", min(aspect, 1.0f), min(1.0f/aspect, 1.0f));
+       set_optical(1.0f, 0.5f);
+       set_natural(1.0f, 1.0f);
+}
+
+void Vignette::set_optical(float pupil, float aperture)
+{
+       if(pupil<0.0f || aperture<0.0f || aperture>pupil)
+               throw std::invalid_argument("Vignette::set_optical");
+
+       float p_sq = pupil*pupil;
+       float a_sq = aperture*aperture;
+       float two_ap = 2*pupil*aperture;
+       shdata.uniform("optical", pupil, aperture, a_sq, a_sq*M_PI);
+       shdata.uniform("optical_range", p_sq-two_ap+a_sq, p_sq+two_ap+a_sq);
+}
+
+void Vignette::set_natural(float radius, float darkening)
+{
+       if(radius<=0.0f || darkening<0.0f)
+               throw std::invalid_argument("Vignette::set_natural");
+
+       float v = pow(2.0f, -darkening);
+       float t_sq = 1/sqrt(v)-1;
+       shdata.uniform("natural", t_sq/(radius*radius));
+}
+
+void Vignette::render(GL::Renderer &renderer, const GL::Texture2D &color, const GL::Texture2D &)
+{
+       renderer.set_texture(&color);
+       renderer.set_shader_program(&shprog, &shdata);
+       mesh.draw(renderer);
+}
+
+
+Vignette::Template::Template():
+       pupil(1.0f),
+       aperture(0.5f),
+       radius(1.0f),
+       darkening(1.0f)
+{ }
+
+Vignette *Vignette::Template::create(unsigned w, unsigned h) const
+{
+       Vignette *vign = new Vignette(static_cast<float>(w)/h);
+       vign->set_optical(pupil, aperture);
+       vign->set_natural(radius, darkening);
+       return vign;
+}
+
+
+Vignette::Template::Loader::Loader(Template &t):
+       DerivedObjectLoader<Template, PostProcessor::Template::Loader>(t)
+{
+       add("optical", &Template::pupil, &Template::aperture);
+       add("natural", &Template::radius, &Template::darkening);
+}
+
+} // namespace DemoScene
+} // namespace Msp