summaryrefslogtreecommitdiff
path: root/src/mbgl/gl/uniform.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/gl/uniform.hpp')
-rw-r--r--src/mbgl/gl/uniform.hpp94
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