]> git.tdb.fi Git - libs/gl.git/blob - source/ambientocclusion.cpp
Move postprocessor shaders to the builtin shaderlib
[libs/gl.git] / source / ambientocclusion.cpp
1 #define _USE_MATH_DEFINES
2 #include <cmath>
3 #include "ambientocclusion.h"
4 #include "blend.h"
5 #include "shader.h"
6 #include "tests.h"
7
8 namespace Msp {
9 namespace GL {
10
11 AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio):
12         occlude_shader("ambientocclusion_occlude.glsl"),
13         combine_shader("ambientocclusion_combine.glsl"),
14         quad(get_fullscreen_quad())
15 {
16         occlusion.storage(RGB, w, h);
17         occlusion.set_min_filter(NEAREST);
18         occlusion.set_mag_filter(NEAREST);
19         occlusion.set_wrap(CLAMP_TO_EDGE);
20         fbo.attach(COLOR_ATTACHMENT0, occlusion, 0);
21         fbo.require_complete();
22
23         combine_texturing.attach(2, occlusion);
24
25         rotate_lookup.storage(RGBA, 4, 4);
26         rotate_lookup.set_min_filter(NEAREST);
27         rotate_lookup.set_mag_filter(NEAREST);
28         unsigned char data[64];
29         for(unsigned i=0; i<16; ++i)
30         {
31                 float a = ((i*541)%16)*M_PI/32;
32                 float c = cos(a);
33                 float s = sin(a);
34                 data[i*3  ] = static_cast<unsigned char>(127+c*127);
35                 data[i*3+1] = static_cast<unsigned char>(127+s*127);
36                 data[i*3+2] = static_cast<unsigned char>(127-s*127);
37                 data[i*3+4] = static_cast<unsigned char>(127+c*127);
38         }
39         rotate_lookup.image(0, RGBA, UNSIGNED_BYTE, data);
40
41         occlude_texturing.attach(1, rotate_lookup);
42
43         occlude_shdata.uniform("depth", 0);
44         occlude_shdata.uniform("rotate", 1);
45         occlude_shdata.uniform("screen_size", static_cast<float>(w), static_cast<float>(h));
46
47         combine_shdata.uniform("source", 1);
48         combine_shdata.uniform("depth", 0);
49         combine_shdata.uniform("occlusion", 2);
50         combine_shdata.uniform("screen_size", static_cast<float>(w), static_cast<float>(h));
51
52         set_depth_ratio(depth_ratio);
53         set_darkness(1.5);
54 }
55
56 void AmbientOcclusion::set_depth_ratio(float depth_ratio)
57 {
58         depth_ratio = 1/depth_ratio;
59
60         occlude_shdata.uniform("depth_ratio", depth_ratio, 1+depth_ratio);
61         combine_shdata.uniform("depth_ratio", depth_ratio, 1+depth_ratio);
62 }
63
64 void AmbientOcclusion::set_darkness(float darkness)
65 {
66         occlude_shdata.uniform("darkness", darkness);
67 }
68
69 void AmbientOcclusion::render(const Texture2D &color, const Texture2D &depth)
70 {
71         occlude_texturing.attach(0, depth);
72         combine_texturing.attach(0, depth);
73         combine_texturing.attach(1, color);
74
75         BindRestore unbind_dtest(static_cast<DepthTest *>(0));
76         BindRestore unbind_blend(static_cast<Blend *>(0));
77         Bind bind_mesh(quad);
78
79         {
80                 BindRestore bind_fbo(fbo);
81                 Bind bind_tex(occlude_texturing);
82                 Bind bind_shader(occlude_shader);
83                 occlude_shdata.apply();
84                 quad.draw();
85         }
86
87         Bind bind_tex(combine_texturing);
88         Bind bind_shader(combine_shader);
89         combine_shdata.apply();
90         quad.draw();
91 }
92
93 } // namespace GL
94 } // namespace Msp