]> git.tdb.fi Git - libs/gl.git/blobdiff - source/effects/ambientocclusion.cpp
Store the ambient occlusion rotate lookup texture in resources
[libs/gl.git] / source / effects / ambientocclusion.cpp
index bae5e780d1b08c64ea538aa3cd991310044b4277..b4050aef92428ceeacf44a8924e4a48d07085279 100644 (file)
@@ -12,18 +12,36 @@ using namespace std;
 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)
        {
@@ -35,20 +53,9 @@ AmbientOcclusion::AmbientOcclusion(Resources &resources, unsigned w, unsigned h,
                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)
@@ -92,14 +99,11 @@ void AmbientOcclusion::set_edge_depth_threshold(float edt)
 
 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);
 
        {
@@ -119,9 +123,9 @@ AmbientOcclusion::Template::Template():
        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);