diff options
Diffstat (limited to 'src/mbgl/gl/value.hpp')
-rw-r--r-- | src/mbgl/gl/value.hpp | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp new file mode 100644 index 0000000000..6436228ed1 --- /dev/null +++ b/src/mbgl/gl/value.hpp @@ -0,0 +1,382 @@ +#pragma once + +#include <cstdint> +#include <tuple> +#include <array> +#include <cassert> + +#include <mbgl/gl/gl.hpp> +#include <mbgl/util/color.hpp> + +namespace mbgl { +namespace gl { +namespace value { + +struct ClearDepth { + using Type = GLfloat; + static const constexpr Type Default = 1; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearDepth(value)); + } + static Type Get() { + Type clearDepth; + MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth)); + return clearDepth; + } +}; + +struct ClearColor { + using Type = Color; + static const constexpr Type Default = { 0, 0, 0, 0 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearColor(value.r, value.g, value.b, value.a)); + } + static Type Get() { + GLfloat floats[4]; + MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_CLEAR_VALUE, floats)); + return { floats[0], floats[1], floats[2], floats[3] }; + } +}; + +struct ClearStencil { + using Type = GLint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearStencil(value)); + } + static Type Get() { + Type clearStencil; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil)); + return clearStencil; + } +}; + +struct StencilMask { + using Type = GLuint; + static const constexpr Type Default = ~0u; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilMask(value)); + } + static Type Get() { + GLint stencilMask; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask)); + return stencilMask; + } +}; + +struct DepthMask { + using Type = GLboolean; + static const constexpr Type Default = GL_TRUE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthMask(value)); + } + static Type Get() { + Type depthMask; + MBGL_CHECK_ERROR(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask)); + return depthMask; + } +}; + +struct ColorMask { + struct Type { bool r, g, b, a; }; + static const constexpr Type Default = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glColorMask(value.r, value.g, value.b, value.a)); + } + static Type Get() { + GLboolean bools[4]; + MBGL_CHECK_ERROR(glGetBooleanv(GL_COLOR_WRITEMASK, bools)); + return { static_cast<bool>(bools[0]), static_cast<bool>(bools[1]), + static_cast<bool>(bools[2]), static_cast<bool>(bools[3]) }; + } +}; + +constexpr bool operator!=(const ColorMask::Type& a, const ColorMask::Type& b) { + return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a; +} + +struct StencilFunc { + struct Type { GLenum func; GLint ref; GLuint mask; }; + static const constexpr Type Default = { GL_ALWAYS, 0, ~0u }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilFunc(value.func, value.ref, value.mask)); + } + static Type Get() { + GLint func, ref, mask; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FUNC, &func)); + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_REF, &ref)); + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask)); + return { static_cast<GLenum>(func), ref, static_cast<GLuint>(mask) }; + } +}; + +constexpr bool operator!=(const StencilFunc::Type& a, const StencilFunc::Type& b) { + return a.func != b.func || a.ref != b.ref || a.mask != b.mask; +} + +struct StencilTest { + using Type = bool; + static const constexpr Type Default = GL_FALSE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST)); + } + static Type Get() { + Type stencilTest; + MBGL_CHECK_ERROR(stencilTest = glIsEnabled(GL_STENCIL_TEST)); + return stencilTest; + } +}; + +struct StencilOp { + struct Type { GLenum sfail, dpfail, dppass; }; + static const constexpr Type Default = { GL_KEEP, GL_KEEP, GL_REPLACE }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilOp(value.sfail, value.dpfail, value.dppass)); + } + static Type Get() { + GLint sfail, dpfail, dppass; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FAIL, &sfail)); + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &dpfail)); + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &dppass)); + return { static_cast<GLenum>(sfail), static_cast<GLenum>(dpfail), static_cast<GLuint>(dppass) }; + } +}; + +constexpr bool operator!=(const StencilOp::Type& a, const StencilOp::Type& b) { + return a.sfail != b.sfail || a.dpfail != b.dpfail || a.dppass != b.dppass; +} + +struct DepthRange { + struct Type { GLfloat near, far; }; + static const constexpr Type Default = { 0, 1 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthRange(value.near, value.far)); + } + static Type Get() { + GLfloat floats[2]; + MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats)); + return { floats[0], floats[1] }; + } +}; + +constexpr bool operator!=(const DepthRange::Type& a, const DepthRange::Type& b) { + return a.near != b.near || a.far != b.far; +} + +struct DepthTest { + using Type = bool; + static const constexpr Type Default = GL_FALSE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST)); + } + static Type Get() { + Type depthTest; + MBGL_CHECK_ERROR(depthTest = glIsEnabled(GL_DEPTH_TEST)); + return depthTest; + } +}; + +struct DepthFunc { + using Type = GLenum; + static const constexpr Type Default = GL_LEQUAL; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthFunc(value)); + } + static Type Get() { + GLint depthFunc; + MBGL_CHECK_ERROR(glGetIntegerv(GL_DEPTH_FUNC, &depthFunc)); + return depthFunc; + } +}; + +struct Blend { + using Type = bool; + static const constexpr Type Default = GL_TRUE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_BLEND) : glDisable(GL_BLEND)); + } + static Type Get() { + Type blend; + MBGL_CHECK_ERROR(blend = glIsEnabled(GL_BLEND)); + return blend; + } +}; + +struct BlendFunc { + struct Type { GLenum sfactor, dfactor; }; + static const constexpr Type Default = { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBlendFunc(value.sfactor, value.dfactor)); + } + static Type Get() { + GLint sfactor, dfactor; + MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_SRC_ALPHA, &sfactor)); + MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_DST_ALPHA, &dfactor)); + return { static_cast<GLenum>(sfactor), static_cast<GLenum>(dfactor) }; + } +}; + +constexpr bool operator!=(const BlendFunc::Type& a, const BlendFunc::Type& b) { + return a.sfactor != b.sfactor || a.dfactor != b.dfactor; +} + +struct BlendColor { + using Type = Color; + static const constexpr Type Default = { 0, 0, 0, 0 }; + inline static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBlendColor(value.r, value.g, value.b, value.a)); + } + inline static Type Get() { + GLfloat floats[4]; + MBGL_CHECK_ERROR(glGetFloatv(GL_BLEND_COLOR, floats)); + return { floats[0], floats[1], floats[2], floats[3] }; + } +}; + +struct Program { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glUseProgram(value)); + } + static Type Get() { + GLint program; + MBGL_CHECK_ERROR(glGetIntegerv(GL_CURRENT_PROGRAM, &program)); + return program; + } +}; + +struct LineWidth { + using Type = GLfloat; + static const constexpr Type Default = 1; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glLineWidth(value)); + } + static Type Get() { + Type lineWidth; + MBGL_CHECK_ERROR(glGetFloatv(GL_LINE_WIDTH, &lineWidth)); + return lineWidth; + } +}; + +struct ActiveTexture { + using Type = uint8_t; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + value)); + } + static Type Get() { + GLint activeTexture; + MBGL_CHECK_ERROR(glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture)); + return activeTexture - GL_TEXTURE0; + } +}; + +struct BindFramebuffer { + using Type = GLint; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, value)); + } + static Type Get() { + Type activeFBO; + MBGL_CHECK_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &activeFBO)); + return activeFBO; + } +}; + +struct Viewport { + using Type = std::array<GLint, 4>; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glViewport(value[0], value[1], value[2], value[3])); + } + static Type Get() { + Type pos; + MBGL_CHECK_ERROR(glGetIntegerv(GL_VIEWPORT, pos.data())); + return pos; + } +}; + + +#ifndef GL_ES_VERSION_2_0 + +struct PixelZoom { + struct Type { GLfloat xfactor; GLfloat yfactor; }; + static const constexpr Type Default = { 1, 1 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glPixelZoom(value.xfactor, value.yfactor)); + } + static Type Get() { + Type value; + MBGL_CHECK_ERROR(glGetFloatv(GL_ZOOM_X, &value.xfactor)); + MBGL_CHECK_ERROR(glGetFloatv(GL_ZOOM_Y, &value.yfactor)); + return value; + } +}; + +constexpr bool operator!=(const PixelZoom::Type& a, const PixelZoom::Type& b) { + return a.xfactor != b.xfactor || a.yfactor != b.yfactor; +} + +struct RasterPos { + using Type = std::array<GLdouble, 4>; + static const constexpr Type Default = {{ 0, 0, 0, 0 }}; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glRasterPos4d(value[0], value[1], value[2], value[3])); + } + static Type Get() { + Type pos; + MBGL_CHECK_ERROR(glGetDoublev(GL_CURRENT_RASTER_POSITION, pos.data())); + return pos; + } +}; + +#endif // GL_ES_VERSION_2_0 + +struct BindTexture { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, value)); + } + static Type Get() { + GLint texture; + MBGL_CHECK_ERROR(glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture)); + return texture; + } +}; + +template <GLenum target> +struct BindBuffer { + static_assert(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER, + "target must be one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER"); + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindBuffer(target, value)); + } + static Type Get() { + GLint binding; + MBGL_CHECK_ERROR(glGetIntegerv(target == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING + : GL_ELEMENT_ARRAY_BUFFER_BINDING, + &binding)); + return binding; + } +}; + +template <GLenum target> +const typename BindBuffer<target>::Type BindBuffer<target>::Default; + +struct BindVAO { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + if (gl::BindVertexArray) { + MBGL_CHECK_ERROR(gl::BindVertexArray(value)); + } + } +}; + + +} // namespace value +} // namespace gl +} // namespace mbgl |