namespace Msp {
namespace GL {
-AmbientOcclusion::AmbientOcclusion(Resources &resources, unsigned w, unsigned h, float):
+AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float):
+ rotate_lookup(get_or_create_rotate_lookup()),
occlude_target(w, h, (RENDER_COLOR,R8)),
- occlude_shader(resources.get<Program>("_ambientocclusion_occlude.glsl.shader")),
- combine_shader(resources.get<Program>("_ambientocclusion_combine.glsl.shader")),
- quad(resources.get<Mesh>("_fullscreen_quad.mesh")),
- linear_sampler(resources.get<Sampler>("_linear_clamp.samp")),
- nearest_sampler(resources.get<Sampler>("_nearest_clamp.samp"))
+ occlude_shader(Resources::get_global().get<Program>("_ambientocclusion_occlude.glsl.shader")),
+ combine_shader(Resources::get_global().get<Program>("_ambientocclusion_combine.glsl.shader")),
+ quad(Resources::get_global().get<Mesh>("_fullscreen_quad.mesh")),
+ linear_sampler(Resources::get_global().get<Sampler>("_linear_clamp.samp")),
+ nearest_clamp_sampler(Resources::get_global().get<Sampler>("_nearest_clamp.samp")),
+ nearest_sampler(Resources::get_global().get<Sampler>("_nearest.samp"))
{
- texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR), &linear_sampler);
+ set_n_samples(16);
+ set_occlusion_radius(0.5f);
+ set_darkness(1.0f);
+ set_edge_depth_threshold(0.1f);
+}
+
+const Texture2D &AmbientOcclusion::get_or_create_rotate_lookup()
+{
+ Resources &resources = Resources::get_global();
+
+ static const string name = "_ambientocclusion_rotate.tex2d";
+ Texture2D *rotate_lookup = resources.find<Texture2D>(name);
+ if(rotate_lookup)
+ return *rotate_lookup;
+
+ rotate_lookup = new Texture2D;
+ rotate_lookup->storage(RGBA8, 4, 4, 1);
+ resources.add(name, rotate_lookup);
unsigned seed = 1;
- rotate_lookup.storage(RGBA8, 4, 4, 1);
unsigned char data[64];
for(unsigned i=0; i<16; ++i)
{
data[i*4+2] = 255-s;
data[i*4+3] = ((i+i/4)%2)*255;
}
- rotate_lookup.image(0, data);
+ rotate_lookup->image(0, data);
- texturing.attach(3, rotate_lookup, &nearest_sampler);
-
- shdata.uniform("source", 0);
- shdata.uniform("depth", 1);
- shdata.uniform("occlusion", 2);
- shdata.uniform("rotate", 3);
- shdata.uniform("inverse_projection", Matrix());
-
- set_n_samples(16);
- set_occlusion_radius(0.5f);
- set_darkness(1.0f);
- set_edge_depth_threshold(0.1f);
+ return *rotate_lookup;
}
float AmbientOcclusion::random(unsigned &seed)
void AmbientOcclusion::render(Renderer &renderer, const Texture2D &color, const Texture2D &depth)
{
- texturing.attach(0, color, &nearest_sampler);
- texturing.attach(1, depth, &nearest_sampler);
-
- if(renderer.get_camera())
- shdata.uniform("inverse_projection", invert(renderer.get_camera()->get_projection_matrix()));
-
Renderer::Push push(renderer);
- renderer.set_texturing(&texturing);
+ renderer.set_texture("source", &color, &nearest_clamp_sampler);
+ renderer.set_texture("depth", &depth, &nearest_clamp_sampler);
+ renderer.set_texture("occlusion", &occlude_target.get_target_texture(RENDER_COLOR), &linear_sampler);
+ renderer.set_texture("rotate", &rotate_lookup, &nearest_sampler);
renderer.set_shader_program(&occlude_shader, &shdata);
{
edge_depth_threshold(0.1f)
{ }
-AmbientOcclusion *AmbientOcclusion::Template::create(Resources &res, unsigned width, unsigned height) const
+AmbientOcclusion *AmbientOcclusion::Template::create(unsigned width, unsigned height) const
{
- RefPtr<AmbientOcclusion> ao = new AmbientOcclusion(res, width/size_divisor, height/size_divisor);
+ RefPtr<AmbientOcclusion> ao = new AmbientOcclusion(width/size_divisor, height/size_divisor);
ao->set_n_samples(n_samples);
ao->set_occlusion_radius(occlusion_radius);
ao->set_darkness(darkness);