3 This file is part of libmspgl
4 Copyright © 2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
9 #include <msp/strings/formatter.h>
11 #include "meshbuilder.h"
18 static const char blur_vs[]=
19 "varying vec2 texcoord;\n"
22 " gl_Position=vec4(gl_Vertex.xy*2.0-1.0, 0.0, 1.0);\n"
23 " texcoord=gl_Vertex.xy;\n"
26 static const char blur_fs[]=
27 "uniform sampler2D source;\n"
28 "uniform vec2 delta;\n"
29 "uniform float factors[19];\n"
31 "varying vec2 texcoord;\n"
34 " gl_FragColor=vec4(0.0, 0.0, 0.0, 0.0);\n"
35 " for(int i=-size; i<=size; ++i)\n"
36 " gl_FragColor+=texture2D(source, texcoord+delta*i)*factors[i+size];\n"
39 static const char combine_vs[]=
40 "varying vec2 texcoord;\n"
43 " gl_Position=vec4(gl_Vertex.xy*2.0-1.0, 0.0, 1.0);\n"
44 " texcoord=gl_Vertex.xy;\n"
47 static const char combine_fs[]=
48 "uniform sampler2D source;\n"
49 "uniform sampler2D blurred;\n"
50 "uniform float strength;\n"
51 "varying vec2 texcoord;\n"
54 " gl_FragColor=mix(texture2D(source, texcoord), texture2D(blurred, texcoord), strength);\n"
62 Bloom::Bloom(unsigned w, unsigned h):
63 blur_shader(blur_vs, blur_fs),
64 combine_shader(combine_vs, combine_fs),
67 int loc=blur_shader.get_uniform_location("delta");
68 blur_shdata[0].uniform(loc, 1.0f/w, 0.0f);
69 blur_shdata[1].uniform(loc, 0.0f, 1.0f/h);
71 loc=blur_shader.get_uniform_location("source");
72 for(unsigned i=0; i<2; ++i)
74 blur_shdata[i].uniform(loc, 0);
75 tex[i].storage(RGB16F, w, h, 0);
76 tex[i].image(0, RGB, UNSIGNED_BYTE, 0);
77 tex[i].set_min_filter(NEAREST);
80 combine_shdata.uniform(combine_shader.get_uniform_location("source"), 1);
81 combine_shdata.uniform(combine_shader.get_uniform_location("blurred"), 0);
86 MeshBuilder mbld(quad);
95 void Bloom::set_radius(float r)
98 throw InvalidParameterValue("Radius must be positive");
100 int size=min(static_cast<int>(r*3.0f), 9);
101 int loc=blur_shader.get_uniform_location("size");
102 blur_shdata[0].uniform(loc, size);
103 blur_shdata[1].uniform(loc, size);
105 vector<float> factors(size*2+1);
108 for(int i=-size; i<=size; ++i)
109 sum+=(factors[size+i]=exp(-i*i/r));
111 for(int i=0; i<=size*2; ++i)
113 loc=blur_shader.get_uniform_location(format("factors[%d]", i));
114 float f=factors[i]/sum;
115 blur_shdata[0].uniform(loc, f);
116 blur_shdata[1].uniform(loc, f);
120 void Bloom::set_strength(float s)
123 throw InvalidParameterValue("Strength must be in the range [0.0, 1.0]");
124 combine_shdata.uniform(combine_shader.get_uniform_location("strength"), s);
127 void Bloom::render(const Texture2D &src)
129 const Framebuffer *dest=Framebuffer::current();
133 for(unsigned i=0; i<2; ++i)
135 fbo.attach(COLOR_ATTACHMENT0, tex[i], 0);
136 blur_shdata[i].apply();
144 Framebuffer::unbind();
146 combine_shader.bind();
147 combine_shdata.apply();
152 TexUnit::activate(0);