Topic/drawable (#1052)

This commit is contained in:
Tim Sylvester
2023-04-21 14:47:57 -07:00
committed by Bart Louwers
parent 92ce58db86
commit e7d32a613a
8 changed files with 79 additions and 45 deletions

View File

@@ -34,15 +34,16 @@ public:
std::size_t getStride() const;
const std::vector<std::uint8_t>& getRaw() const;
const std::vector<std::uint8_t>& 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;
};

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({{{ (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);
}

View File

@@ -4,11 +4,13 @@
#include <mbgl/programs/segment.hpp>
#include <mbgl/util/color.hpp>
#include <cstdint>
namespace mbgl {
namespace gfx {
struct DrawableBuilder::Impl {
using VT = gfx::detail::VertexType<gfx::AttributeType<float,2>>;
using VT = gfx::detail::VertexType<gfx::AttributeType<std::int16_t,2>>;
gfx::VertexVector<VT> vertices;
gfx::IndexVector<gfx::Triangles> indexes;
SegmentVector<TypeList<void>> segments;

View File

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

View File

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

View File

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

View File

@@ -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<const gl::VertexAttributeGL&>(effectiveAttr);
@@ -155,13 +157,13 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
const auto offset = static_cast<uint8_t>(allData.size());
bindings.emplace_back(gfx::AttributeBinding{
.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())
/*.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();
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());

View File

@@ -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 <typename T, typename R>
static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer, std::function<R(T)> f) {
if (auto* p = std::get_if<T>(&element)) {
*reinterpret_cast<R*>(buffer) = f(*p);
return true;
}
return false;
}
// Copy the value into the buffer with a simple cast, returning true if it works.
template <typename T, typename R>
static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer) {
return get<T,R>(element, buffer, [](T x)->R{ return static_cast<R>(x); });
}
// Copy a particular type from the variant into the specified buffer, returning true if it works.
template <typename T>
static bool get(const gfx::VertexAttribute::ElementType& element, uint8_t* buffer) {
return get<T,T>(element, buffer, [](T x)->T{ return x; });
}
template <typename T, typename R> R cast(T x) { return static_cast<R>(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<float>(element, buffer) ||
gl::get<float,std::int32_t>(element, buffer);
case GL_FLOAT_VEC2: return gl::get<float2>(element, buffer) ||
gl::get<int2,float2>(element, buffer, [](int2 x){ return float2{(float)x[0],(float)x[1]}; });
case GL_FLOAT_VEC3: return gl::get<float3>(element, buffer);
case GL_FLOAT_VEC4:
case GL_FLOAT_MAT2: return std::get_if<float>(&element);
case GL_INT:
case GL_UNSIGNED_INT:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4: return std::get_if<int>(&element);
default: return nullptr;
case GL_FLOAT_MAT2: return gl::get<float4>(element, buffer);
case GL_INT: return gl::get<std::int32_t>(element, buffer) ||
gl::get<float, std::int32_t> (element, buffer);
case GL_UNSIGNED_INT: return gl::get<std::int32_t,std::uint32_t>(element, buffer) ||
gl::get<float, std::uint32_t>(element, buffer);
case GL_INT_VEC2: return gl::get<int2>(element, buffer) ||
gl::get<float2,int2>(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<int3>(element, buffer);
case GL_UNSIGNED_INT_VEC3: return false; // TODO
case GL_INT_VEC4: return gl::get<int4>(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<std::uint8_t>& VertexAttributeGL::getRaw() const {
if (dirty) {
const std::vector<std::uint8_t>& 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;
}