Rework attributes (#1048)
This commit is contained in:
committed by
Bart Louwers
parent
f76fb98745
commit
92ce58db86
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,9 @@ void DrawableGL::draw(const PaintParameters ¶meters) 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_);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user