occlude_target(w, h, (RENDER_COLOR,R8)),
occlude_shader("ambientocclusion_occlude.glsl"),
combine_shader("ambientocclusion_combine.glsl"),
- quad(get_fullscreen_quad())
+ quad(get_fullscreen_quad()),
+ linear_sampler(get_linear_sampler()),
+ nearest_sampler(get_nearest_sampler())
{
- occlude_target.set_texture_filter(LINEAR);
- texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR));
+ texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR), linear_sampler.get());
unsigned seed = 1;
rotate_lookup.storage(RGBA8, 4, 4, 1);
- rotate_lookup.get_default_sampler().set_filter(NEAREST);
unsigned char data[64];
for(unsigned i=0; i<16; ++i)
{
}
rotate_lookup.image(0, data);
- texturing.attach(3, rotate_lookup);
+ texturing.attach(3, rotate_lookup, nearest_sampler.get());
shdata.uniform("source", 0);
shdata.uniform("depth", 1);
void AmbientOcclusion::render(Renderer &renderer, const Texture2D &color, const Texture2D &depth)
{
- texturing.attach(0, color);
- texturing.attach(1, depth);
+ texturing.attach(0, color, nearest_sampler.get());
+ texturing.attach(1, depth, nearest_sampler.get());
if(renderer.get_camera())
shdata.uniform("inverse_projection", invert(renderer.get_camera()->get_projection_matrix()));
Program combine_shader;
mutable ProgramData shdata;
RefPtr<Mesh> quad;
+ RefPtr<Sampler> linear_sampler;
+ RefPtr<Sampler> nearest_sampler;
public:
AmbientOcclusion(unsigned, unsigned, float = 1.0f);
Bloom::Bloom(unsigned w, unsigned h):
blur_shader("bloom_blur.glsl"),
combine_shader("bloom_combine.glsl"),
- quad(get_fullscreen_quad())
+ quad(get_fullscreen_quad()),
+ nearest_sampler(get_nearest_sampler()),
+ linear_sampler(get_linear_sampler())
{
blur_shdata[0].uniform("delta", 1.0f/w, 0.0f);
blur_shdata[1].uniform("delta", 0.0f, 1.0f/h);
for(unsigned i=0; i<2; ++i)
target[i] = new RenderTarget(w, h, (RENDER_COLOR,RGB16F));
- target[1]->set_texture_filter(LINEAR);
common_shdata.uniform("source", 0);
common_shdata.uniform("blurred", 1);
- combine_texturing.attach(1, target[1]->get_target_texture(RENDER_COLOR));
+ combine_texturing.attach(1, target[1]->get_target_texture(RENDER_COLOR), linear_sampler.get());
set_radius(2.0f);
set_strength(0.2f);
{
BindRestore bind_fbo(target[i]->get_framebuffer());
Renderer::Push push2(renderer);
- renderer.set_texture(i ? &target[0]->get_target_texture(RENDER_COLOR) : &src);
+ renderer.set_texture(i ? &target[0]->get_target_texture(RENDER_COLOR) : &src, nearest_sampler.get());
renderer.add_shader_data(blur_shdata[i]);
quad->draw(renderer);
}
- combine_texturing.attach(0, src);
+ combine_texturing.attach(0, src, nearest_sampler.get());
renderer.set_texturing(&combine_texturing);
renderer.set_shader_program(&combine_shader);
quad->draw(renderer);
Program combine_shader;
Texturing combine_texturing;
RefPtr<Mesh> quad;
+ RefPtr<Sampler> nearest_sampler;
+ RefPtr<Sampler> linear_sampler;
public:
Bloom(unsigned, unsigned);
ColorCurve::ColorCurve():
shprog("colorcurve.glsl"),
- quad(get_fullscreen_quad())
+ quad(get_fullscreen_quad()),
+ linear_sampler(get_linear_sampler()),
+ nearest_sampler(get_nearest_sampler())
{
shdata.uniform("source", 0);
shdata.uniform("curve", 1);
curve.storage(LUMINANCE8, 256, 1);
- Sampler &sampler = curve.get_default_sampler();
- sampler.set_min_filter(LINEAR);
- sampler.set_wrap(CLAMP_TO_EDGE);
- texturing.attach(1, curve);
+ texturing.attach(1, curve, linear_sampler.get());
set_exposure_adjust(0.0f);
set_brightness_response(0.4f);
void ColorCurve::render(Renderer &renderer, const Texture2D &color_buf, const Texture2D &)
{
- texturing.attach(0, color_buf);
+ texturing.attach(0, color_buf, nearest_sampler.get());
Renderer::Push push(renderer);
renderer.set_shader_program(&shprog, &shdata);
Texture1D curve;
Texturing texturing;
RefPtr<Mesh> quad;
+ RefPtr<Sampler> linear_sampler;
+ RefPtr<Sampler> nearest_sampler;
public:
ColorCurve();
#include "effect.h"
+#include "sampler.h"
namespace Msp {
namespace GL {
+WeakPtr<Sampler> Effect::linear_sampler;
+
Effect::Effect(Renderable &r):
renderable(r)
{
enabled_passes.erase(tag);
}
+RefPtr<Sampler> Effect::get_linear_sampler()
+{
+ RefPtr<Sampler> sampler = linear_sampler;
+ if(!sampler)
+ {
+ sampler = new Sampler;
+ sampler->set_filter(LINEAR);
+ sampler->set_wrap(CLAMP_TO_EDGE);
+ linear_sampler = sampler;
+ }
+ return sampler;
+}
+
} // namespace GL
} // namespace Msp
#define MSP_GL_EFFECT_H_
#include <set>
+#include <msp/core/refptr.h>
#include "renderable.h"
namespace Msp {
namespace GL {
+class Sampler;
+
/**
Effects are used to wrap other renderables and give them additional visual
properties. An Effect's render method should set up the necessary state, call
Renderable &renderable;
std::set<Tag> enabled_passes;
+private:
+ static WeakPtr<Sampler> linear_sampler;
+
+protected:
Effect(Renderable &);
public:
virtual ~Effect() { }
virtual void setup_frame(Renderer &r) { renderable.setup_frame(r); }
virtual void finish_frame() { renderable.finish_frame(); }
+
+protected:
+ static RefPtr<Sampler> get_linear_sampler();
};
} // namespace GL
Effect(r),
size(s),
environment(e),
+ sampler(get_linear_sampler()),
rendered(false),
update_interval(1),
update_delay(0)
{
env_tex.storage(RGB8, size, 1);
- Sampler &env_samp = env_tex.get_default_sampler();
- env_samp.set_wrap(CLAMP_TO_EDGE);
- env_samp.set_min_filter(LINEAR);
depth_buf.storage(DEPTH_COMPONENT32F, size, size);
for(unsigned i=0; i<6; ++i)
{
unsigned unit = renderer.allocate_effect_texunit();
shdata.uniform("environment", static_cast<int>(unit));
+ Bind _bind_sampler(*sampler, unit);
Bind _bind_env(env_tex, unit);
const Matrix &camera_matrix = renderer.get_camera()->get_object_matrix();
TextureCube env_tex;
Renderbuffer depth_buf;
Framebuffer fbo[6];
+ RefPtr<Sampler> sampler;
Camera camera;
mutable ProgramData shdata;
bool rendered;
#include "mesh.h"
#include "meshbuilder.h"
#include "postprocessor.h"
+#include "sampler.h"
#include "shader.h"
namespace Msp {
namespace GL {
WeakPtr<Mesh> PostProcessor::fullscreen_quad;
+WeakPtr<Sampler> PostProcessor::nearest_sampler;
+WeakPtr<Sampler> PostProcessor::linear_sampler;
void PostProcessor::render(Renderer &, const Texture2D &color, const Texture2D &depth)
{
RefPtr<Mesh> PostProcessor::get_fullscreen_quad()
{
- RefPtr<Mesh> mesh;
- mesh = fullscreen_quad;
+ RefPtr<Mesh> mesh = fullscreen_quad;
if(!mesh)
{
mesh = new Mesh(VERTEX2);
return mesh;
}
+RefPtr<Sampler> PostProcessor::get_nearest_sampler()
+{
+ RefPtr<Sampler> sampler = nearest_sampler;
+ if(!sampler)
+ {
+ sampler = new Sampler;
+ sampler->set_filter(NEAREST);
+ sampler->set_wrap(CLAMP_TO_EDGE);
+ nearest_sampler = sampler;
+ }
+ return sampler;
+}
+
+RefPtr<Sampler> PostProcessor::get_linear_sampler()
+{
+ RefPtr<Sampler> sampler = linear_sampler;
+ if(!sampler)
+ {
+ sampler = new Sampler;
+ sampler->set_filter(LINEAR);
+ sampler->set_wrap(CLAMP_TO_EDGE);
+ linear_sampler = sampler;
+ }
+ return sampler;
+}
+
PostProcessor::Template::Template():
size_divisor(1)
class Mesh;
class Renderer;
+class Sampler;
class Shader;
class Texture2D;
private:
static WeakPtr<Mesh> fullscreen_quad;
+ static WeakPtr<Sampler> nearest_sampler;
+ static WeakPtr<Sampler> linear_sampler;
protected:
PostProcessor() { }
/** Returns a mesh consisting of a single quad, covering the entire screen.
The vertices are in normalized device coordinates. */
static RefPtr<Mesh> get_fullscreen_quad();
+
+ static RefPtr<Sampler> get_nearest_sampler();
+ static RefPtr<Sampler> get_linear_sampler();
};
} // namespace GL
namespace Msp {
namespace GL {
+WeakPtr<Sampler> ShadowMap::shadow_sampler;
+
ShadowMap::ShadowMap(unsigned s, Renderable &r, const Light &l):
Effect(r),
size(s),
depth_bias(4),
rendered(false)
{
- Sampler &depth_samp = depth_buf.get_default_sampler();
- depth_samp.set_min_filter(LINEAR);
- depth_samp.set_compare(LEQUAL);
- depth_samp.set_wrap(CLAMP_TO_EDGE);
+ sampler = shadow_sampler;
+ if(!sampler)
+ {
+ sampler = new Sampler;
+ sampler->set_filter(LINEAR);
+ sampler->set_compare(LEQUAL);
+ sampler->set_wrap(CLAMP_TO_EDGE);
+ shadow_sampler = sampler;
+ }
depth_buf.storage(DEPTH_COMPONENT32F, size, size, 1);
fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
fbo.require_complete();
int iunit = unit;
shdata.uniform("shadow_map", iunit);
+ Bind _bind_sampler(*sampler, unit);
Bind _bind_depth(depth_buf, unit);
if(const Camera *camera = renderer.get_camera())
Framebuffer fbo;
Matrix shadow_matrix;
Texture2D depth_buf;
+ RefPtr<Sampler> sampler;
Vector3 target;
float radius;
float depth_bias;
mutable ProgramData shdata;
bool rendered;
+ static WeakPtr<Sampler> shadow_sampler;
+
public:
ShadowMap(unsigned, Renderable &, const Light &);