Topic/drawable (#1052)
This commit is contained in:
committed by
Bart Louwers
parent
92ce58db86
commit
e7d32a613a
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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]});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user