[core] make vertex descriptors constexpr
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user