// either will be fine.
virtual bool needs_texture_bounce() const { return false; }
- // Whether this effect expects mipmaps or not. If you set this to
- // true, you will be sampling with bilinear filtering; if not,
- // you could be sampling with simple linear filtering and no mipmaps
- // (although there is no guarantee; if a different effect in the chain
- // needs mipmaps, you will also get them).
- virtual bool needs_mipmaps() const { return false; }
+ // Whether this effect expects mipmaps or not.
+ enum MipmapRequirements {
+ // If chosen, you will be sampling with bilinear filtering,
+ // ie. the closest mipmap will be chosen, and then there will be
+ // bilinear interpolation inside it (GL_LINEAR_MIPMAP_NEAREST).
+ NEEDS_MIPMAPS,
+
+ // Whether the effect doesn't really care whether input textures
+ // are with or without mipmaps. You could get the same effect
+ // as NEEDS_MIPMAPS or CANNOT_ACCEPT_MIPMAPS; normally, you won't
+ // get them, but if a different effect in the same phase needs mipmaps,
+ // you will also get them.
+ DOES_NOT_NEED_MIPMAPS,
+
+ // The opposite of NEEDS_MIPMAPS; you will always be sampling from
+ // the most detailed mip level (GL_LINEAR). Effects with NEEDS_MIPMAPS
+ // and CANNOT_ACCEPT_MIPMAPS can not coexist within the same phase;
+ // such phases will be split.
+ //
+ // This is the only choice that makes sense for a compute shader,
+ // given that it doesn't have screen-space derivatives and thus
+ // always will sample the most detailed mip level.
+ CANNOT_ACCEPT_MIPMAPS,
+ };
+ virtual MipmapRequirements needs_mipmaps() const {
+ if (is_compute_shader()) {
+ return CANNOT_ACCEPT_MIPMAPS;
+ } else {
+ return DOES_NOT_NEED_MIPMAPS;
+ }
+ }
// Whether there is a direct correspondence between input and output
// texels. Specifically, the effect must not:
virtual bool one_to_one_sampling() const { return strong_one_to_one_sampling(); }
// Similar in use to one_to_one_sampling(), but even stricter:
- // The effect must not use texture coordinate in any way beyond
- // giving it unmodified to its (single) input. This allows it to
- // also be used after a compute shader, in the same phase.
+ // The effect must not modify texture coordinate in any way when
+ // calling its input(s). This allows it to also be used after
+ // a compute shader, in the same phase.
//
// An effect that it strong one-to-one must also be one-to-one.
virtual bool strong_one_to_one_sampling() const { return false; }
// Set a parameter; intended to be called from user code.
// Neither of these take ownership of the pointer.
- virtual bool set_int(const std::string&, int value) MUST_CHECK_RESULT;
+ virtual bool set_int(const std::string &key, int value) MUST_CHECK_RESULT;
+ virtual bool set_ivec2(const std::string &key, const int *values) MUST_CHECK_RESULT;
virtual bool set_float(const std::string &key, float value) MUST_CHECK_RESULT;
virtual bool set_vec2(const std::string &key, const float *values) MUST_CHECK_RESULT;
virtual bool set_vec3(const std::string &key, const float *values) MUST_CHECK_RESULT;
// These correspond directly to int/float/vec2/vec3/vec4 in GLSL.
void register_int(const std::string &key, int *value);
+ void register_ivec2(const std::string &key, int *values);
void register_float(const std::string &key, float *value);
void register_vec2(const std::string &key, float *values);
void register_vec3(const std::string &key, float *values);
// except for register_int as noted above.
void register_uniform_sampler2d(const std::string &key, const int *value);
void register_uniform_bool(const std::string &key, const bool *value);
- void register_uniform_int(const std::string &key, const int *value); // Note: Requires GLSL 1.30 or newer.
+ void register_uniform_int(const std::string &key, const int *value);
+ void register_uniform_ivec2(const std::string &key, const int *values);
void register_uniform_float(const std::string &key, const float *value);
void register_uniform_vec2(const std::string &key, const float *values);
void register_uniform_vec3(const std::string &key, const float *values);
private:
std::map<std::string, int *> params_int;
+ std::map<std::string, int *> params_ivec2;
std::map<std::string, float *> params_float;
std::map<std::string, float *> params_vec2;
std::map<std::string, float *> params_vec3;
std::vector<Uniform<int>> uniforms_sampler2d;
std::vector<Uniform<bool>> uniforms_bool;
std::vector<Uniform<int>> uniforms_int;
+ std::vector<Uniform<int>> uniforms_ivec2;
std::vector<Uniform<float>> uniforms_float;
std::vector<Uniform<float>> uniforms_vec2;
std::vector<Uniform<float>> uniforms_vec3;