From e7d32a613ae00abacc248116f68dd66dd1e771c2 Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Fri, 21 Apr 2023 14:47:57 -0700 Subject: [PATCH] Topic/drawable (#1052) --- include/mbgl/gl/vertex_attribute_gl.hpp | 5 +- src/mbgl/gfx/drawable_builder.cpp | 10 ++-- src/mbgl/gfx/drawable_builder_impl.hpp | 4 +- src/mbgl/gfx/vertex_attribute.cpp | 2 +- src/mbgl/gl/drawable_gl_builder.cpp | 2 +- src/mbgl/gl/renderer_backend.cpp | 9 --- src/mbgl/gl/upload_pass.cpp | 14 +++-- src/mbgl/gl/vertex_attribute_gl.cpp | 78 ++++++++++++++++++------- 8 files changed, 79 insertions(+), 45 deletions(-) diff --git a/include/mbgl/gl/vertex_attribute_gl.hpp b/include/mbgl/gl/vertex_attribute_gl.hpp index 7e3a670bc..fa02d5a41 100644 --- a/include/mbgl/gl/vertex_attribute_gl.hpp +++ b/include/mbgl/gl/vertex_attribute_gl.hpp @@ -34,15 +34,16 @@ public: std::size_t getStride() const; - const std::vector& getRaw() const; + const std::vector& getRaw(platform::GLenum) 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); + static bool get(const gfx::VertexAttribute::ElementType&, platform::GLenum glType, uint8_t* buffer); private: platform::GLenum glType = 0; + mutable platform::GLenum rawType = 0; bool normalized = false; }; diff --git a/src/mbgl/gfx/drawable_builder.cpp b/src/mbgl/gfx/drawable_builder.cpp index 4fca63207..48f737b33 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({{{ (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->vertices.emplace_back(Impl::VT({{{ x0, y0 }}})); + impl->vertices.emplace_back(Impl::VT({{{ x1, y1 }}})); + impl->vertices.emplace_back(Impl::VT({{{ x2, 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({{{ (float)x0, (float)y0 }}})); - impl->indexes.emplace_back(n-3, n-1, n); + impl->vertices.emplace_back(Impl::VT({{{ x0, y0 }}})); + impl->indexes.emplace_back(n-2, 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 4a86f1c29..6b949e890 100644 --- a/src/mbgl/gfx/drawable_builder_impl.hpp +++ b/src/mbgl/gfx/drawable_builder_impl.hpp @@ -4,11 +4,13 @@ #include #include +#include + 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/vertex_attribute.cpp b/src/mbgl/gfx/vertex_attribute.cpp index 40e1c902f..6abea9def 100644 --- a/src/mbgl/gfx/vertex_attribute.cpp +++ b/src/mbgl/gfx/vertex_attribute.cpp @@ -59,7 +59,7 @@ VertexAttribute* VertexAttributeArray::getOrAdd(std::string name, int index, } std::size_t VertexAttributeArray::getTotalSize() const { - return std::accumulate(attrs.begin(), attrs.end(), 0, [](const auto acc, const auto& kv) { + return std::accumulate(attrs.begin(), attrs.end(), std::size_t(0), [](const auto acc, const auto& kv) { return acc + kv.second->getStride(); }); } diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 2b40632a3..d6cb3b837 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -17,7 +17,7 @@ void DrawableGLBuilder::init() { if (auto posAttr = attrs.getOrAdd("a_pos")) { std::size_t index = 0; for (const auto& vert : impl->vertices.vector()) { - posAttr->set(index++, vert.a1); + posAttr->set(index++, gfx::VertexAttribute::int2{vert.a1[0], vert.a1[1]}); } } diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index 053df098e..70588f51f 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -83,15 +83,6 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1); - - switch (gl_VertexID) { // fake it for now - case 0: gl_Position = vec4(-1.0, -1.0, 1.0, 1.0); break; - case 1: gl_Position = vec4( 1.0, -1.0, 1.0, 1.0); break; - case 2: gl_Position = vec4( 1.0, 1.0, 1.0, 1.0); break; - case 3: gl_Position = vec4(-1.0, 1.0, 1.0, 1.0); break; - } - gl_Position = u_matrix * vec4(gl_Position.xy * 8192.0, 0, 1); - //gl_Position = u_matrix * vec4(a_pos, 0, 1); })"; constexpr auto frag = R"(#version 300 es precision highp float; diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index f7b140215..645b8ceda 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -147,7 +147,9 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( allData.reserve(defaults.getTotalSize() * vertexCount); // For each attribute in the program, with the corresponding default and optional override... - defaults.resolve(overrides, [&](auto& /*name*/, auto& defaultAttr, auto* overrideAttr) { + defaults.resolve(overrides, [&](const std::string& /*name*/, + const gfx::VertexAttribute& defaultAttr, + const gfx::VertexAttribute* overrideAttr)->void { const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr; const auto& effectiveGL = static_cast(effectiveAttr); @@ -155,13 +157,13 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( const auto offset = static_cast(allData.size()); bindings.emplace_back(gfx::AttributeBinding{ - .attribute = gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset }, - .vertexStride = static_cast(defaultAttr.getStride()), - .vertexBufferResource = nullptr, // buffer pointer established later - .vertexOffset = 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(); + const auto& rawData = effectiveGL.getRaw(defaultGL.getGLType()); if (rawData.size() == defaultAttr.getStride()) { for (std::size_t i = 0; i < vertexCount; ++i) { allData.insert(allData.begin(), rawData.begin(), rawData.end()); diff --git a/src/mbgl/gl/vertex_attribute_gl.cpp b/src/mbgl/gl/vertex_attribute_gl.cpp index aeece9399..77791c081 100644 --- a/src/mbgl/gl/vertex_attribute_gl.cpp +++ b/src/mbgl/gl/vertex_attribute_gl.cpp @@ -45,19 +45,53 @@ int VertexAttributeGL::getStride(GLenum glType) { } } -const void* VertexAttributeGL::getPtr(const gfx::VertexAttribute::ElementType& element, GLenum glType) { +// Copy the transformed type into the buffer, returning true if it works. +template +static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer, std::function f) { + if (auto* p = std::get_if(&element)) { + *reinterpret_cast(buffer) = f(*p); + return true; + } + return false; +} + +// Copy the value into the buffer with a simple cast, returning true if it works. +template +static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer) { + return get(element, buffer, [](T x)->R{ return static_cast(x); }); +} + +// Copy a particular type from the variant into the specified buffer, returning true if it works. +template +static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer) { + return get(element, buffer, [](T x)->T{ return x; }); +} + +template R cast(T x) { return static_cast(x); } + +// Copy the variant value into the buffer, converting the type if necessary and possible +bool VertexAttributeGL::get(const gfx::VertexAttribute::ElementType& element, GLenum glType, uint8_t* buffer) { + // TODO: do we need to handle unsigned inputs? switch (glType) { - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: + case GL_FLOAT: return gl::get(element, buffer) || + gl::get(element, buffer); + case GL_FLOAT_VEC2: return gl::get(element, buffer) || + gl::get(element, buffer, [](int2 x){ return float2{(float)x[0],(float)x[1]}; }); + case GL_FLOAT_VEC3: return gl::get(element, buffer); case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: return std::get_if(&element); - case GL_INT: - case GL_UNSIGNED_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: return std::get_if(&element); - default: return nullptr; + case GL_FLOAT_MAT2: return gl::get(element, buffer); + case GL_INT: return gl::get(element, buffer) || + gl::get (element, buffer); + case GL_UNSIGNED_INT: return gl::get(element, buffer) || + gl::get(element, buffer); + case GL_INT_VEC2: return gl::get(element, buffer) || + gl::get(element, buffer, [](float2 x){ return int2{(std::int32_t)x[0],(std::int32_t)x[1]}; }); + case GL_UNSIGNED_INT_VEC2: return false; // TODO + case GL_INT_VEC3: return gl::get(element, buffer); + case GL_UNSIGNED_INT_VEC3: return false; // TODO + case GL_INT_VEC4: return gl::get(element, buffer); + case GL_UNSIGNED_INT_VEC4: return false; // TODO + default: return false; } } @@ -70,23 +104,27 @@ std::size_t VertexAttributeGL::getStride() const { return getStride(getGLType()); } -const std::vector& VertexAttributeGL::getRaw() const { - if (dirty) { +const std::vector& VertexAttributeGL::getRaw(platform::GLenum type) const { + if (dirty || rawType != type) { const auto count = getCount(); - const auto size_ = getSize(getGLType()); + //const auto size_ = getSize(type); + const auto stride_ = getStride(type); - rawData.resize(stride * count); + rawData.resize(stride_ * count); std::fill(rawData.begin(), rawData.end(), 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, size_); + if (!rawData.empty()) { + std::uint8_t* outPtr = &rawData[0]; + for (std::size_t i = 0; i < count; ++i) { + if (!get(items[i], type, outPtr)) { + // throw? + } + outPtr += stride_; } - outPtr += stride; } dirty = false; + rawType = type; } return rawData; }