Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
OpenGL state WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Sep 14, 2016
1 parent 922bb3b commit 119100b
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 53 deletions.
35 changes: 35 additions & 0 deletions include/mbgl/util/traits.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <type_traits>
#include <tuple>

namespace mbgl {

Expand All @@ -9,4 +10,38 @@ constexpr auto underlying_type(T t) -> typename std::underlying_type_t<T> {
return typename std::underlying_type_t<T>(t);
}

template <std::size_t I = 0, typename T, typename Fn>
std::enable_if_t<I == std::tuple_size<std::decay_t<T>>::value, void> apply(T&&, Fn&&) {
}

template <std::size_t I = 0, typename T, typename Fn>
std::enable_if_t<I != std::tuple_size<std::decay_t<T>>::value, void> apply(T&& t, Fn&& fn) {
fn(std::get<I>(std::forward<T>(t)));
apply<I + 1>(std::forward<T>(t), std::forward<Fn>(fn));
}

// Checks whether the template parameter pack contains T
template <typename T, typename Tuple>
struct tuple_contains;

template <typename T>
struct tuple_contains<T, std::tuple<>> : std::false_type {};

template <typename T, typename A, typename... Args>
struct tuple_contains<T, std::tuple<A, Args...>> : tuple_contains<T, std::tuple<Args...>> {};

template <typename T, typename... Args>
struct tuple_contains<T, std::tuple<T, Args...>> : std::true_type {};

// Obtains the type T from the Tuple, or the first (default) parameter otherwise.
template <typename T, typename Tuple>
constexpr std::enable_if_t<tuple_contains<T, Tuple>::value, T&&> get_tuple_type(T&&, Tuple&& tuple) {
return std::forward<T>(std::get<T>(std::forward<Tuple>(tuple)));
}

template <typename T, typename Tuple>
constexpr std::enable_if_t<!tuple_contains<T, Tuple>::value, T&&> get_tuple_type(T&& t, Tuple&&) {
return std::forward<T>(t);
}

} // namespace mbgl
8 changes: 4 additions & 4 deletions src/mbgl/renderer/painter_background.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye

} else {
config.program = plainShader.getID();
plainShader.u_color = properties.backgroundColor;
plainShader.u_opacity = properties.backgroundOpacity;

arrayBackground.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET(0), store);
}

Expand Down Expand Up @@ -80,7 +77,10 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
patternShader.u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
patternShader.u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
} else {
plainShader.u_matrix = vertexMatrix;
plainShader.setUniforms(
UniformValue<PlainShader::color>{ properties.backgroundColor },
UniformValue<PlainShader::opacity>{ properties.backgroundOpacity },
UniformValue<PlainShader::matrix>{ vertexMatrix });
}

MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index()));
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/painter_clipping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr
MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(id));
state.matrixFor(matrix, id);
matrix::multiply(matrix, projMatrix, matrix);
plainShader.u_matrix = matrix;
plainShader.setUniforms(UniformValue<PlainShader::matrix>{ matrix });

const GLint ref = (GLint)(clip.reference.to_ulong());
config.stencilFunc = { GL_ALWAYS, ref, mask };
Expand Down
16 changes: 9 additions & 7 deletions src/mbgl/renderer/painter_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {

auto& plainShader = shaders->plain;
config.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;

// Draw white outline
plainShader.u_color = Color::white();
plainShader.setUniforms(UniformValue<PlainShader::matrix>{ matrix },
UniformValue<PlainShader::opacity>{ 1.0f },
UniformValue<PlainShader::color>{ Color::white() });
config.lineWidth = 4.0f * frame.pixelRatio;
tile.debugBucket->drawLines(plainShader, store);

Expand All @@ -57,7 +57,9 @@ void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {
#endif

// Draw black text.
plainShader.u_color = Color::black();
plainShader.setUniforms(UniformValue<PlainShader::matrix>{ matrix },
UniformValue<PlainShader::opacity>{ 1.0f },
UniformValue<PlainShader::color>{ Color::black() });
config.lineWidth = 2.0f * frame.pixelRatio;
tile.debugBucket->drawLines(plainShader, store);

Expand All @@ -77,12 +79,12 @@ void Painter::renderDebugFrame(const mat4 &matrix) {

auto& plainShader = shaders->plain;
config.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;

// draw tile outline
tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, store);
plainShader.u_color = { 1.0f, 0.0f, 0.0f, 1.0f };
plainShader.setUniforms(UniformValue<PlainShader::matrix>{ matrix },
UniformValue<PlainShader::opacity>{ 1.0f },
UniformValue<PlainShader::color>{ { 1.0f, 0.0f, 0.0f, 1.0f } });
config.lineWidth = 4.0f * frame.pixelRatio;
MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()));
}
Expand Down
8 changes: 5 additions & 3 deletions src/mbgl/renderer/painter_fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ void Painter::renderFill(PaintParameters& parameters,
// fragments
// Draw filling rectangle.
config.program = plainShader.getID();
plainShader.u_matrix = vertexMatrix;
plainShader.u_color = fillColor;
plainShader.u_opacity = opacity;
plainShader.setUniforms(
UniformValue<PlainShader::matrix>{ vertexMatrix },
UniformValue<PlainShader::color>{ fillColor },
UniformValue<PlainShader::opacity>{ opacity }
);

// Draw the actual triangles into the color & stencil buffer.
setDepthSublayer(1);
Expand Down
5 changes: 5 additions & 0 deletions src/mbgl/shader/plain_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
#include <mbgl/shader/fill.fragment.hpp>
#include <mbgl/gl/gl.hpp>

#include <tuple>

namespace mbgl {

PlainShader::PlainShader(gl::ObjectStore& store, Defines defines)
: Shader(shaders::fill::name,
shaders::fill::vertex,
shaders::fill::fragment,
store, defines) {
apply(uniforms, [this](auto& uniform) {
uniform.location = MBGL_CHECK_ERROR(glGetUniformLocation(getID(), uniform.name));
});
}

void PlainShader::bind(GLbyte* offset) {
Expand Down
30 changes: 27 additions & 3 deletions src/mbgl/shader/plain_shader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,42 @@
#include <mbgl/shader/shader.hpp>
#include <mbgl/shader/uniform.hpp>
#include <mbgl/util/color.hpp>
#include <mbgl/util/traits.hpp>

namespace mbgl {

template <typename U>
struct UniformValue {
const typename U::ArgType& value;
};

class PlainShader : public Shader {
public:
PlainShader(gl::ObjectStore&, Defines defines = None);

void bind(GLbyte *offset) final;

UniformMatrix<4> u_matrix = {"u_matrix", *this};
Uniform<Color> u_color = {"u_color", *this};
Uniform<GLfloat> u_opacity = {"u_opacity", *this};
struct matrix : public UniformMatrix<4> {
matrix() : UniformMatrix{ "u_matrix" } {};
};
struct color : public Uniform<Color> {
color() : Uniform{ "u_color" } {};
};
struct opacity : public Uniform<GLfloat> {
opacity() : Uniform{ "u_opacity" } {};
};

template <typename... Args>
void setUniforms(Args&&... args) {
auto x = std::make_tuple(std::forward<Args>(args)...);
apply(uniforms, [this, &x](auto& uniform) {
using U = std::remove_cv_t<std::remove_reference_t<decltype(uniform)>>;
uniform.set(get_tuple_type<UniformValue<U>>({ {} }, std::forward<decltype(x)>(x)).value);
});
}

private:
std::tuple<color, opacity, matrix> uniforms;
};

} // namespace mbgl
37 changes: 18 additions & 19 deletions src/mbgl/shader/uniform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,48 @@
namespace mbgl {

template <>
void Uniform<GLfloat>::bind(const GLfloat& t) {
MBGL_CHECK_ERROR(glUniform1f(location, t));
void Uniform<GLfloat>::bind() {
MBGL_CHECK_ERROR(glUniform1f(location, current));
}

template <>
void Uniform<GLint>::bind(const GLint& t) {
MBGL_CHECK_ERROR(glUniform1i(location, t));
void Uniform<GLint>::bind() {
MBGL_CHECK_ERROR(glUniform1i(location, current));
}

template <>
void Uniform<std::array<GLfloat, 2>>::bind(const std::array<GLfloat, 2>& t) {
MBGL_CHECK_ERROR(glUniform2fv(location, 1, t.data()));
void Uniform<std::array<GLfloat, 2>>::bind() {
MBGL_CHECK_ERROR(glUniform2fv(location, 1, current.data()));
}

template <>
void Uniform<std::array<GLfloat, 3>>::bind(const std::array<GLfloat, 3>& t) {
MBGL_CHECK_ERROR(glUniform3fv(location, 1, t.data()));
void Uniform<std::array<GLfloat, 3>>::bind() {
MBGL_CHECK_ERROR(glUniform3fv(location, 1, current.data()));
}

template <>
void Uniform<std::array<GLfloat, 4>>::bind(const std::array<GLfloat, 4>& t) {
MBGL_CHECK_ERROR(glUniform4fv(location, 1, t.data()));
void Uniform<std::array<GLfloat, 4>>::bind() {
MBGL_CHECK_ERROR(glUniform4fv(location, 1, current.data()));
}

template <>
void Uniform<Color>::bind(const Color& t) {
std::array<GLfloat, 4> a = {{ t.r, t.g, t.b, t.a }};
MBGL_CHECK_ERROR(glUniform4fv(location, 1, a.data()));
void Uniform<Color>::bind() {
MBGL_CHECK_ERROR(glUniform4f(location, current.r, current.g, current.b, current.a));
}

template <>
void UniformMatrix<2>::bind(const std::array<GLfloat, 4>& t) {
MBGL_CHECK_ERROR(glUniformMatrix2fv(location, 1, GL_FALSE, t.data()));
void UniformMatrix<2>::bind() {
MBGL_CHECK_ERROR(glUniformMatrix2fv(location, 1, GL_FALSE, current.data()));
}

template <>
void UniformMatrix<3>::bind(const std::array<GLfloat, 9>& t) {
MBGL_CHECK_ERROR(glUniformMatrix3fv(location, 1, GL_FALSE, t.data()));
void UniformMatrix<3>::bind() {
MBGL_CHECK_ERROR(glUniformMatrix3fv(location, 1, GL_FALSE, current.data()));
}

template <>
void UniformMatrix<4>::bind(const std::array<GLfloat, 16>& t) {
MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, t.data()));
void UniformMatrix<4>::bind() {
MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, current.data()));
}

// Add more as needed.
Expand Down
50 changes: 34 additions & 16 deletions src/mbgl/shader/uniform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,48 @@ namespace mbgl {
template <typename T>
class Uniform {
public:
Uniform(const GLchar* name, const Shader& shader) : current() {
location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.getID(), name));
using Type = T;
using ArgType = T;

Uniform(const GLchar* name_, const Shader& shader) : name(name_), current() {
location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.getID(), name));
}

void operator=(const T& t) {
Uniform(const GLchar* name_) : name(name_), current() {
}

void operator=(const ArgType& t) {
if (current != t) {
current = t;
bind(t);
bind();
}
}

private:
void bind(const T&);
void set(const ArgType& t) {
operator=(t);
}

void bind();

T current;
GLint location;
const char* const name;
Type current;
GLint location = -1;
};

template <size_t C, size_t R = C>
class UniformMatrix {
public:
typedef std::array<float, C*R> T;
using Type = std::array<float, C*R>;
using ArgType = std::array<double, C*R>;

UniformMatrix(const GLchar* name, const Shader& shader) : current() {
UniformMatrix(const GLchar* name_, const Shader& shader) : name(name_), current() {
location = MBGL_CHECK_ERROR(glGetUniformLocation(shader.getID(), name));
}

void operator=(const std::array<double, C*R>& t) {
UniformMatrix(const GLchar* name_) : name(name_), current() {
}

void operator=(const ArgType& t) {
bool dirty = false;
for (unsigned int i = 0; i < C*R; i++) {
if (current[i] != t[i]) {
Expand All @@ -46,15 +60,19 @@ class UniformMatrix {
}
}
if (dirty) {
bind(current);
bind();
}
}

private:
void bind(const T&);
void set(const ArgType& t) {
operator=(t);
}

void bind();

T current;
GLint location;
const char* const name;
Type current;
GLint location = -1;
};

} // namespace mbgl

0 comments on commit 119100b

Please sign in to comment.