#include #include #include #include #include #include #include namespace mbgl { namespace gl { class VertexAttributeArrayGL; using namespace platform; int VertexAttributeGL::getSize(GLenum glType) { switch (glType) { 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; } } 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; } } // 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: 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 gl::get(element, buffer) || gl::get(element, buffer, [](int4 x) { return float4{(float)x[0], (float)x[1], (float)x[2], (float)x[3]}; }); 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; } } void VertexAttributeGL::setGLType(platform::GLenum value) { glType = value; stride = getStride(glType); } std::size_t VertexAttributeGL::getStride() const { return getStride(getGLType()); } const std::vector& VertexAttributeGL::getRaw(platform::GLenum type) const { if (dirty || rawType != type) { const auto count = getCount(); // const auto size_ = getSize(type); const auto stride_ = getStride(type); rawData.resize(stride_ * count); std::fill(rawData.begin(), rawData.end(), 0); if (!rawData.empty()) { std::uint8_t* outPtr = rawData.data(); for (std::size_t i = 0; i < count; ++i) { if (!get(items[i], type, outPtr)) { // throw? } outPtr += stride_; } } dirty = false; rawType = type; } return rawData; } } // namespace gl } // namespace mbgl