[core] make vertex descriptors constexpr

This commit is contained in:
Konstantin Käfer
2019-03-04 13:09:51 +01:00
parent d5816b6db2
commit 2f646af255
9 changed files with 315 additions and 157 deletions

View File

@@ -1,9 +1,11 @@
#pragma once
#include <mbgl/gfx/types.hpp>
#include <mbgl/util/type_list.hpp>
#include <mbgl/util/indexed_tuple.hpp>
#include <array>
#include <type_traits>
#include <cstddef>
#define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \
@@ -14,17 +16,69 @@
} \
}
#define MBGL_VERTEX_ALIGN __attribute__((aligned(4)))
namespace mbgl {
namespace gfx {
namespace {
template <typename, std::size_t> struct AttributeDataTypeOf;
template <> struct AttributeDataTypeOf<int8_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Byte> {};
template <> struct AttributeDataTypeOf<int8_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Byte2> {};
template <> struct AttributeDataTypeOf<int8_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Byte3> {};
template <> struct AttributeDataTypeOf<int8_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Byte4> {};
template <> struct AttributeDataTypeOf<uint8_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UByte> {};
template <> struct AttributeDataTypeOf<uint8_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UByte2> {};
template <> struct AttributeDataTypeOf<uint8_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UByte3> {};
template <> struct AttributeDataTypeOf<uint8_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UByte4> {};
template <> struct AttributeDataTypeOf<int16_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Short> {};
template <> struct AttributeDataTypeOf<int16_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Short2> {};
template <> struct AttributeDataTypeOf<int16_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Short3> {};
template <> struct AttributeDataTypeOf<int16_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Short4> {};
template <> struct AttributeDataTypeOf<uint16_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UShort> {};
template <> struct AttributeDataTypeOf<uint16_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UShort2> {};
template <> struct AttributeDataTypeOf<uint16_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UShort3> {};
template <> struct AttributeDataTypeOf<uint16_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UShort4> {};
template <> struct AttributeDataTypeOf<int32_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Int> {};
template <> struct AttributeDataTypeOf<int32_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Int2> {};
template <> struct AttributeDataTypeOf<int32_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Int3> {};
template <> struct AttributeDataTypeOf<int32_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Int4> {};
template <> struct AttributeDataTypeOf<uint32_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UInt> {};
template <> struct AttributeDataTypeOf<uint32_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UInt2> {};
template <> struct AttributeDataTypeOf<uint32_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UInt3> {};
template <> struct AttributeDataTypeOf<uint32_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UInt4> {};
template <> struct AttributeDataTypeOf<float, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Float> {};
template <> struct AttributeDataTypeOf<float, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Float2> {};
template <> struct AttributeDataTypeOf<float, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Float3> {};
template <> struct AttributeDataTypeOf<float, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Float4> {};
} // namespace
template <typename T, std::size_t N>
class AttributeType {
public:
using ValueType = T;
using ElementType = T;
static constexpr AttributeDataType DataType = AttributeDataTypeOf<T, N>::value;
static constexpr size_t Dimensions = N;
using Value = std::array<T, N>;
};
struct AttributeDescriptor {
AttributeDataType dataType;
uint8_t offset;
};
inline bool operator==(const AttributeDescriptor& lhs, const AttributeDescriptor& rhs) {
return lhs.dataType == rhs.dataType && lhs.offset == rhs.offset;
}
struct VertexDescriptor {
uint8_t stride;
uint8_t count;
AttributeDescriptor attributes[5];
};
// Attribute binding requires member offsets. The only standard way to
// obtain an offset is the offsetof macro. The offsetof macro has defined
// behavior only for standard layout types. That rules out std::tuple and
@@ -35,114 +89,138 @@ public:
namespace detail {
template <class...>
class Vertex;
struct Vertex;
template <>
class Vertex<> {
public:
using VertexType = Vertex<>;
template <class A1>
struct Vertex<A1> {
using Type = Vertex<A1>;
typename A1::Value a1;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2>
struct Vertex<A1, A2> {
using Type = Vertex<A1, A2>;
typename A1::Value a1;
typename A2::Value a2;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3>
struct Vertex<A1, A2, A3> {
using Type = Vertex<A1, A2, A3>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3, class A4>
struct Vertex<A1, A2, A3, A4> {
using Type = Vertex<A1, A2, A3, A4>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
typename A4::Value a4;
} MBGL_VERTEX_ALIGN;
template <class A1, class A2, class A3, class A4, class A5>
struct Vertex<A1, A2, A3, A4, A5> {
using Type = Vertex<A1, A2, A3, A4, A5>;
typename A1::Value a1;
typename A2::Value a2;
typename A3::Value a3;
typename A4::Value a4;
typename A5::Value a5;
} MBGL_VERTEX_ALIGN;
template <class>
struct Descriptor;
template <class A1>
struct Descriptor<Vertex<A1>> {
using Type = Vertex<A1>;
static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout");
static constexpr const VertexDescriptor data = { sizeof(Type), 1, {
{ A1::DataType, offsetof(Type, a1) },
}};
};
template <class A1>
class Vertex<A1> {
public:
A1 a1;
constexpr const VertexDescriptor Descriptor<Vertex<A1>>::data;
using VertexType = Vertex<A1>;
static const std::size_t attributeOffsets[1];
template <class A1, class A2>
struct Descriptor<Vertex<A1, A2>> {
using Type = Vertex<A1, A2>;
static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout");
static constexpr const VertexDescriptor data = { sizeof(Type), 2, {
{ A1::DataType, offsetof(Type, a1) },
{ A2::DataType, offsetof(Type, a2) },
}};
};
template <class A1, class A2>
class Vertex<A1, A2> {
public:
A1 a1;
A2 a2;
constexpr const VertexDescriptor Descriptor<Vertex<A1, A2>>::data;
using VertexType = Vertex<A1, A2>;
static const std::size_t attributeOffsets[2];
template <class A1, class A2, class A3>
struct Descriptor<Vertex<A1, A2, A3>> {
using Type = Vertex<A1, A2, A3>;
static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout");
static constexpr const VertexDescriptor data = { sizeof(Type), 3, {
{ A1::DataType, offsetof(Type, a1) },
{ A2::DataType, offsetof(Type, a2) },
{ A3::DataType, offsetof(Type, a3) },
}};
};
template <class A1, class A2, class A3>
class Vertex<A1, A2, A3> {
public:
A1 a1;
A2 a2;
A3 a3;
constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3>>::data;
using VertexType = Vertex<A1, A2, A3>;
static const std::size_t attributeOffsets[3];
template <class A1, class A2, class A3, class A4>
struct Descriptor<Vertex<A1, A2, A3, A4>> {
using Type = Vertex<A1, A2, A3, A4>;
static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout");
static constexpr const VertexDescriptor data = { sizeof(Type), 4, {
{ A1::DataType, offsetof(Type, a1) },
{ A2::DataType, offsetof(Type, a2) },
{ A3::DataType, offsetof(Type, a3) },
{ A4::DataType, offsetof(Type, a4) },
}};
};
template <class A1, class A2, class A3, class A4>
class Vertex<A1, A2, A3, A4> {
public:
A1 a1;
A2 a2;
A3 a3;
A4 a4;
constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4>>::data;
using VertexType = Vertex<A1, A2, A3, A4>;
static const std::size_t attributeOffsets[4];
template <class A1, class A2, class A3, class A4, class A5>
struct Descriptor<Vertex<A1, A2, A3, A4, A5>> {
using Type = Vertex<A1, A2, A3, A4, A5>;
static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes");
static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout");
static constexpr const VertexDescriptor data = { sizeof(Type), 5, {
{ A1::DataType, offsetof(Type, a1) },
{ A2::DataType, offsetof(Type, a2) },
{ A3::DataType, offsetof(Type, a3) },
{ A4::DataType, offsetof(Type, a4) },
{ A5::DataType, offsetof(Type, a5) },
}};
};
template <class A1, class A2, class A3, class A4, class A5>
class Vertex<A1, A2, A3, A4, A5> {
public:
A1 a1;
A2 a2;
A3 a3;
A4 a4;
A5 a5;
using VertexType = Vertex<A1, A2, A3, A4, A5>;
static const std::size_t attributeOffsets[5];
};
template <class A1>
const std::size_t Vertex<A1>::attributeOffsets[1] = {
offsetof(VertexType, a1)
};
template <class A1, class A2>
const std::size_t Vertex<A1, A2>::attributeOffsets[2] = {
offsetof(VertexType, a1),
offsetof(VertexType, a2)
};
template <class A1, class A2, class A3>
const std::size_t Vertex<A1, A2, A3>::attributeOffsets[3] = {
offsetof(VertexType, a1),
offsetof(VertexType, a2),
offsetof(VertexType, a3)
};
template <class A1, class A2, class A3, class A4>
const std::size_t Vertex<A1, A2, A3, A4>::attributeOffsets[4] = {
offsetof(VertexType, a1),
offsetof(VertexType, a2),
offsetof(VertexType, a3),
offsetof(VertexType, a4)
};
template <class A1, class A2, class A3, class A4, class A5>
const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {
offsetof(VertexType, a1),
offsetof(VertexType, a2),
offsetof(VertexType, a3),
offsetof(VertexType, a4),
offsetof(VertexType, a5)
};
constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4, A5>>::data;
template <class... As>
class Vertex<TypeList<As...>> {
public:
using VertexType = Vertex<typename As::Type::Value...>;
struct Vertex<TypeList<As...>> {
using Type = Vertex<typename As::Type...>;
};
} // namespace detail
template <class A>
using Vertex = typename detail::Vertex<A>::VertexType;
using Vertex = typename detail::Vertex<A>::Type;
template <class V>
using VertexDescriptorOf = detail::Descriptor<V>;
} // namespace gfx
} // namespace mbgl

View File

@@ -15,6 +15,45 @@ enum class PrimitiveType : uint8_t {
TriangleFan,
};
enum class AttributeDataType : uint8_t {
Byte,
Byte2,
Byte3,
Byte4,
UByte,
UByte2,
UByte3,
UByte4,
Short,
Short2,
Short3,
Short4,
UShort,
UShort2,
UShort3,
UShort4,
Int,
Int2,
Int3,
Int4,
UInt,
UInt2,
UInt3,
UInt4,
Float,
Float2,
Float3,
Float4,
Invalid = 255,
};
enum class ColorBlendEquationType : uint8_t {
Add,
Subtract,

View File

@@ -18,29 +18,17 @@
namespace mbgl {
namespace gl {
template <class> struct DataTypeOf;
template <> struct DataTypeOf< int8_t> : std::integral_constant<DataType, DataType::Byte> {};
template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {};
template <> struct DataTypeOf< int16_t> : std::integral_constant<DataType, DataType::Short> {};
template <> struct DataTypeOf<uint16_t> : std::integral_constant<DataType, DataType::UnsignedShort> {};
template <> struct DataTypeOf< int32_t> : std::integral_constant<DataType, DataType::Integer> {};
template <> struct DataTypeOf<uint32_t> : std::integral_constant<DataType, DataType::UnsignedInteger> {};
template <> struct DataTypeOf<float> : std::integral_constant<DataType, DataType::Float> {};
class AttributeBinding {
public:
DataType attributeType;
uint8_t attributeSize;
uint32_t attributeOffset;
gfx::AttributeDescriptor attribute;
uint8_t vertexStride;
BufferID vertexBuffer;
uint32_t vertexSize;
uint32_t vertexOffset;
friend bool operator==(const AttributeBinding& lhs,
const AttributeBinding& rhs) {
return std::tie(lhs.attributeType, lhs.attributeSize, lhs.attributeOffset, lhs.vertexBuffer, lhs.vertexSize, lhs.vertexOffset)
== std::tie(rhs.attributeType, rhs.attributeSize, rhs.attributeOffset, rhs.vertexBuffer, rhs.vertexSize, rhs.vertexOffset);
return std::tie(lhs.attribute, lhs.vertexStride, lhs.vertexBuffer, lhs.vertexOffset)
== std::tie(rhs.attribute, rhs.vertexStride, rhs.vertexBuffer, rhs.vertexOffset);
}
};
@@ -51,21 +39,13 @@ using AttributeBindingArray = std::vector<optional<AttributeBinding>>;
override the number of components available in the buffer for each vertex. Thus,
a buffer with only one float for each vertex can be bound to a `vec2` attribute
*/
template <class AttributeType, class Vertex>
AttributeBinding attributeBinding(const VertexBuffer<Vertex>& buffer,
std::size_t attributeIndex,
std::size_t attributeSize = AttributeType::Dimensions) {
static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout");
assert(attributeSize >= 1);
assert(attributeSize <= 4);
assert(Vertex::attributeOffsets[attributeIndex] <= std::numeric_limits<uint32_t>::max());
static_assert(sizeof(Vertex) <= std::numeric_limits<uint32_t>::max(), "vertex too large");
return AttributeBinding {
DataTypeOf<typename AttributeType::ValueType>::value,
static_cast<uint8_t>(attributeSize),
static_cast<uint32_t>(Vertex::attributeOffsets[attributeIndex]),
template <std::size_t I, typename Vertex>
AttributeBinding attributeBinding(const VertexBuffer<Vertex>& buffer) {
static_assert(I < gfx::VertexDescriptorOf<Vertex>::data.count, "vertex attribute index out of range");
return {
gfx::VertexDescriptorOf<Vertex>::data.attributes[I],
gfx::VertexDescriptorOf<Vertex>::data.stride,
buffer.buffer,
static_cast<uint32_t>(sizeof(Vertex)),
0,
};
}
@@ -127,7 +107,7 @@ public:
}
static Bindings bindings(const VertexBuffer<gfx::Vertex<Types>>& buffer) {
return Bindings { attributeBinding<typename As::Type>(buffer, TypeIndex<As, As...>::value)... };
return Bindings { attributeBinding<TypeIndex<As, As...>::value>(buffer)... };
}
static Bindings offsetBindings(const Bindings& bindings, std::size_t vertexOffset) {

View File

@@ -17,14 +17,6 @@ using namespace platform;
static_assert(underlying_type(ShaderType::Vertex) == GL_VERTEX_SHADER, "OpenGL type mismatch");
static_assert(underlying_type(ShaderType::Fragment) == GL_FRAGMENT_SHADER, "OpenGL type mismatch");
static_assert(underlying_type(DataType::Byte) == GL_BYTE, "OpenGL type mismatch");
static_assert(underlying_type(DataType::UnsignedByte) == GL_UNSIGNED_BYTE, "OpenGL type mismatch");
static_assert(underlying_type(DataType::Short) == GL_SHORT, "OpenGL type mismatch");
static_assert(underlying_type(DataType::UnsignedShort) == GL_UNSIGNED_SHORT, "OpenGL type mismatch");
static_assert(underlying_type(DataType::Integer) == GL_INT, "OpenGL type mismatch");
static_assert(underlying_type(DataType::UnsignedInteger) == GL_UNSIGNED_INT, "OpenGL type mismatch");
static_assert(underlying_type(DataType::Float) == GL_FLOAT, "OpenGL type mismatch");
#if not MBGL_USE_GLES2
static_assert(underlying_type(RenderbufferType::RGBA) == GL_RGBA8, "OpenGL type mismatch");
#else

View File

@@ -32,16 +32,6 @@ enum class ShaderType : uint32_t {
Fragment = 0x8B30
};
enum class DataType : uint16_t {
Byte = 0x1400,
UnsignedByte = 0x1401,
Short = 0x1402,
UnsignedShort = 0x1403,
Integer = 0x1404,
UnsignedInteger = 0x1405,
Float = 0x1406
};
enum class RenderbufferType : uint32_t {
RGBA = 0x8058,
DepthStencil = 0x88F0,

View File

@@ -398,17 +398,102 @@ BindVertexArray::Type BindVertexArray::Get(const Context& context) {
const optional<AttributeBinding> VertexAttribute::Default {};
namespace {
GLenum vertexType(const gfx::AttributeDataType type) {
switch (type) {
case gfx::AttributeDataType::Byte:
case gfx::AttributeDataType::Byte2:
case gfx::AttributeDataType::Byte3:
case gfx::AttributeDataType::Byte4:
return GL_BYTE;
case gfx::AttributeDataType::UByte:
case gfx::AttributeDataType::UByte2:
case gfx::AttributeDataType::UByte3:
case gfx::AttributeDataType::UByte4:
return GL_UNSIGNED_BYTE;
case gfx::AttributeDataType::Short:
case gfx::AttributeDataType::Short2:
case gfx::AttributeDataType::Short3:
case gfx::AttributeDataType::Short4:
return GL_SHORT;
case gfx::AttributeDataType::UShort:
case gfx::AttributeDataType::UShort2:
case gfx::AttributeDataType::UShort3:
case gfx::AttributeDataType::UShort4:
return GL_UNSIGNED_SHORT;
case gfx::AttributeDataType::Int:
case gfx::AttributeDataType::Int2:
case gfx::AttributeDataType::Int3:
case gfx::AttributeDataType::Int4:
return GL_INT;
case gfx::AttributeDataType::UInt:
case gfx::AttributeDataType::UInt2:
case gfx::AttributeDataType::UInt3:
case gfx::AttributeDataType::UInt4:
return GL_UNSIGNED_INT;
case gfx::AttributeDataType::Float:
case gfx::AttributeDataType::Float2:
case gfx::AttributeDataType::Float3:
case gfx::AttributeDataType::Float4:
return GL_FLOAT;
default:
return GL_FLOAT;
}
}
GLint components(const gfx::AttributeDataType type) {
switch (type) {
case gfx::AttributeDataType::Byte:
case gfx::AttributeDataType::UByte:
case gfx::AttributeDataType::Short:
case gfx::AttributeDataType::UShort:
case gfx::AttributeDataType::Int:
case gfx::AttributeDataType::UInt:
case gfx::AttributeDataType::Float:
return 1;
case gfx::AttributeDataType::Byte2:
case gfx::AttributeDataType::UByte2:
case gfx::AttributeDataType::Short2:
case gfx::AttributeDataType::UShort2:
case gfx::AttributeDataType::Int2:
case gfx::AttributeDataType::UInt2:
case gfx::AttributeDataType::Float2:
return 2;
case gfx::AttributeDataType::Byte3:
case gfx::AttributeDataType::UByte3:
case gfx::AttributeDataType::Short3:
case gfx::AttributeDataType::UShort3:
case gfx::AttributeDataType::Int3:
case gfx::AttributeDataType::UInt3:
case gfx::AttributeDataType::Float3:
return 3;
case gfx::AttributeDataType::Byte4:
case gfx::AttributeDataType::UByte4:
case gfx::AttributeDataType::Short4:
case gfx::AttributeDataType::UShort4:
case gfx::AttributeDataType::Int4:
case gfx::AttributeDataType::UInt4:
case gfx::AttributeDataType::Float4:
return 4;
default:
return 0;
}
}
} // namespace
void VertexAttribute::Set(const optional<AttributeBinding>& binding, Context& context, AttributeLocation location) {
if (binding) {
context.vertexBuffer = binding->vertexBuffer;
MBGL_CHECK_ERROR(glEnableVertexAttribArray(location));
MBGL_CHECK_ERROR(glVertexAttribPointer(
location,
static_cast<GLint>(binding->attributeSize),
static_cast<GLenum>(binding->attributeType),
components(binding->attribute.dataType),
vertexType(binding->attribute.dataType),
static_cast<GLboolean>(false),
static_cast<GLsizei>(binding->vertexSize),
reinterpret_cast<GLvoid*>(binding->attributeOffset + (binding->vertexSize * binding->vertexOffset))));
static_cast<GLsizei>(binding->vertexStride),
reinterpret_cast<GLvoid*>(binding->attribute.offset + (binding->vertexStride * binding->vertexOffset))));
} else {
MBGL_CHECK_ERROR(glDisableVertexAttribArray(location));
}

View File

@@ -2,17 +2,12 @@
#include <mbgl/gl/object.hpp>
#include <vector>
namespace mbgl {
namespace gl {
template <class V>
class VertexBuffer {
public:
using Vertex = V;
static constexpr std::size_t vertexSize = sizeof(Vertex);
std::size_t vertexCount;
UniqueBuffer buffer;
};

View File

@@ -2,6 +2,6 @@
namespace mbgl {
static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 14, "expected CollisionBoxVertex size");
static_assert(sizeof(CollisionBoxProgram::LayoutVertex) == 16, "expected CollisionBoxVertex size");
} // namespace mbgl

View File

@@ -25,7 +25,7 @@ namespace mbgl {
being zoomed.
*/
template <class AttributeType>
using ZoomInterpolatedAttributeType = gfx::AttributeType<typename AttributeType::ValueType, AttributeType::Dimensions * 2>;
using ZoomInterpolatedAttributeType = gfx::AttributeType<typename AttributeType::ElementType, AttributeType::Dimensions * 2>;
inline std::array<float, 1> attributeValue(float v) {
return {{ v }};
@@ -174,8 +174,7 @@ template <class T, class A>
class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, T, PossiblyEvaluatedPropertyValue<T>, A> {
public:
using BaseAttributeType = A;
using BaseAttributeValue = typename A::Value;
using BaseVertex = gfx::Vertex<BaseAttributeValue>;
using BaseVertex = gfx::Vertex<BaseAttributeType>;
using AttributeType = ZoomInterpolatedAttributeType<A>;
@@ -201,7 +200,9 @@ public:
if (currentValue.isConstant()) {
return {};
} else {
return std::tuple<optional<gl::AttributeBinding>> { gl::attributeBinding<AttributeType>(*vertexBuffer, 0, BaseAttributeType::Dimensions) };
return std::tuple<optional<gl::AttributeBinding>>{
gl::attributeBinding<0>(*vertexBuffer)
};
}
}
@@ -231,7 +232,7 @@ public:
using AttributeType = ZoomInterpolatedAttributeType<A>;
using AttributeValue = typename AttributeType::Value;
using Vertex = gfx::Vertex<AttributeValue>;
using Vertex = gfx::Vertex<AttributeType>;
CompositeFunctionPaintPropertyBinder(style::PropertyExpression<T> expression_, float zoom, T defaultValue_)
: expression(std::move(expression_)),
@@ -259,7 +260,9 @@ public:
if (currentValue.isConstant()) {
return {};
} else {
return std::tuple<optional<gl::AttributeBinding>> { gl::attributeBinding<AttributeType>(*vertexBuffer, 0) };
return std::tuple<optional<gl::AttributeBinding>>{
gl::attributeBinding<0>(*vertexBuffer)
};
}
}
@@ -295,13 +298,10 @@ public:
using AttributeType2 = ZoomInterpolatedAttributeType<A2>;
using BaseAttributeType = A1;
using BaseAttributeValue = typename BaseAttributeType::Value;
using BaseAttributeType2 = A2;
using BaseAttributeValue2 = typename BaseAttributeType2::Value;
using Vertex = gfx::Vertex<BaseAttributeValue>;
using Vertex2 = gfx::Vertex<BaseAttributeValue2>;
using Vertex = gfx::Vertex<BaseAttributeType>;
using Vertex2 = gfx::Vertex<BaseAttributeType2>;
CompositeCrossFadedPaintPropertyBinder(style::PropertyExpression<T> expression_, float zoom, T defaultValue_)
: expression(std::move(expression_)),
@@ -354,11 +354,10 @@ public:
if (currentValue.isConstant()) {
return {};
} else {
return std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> {
gl::attributeBinding<AttributeType>(*patternToVertexBuffer, 0, BaseAttributeType::Dimensions),
gl::attributeBinding<AttributeType2>(
crossfade.fromScale == 2 ? *zoomInVertexBuffer : *zoomOutVertexBuffer,
0, BaseAttributeType2::Dimensions) };
return std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>>{
gl::attributeBinding<0>(*patternToVertexBuffer),
gl::attributeBinding<0>(crossfade.fromScale == 2 ? *zoomInVertexBuffer : *zoomOutVertexBuffer)
};
}
}