diff --git a/include/mbgl/gfx/drawable.hpp b/include/mbgl/gfx/drawable.hpp index 00e7d1ed3..91f7d6c7e 100644 --- a/include/mbgl/gfx/drawable.hpp +++ b/include/mbgl/gfx/drawable.hpp @@ -47,6 +47,7 @@ public: virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0; virtual std::vector& getIndexData() const = 0; + virtual std::vector& 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)); } diff --git a/include/mbgl/gl/drawable_gl.hpp b/include/mbgl/gl/drawable_gl.hpp index 68e11d437..0898b88fc 100644 --- a/include/mbgl/gl/drawable_gl.hpp +++ b/include/mbgl/gl/drawable_gl.hpp @@ -27,7 +27,10 @@ public: void draw(const PaintParameters &) const override; - void setVertData(std::vector vertexData_, std::vector indexes_); + void setVertexData(std::vector vertexData, std::vector indexes, + std::size_t indexOffset, std::size_t indexLength); + std::vector& getIndexData() const override; + std::vector& getVertexData() const override; const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; } void setVertexAttributes(const gfx::VertexAttributeArray& value) override { @@ -38,9 +41,8 @@ public: } const gl::VertexArray& getVertexArray() const; - void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&); - - std::vector& getIndexData() const override; + void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, + gfx::IndexBuffer&&, std::size_t attrOffset); protected: class Impl; diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index d8dfa8320..29ed3f80a 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -89,14 +89,8 @@ public: public: - const gfx::ShaderProgramBasePtr& getCurrentShader() const { return currentShader; } - virtual void setCurrentShader(ShaderProgramBasePtr) = 0; - /// Activate the shader, vertex attributes, etc., specified by the drawable virtual void setupDraw(const gfx::Drawable&) = 0; - -protected: - ShaderProgramBasePtr currentShader; }; } // namespace gfx diff --git a/src/mbgl/gfx/upload_pass.hpp b/src/mbgl/gfx/upload_pass.hpp index d48c37be7..302bc462a 100644 --- a/src/mbgl/gfx/upload_pass.hpp +++ b/src/mbgl/gfx/upload_pass.hpp @@ -59,10 +59,13 @@ public: updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes()); } - virtual std::pair> - buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - gfx::BufferUsageType) = 0; + virtual gfx::AttributeBindingArray buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + gfx::BufferUsageType, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) = 0; protected: virtual std::unique_ptr createVertexBufferResource(const void* data, diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index e57e59578..0691cfe3e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -448,12 +448,23 @@ void Context::setDirtyState() { } void Context::setupDraw(const gfx::Drawable& drawable) { - if (auto &shader = drawable.getShader()) { - if (shader != currentShader) { - setCurrentShader(shader); + if (const auto &shader = drawable.getShader()) { + const auto& shaderGL = static_cast(*shader); + if (shaderGL.getGLProgramID() != program.getCurrentValue()) { + program = shaderGL.getGLProgramID(); } + } else if (program != value::Program::Default) { + program = value::Program::Default; } + // setDepthMode(depthMode); + // setStencilMode(stencilMode); + // setColorMode(colorMode); + // setCullFaceMode(cullFaceMode); + + // uniformStates.bind(uniformValues); + // textureStates.bind(context, textureBindings); + auto& drawableGL = static_cast(drawable); auto& vao = drawableGL.getVertexArray(); if (vao.isValid()) { @@ -463,15 +474,6 @@ void Context::setupDraw(const gfx::Drawable& drawable) { } } -void Context::setCurrentShader(gfx::ShaderProgramBasePtr value) { - if ((currentShader = std::move(value))) { - auto& shaderGL = static_cast(*currentShader); - this->program = shaderGL.getGLProgramID(); - } else { - this->program = value::Program::Default; - } -} - void Context::clear(std::optional color, std::optional depth, std::optional stencil) { diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 1819492b7..1b7fc1f3d 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -106,8 +106,6 @@ public: void setupDraw(const gfx::Drawable&) override; - void setCurrentShader(gfx::ShaderProgramBasePtr) override; - private: RendererBackend& backend; bool cleanupOnDestruction = true; diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index 3e76e22c9..415da321e 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -16,25 +16,35 @@ void DrawableGL::draw(const PaintParameters ¶meters) const impl->draw(parameters); } -void DrawableGL::setVertData(std::vector vertexData_, - std::vector indexes_) { - impl->vertData = std::move(vertexData_); - impl->indexes = std::move(indexes_); +void DrawableGL::setVertexData(std::vector vertexData, + std::vector indexes, + const std::size_t indexOffset, + const std::size_t indexLength) { + impl->vertData = std::move(vertexData); + impl->indexes = std::move(indexes); + impl->indexOffset = indexOffset; + impl->indexLength = indexLength; } std::vector& DrawableGL::getIndexData() const { return impl->indexes; } +std::vector& DrawableGL::getVertexData() const { + return impl->vertData; +} + const gl::VertexArray& DrawableGL::getVertexArray() const { return impl->vertexArray; } void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_, gfx::UniqueVertexBufferResource&& attributeBuffer_, - gfx::IndexBuffer&& indexBuffer_) { + gfx::IndexBuffer&& indexBuffer_, + std::size_t attrOffset) { impl->vertexArray = std::move(vertexArray_); impl->attributeBuffer = std::move(attributeBuffer_); + impl->attributeOffset = attrOffset; impl->indexBuffer = std::move(indexBuffer_); } diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 1e344ffad..498d1f407 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -12,10 +12,8 @@ gfx::DrawablePtr DrawableGLBuilder::createDrawable() const { void DrawableGLBuilder::init() { const auto n = impl->vertices.elements(); - assert(n <= impl->indexes.elements()); assert(n == impl->colors.size()); - // temp const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float); std::vector rawVert(n * vertSize); @@ -28,7 +26,10 @@ void DrawableGLBuilder::init() { *(float*)p = impl->colors[i].a; p += sizeof(float); } - ((DrawableGL*)currentDrawable.get())->setVertData(std::move(rawVert), impl->indexes.vector()); + auto& drawableGL = static_cast(*currentDrawable); + constexpr auto indexOffset = 0; + const auto indexCount = impl->indexes.elements(); + drawableGL.setVertexData(std::move(rawVert), impl->indexes.vector(), indexOffset, indexCount); } } // namespace gl diff --git a/src/mbgl/gl/drawable_gl_impl.hpp b/src/mbgl/gl/drawable_gl_impl.hpp index 43d1890f3..4623c37d1 100644 --- a/src/mbgl/gl/drawable_gl_impl.hpp +++ b/src/mbgl/gl/drawable_gl_impl.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -27,13 +28,10 @@ public: } ~Impl() = default; - void draw(const PaintParameters& /*parameters*/) const { - MBGL_CHECK_ERROR(glDrawElements( - Enum::to(type), - static_cast(indexLength), - GL_UNSIGNED_SHORT, - reinterpret_cast(sizeof(uint16_t) * indexOffset))); - + void draw(const PaintParameters& parameters) const { + + auto& glContext = static_cast(parameters.context); + glContext.draw(gfx::Triangles(), indexOffset, indexLength); } const gfx::DrawModeType type = gfx::DrawModeType::Triangles; @@ -50,6 +48,7 @@ public: std::size_t indexOffset = 0; std::size_t indexLength = 0; + std::size_t attributeOffset = 0; mat4 matrix; gfx::DepthMode depthMode = gfx::DepthMode::disabled(); gfx::StencilMode stencilMode; diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index cee61b53a..0235458eb 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -84,8 +84,14 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { in mat2 f; in mat4 g; void main() { - gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12; + gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12; // optimized away if unused gl_Position = vec4(pos, 1.0); + 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; + } })"; constexpr auto frag = R"( #version 300 es @@ -93,7 +99,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { in vec4 pos; out vec4 color; void main() { - color = vec4(1.0,0.0,0.0,1.0); + color = vec4(0.5,0.0,0.0,0.5); })"; try { diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index 9f6d9f876..1e375acbe 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -122,18 +122,30 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, data)); } +template +static void pad(std::vector& vector, int size) { + vector.insert(vector.end(), size - vector.size() % size, 0); +} -std::pair> - UploadPass::buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - const gfx::BufferUsageType usage) { +gfx::AttributeBindingArray UploadPass::buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + const gfx::BufferUsageType usage, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) { AttributeBindingArray bindings; bindings.reserve(defaults.size()); std::vector allData; constexpr auto ExpectedSize = 32; - allData.reserve(defaults.size() * ExpectedSize); + allData.reserve(vertexData.size() + defaults.size() * ExpectedSize); + + allData.insert(allData.end(), vertexData.begin(), vertexData.end()); + + pad(allData, 16); + outAttrOffset = allData.size(); defaults.resolve(overrides, [&](const std::string& /*name*/, const gfx::VertexAttribute& defaultAttr, @@ -143,8 +155,7 @@ std::pair const auto& effectiveGL = static_cast(effectiveAttr); const auto& defaultGL = static_cast(defaultAttr); - // Pad to 16 bytes - allData.insert(allData.end(), 16 - allData.size() % 16, 0); + pad(allData, 16); const auto offset = static_cast(allData.size()); @@ -164,10 +175,8 @@ std::pair // Assign to each element std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); }); - gfx::AttributeBindingArray& a = bindings; - std::unique_ptr& b = vertBuf; - return std::make_pair(std::move(a), std::move(b)); - //return std::make_pair(bindings, vertBuf); + outBuffer = std::move(vertBuf); + return bindings; } void UploadPass::pushDebugGroup(const char* name) { diff --git a/src/mbgl/gl/upload_pass.hpp b/src/mbgl/gl/upload_pass.hpp index 0beb9a034..72b9b2a00 100644 --- a/src/mbgl/gl/upload_pass.hpp +++ b/src/mbgl/gl/upload_pass.hpp @@ -34,10 +34,13 @@ public: gfx::BufferUsageType) override; void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; - std::pair> - buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - gfx::BufferUsageType) override; + gfx::AttributeBindingArray buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + gfx::BufferUsageType, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) override; public: std::unique_ptr createTextureResource(Size, diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 8348b6a4e..405557f5c 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -130,15 +130,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Apply drawable values to shader defaults const auto& defaults = shader->getVertexAttributes(); const auto& overrides = drawable.getVertexAttributes(); - auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage); + const auto& vertexData = drawableGL.getVertexData(); + std::unique_ptr vertexBuffer; + std::size_t attrOffset = 0; + auto bindings = uploadPass->buildAttributeBindings(defaults, overrides, vertexData, usage, + vertexBuffer, attrOffset); auto& glContext = static_cast(context); auto vertexArray = glContext.createVertexArray(); - vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first); - + vertexArray.bind(glContext, indexBuffer, bindings); + drawableGL.setVertexArray(std::move(vertexArray), - std::move(bindingsAndBuffer.second), - std::move(indexBuffer)); + std::move(vertexBuffer), + std::move(indexBuffer), + attrOffset); } } } @@ -193,21 +198,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Run changes orchestrator.processChanges(); - - // Draw Drawables - { - for (const auto &pair : orchestrator.getDrawables()) { - const auto& drawable = *pair.second; - context.setupDraw(drawable); - - drawable.draw(parameters); - } - } - // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. { + parameters.pass = RenderPass::Opaque; const auto debugGroup(parameters.renderPass->createDebugGroup("opaque")); @@ -239,8 +234,18 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } - // - DEBUG PASS - // -------------------------------------------------------------------------------- + // Draw Drawables + { + for (const auto &pair : orchestrator.getDrawables()) { + const auto& drawable = *pair.second; + + context.setupDraw(drawable); + + drawable.draw(parameters); + } + } + + // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { const auto debugGroup(parameters.renderPass->createDebugGroup("debug"));