--- /dev/null
+import postprocess;
+
+uniform Vignette
+{
+ vec2 coord_scale;
+ vec4 optical;
+ vec2 optical_range;
+ float natural;
+};
+
+#pragma MSP stage(fragment)
+void main()
+{
+ vec4 incoming = texture(source, texcoord);
+ vec2 r = vertex.xy*coord_scale;
+ float r_sq = dot(r, r);
+
+ float vignette = 1.0;
+ if(r_sq>=optical_range.y)
+ vignette = 0.0;
+ else if(r_sq>=optical_range.x)
+ {
+ float r = sqrt(r_sq)-optical.x;
+ float v = (optical.z*acos(r/optical.y)-sqrt(optical.z-r*r)*r);
+ vignette = v/optical.w;
+ }
+
+ float c_sq = 1/(1+r_sq*natural);
+ vignette *= c_sq*c_sq;
+
+ frag_color = vec4(incoming.rgb*vignette, incoming.a);
+}
#include <cmath>
#include <msp/core/getopt.h>
+#include <msp/gl/pipelinetemplate.h>
#include <msp/input/keys.h>
#include <msp/io/console.h>
#include <msp/io/file.h>
#include "demo.h"
#include "launcher.h"
#include "launchscreen.h"
+#include "vignette.h"
using namespace std;
gl_context.set_swap_interval(options.no_vsync ? 0 : 1);
window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &LauncherBase::exit), 0));
keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &LauncherBase::key_press), false));
+
+ GL::PipelineTemplate::register_postprocessor<Vignette>("vignette");
}
LauncherBase::~LauncherBase()
--- /dev/null
+#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
--- /dev/null
+#ifndef MSP_DEMOSCENE_VIGNETTE_H_
+#define MSP_DEMOSCENE_VIGNETTE_H_
+
+#include <msp/gl/postprocessor.h>
+#include <msp/gl/program.h>
+#include <msp/gl/programdata.h>
+
+namespace Msp {
+namespace DemoScene {
+
+class Vignette: public Msp::GL::PostProcessor
+{
+public:
+ struct Template: PostProcessor::Template
+ {
+ class Loader: public Msp::DataFile::DerivedObjectLoader<Template, PostProcessor::Template::Loader>
+ {
+ public:
+ Loader(Template &);
+ };
+
+ float pupil;
+ float aperture;
+ float radius;
+ float darkening;
+
+ Template();
+
+ virtual Vignette *create(unsigned, unsigned) const;
+ };
+
+private:
+ const Msp::GL::Mesh &mesh;
+ const Msp::GL::Program &shprog;
+ Msp::GL::ProgramData shdata;
+
+public:
+ Vignette(float);
+
+ void set_optical(float, float);
+ void set_natural(float, float);
+private:
+ void update_shdata();
+
+public:
+ virtual void render(Msp::GL::Renderer &, const Msp::GL::Texture2D &, const Msp::GL::Texture2D &);
+};
+
+} // namespace DemoScene
+} // namespace Msp
+
+#endif