diff options
Diffstat (limited to 'src/mbgl/gl/uniform.hpp')
-rw-r--r-- | src/mbgl/gl/uniform.hpp | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 5af781043d..726cd4fe10 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -1,60 +1,80 @@ #pragma once -#include <mbgl/gl/shader.hpp> +#include <mbgl/gl/types.hpp> +#include <mbgl/util/optional.hpp> +#include <mbgl/util/ignore.hpp> +#include <mbgl/util/indexed_tuple.hpp> #include <array> +#include <functional> namespace mbgl { namespace gl { -template <typename T> +template <class T> +void bindUniform(UniformLocation, const T&); + +template <class Tag, class T> +class UniformValue { +public: + explicit UniformValue(T t_) : t(std::move(t_)) {} + T t; +}; + +template <class Tag, class T> class Uniform { public: - Uniform(const char* name, const Shader& shader) - : current(), location(shader.getUniformLocation(name)) { - } + using Value = UniformValue<Tag, T>; - void operator=(const T& t) { - if (current != t) { - current = t; - bind(t); + class State { + public: + void operator=(const Value& value) { + if (!current || *current != value.t) { + current = value.t; + bindUniform(location, value.t); + } } - } - -private: - void bind(const T&); - T current; - UniformLocation location; + UniformLocation location; + optional<T> current = {}; + }; }; -template <size_t C, size_t R = C> -class UniformMatrix { +template <class Tag, class T> +using UniformScalar = Uniform<Tag, T>; + +template <class Tag, class T, size_t N> +using UniformVector = Uniform<Tag, std::array<T, N>>; + +template <class Tag, class T, size_t N> +using UniformMatrix = Uniform<Tag, std::array<T, N*N>>; + +#define MBGL_DEFINE_UNIFORM_SCALAR(type_, name_) \ + struct name_ : ::mbgl::gl::UniformScalar<name_, type_> { static constexpr auto name = #name_; } + +#define MBGL_DEFINE_UNIFORM_VECTOR(type_, n_, name_) \ + struct name_ : ::mbgl::gl::UniformVector<name_, type_, n_> { static constexpr auto name = #name_; } + +#define MBGL_DEFINE_UNIFORM_MATRIX(type_, n_, name_) \ + struct name_ : ::mbgl::gl::UniformMatrix<name_, type_, n_> { static constexpr auto name = #name_; } + +UniformLocation uniformLocation(ProgramID, const char * name); + +template <class... Us> +class Uniforms { public: - typedef std::array<float, C*R> T; + using State = IndexedTuple<TypeList<Us...>, TypeList<typename Us::State...>>; + using Values = IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>>; - UniformMatrix(const char* name, const Shader& shader) - : current(), location(shader.getUniformLocation(name)) { + static State state(const ProgramID& id) { + return State { { uniformLocation(id, Us::name) }... }; } - void operator=(const std::array<double, C*R>& t) { - bool dirty = false; - for (unsigned int i = 0; i < C*R; i++) { - if (current[i] != t[i]) { - current[i] = t[i]; - dirty = true; - } - } - if (dirty) { - bind(current); - } + static std::function<void ()> binder(State& state, Values&& values_) { + return [&state, values = std::move(values_)] () mutable { + util::ignore({ (state.template get<Us>() = values.template get<Us>(), 0)... }); + }; } - -private: - void bind(const T&); - - T current; - UniformLocation location; }; } // namespace gl |