diff --git a/include/mbgl/gfx/drawable.hpp b/include/mbgl/gfx/drawable.hpp index 91f7d6c7e..2f2817f18 100644 --- a/include/mbgl/gfx/drawable.hpp +++ b/include/mbgl/gfx/drawable.hpp @@ -22,8 +22,7 @@ using DrawableTweakerPtr = std::shared_ptr; class Drawable { protected: - Drawable() { - } + Drawable() = default; public: virtual ~Drawable() = default; @@ -41,13 +40,15 @@ public: DrawPriority getDrawPriority() const { return drawPriority; } void setDrawPriority(DrawPriority value) { drawPriority = value; } + /// Get the number of vertexes + std::size_t getVertexCount() const { return getVertexAttributes().getMaxCount(); } + /// Get the vertex attributes that override default values in the shader program virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0; virtual void setVertexAttributes(const gfx::VertexAttributeArray&) = 0; virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0; virtual std::vector& getIndexData() const = 0; - virtual std::vector& getVertexData() const = 0; /// Attach a tweaker to be run on this drawable for each frame void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); } @@ -55,7 +56,7 @@ public: void addTweakers(TIter beg, TIter end) { tweakers.insert(tweakers.end(), beg, end); } /// Get the tweakers attached to this drawable - std::vector getTweakers() const { return tweakers; } + const std::vector& getTweakers() const { return tweakers; } protected: util::SimpleIdentity uniqueID; diff --git a/include/mbgl/gfx/vertex_attribute.hpp b/include/mbgl/gfx/vertex_attribute.hpp index ff018f539..5daedc5e7 100644 --- a/include/mbgl/gfx/vertex_attribute.hpp +++ b/include/mbgl/gfx/vertex_attribute.hpp @@ -39,9 +39,11 @@ public: // Can only be created by VertexAttributeArray implementations protected: - VertexAttribute(int index_, AttributeDataType dataType_, int size_, std::size_t count_) + VertexAttribute(int index_, AttributeDataType dataType_, + int size_, std::size_t count_, std::size_t stride_) : index(index_), size(size_), + stride((int)stride_), dataType(dataType_), items(count_) { } @@ -59,7 +61,9 @@ public: int getIndex() const { return index; } void setIndex(int value) { index = value; } - int getSize() const { return size; } + std::size_t getSize() const { return size; } + + std::size_t getStride() const { return stride; } std::size_t getCount() const { return items.size(); } AttributeDataType getDataType() const { return dataType; } @@ -69,11 +73,15 @@ public: template const ElementType& set(std::size_t i, T value) { dirty = true; // need to rebuild the raw data next time + items.resize(std::max(items.size(), i + 1)); return items[i] = value; } bool getDirty() const { return dirty; } - void clearDirty() { dirty = false; } + void clearDirty() { + dirty = false; + rawData.clear(); + } protected: VertexAttribute& operator=(const VertexAttribute&) = default; @@ -88,12 +96,14 @@ protected: protected: int index; int size; + int stride; /// indicates that a value has changed and any cached result should be discarded mutable bool dirty = true; AttributeDataType dataType; std::vector items; + mutable std::vector rawData; }; /// Stores a collection of vertex attributes by name @@ -107,8 +117,15 @@ public: VertexAttributeArray(const VertexAttributeArray&) = delete; virtual ~VertexAttributeArray() = default; + /// Number of elements std::size_t size() const { return attrs.size(); } + /// Sum of element strides, and the total size of a vertex in the buffer + std::size_t getTotalSize() const; + + /// Get the largest count value of the attribute elements + std::size_t getMaxCount() const; + /// Add a new attribute element. /// Returns a pointer to the new element on success, or null if the attribute already exists. /// The result is valid only until the next non-const method call on this class. @@ -117,12 +134,20 @@ public: /// Add a new attribute element. /// Returns a pointer to the new element on success, or null if the attribute already exists. /// The result is valid only until the next non-const method call on this class. - VertexAttribute* add(std::string name, int index, AttributeDataType, int size, std::size_t count); + VertexAttribute* add(std::string name, + int index = -1, + AttributeDataType = AttributeDataType::Invalid, + int size = 1, + std::size_t count = 1); /// Add a new attribute element if it doesn't already exist. /// Returns a pointer to the new element on success, or null if the type or count conflict with an existing entry. /// The result is valid only until the next non-const method call on this class. - VertexAttribute* getOrAdd(std::string name, int index, AttributeDataType, int size, std::size_t count); + VertexAttribute* getOrAdd(std::string name, + int index = -1, + AttributeDataType = AttributeDataType::Invalid, + int size = 1, + std::size_t count = 1); // Set a value if the element is present template diff --git a/include/mbgl/gl/drawable_gl.hpp b/include/mbgl/gl/drawable_gl.hpp index 0898b88fc..453438d3a 100644 --- a/include/mbgl/gl/drawable_gl.hpp +++ b/include/mbgl/gl/drawable_gl.hpp @@ -27,22 +27,19 @@ public: void draw(const PaintParameters &) const override; - void setVertexData(std::vector vertexData, std::vector indexes, - std::size_t indexOffset, std::size_t indexLength); + void setIndexData(std::vector indexes, + std::size_t indexOffset = 0, + std::size_t indexLength = 0); std::vector& getIndexData() const override; - std::vector& getVertexData() const override; - const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; } - void setVertexAttributes(const gfx::VertexAttributeArray& value) override { - vertexAttributes = static_cast(value); - } - void setVertexAttributes(gfx::VertexAttributeArray&& value) override { - vertexAttributes = std::move(static_cast(value)); - } + const gfx::VertexAttributeArray& getVertexAttributes() const override; + void setVertexAttributes(const gfx::VertexAttributeArray& value) override; + void setVertexAttributes(gfx::VertexAttributeArray&& value) override; + + gfx::VertexAttributeArray& mutableVertexAttributes(); const gl::VertexArray& getVertexArray() const; - void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, - gfx::IndexBuffer&&, std::size_t attrOffset); + void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&); protected: class Impl; @@ -52,7 +49,6 @@ protected: DrawableGL(std::unique_ptr); private: - VertexAttributeArrayGL vertexAttributes; }; } // namespace gl diff --git a/include/mbgl/gl/vertex_attribute_gl.hpp b/include/mbgl/gl/vertex_attribute_gl.hpp index 58dd2ec37..7e3a670bc 100644 --- a/include/mbgl/gl/vertex_attribute_gl.hpp +++ b/include/mbgl/gl/vertex_attribute_gl.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace mbgl { @@ -13,7 +14,7 @@ class VertexAttributeGL final : public gfx::VertexAttribute { private: friend VertexAttributeArrayGL; VertexAttributeGL(int index_, gfx::AttributeDataType dataType_, int size_, std::size_t count_) - : VertexAttribute(index_, dataType_, size_, count_) { + : VertexAttribute(index_, dataType_, size_, count_, /*stride_=*/0) { } VertexAttributeGL(const VertexAttributeGL& other) : VertexAttribute(other), @@ -26,19 +27,23 @@ private: public: platform::GLenum getGLType() const { return glType; } - void setGLType(platform::GLenum value) { glType = value; } + void setGLType(platform::GLenum value); bool getNormalized() const { return normalized; } void setNormalized(bool value) { normalized = value; } - std::size_t getStride() const { return stride; } - const std::vector& getRaw() const; + std::size_t getStride() const; + + const std::vector& getRaw() const; + +private: + static int getSize(platform::GLenum glType); + static int getStride(platform::GLenum glType); + static const void* getPtr(const gfx::VertexAttribute::ElementType&, platform::GLenum glType); private: platform::GLenum glType = 0; bool normalized = false; - mutable int stride = 0; - mutable std::vector rawData; }; /// Stores a collection of vertex attributes by name diff --git a/src/mbgl/gfx/drawable_builder.cpp b/src/mbgl/gfx/drawable_builder.cpp index cd18b94a6..4fca63207 100644 --- a/src/mbgl/gfx/drawable_builder.cpp +++ b/src/mbgl/gfx/drawable_builder.cpp @@ -63,17 +63,17 @@ void DrawableBuilder::resetDrawPriority(DrawPriority value) { void DrawableBuilder::addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) { const auto n = (uint16_t)impl->vertices.elements(); - impl->vertices.emplace_back(Impl::VT({{{ x0, y0 }}})); - impl->vertices.emplace_back(Impl::VT({{{ x1, y1 }}})); - impl->vertices.emplace_back(Impl::VT({{{ x2, y2 }}})); + impl->vertices.emplace_back(Impl::VT({{{ (float)x0, (float)y0 }}})); + impl->vertices.emplace_back(Impl::VT({{{ (float)x1, (float)y1 }}})); + impl->vertices.emplace_back(Impl::VT({{{ (float)x2, (float)y2 }}})); impl->indexes.emplace_back(n, n+1, n+2); impl->colors.insert(impl->colors.end(), 3, impl->currentColor); } void DrawableBuilder::appendTriangle(int16_t x0, int16_t y0) { const auto n = (uint16_t)impl->vertices.elements(); - impl->vertices.emplace_back(Impl::VT({{{ x0, y0 }}})); - impl->indexes.emplace_back(n-1, n, n+1); + impl->vertices.emplace_back(Impl::VT({{{ (float)x0, (float)y0 }}})); + impl->indexes.emplace_back(n-3, n-1, n); impl->colors.emplace_back(impl->currentColor); } diff --git a/src/mbgl/gfx/drawable_builder_impl.hpp b/src/mbgl/gfx/drawable_builder_impl.hpp index 7fc6e1ca2..4a86f1c29 100644 --- a/src/mbgl/gfx/drawable_builder_impl.hpp +++ b/src/mbgl/gfx/drawable_builder_impl.hpp @@ -8,7 +8,7 @@ namespace mbgl { namespace gfx { struct DrawableBuilder::Impl { - using VT = gfx::detail::VertexType>; + using VT = gfx::detail::VertexType>; gfx::VertexVector vertices; gfx::IndexVector indexes; SegmentVector> segments; diff --git a/src/mbgl/gfx/upload_pass.hpp b/src/mbgl/gfx/upload_pass.hpp index 302bc462a..f000d1969 100644 --- a/src/mbgl/gfx/upload_pass.hpp +++ b/src/mbgl/gfx/upload_pass.hpp @@ -60,12 +60,11 @@ public: } virtual gfx::AttributeBindingArray buildAttributeBindings( + const std::size_t vertexCount, const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& overrides, - const std::vector& vertexData, gfx::BufferUsageType, - /*out*/ std::unique_ptr& outBuffer, - /*out*/ std::size_t& outAttrOffset) = 0; + /*out*/ std::unique_ptr& outBuffer) = 0; protected: virtual std::unique_ptr createVertexBufferResource(const void* data, diff --git a/src/mbgl/gfx/vertex_attribute.cpp b/src/mbgl/gfx/vertex_attribute.cpp index e825336e6..40e1c902f 100644 --- a/src/mbgl/gfx/vertex_attribute.cpp +++ b/src/mbgl/gfx/vertex_attribute.cpp @@ -1,5 +1,9 @@ #include +#include +#include +#include + namespace mbgl { namespace gfx { @@ -47,33 +51,30 @@ VertexAttribute* VertexAttributeArray::getOrAdd(std::string name, int index, if (result.second) { result.first->second = create(index, dataType, size, count); } else if (result.first->second->getDataType() != dataType || - result.first->second->getSize() != size || + result.first->second->getSize() != (std::size_t)size || result.first->second->getCount() != count) { return nullptr; } return result.first->second.get(); } -bool VertexAttributeArray::isDirty() const { - for (const auto& kv : attrs) { - if (kv.second->getDirty()) { - return true; - } - } - return false; +std::size_t VertexAttributeArray::getTotalSize() const { + return std::accumulate(attrs.begin(), attrs.end(), 0, [](const auto acc, const auto& kv) { + return acc + kv.second->getStride(); + }); } -void VertexAttributeArray::resetDirty() { - for (auto& kv : attrs) { - kv.second->clearDirty(); - } +std::size_t VertexAttributeArray::getMaxCount() const { + return std::accumulate(attrs.begin(), attrs.end(), std::size_t(0), + [](const auto acc, const auto& kv) { + return std::max(acc, kv.second->getCount()); + }); } void VertexAttributeArray::resolve(const VertexAttributeArray& overrides, ResolveDelegate delegate) const { for (auto& kv : attrs) { - const auto overrideAttr = overrides.get(kv.first); - delegate(kv.first, *kv.second, overrideAttr); + delegate(kv.first, *kv.second, overrides.get(kv.first)); } } diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index 415da321e..5bd0934f6 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -16,11 +16,9 @@ void DrawableGL::draw(const PaintParameters ¶meters) const impl->draw(parameters); } -void DrawableGL::setVertexData(std::vector vertexData, - std::vector indexes, - const std::size_t indexOffset, - const std::size_t indexLength) { - impl->vertData = std::move(vertexData); +void DrawableGL::setIndexData(std::vector indexes, + const std::size_t indexOffset, + const std::size_t indexLength) { impl->indexes = std::move(indexes); impl->indexOffset = indexOffset; impl->indexLength = indexLength; @@ -30,21 +28,31 @@ std::vector& DrawableGL::getIndexData() const { return impl->indexes; } -std::vector& DrawableGL::getVertexData() const { - return impl->vertData; -} - const gl::VertexArray& DrawableGL::getVertexArray() const { return impl->vertexArray; } +const gfx::VertexAttributeArray& DrawableGL::getVertexAttributes() const { + return impl->vertexAttributes; +} + +gfx::VertexAttributeArray& DrawableGL::mutableVertexAttributes() { + return impl->vertexAttributes; +} + +void DrawableGL::setVertexAttributes(const gfx::VertexAttributeArray& value) { + impl->vertexAttributes = static_cast(value); +} +void DrawableGL::setVertexAttributes(gfx::VertexAttributeArray&& value) { + impl->vertexAttributes = std::move(static_cast(value)); +} + void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_, gfx::UniqueVertexBufferResource&& attributeBuffer_, - gfx::IndexBuffer&& indexBuffer_, - std::size_t attrOffset) { + gfx::IndexBuffer&& indexBuffer_) { impl->vertexArray = std::move(vertexArray_); impl->attributeBuffer = std::move(attributeBuffer_); - impl->attributeOffset = attrOffset; + impl->attributeOffset = 0; impl->indexBuffer = std::move(indexBuffer_); } diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 498d1f407..2b40632a3 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -11,25 +11,19 @@ gfx::DrawablePtr DrawableGLBuilder::createDrawable() const { }; void DrawableGLBuilder::init() { - const auto n = impl->vertices.elements(); - assert(n == impl->colors.size()); + auto& drawableGL = static_cast(*currentDrawable); - const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float); - std::vector rawVert(n * vertSize); - - auto p = &rawVert[0]; - for (auto i = 0ULL; i < n; ++i) { - *(Impl::VT*)p = impl->vertices.at(i); p += sizeof(Impl::VT); - *(float*)p = impl->colors[i].r; p += sizeof(float); - *(float*)p = impl->colors[i].g; p += sizeof(float); - *(float*)p = impl->colors[i].b; p += sizeof(float); - *(float*)p = impl->colors[i].a; p += sizeof(float); + auto& attrs = drawableGL.mutableVertexAttributes(); + if (auto posAttr = attrs.getOrAdd("a_pos")) { + std::size_t index = 0; + for (const auto& vert : impl->vertices.vector()) { + posAttr->set(index++, vert.a1); + } } - auto& drawableGL = static_cast(*currentDrawable); constexpr auto indexOffset = 0; const auto indexCount = impl->indexes.elements(); - drawableGL.setVertexData(std::move(rawVert), impl->indexes.vector(), indexOffset, indexCount); + drawableGL.setIndexData(impl->indexes.vector(), indexOffset, indexCount); } } // namespace gl diff --git a/src/mbgl/gl/drawable_gl_impl.hpp b/src/mbgl/gl/drawable_gl_impl.hpp index 4623c37d1..b22af0932 100644 --- a/src/mbgl/gl/drawable_gl_impl.hpp +++ b/src/mbgl/gl/drawable_gl_impl.hpp @@ -24,24 +24,26 @@ using namespace platform; class DrawableGL::Impl final { public: - Impl() { - } + Impl() = default; ~Impl() = default; void draw(const PaintParameters& parameters) const { - auto& glContext = static_cast(parameters.context); - glContext.draw(gfx::Triangles(), indexOffset, indexLength); + glContext.draw(drawMode, indexOffset, indexLength); } - const gfx::DrawModeType type = gfx::DrawModeType::Triangles; - ShaderID shaderId; - RenderbufferID renderTarget; + const gfx::Triangles drawMode; + //const gfx::DrawModeType type = gfx::DrawModeType::Triangles; + + //ShaderID shaderId; + //RenderbufferID renderTarget; std::vector textures; - std::vector vertData; + //std::vector vertData; std::vector indexes; + VertexAttributeArrayGL vertexAttributes; + VertexArray vertexArray = { { nullptr, false } }; gfx::IndexBuffer indexBuffer = { 0, nullptr }; gfx::UniqueVertexBufferResource attributeBuffer; diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index 1e375acbe..f7b140215 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -122,52 +122,58 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, data)); } +static std::size_t padSize(std::size_t size, std::size_t padding) { + return (padding - (size % padding)) % padding; +} template -static void pad(std::vector& vector, int size) { - vector.insert(vector.end(), size - vector.size() % size, 0); +static void pad(std::vector& vector, std::size_t size, T value) { + vector.insert(vector.end(), padSize(vector.size(), size), value); } gfx::AttributeBindingArray UploadPass::buildAttributeBindings( + const std::size_t vertexCount, const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& overrides, - const std::vector& vertexData, const gfx::BufferUsageType usage, - /*out*/ std::unique_ptr& outBuffer, - /*out*/ std::size_t& outAttrOffset) { + /*out*/ std::unique_ptr& outBuffer) { AttributeBindingArray bindings; bindings.reserve(defaults.size()); + constexpr std::size_t align = 16; + constexpr std::uint8_t padding = 0; + std::vector allData; - constexpr auto ExpectedSize = 32; - allData.reserve(vertexData.size() + defaults.size() * ExpectedSize); + allData.reserve(defaults.getTotalSize() * vertexCount); - allData.insert(allData.end(), vertexData.begin(), vertexData.end()); + // For each attribute in the program, with the corresponding default and optional override... + defaults.resolve(overrides, [&](auto& /*name*/, auto& defaultAttr, auto* overrideAttr) { - pad(allData, 16); - outAttrOffset = allData.size(); - - defaults.resolve(overrides, [&](const std::string& /*name*/, - const gfx::VertexAttribute& defaultAttr, - const gfx::VertexAttribute* overrideAttr) { - - const auto& effectiveAttr = *(overrideAttr ? overrideAttr : &defaultAttr); + const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr; const auto& effectiveGL = static_cast(effectiveAttr); const auto& defaultGL = static_cast(defaultAttr); - - pad(allData, 16); - const auto offset = static_cast(allData.size()); bindings.emplace_back(gfx::AttributeBinding{ - gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset }, - static_cast(effectiveGL.getStride()), - nullptr, // buffer pointer established later - static_cast(defaultGL.getIndex()) + .attribute = gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset }, + .vertexStride = static_cast(defaultAttr.getStride()), + .vertexBufferResource = nullptr, // buffer pointer established later + .vertexOffset = static_cast(defaultGL.getIndex()) }); const auto& rawData = effectiveGL.getRaw(); - allData.insert(allData.begin(), rawData.begin(), rawData.end()); + if (rawData.size() == defaultAttr.getStride()) { + for (std::size_t i = 0; i < vertexCount; ++i) { + allData.insert(allData.begin(), rawData.begin(), rawData.end()); + } + } else if (rawData.size() == defaultAttr.getStride() * vertexCount) { + allData.insert(allData.begin(), rawData.begin(), rawData.end()); + } else { + // TODO: log? throw? + allData.insert(allData.begin(), defaultAttr.getStride() * vertexCount, 0); + } + + pad(allData, align, padding); }); auto vertBuf = createVertexBufferResource(&allData[0], allData.size(), usage); diff --git a/src/mbgl/gl/upload_pass.hpp b/src/mbgl/gl/upload_pass.hpp index 72b9b2a00..07e0ddc14 100644 --- a/src/mbgl/gl/upload_pass.hpp +++ b/src/mbgl/gl/upload_pass.hpp @@ -35,12 +35,11 @@ public: void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; gfx::AttributeBindingArray buildAttributeBindings( + const std::size_t vertexCount, const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& overrides, - const std::vector& vertexData, gfx::BufferUsageType, - /*out*/ std::unique_ptr& outBuffer, - /*out*/ std::size_t& outAttrOffset) override; + /*out*/ std::unique_ptr& outBuffer) override; public: std::unique_ptr createTextureResource(Size, diff --git a/src/mbgl/gl/vertex_attribute_gl.cpp b/src/mbgl/gl/vertex_attribute_gl.cpp index 75677db37..aeece9399 100644 --- a/src/mbgl/gl/vertex_attribute_gl.cpp +++ b/src/mbgl/gl/vertex_attribute_gl.cpp @@ -13,23 +13,39 @@ class VertexAttributeArrayGL; using namespace platform; -static std::pair getSizeAndStride(GLenum glType) { +int VertexAttributeGL::getSize(GLenum glType) { switch (glType) { - case GL_FLOAT: return { 4*1, 4*1 }; - case GL_FLOAT_VEC2: return { 4*2, 4*2 }; - case GL_FLOAT_VEC3: return { 4*3, 4*4 }; - case GL_FLOAT_VEC4: return { 4*4, 4*4 }; - case GL_FLOAT_MAT2: return { 4*4, 4*4 }; - case GL_INT: return { 4*1, 4*1 }; - case GL_UNSIGNED_INT: return { 4*1, 4*1 }; - case GL_INT_VEC2: return { 4*2, 4*2 }; - case GL_INT_VEC3: return { 4*3, 4*4 }; - case GL_INT_VEC4: return { 4*4, 4*4 }; - default: return { 0, 0 }; + case GL_FLOAT: return 4*1; + case GL_FLOAT_VEC2: return 4*2; + case GL_FLOAT_VEC3: return 4*3; + case GL_FLOAT_VEC4: return 4*4; + case GL_FLOAT_MAT2: return 4*4; + case GL_INT: return 4*1; + case GL_UNSIGNED_INT: return 4*1; + case GL_INT_VEC2: return 4*2; + case GL_INT_VEC3: return 4*3; + case GL_INT_VEC4: return 4*4; + default: return 0; } } -static const void* getPtr(const gfx::VertexAttribute::ElementType& element, GLenum glType) { +int VertexAttributeGL::getStride(GLenum glType) { + switch (glType) { + case GL_FLOAT: return 4*1; + case GL_FLOAT_VEC2: return 4*2; + case GL_FLOAT_VEC3: return 4*4; + case GL_FLOAT_VEC4: return 4*4; + case GL_FLOAT_MAT2: return 4*4; + case GL_INT: return 4*1; + case GL_UNSIGNED_INT: return 4*1; + case GL_INT_VEC2: return 4*2; + case GL_INT_VEC3: return 4*4; + case GL_INT_VEC4: return 4*4; + default: return 0; + } +} + +const void* VertexAttributeGL::getPtr(const gfx::VertexAttribute::ElementType& element, GLenum glType) { switch (glType) { case GL_FLOAT: case GL_FLOAT_VEC2: @@ -45,25 +61,29 @@ static const void* getPtr(const gfx::VertexAttribute::ElementType& element, GLen } } -const std::vector& VertexAttributeGL::getRaw() const { +void VertexAttributeGL::setGLType(platform::GLenum value) { + glType = value; + stride = getStride(glType); +} + +std::size_t VertexAttributeGL::getStride() const { + return getStride(getGLType()); +} + +const std::vector& VertexAttributeGL::getRaw() const { if (dirty) { const auto count = getCount(); - const auto sizes = getSizeAndStride(getGLType()); - - stride = sizes.second; + const auto size_ = getSize(getGLType()); rawData.resize(stride * count); std::fill(rawData.begin(), rawData.end(), 0); - if (rawData.size() > 0) { - std::uint8_t* outPtr = &rawData[0]; - - for (std::size_t i = 0; i < count; ++i) { - if (const auto rawPtr = getPtr(items[i], getGLType())) { - std::memcpy(outPtr, rawPtr, sizes.first); - } - outPtr += stride; + std::uint8_t* outPtr = &rawData[0]; + for (std::size_t i = 0; i < count; ++i) { + if (const auto rawPtr = getPtr(items[i], getGLType())) { + std::memcpy(outPtr, rawPtr, size_); } + outPtr += stride; } dirty = false; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 13fd9bd04..4eb960e6b 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -138,11 +138,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Apply drawable values to shader defaults const auto& defaults = shader->getVertexAttributes(); const auto& overrides = drawable.getVertexAttributes(); - const auto& vertexData = drawableGL.getVertexData(); + const auto vertexCount = drawable.getVertexCount(); std::unique_ptr vertexBuffer; - std::size_t attrOffset = 0; - auto bindings = uploadPass->buildAttributeBindings(defaults, overrides, vertexData, usage, - vertexBuffer, attrOffset); + auto bindings = uploadPass->buildAttributeBindings(vertexCount, defaults, overrides, usage, vertexBuffer); auto& glContext = static_cast(context); auto vertexArray = glContext.createVertexArray(); @@ -150,8 +148,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) { drawableGL.setVertexArray(std::move(vertexArray), std::move(vertexBuffer), - std::move(indexBuffer), - attrOffset); + std::move(indexBuffer)); } } } diff --git a/src/mbgl/shaders/gl/shader_program_gl.cpp b/src/mbgl/shaders/gl/shader_program_gl.cpp index 047c8c3f7..d3f0fab97 100644 --- a/src/mbgl/shaders/gl/shader_program_gl.cpp +++ b/src/mbgl/shaders/gl/shader_program_gl.cpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace mbgl { @@ -90,7 +91,8 @@ static void addAttr(VertexAttributeArrayGL& attrs, const char* name, GLint index const auto elementCount = mapCount(glType); // number of `elementType`, hopefully temporary if (elementType != gfx::AttributeDataType::Invalid && length > 0) { if (auto newAttr = attrs.add(name, index, elementType, elementCount, count)) { - static_cast(newAttr)->setGLType(glType); + auto* glAttr = static_cast(newAttr); + glAttr->setGLType(glType); } } } @@ -125,7 +127,8 @@ std::shared_ptr ShaderProgramGL::create( GLint size = 0; GLenum glType = 0; MBGL_CHECK_ERROR(glGetActiveUniform(program, index, maxLength, &length, &size, &glType, &name[0])); - addAttr(uniforms, &name[0], index, length, size, glType); + const GLint location = MBGL_CHECK_ERROR(glGetUniformLocation(program, &name[0])); + addAttr(uniforms, &name[0], location, length, size, glType); } VertexAttributeArrayGL attrs; @@ -139,7 +142,11 @@ std::shared_ptr ShaderProgramGL::create( GLint size = 0; // "size of the attribute variable, in units of the type returned in type" GLenum glType = 0; MBGL_CHECK_ERROR(glGetActiveAttrib(program, index, maxLength, &length, &size, &glType, &name[0])); - addAttr(attrs, &name[0], index, length, size, glType); + if (!strncmp(&name[0], "gl_", 3)) { // Is there a better way to detect built-in attributes? + continue; + } + const GLint location = MBGL_CHECK_ERROR(glGetAttribLocation(program, &name[0])); + addAttr(attrs, &name[0], location, length, size, glType); } return std::make_shared(std::move(program), std::move(uniforms), std::move(attrs));