--- /dev/null
+uniform sampler2D depth;
+uniform sampler2D occlusion;
+uniform sampler2D rotate;
+uniform AmbientOcclusionParams
+{
+ vec2 screen_size;
+ vec2 depth_ratio;
+ float darkness;
+};
--- /dev/null
+import postprocess;
+import ambientocclusion;
+
+////// fragment
+void main()
+{
+ float sample = depth_ratio.x/(texture(depth, texcoord).r-depth_ratio.y);
+ float sum = 1.0;
+ float count = 1.0;
+ for(int i=0; i<=3; ++i)
+ for(int j=0; j<=3; ++j)
+ {
+ vec2 offs = vec2(float(i)-1.5, float(j)-1.5)/screen_size;
+ float dxy = length(offs)*-sample;
+ float dz = depth_ratio.x/(texture(depth, texcoord+offs).r-depth_ratio.y)-sample;
+ if(abs(dz)<3.0*dxy)
+ {
+ sum += texture(occlusion, texcoord+offs).r;
+ count += 1.0;
+ }
+ }
+ frag_color = texture(source, texcoord)*sum/count;
+}
--- /dev/null
+import postprocess;
+import ambientocclusion;
+
+////// fragment
+void main()
+{
+ mat2 transform = mat2(texture(rotate, texcoord*screen_size/4.0)*2.0-1.0)
+ *mat2(screen_size.y/screen_size.x, 0.0, 0.0, 1.0)*3.0/screen_size.y;
+ float sample = depth_ratio.x/(texture(depth, texcoord).r-depth_ratio.y);
+ float sum = 0.0;
+ for(int i=0; i<=3; ++i)
+ for(int j=0; j<=3; ++j)
+ {
+ vec2 offs = transform*vec2(float(i)-1.5, float(j)-1.5);
+ float dxy = length(offs)*-sample;
+ float dz = depth_ratio.x/(texture(depth, texcoord+offs).r-depth_ratio.y)-sample;
+ if(abs(dz)<3.0*dxy)
+ sum += atan(dz/dxy)/1.570796;
+ else if(dz<0.0)
+ sum -= 0.8;
+ }
+ frag_color = vec4(min(1.0-sum*darkness/16.0, 1.0), 0.0, 0.0, 1.0);
+}
--- /dev/null
+uniform sampler2D blurred;
+uniform BloomParams
+{
+ vec2 delta;
+ float factors[19];
+ int size;
+ float strength;
+};
--- /dev/null
+import postprocess;
+import bloom;
+
+////// fragment
+void main()
+{
+ frag_color = vec4(0.0, 0.0, 0.0, 0.0);
+ for(int i=0; i<=size*2; ++i)
+ frag_color += texture(source, texcoord+delta*float(i-size))*factors[i];
+}
--- /dev/null
+import postprocess;
+import bloom;
+
+////// fragment
+void main()
+{
+ frag_color = mix(texture(source, texcoord), texture(blurred, texcoord), strength);
+}
--- /dev/null
+import postprocess;
+
+uniform sampler1D curve;
+uniform ToneMapping
+{
+ float peak;
+ float brightness;
+};
+
+////// fragment
+void main()
+{
+ vec4 sample = texture(source, texcoord);
+ float maxc = max(sample.r, max(sample.g, sample.b));
+ if(maxc>1.0-peak)
+ {
+ vec3 saturated = sample.rgb/maxc;
+ if(maxc>1.0+peak)
+ {
+ sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));
+ }
+ else
+ {
+ float x = (1.0+peak-maxc)/(2.0*peak);
+ sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);
+ }
+ }
+ frag_color = vec4(texture(curve, sample.r).r, texture(curve, sample.g).r, texture(curve, sample.b).r, sample.a);
+}
--- /dev/null
+uniform sampler2D source;
+
+////// vertex
+in vec4 vertex;
+void main()
+{
+ gl_Position = vertex;
+ out vec2 texcoord = vertex.xy*0.5+0.5;
+}
+
+////// fragment
+out vec4 frag_color;
#include "shader.h"
#include "tests.h"
-namespace {
-
-const char occlude_fs[] =
- "uniform sampler2D depth;\n"
- "uniform sampler2D rotate;\n"
- "uniform vec2 screen_size;\n"
- "uniform vec2 depth_ratio;\n"
- "uniform float darkness;\n"
- "varying vec2 texcoord;\n"
- "void main()\n"
- "{\n"
- " mat2 transform = mat2(texture2D(rotate, texcoord*screen_size/4.0)*2.0-1.0)\n"
- " *mat2(screen_size.y/screen_size.x, 0.0, 0.0, 1.0)*3.0/screen_size.y;\n"
- " float sample = depth_ratio.x/(texture2D(depth, texcoord).r-depth_ratio.y);\n"
- " float sum = 0.0;\n"
- " for(int i=0; i<=3; ++i)\n"
- " for(int j=0; j<=3; ++j)\n"
- " {\n"
- " vec2 offs = transform*vec2(float(i)-1.5, float(j)-1.5);\n"
- " float dxy = length(offs)*-sample;\n"
- " float dz = depth_ratio.x/(texture2D(depth, texcoord+offs).r-depth_ratio.y)-sample;\n"
- " if(abs(dz)<3.0*dxy)\n"
- " sum += atan(dz/dxy)/1.570796;\n"
- " else if(dz<0.0)\n"
- " sum -= 0.8;\n"
- " }\n"
- " gl_FragColor = vec4(min(1.0-sum*darkness/16.0, 1.0), 0.0, 0.0, 1.0);\n"
- "}\n";
-
-const char combine_fs[] =
- "uniform sampler2D color;\n"
- "uniform sampler2D depth;\n"
- "uniform sampler2D occlusion;\n"
- "uniform vec2 screen_size;\n"
- "uniform vec2 depth_ratio;\n"
- "varying vec2 texcoord;\n"
- "void main()\n"
- "{\n"
- " float sample = depth_ratio.x/(texture2D(depth, texcoord).r-depth_ratio.y);\n"
- " float sum = 1.0;\n"
- " float count = 1.0;\n"
- " for(int i=0; i<=3; ++i)\n"
- " for(int j=0; j<=3; ++j)\n"
- " {\n"
- " vec2 offs = vec2(float(i)-1.5, float(j)-1.5)/screen_size;\n"
- " float dxy = length(offs)*-sample;\n"
- " float dz = depth_ratio.x/(texture2D(depth, texcoord+offs).r-depth_ratio.y)-sample;\n"
- " if(abs(dz)<3.0*dxy)\n"
- " {\n"
- " sum += texture2D(occlusion, texcoord+offs).r;\n"
- " count += 1.0;\n"
- " }\n"
- " }\n"
- " gl_FragColor = texture2D(color, texcoord)*sum/count;\n"
- "}\n";
-
-}
-
namespace Msp {
namespace GL {
AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float depth_ratio):
+ occlude_shader("ambientocclusion_occlude.glsl"),
+ combine_shader("ambientocclusion_combine.glsl"),
quad(get_fullscreen_quad())
{
- occlude_shader.attach_shader(get_fullscreen_vertex_shader());
- occlude_shader.attach_shader_owned(new FragmentShader(occlude_fs));
- occlude_shader.bind_attribute(get_component_type(VERTEX2), "vertex");
- occlude_shader.link();
-
- combine_shader.attach_shader(get_fullscreen_vertex_shader());
- combine_shader.attach_shader_owned(new FragmentShader(combine_fs));
- combine_shader.bind_attribute(get_component_type(VERTEX2), "vertex");
- combine_shader.link();
-
occlusion.storage(RGB, w, h);
occlusion.set_min_filter(NEAREST);
occlusion.set_mag_filter(NEAREST);
occlude_shdata.uniform("rotate", 1);
occlude_shdata.uniform("screen_size", static_cast<float>(w), static_cast<float>(h));
- combine_shdata.uniform("color", 1);
+ combine_shdata.uniform("source", 1);
combine_shdata.uniform("depth", 0);
combine_shdata.uniform("occlusion", 2);
combine_shdata.uniform("screen_size", static_cast<float>(w), static_cast<float>(h));
using namespace std;
-namespace {
-
-static const char blur_fs[]=
- "uniform sampler2D source;\n"
- "uniform vec2 delta;\n"
- "uniform float factors[19];\n"
- "uniform int size;\n"
- "varying vec2 texcoord;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
- " for(int i=0; i<=size*2; ++i)\n"
- " gl_FragColor += texture2D(source, texcoord+delta*float(i-size))*factors[i];\n"
- "}";
-
-static const char combine_fs[]=
- "uniform sampler2D source;\n"
- "uniform sampler2D blurred;\n"
- "uniform float strength;\n"
- "varying vec2 texcoord;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = mix(texture2D(source, texcoord), texture2D(blurred, texcoord), strength);\n"
- "}";
-
-}
-
namespace Msp {
namespace GL {
Bloom::Bloom(unsigned w, unsigned h):
+ blur_shader("bloom_blur.glsl"),
+ combine_shader("bloom_combine.glsl"),
quad(get_fullscreen_quad())
{
- blur_shader.attach_shader(get_fullscreen_vertex_shader());
- blur_shader.attach_shader_owned(new FragmentShader(blur_fs));
- blur_shader.bind_attribute(get_component_type(VERTEX2), "vertex");
- blur_shader.link();
-
- combine_shader.attach_shader(get_fullscreen_vertex_shader());
- combine_shader.attach_shader_owned(new FragmentShader(combine_fs));
- combine_shader.bind_attribute(get_component_type(VERTEX2), "vertex");
- combine_shader.link();
-
blur_shdata[0].uniform("delta", 1.0f/w, 0.0f);
blur_shdata[1].uniform("delta", 0.0f, 1.0f/h);
using namespace std;
-namespace {
-
-static const char fragment_src[] =
- "uniform sampler2D texture;\n"
- "uniform sampler1D curve;\n"
- "uniform float peak;\n"
- "uniform float brightness;\n"
- "varying vec2 texcoord;\n"
- "void main()\n"
- "{\n"
- " vec4 sample = texture2D(texture, texcoord);\n"
- " float maxc = max(sample.r, max(sample.g, sample.b));\n"
- " if(maxc>1.0-peak)\n"
- " {\n"
- " vec3 saturated = sample.rgb/maxc;\n"
- " if(maxc>1.0+peak)\n"
- " {\n"
- " sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));\n"
- " }\n"
- " else\n"
- " {\n"
- " float x = (1.0+peak-maxc)/(2.0*peak);\n"
- " sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);\n"
- " }\n"
- " }\n"
- " gl_FragColor = vec4(texture1D(curve, sample.r).r, texture1D(curve, sample.g).r, texture1D(curve, sample.b).r, sample.a);\n"
- "}";
-
-}
-
namespace Msp {
namespace GL {
ColorCurve::ColorCurve():
+ shprog("colorcurve.glsl"),
quad(get_fullscreen_quad())
{
- shprog.attach_shader(get_fullscreen_vertex_shader());
- shprog.attach_shader_owned(new FragmentShader(fragment_src));
- shprog.bind_attribute(get_component_type(VERTEX2), "vertex");
- shprog.link();
-
- shdata.uniform("texture", 0);
+ shdata.uniform("source", 0);
shdata.uniform("curve", 1);
curve.storage(LUMINANCE, 256);
/** Returns a vertex shader suitable for rendering a full-screen quad.
Input vertices are assumed to be in normalized device coordinates; no
transform is performed. The shader provides a varying vec2 texcoord for
- a fragment shader to access textures. */
+ a fragment shader to access textures.
+
+ Deprecated in favor of the builtin postprocess.glsl module. */
static Shader &get_fullscreen_vertex_shader();
/** Returns a mesh consisting of a single quad, covering the entire screen.
#include "misc.h"
#include "program.h"
#include "programcompiler.h"
+#include "resources.h"
#include "shader.h"
using namespace std;
init();
ProgramCompiler compiler;
- compiler.compile(source);
+ if(source.find(';')==string::npos && source.size()>5 && !source.compare(source.size()-5, 5, ".glsl"))
+ {
+ if(RefPtr<IO::Seekable> io = Resources::get_builtins().open(source))
+ compiler.compile(*io);
+ else
+ throw IO::file_not_found(source);
+ }
+ else
+ compiler.compile(source);
compiler.add_shaders(*this);
link();
}
void ProgramCompiler::import(const string &name)
{
- if(!resources)
- throw runtime_error("no resources");
- RefPtr<IO::Seekable> io = resources->open_raw(name+".glsl");
+ string fn = name+".glsl";
+ RefPtr<IO::Seekable> io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn));
if(!io)
throw runtime_error(format("module %s not found", name));
ProgramParser import_parser;
+#include <msp/datafile/builtinsource.h>
#include <msp/fs/utils.h>
#include <msp/gl/extensions/sgis_generate_mipmap.h>
#include "animation.h"
add_source(get_builtins());
}
-DataFile::BuiltinSource &Resources::get_builtins()
+const DataFile::CollectionSource &Resources::get_builtins()
{
static DataFile::BuiltinSource builtins;
bool init_done = false;
#ifndef MSP_GL_RESOURCES_H_
#define MSP_GL_RESOURCES_H_
-#include <msp/datafile/builtinsource.h>
#include <msp/datafile/collection.h>
#include "texture.h"
public:
Resources();
-private:
- static DataFile::BuiltinSource &get_builtins();
+ static const DataFile::CollectionSource &get_builtins();
-public:
void set_default_texture_filter(TextureFilter);
/** Enables or disables sRGB conversion. If enabled, textures and material