diff options
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/attribute.cpp | 61 | ||||
-rw-r--r-- | src/mbgl/gl/attribute.hpp | 150 | ||||
-rw-r--r-- | src/mbgl/gl/context.cpp | 31 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 12 | ||||
-rw-r--r-- | src/mbgl/gl/object.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/gl/program.hpp | 26 | ||||
-rw-r--r-- | src/mbgl/gl/segment.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/gl/segment.hpp | 73 | ||||
-rw-r--r-- | src/mbgl/gl/types.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/gl/value.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/gl/value.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/gl/vertex_array.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/gl/vertex_array.hpp | 58 |
14 files changed, 226 insertions, 243 deletions
diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 2f817cdcd8..bb5b2ddc34 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -1,16 +1,14 @@ #include <mbgl/gl/attribute.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/gl/gl.hpp> -#include <cstring> - namespace mbgl { namespace gl { -AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { - assert(location < 8); +void bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) { + if (location >= MAX_ATTRIBUTES) { + throw gl::Error("too many vertex attributes"); + } MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name)); - return location; } std::set<std::string> getActiveAttributes(ProgramID id) { @@ -37,56 +35,5 @@ std::set<std::string> getActiveAttributes(ProgramID id) { return activeAttributes; } -void DisabledAttribute::bind(Context&, AttributeLocation location, std::size_t) const { - MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); -} - -template <class T> DataType DataTypeOf = static_cast<DataType>(0); -template <> DataType DataTypeOf< int8_t> = DataType::Byte; -template <> DataType DataTypeOf<uint8_t> = DataType::UnsignedByte; -template <> DataType DataTypeOf< int16_t> = DataType::Short; -template <> DataType DataTypeOf<uint16_t> = DataType::UnsignedShort; -template <> DataType DataTypeOf< int32_t> = DataType::Integer; -template <> DataType DataTypeOf<uint32_t> = DataType::UnsignedInteger; -template <> DataType DataTypeOf<float> = DataType::Float; - -template <class T, std::size_t N> -void AttributeBinding<T, N>::bind(Context& context, AttributeLocation location, std::size_t vertexOffset) const { - // FillProgram will attempt to bind at location -1 because it includes - // a fill-outline-color paint property but does not use it or have an - // a_outline_color shader attribute - in this case, we have nothing to bind. - if (location == -1) return; - - context.vertexBuffer = vertexBuffer; - MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); - MBGL_CHECK_ERROR(glVertexAttribPointer( - location, - static_cast<GLint>(attributeSize), - static_cast<GLenum>(DataTypeOf<T>), - static_cast<GLboolean>(false), - static_cast<GLsizei>(vertexSize), - reinterpret_cast<GLvoid*>(attributeOffset + (vertexSize * vertexOffset)))); -} - -template class AttributeBinding<uint8_t, 1>; -template class AttributeBinding<uint8_t, 2>; -template class AttributeBinding<uint8_t, 3>; -template class AttributeBinding<uint8_t, 4>; - -template class AttributeBinding<uint16_t, 1>; -template class AttributeBinding<uint16_t, 2>; -template class AttributeBinding<uint16_t, 3>; -template class AttributeBinding<uint16_t, 4>; - -template class AttributeBinding<int16_t, 1>; -template class AttributeBinding<int16_t, 2>; -template class AttributeBinding<int16_t, 3>; -template class AttributeBinding<int16_t, 4>; - -template class AttributeBinding<float, 1>; -template class AttributeBinding<float, 2>; -template class AttributeBinding<float, 3>; -template class AttributeBinding<float, 4>; - } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index f018a1d261..ed4168c21f 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -1,59 +1,51 @@ #pragma once #include <mbgl/gl/types.hpp> -#include <mbgl/gl/segment.hpp> +#include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/util/ignore.hpp> #include <mbgl/util/indexed_tuple.hpp> -#include <mbgl/util/variant.hpp> +#include <mbgl/util/optional.hpp> #include <cstddef> #include <vector> #include <set> #include <functional> +#include <string> +#include <array> namespace mbgl { namespace gl { -class DisabledAttribute { -public: - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; +static constexpr std::size_t MAX_ATTRIBUTES = 8; - friend bool operator==(const DisabledAttribute&, - const DisabledAttribute&) { - return true; - } -}; +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> {}; -template <class T, std::size_t N> class AttributeBinding { public: - AttributeBinding(BufferID vertexBuffer_, - std::size_t vertexSize_, - std::size_t attributeOffset_, - std::size_t attributeSize_ = N) - : vertexBuffer(vertexBuffer_), - vertexSize(vertexSize_), - attributeOffset(attributeOffset_), - attributeSize(attributeSize_) - {} - - void bind(Context&, AttributeLocation, std::size_t vertexOffset) const; + DataType attributeType; + std::size_t attributeSize; + std::size_t attributeOffset; + + BufferID vertexBuffer; + std::size_t vertexSize; + std::size_t vertexOffset; friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) { - return lhs.vertexBuffer == rhs.vertexBuffer - && lhs.vertexSize == rhs.vertexSize - && lhs.attributeOffset == rhs.attributeOffset - && lhs.attributeSize == rhs.attributeSize; + 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); } - -private: - BufferID vertexBuffer; - std::size_t vertexSize; - std::size_t attributeOffset; - std::size_t attributeSize; }; +using AttributeBindingArray = std::array<optional<AttributeBinding>, MAX_ATTRIBUTES>; + /* gl::Attribute<T,N> manages the binding of a vertex buffer to a GL program attribute. - T is the underlying primitive type (exposed as Attribute<T,N>::ValueType) @@ -67,10 +59,7 @@ public: using Value = std::array<T, N>; using Location = AttributeLocation; - - using Binding = variant< - DisabledAttribute, - AttributeBinding<T, N>>; + using Binding = AttributeBinding; /* Create a binding for this attribute. The `attributeSize` parameter may be used to @@ -82,28 +71,24 @@ public: std::size_t attributeIndex, std::size_t attributeSize = N) { static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout"); - return AttributeBinding<T, N> { + return AttributeBinding { + DataTypeOf<T>::value, + attributeSize, + Vertex::attributeOffsets[attributeIndex], buffer.buffer, sizeof(Vertex), - Vertex::attributeOffsets[attributeIndex], - attributeSize + 0, }; } - static void bind(Context& context, - const Location& location, - Binding& oldBinding, - const Binding& newBinding, - std::size_t vertexOffset) { - if (oldBinding == newBinding) { - return; + static optional<Binding> offsetBinding(const optional<Binding>& binding, std::size_t vertexOffset) { + if (binding) { + AttributeBinding result = *binding; + result.vertexOffset = vertexOffset; + return result; + } else { + return binding; } - - Binding::visit(newBinding, [&] (const auto& binding) { - binding.bind(context, location, vertexOffset); - }); - - oldBinding = newBinding; } }; @@ -223,7 +208,7 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = { } // namespace detail -AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name); +void bindAttributeLocation(ProgramID, AttributeLocation, const char * name); std::set<std::string> getActiveAttributes(ProgramID); template <class... As> @@ -232,10 +217,10 @@ public: using Types = TypeList<As...>; using Locations = IndexedTuple< TypeList<As...>, - TypeList<typename As::Type::Location...>>; + TypeList<optional<typename As::Type::Location>...>>; using Bindings = IndexedTuple< TypeList<As...>, - TypeList<typename As::Type::Binding...>>; + TypeList<optional<typename As::Type::Binding>...>>; using NamedLocations = std::vector<std::pair<const std::string, AttributeLocation>>; using Vertex = detail::Vertex<typename As::Type...>; @@ -246,13 +231,17 @@ public: static Locations bindLocations(const ProgramID& id) { std::set<std::string> activeAttributes = getActiveAttributes(id); - AttributeLocation location = -1; - auto bindAndIncrement = [&](const char* name) { - location++; - return bindAttributeLocation(id, location, name); + AttributeLocation location = 0; + auto maybeBindLocation = [&](const char* name) -> optional<AttributeLocation> { + if (activeAttributes.count(name)) { + bindAttributeLocation(id, location, name); + return location++; + } else { + return {}; + } }; - return Locations{ (activeAttributes.count(As::name()) ? bindAndIncrement(As::name()) - : -1)... }; + + return Locations { maybeBindLocation(As::name())... }; } template <class Program> @@ -261,7 +250,17 @@ public: } static NamedLocations getNamedLocations(const Locations& locations) { - return NamedLocations{ { As::name(), locations.template get<As>() }... }; + NamedLocations result; + + auto maybeAddLocation = [&] (const std::string& name, const optional<AttributeLocation>& location) { + if (location) { + result.emplace_back(name, *location); + } + }; + + util::ignore({ (maybeAddLocation(As::name(), locations.template get<As>()), 0)... }); + + return result; } template <class DrawMode> @@ -269,16 +268,23 @@ public: return Bindings { As::Type::binding(buffer, Index<As>)... }; } - static void bind(Context& context, - const Locations& locations, - Bindings& oldBindings, - const Bindings& newBindings, - std::size_t vertexOffset) { - util::ignore({ (As::Type::bind(context, - locations.template get<As>(), - oldBindings.template get<As>(), - newBindings.template get<As>(), - vertexOffset), 0)... }); + static Bindings offsetBindings(const Bindings& bindings, std::size_t vertexOffset) { + return Bindings { As::Type::offsetBinding(bindings.template get<As>(), vertexOffset)... }; + } + + static AttributeBindingArray toBindingArray(const Locations& locations, const Bindings& bindings) { + AttributeBindingArray result; + + auto maybeAddBinding = [&] (const optional<AttributeLocation>& location, + const optional<AttributeBinding>& binding) { + if (location) { + result.at(*location) = binding; + } + }; + + util::ignore({ (maybeAddBinding(locations.template get<As>(), bindings.template get<As>()), 0)... }); + + return result; } }; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 3ab1260d27..2d7354a64e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -177,8 +177,8 @@ UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); UniqueBuffer result { std::move(id), { this } }; - vertexArrayObject = 0; - elementBuffer = result; + bindVertexArray = 0; + globalVertexArrayState.indexBuffer = result; MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); return result; } @@ -229,11 +229,16 @@ optional<std::pair<BinaryProgramFormat, std::string>> Context::getBinaryProgram( } #endif -UniqueVertexArray Context::createVertexArray() { - assert(supportsVertexArrays()); - VertexArrayID id = 0; - MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); - return UniqueVertexArray(std::move(id), { this }); +VertexArray Context::createVertexArray() { + if (supportsVertexArrays()) { + VertexArrayID id = 0; + MBGL_CHECK_ERROR(vertexArray->genVertexArrays(1, &id)); + return { std::make_unique<VertexArrayState>(UniqueVertexArray(std::move(id), { this }), *this) }; + } else { + // On GL implementations which do not support vertex arrays, attribute bindings are global state. + // So return a VertexArray which shares our global state tracking and whose deleter is a no-op. + return { UniqueVertexArrayState(&globalVertexArrayState, [] (VertexArrayState*) {}) }; + } } UniqueFramebuffer Context::createFramebuffer() { @@ -502,8 +507,8 @@ void Context::setDirtyState() { tex.setDirty(); } vertexBuffer.setDirty(); - elementBuffer.setDirty(); - vertexArrayObject.setDirty(); + bindVertexArray.setDirty(); + globalVertexArrayState.setDirty(); } void Context::clear(optional<mbgl::Color> color, @@ -622,8 +627,8 @@ void Context::performCleanup() { for (const auto id : abandonedBuffers) { if (vertexBuffer == id) { vertexBuffer.setDirty(); - } else if (elementBuffer == id) { - elementBuffer.setDirty(); + } else if (globalVertexArrayState.indexBuffer == id) { + globalVertexArrayState.indexBuffer.setDirty(); } } MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); @@ -643,8 +648,8 @@ void Context::performCleanup() { if (!abandonedVertexArrays.empty()) { assert(supportsVertexArrays()); for (const auto id : abandonedVertexArrays) { - if (vertexArrayObject == id) { - vertexArrayObject.setDirty(); + if (bindVertexArray == id) { + bindVertexArray.setDirty(); } } MBGL_CHECK_ERROR(vertexArray->deleteVertexArrays(int(abandonedVertexArrays.size()), diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 56c0618989..8929d24e54 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -9,6 +9,7 @@ #include <mbgl/gl/framebuffer.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/types.hpp> #include <mbgl/gl/draw_mode.hpp> #include <mbgl/gl/depth_mode.hpp> @@ -53,9 +54,7 @@ public: void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createTexture(); - - bool supportsVertexArrays() const; - UniqueVertexArray createVertexArray(); + VertexArray createVertexArray(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; @@ -200,10 +199,11 @@ public: State<value::BindFramebuffer> bindFramebuffer; State<value::Viewport> viewport; std::array<State<value::BindTexture>, 2> texture; - State<value::BindVertexArray, const Context&> vertexArrayObject { *this }; State<value::Program> program; State<value::BindVertexBuffer> vertexBuffer; - State<value::BindElementBuffer> elementBuffer; + + State<value::BindVertexArray, const Context&> bindVertexArray { *this }; + VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }), *this }; #if not MBGL_USE_GLES2 State<value::PixelZoom> pixelZoom; @@ -248,6 +248,8 @@ private: void drawPixels(Size size, const void* data, TextureFormat); #endif // MBGL_USE_GLES2 + bool supportsVertexArrays() const; + friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index e2d476e0c0..2c5f1bca1f 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -33,7 +33,9 @@ void TextureDeleter::operator()(TextureID id) const { void VertexArrayDeleter::operator()(VertexArrayID id) const { assert(context); - context->abandonedVertexArrays.push_back(id); + if (id != 0) { + context->abandonedVertexArrays.push_back(id); + } } void FramebufferDeleter::operator()(FramebufferID id) const { diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index ce2b5a335b..9d8b0a5b04 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -5,6 +5,7 @@ #include <mbgl/gl/context.hpp> #include <mbgl/gl/vertex_buffer.hpp> #include <mbgl/gl/index_buffer.hpp> +#include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/attribute.hpp> #include <mbgl/gl/uniform.hpp> @@ -116,10 +117,12 @@ public: DepthMode depthMode, StencilMode stencilMode, ColorMode colorMode, - UniformValues&& uniformValues, - AttributeBindings&& attributeBindings, + const UniformValues& uniformValues, + VertexArray& vertexArray, + const AttributeBindings& attributeBindings, const IndexBuffer<DrawMode>& indexBuffer, - const SegmentVector<Attributes>& segments) { + std::size_t indexOffset, + std::size_t indexLength) { static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::value, "incompatible draw mode"); context.setDrawMode(drawMode); @@ -129,18 +132,15 @@ public: context.program = program; - Uniforms::bind(uniformsState, std::move(uniformValues)); + Uniforms::bind(uniformsState, uniformValues); - for (const auto& segment : segments) { - segment.bind(context, - indexBuffer.buffer, - attributeLocations, - attributeBindings); + vertexArray.bind(context, + indexBuffer.buffer, + Attributes::toBindingArray(attributeLocations, attributeBindings)); - context.draw(drawMode.primitiveType, - segment.indexOffset, - segment.indexLength); - } + context.draw(drawMode.primitiveType, + indexOffset, + indexLength); } private: diff --git a/src/mbgl/gl/segment.cpp b/src/mbgl/gl/segment.cpp deleted file mode 100644 index aabdc83cd4..0000000000 --- a/src/mbgl/gl/segment.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include <mbgl/gl/segment.hpp> - -namespace mbgl { -namespace gl { - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp deleted file mode 100644 index fe0658bf8e..0000000000 --- a/src/mbgl/gl/segment.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include <mbgl/gl/context.hpp> -#include <mbgl/gl/vertex_buffer.hpp> -#include <mbgl/util/optional.hpp> -#include <mbgl/util/logging.hpp> - -#include <cstddef> -#include <vector> - -namespace mbgl { -namespace gl { - -template <class Attributes> -class Segment { -public: - Segment(std::size_t vertexOffset_, - std::size_t indexOffset_, - std::size_t vertexLength_ = 0, - std::size_t indexLength_ = 0) - : vertexOffset(vertexOffset_), - indexOffset(indexOffset_), - vertexLength(vertexLength_), - indexLength(indexLength_) {} - - const std::size_t vertexOffset; - const std::size_t indexOffset; - - std::size_t vertexLength; - std::size_t indexLength; - - void bind(Context& context, - BufferID indexBuffer_, - const typename Attributes::Locations& attributeLocations, - const typename Attributes::Bindings& attributeBindings_) const { - if (context.supportsVertexArrays()) { - if (!vao) { - vao = context.createVertexArray(); - context.vertexBuffer.setDirty(); - } - context.vertexArrayObject = *vao; - if (indexBuffer != indexBuffer_) { - indexBuffer = indexBuffer_; - context.elementBuffer.setDirty(); - context.elementBuffer = indexBuffer_; - } - } else { - // No VAO support. Force attributes to be rebound. - context.elementBuffer = indexBuffer_; - attributeBindings = {}; - } - - Attributes::bind(context, - attributeLocations, - attributeBindings, - attributeBindings_, - vertexOffset); - } - -private: - mutable optional<UniqueVertexArray> vao; - mutable optional<BufferID> indexBuffer; - mutable typename Attributes::Bindings attributeBindings; -}; - -template <class Attributes> -class SegmentVector : public std::vector<Segment<Attributes>> { -public: - SegmentVector() = default; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 0595419674..c80399016e 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -15,7 +15,7 @@ using VertexArrayID = uint32_t; using FramebufferID = uint32_t; using RenderbufferID = uint32_t; -using AttributeLocation = int32_t; +using AttributeLocation = uint32_t; using UniformLocation = int32_t; using TextureUnit = uint8_t; diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index bb3453b2d8..3cac09c526 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -82,7 +82,7 @@ public: return NamedLocations{ { Us::name(), state.template get<Us>().location }... }; } - static void bind(State& state, Values&& values) { + static void bind(State& state, const Values& values) { util::ignore({ (state.template get<Us>() = values.template get<Us>(), 0)... }); } }; diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp index c081c941f5..10818e8499 100644 --- a/src/mbgl/gl/value.cpp +++ b/src/mbgl/gl/value.cpp @@ -353,6 +353,24 @@ BindVertexArray::Type BindVertexArray::Get(const Context& context) { return binding; } +const optional<AttributeBinding> VertexAttribute::Default {}; + +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), + static_cast<GLboolean>(false), + static_cast<GLsizei>(binding->vertexSize), + reinterpret_cast<GLvoid*>(binding->attributeOffset + (binding->vertexSize * binding->vertexOffset)))); + } else { + MBGL_CHECK_ERROR(glDisableVertexAttribArray(location)); + } +} + #if not MBGL_USE_GLES2 const constexpr PointSize::Type PointSize::Default; diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp index aa5cca6fec..62fe88a2f4 100644 --- a/src/mbgl/gl/value.hpp +++ b/src/mbgl/gl/value.hpp @@ -4,6 +4,7 @@ #include <mbgl/gl/depth_mode.hpp> #include <mbgl/gl/stencil_mode.hpp> #include <mbgl/gl/color_mode.hpp> +#include <mbgl/gl/attribute.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/size.hpp> #include <mbgl/util/range.hpp> @@ -232,6 +233,12 @@ struct BindVertexArray { static Type Get(const Context&); }; +struct VertexAttribute { + using Type = optional<gl::AttributeBinding>; + static const Type Default; + static void Set(const Type&, Context&, AttributeLocation); +}; + #if not MBGL_USE_GLES2 struct PointSize { diff --git a/src/mbgl/gl/vertex_array.cpp b/src/mbgl/gl/vertex_array.cpp new file mode 100644 index 0000000000..68a500ac45 --- /dev/null +++ b/src/mbgl/gl/vertex_array.cpp @@ -0,0 +1,18 @@ +#include <mbgl/gl/vertex_array.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/gl.hpp> + +namespace mbgl { +namespace gl { + +void VertexArray::bind(Context& context, BufferID indexBuffer, const AttributeBindingArray& bindings) { + context.bindVertexArray = state->vertexArray; + state->indexBuffer = indexBuffer; + + for (AttributeLocation location = 0; location < MAX_ATTRIBUTES; ++location) { + state->bindings[location] = bindings[location]; + } +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/vertex_array.hpp b/src/mbgl/gl/vertex_array.hpp new file mode 100644 index 0000000000..9ccf48d9bd --- /dev/null +++ b/src/mbgl/gl/vertex_array.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include <mbgl/gl/object.hpp> +#include <mbgl/gl/attribute.hpp> +#include <mbgl/gl/state.hpp> +#include <mbgl/gl/value.hpp> + +#include <array> +#include <memory> + +namespace mbgl { +namespace gl { + +class Context; + +class VertexArrayState { +public: + VertexArrayState(UniqueVertexArray vertexArray_, Context& context) + : vertexArray(std::move(vertexArray_)), + bindings(makeBindings(context, std::make_index_sequence<MAX_ATTRIBUTES>())) { + } + + void setDirty() { + indexBuffer.setDirty(); + for (auto& binding : bindings) { + binding.setDirty(); + } + } + + UniqueVertexArray vertexArray; + State<value::BindElementBuffer> indexBuffer; + + using AttributeState = State<value::VertexAttribute, Context&, AttributeLocation>; + std::array<AttributeState, MAX_ATTRIBUTES> bindings; + +private: + template <std::size_t... I> + std::array<AttributeState, MAX_ATTRIBUTES> makeBindings(Context& context, std::index_sequence<I...>) { + return {{ AttributeState { context, I }... }}; + } +}; + +using UniqueVertexArrayState = std::unique_ptr<VertexArrayState, std::function<void (VertexArrayState*)>>; + +class VertexArray { +public: + VertexArray(UniqueVertexArrayState state_) + : state(std::move(state_)) { + } + + void bind(Context&, BufferID indexBuffer, const AttributeBindingArray&); + +private: + UniqueVertexArrayState state; +}; + +} // namespace gl +} // namespace mbgl |