Rework attributes (#1048)

This commit is contained in:
Tim Sylvester
2023-04-20 15:33:27 -07:00
committed by Bart Louwers
parent f76fb98745
commit 92ce58db86
16 changed files with 206 additions and 146 deletions

View File

@@ -22,8 +22,7 @@ using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
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<std::uint16_t>& getIndexData() const = 0;
virtual std::vector<std::uint8_t>& 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<DrawableTweakerPtr> getTweakers() const { return tweakers; }
const std::vector<DrawableTweakerPtr>& getTweakers() const { return tweakers; }
protected:
util::SimpleIdentity uniqueID;

View File

@@ -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 <typename T>
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<ElementType> items;
mutable std::vector<std::uint8_t> 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 <typename T>

View File

@@ -27,22 +27,19 @@ public:
void draw(const PaintParameters &) const override;
void setVertexData(std::vector<std::uint8_t> vertexData, std::vector<uint16_t> indexes,
std::size_t indexOffset, std::size_t indexLength);
void setIndexData(std::vector<uint16_t> indexes,
std::size_t indexOffset = 0,
std::size_t indexLength = 0);
std::vector<std::uint16_t>& getIndexData() const override;
std::vector<std::uint8_t>& getVertexData() const override;
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
void setVertexAttributes(const gfx::VertexAttributeArray& value) override {
vertexAttributes = static_cast<const VertexAttributeArrayGL&>(value);
}
void setVertexAttributes(gfx::VertexAttributeArray&& value) override {
vertexAttributes = std::move(static_cast<VertexAttributeArrayGL&&>(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<Impl>);
private:
VertexAttributeArrayGL vertexAttributes;
};
} // namespace gl

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/gfx/vertex_attribute.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/platform/gl_functions.hpp>
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<uint8_t>& getRaw() const;
std::size_t getStride() const;
const std::vector<std::uint8_t>& 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<uint8_t> rawData;
};
/// Stores a collection of vertex attributes by name

View File

@@ -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);
}

View File

@@ -8,7 +8,7 @@ namespace mbgl {
namespace gfx {
struct DrawableBuilder::Impl {
using VT = gfx::detail::VertexType<gfx::AttributeType<short,2>>;
using VT = gfx::detail::VertexType<gfx::AttributeType<float,2>>;
gfx::VertexVector<VT> vertices;
gfx::IndexVector<gfx::Triangles> indexes;
SegmentVector<TypeList<void>> segments;

View File

@@ -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<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) = 0;
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer) = 0;
protected:
virtual std::unique_ptr<VertexBufferResource> createVertexBufferResource(const void* data,

View File

@@ -1,5 +1,9 @@
#include <mbgl/gfx/vertex_attribute.hpp>
#include <algorithm>
#include <numeric>
#include <optional>
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));
}
}

View File

@@ -16,11 +16,9 @@ void DrawableGL::draw(const PaintParameters &parameters) const
impl->draw(parameters);
}
void DrawableGL::setVertexData(std::vector<std::uint8_t> vertexData,
std::vector<std::uint16_t> indexes,
const std::size_t indexOffset,
const std::size_t indexLength) {
impl->vertData = std::move(vertexData);
void DrawableGL::setIndexData(std::vector<std::uint16_t> 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<std::uint16_t>& DrawableGL::getIndexData() const {
return impl->indexes;
}
std::vector<std::uint8_t>& 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<const VertexAttributeArrayGL&>(value);
}
void DrawableGL::setVertexAttributes(gfx::VertexAttributeArray&& value) {
impl->vertexAttributes = std::move(static_cast<VertexAttributeArrayGL&&>(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_);
}

View File

@@ -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<DrawableGL&>(*currentDrawable);
const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float);
std::vector<uint8_t> 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<DrawableGL&>(*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

View File

@@ -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<gl::Context&>(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<TextureID> textures;
std::vector<std::uint8_t> vertData;
//std::vector<std::uint8_t> vertData;
std::vector<std::uint16_t> indexes;
VertexAttributeArrayGL vertexAttributes;
VertexArray vertexArray = { { nullptr, false } };
gfx::IndexBuffer indexBuffer = { 0, nullptr };
gfx::UniqueVertexBufferResource attributeBuffer;

View File

@@ -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 <typename T>
static void pad(std::vector<T>& vector, int size) {
vector.insert(vector.end(), size - vector.size() % size, 0);
static void pad(std::vector<T>& 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<uint8_t>& vertexData,
const gfx::BufferUsageType usage,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) {
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer) {
AttributeBindingArray bindings;
bindings.reserve(defaults.size());
constexpr std::size_t align = 16;
constexpr std::uint8_t padding = 0;
std::vector<std::uint8_t> 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<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
pad(allData, 16);
const auto offset = static_cast<uint8_t>(allData.size());
bindings.emplace_back(gfx::AttributeBinding{
gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset },
static_cast<uint8_t>(effectiveGL.getStride()),
nullptr, // buffer pointer established later
static_cast<uint32_t>(defaultGL.getIndex())
.attribute = gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset },
.vertexStride = static_cast<uint8_t>(defaultAttr.getStride()),
.vertexBufferResource = nullptr, // buffer pointer established later
.vertexOffset = static_cast<uint32_t>(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);

View File

@@ -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<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) override;
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer) override;
public:
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,

View File

@@ -13,23 +13,39 @@ class VertexAttributeArrayGL;
using namespace platform;
static std::pair<int,int> 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<uint8_t>& 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<std::uint8_t>& 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;

View File

@@ -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<gfx::VertexBufferResource> 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<gl::Context&>(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));
}
}
}

View File

@@ -5,6 +5,7 @@
#include <mbgl/gl/vertex_attribute_gl.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <cstring>
#include <utility>
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<VertexAttributeGL*>(newAttr)->setGLType(glType);
auto* glAttr = static_cast<VertexAttributeGL*>(newAttr);
glAttr->setGLType(glType);
}
}
}
@@ -125,7 +127,8 @@ std::shared_ptr<ShaderProgramGL> 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> 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<ShaderProgramGL>(std::move(program), std::move(uniforms), std::move(attrs));