Topic/drawable 2 (#1032)

More vertex attribute work
Move drawables above existing layer rendering. 
Use context for the actual draw call.
Fake the vertexes in the shader to get something actually showing up.
Simplify shader state management
This commit is contained in:
Tim Sylvester
2023-04-18 12:31:41 -07:00
committed by Bart Louwers
parent e2bc75289c
commit aceb0394ba
13 changed files with 111 additions and 78 deletions

View File

@@ -47,6 +47,7 @@ public:
virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0;
virtual std::vector<std::uint16_t>& getIndexData() const = 0;
virtual std::vector<std::uint8_t>& 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)); }

View File

@@ -27,7 +27,10 @@ public:
void draw(const PaintParameters &) const override;
void setVertData(std::vector<std::uint8_t> vertexData_, std::vector<uint16_t> indexes_);
void setVertexData(std::vector<std::uint8_t> vertexData, std::vector<uint16_t> indexes,
std::size_t indexOffset, std::size_t indexLength);
std::vector<std::uint16_t>& getIndexData() const override;
std::vector<std::uint8_t>& 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<std::uint16_t>& getIndexData() const override;
void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&,
gfx::IndexBuffer&&, std::size_t attrOffset);
protected:
class Impl;

View File

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

View File

@@ -59,10 +59,13 @@ public:
updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes());
}
virtual std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
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<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) = 0;
protected:
virtual std::unique_ptr<VertexBufferResource> createVertexBufferResource(const void* data,

View File

@@ -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<const ShaderProgramGL&>(*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<const DrawableGL&>(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<ShaderProgramGL&>(*currentShader);
this->program = shaderGL.getGLProgramID();
} else {
this->program = value::Program::Default;
}
}
void Context::clear(std::optional<mbgl::Color> color,
std::optional<float> depth,
std::optional<int32_t> stencil) {

View File

@@ -106,8 +106,6 @@ public:
void setupDraw(const gfx::Drawable&) override;
void setCurrentShader(gfx::ShaderProgramBasePtr) override;
private:
RendererBackend& backend;
bool cleanupOnDestruction = true;

View File

@@ -16,25 +16,35 @@ void DrawableGL::draw(const PaintParameters &parameters) const
impl->draw(parameters);
}
void DrawableGL::setVertData(std::vector<std::uint8_t> vertexData_,
std::vector<std::uint16_t> indexes_) {
impl->vertData = std::move(vertexData_);
impl->indexes = std::move(indexes_);
void DrawableGL::setVertexData(std::vector<std::uint8_t> vertexData,
std::vector<std::uint16_t> 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<std::uint16_t>& DrawableGL::getIndexData() const {
return impl->indexes;
}
std::vector<std::uint8_t>& 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_);
}

View File

@@ -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<uint8_t> 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<DrawableGL&>(*currentDrawable);
constexpr auto indexOffset = 0;
const auto indexCount = impl->indexes.elements();
drawableGL.setVertexData(std::move(rawVert), impl->indexes.vector(), indexOffset, indexCount);
}
} // namespace gl

View File

@@ -9,6 +9,7 @@
#include <mbgl/gl/program.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/util/mat4.hpp>
#include <cstdint>
@@ -27,13 +28,10 @@ public:
}
~Impl() = default;
void draw(const PaintParameters& /*parameters*/) const {
MBGL_CHECK_ERROR(glDrawElements(
Enum<gfx::DrawModeType>::to(type),
static_cast<GLsizei>(indexLength),
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(sizeof(uint16_t) * indexOffset)));
void draw(const PaintParameters& parameters) const {
auto& glContext = static_cast<gl::Context&>(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;

View File

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

View File

@@ -122,18 +122,30 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource,
data));
}
template <typename T>
static void pad(std::vector<T>& vector, int size) {
vector.insert(vector.end(), size - vector.size() % size, 0);
}
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
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<uint8_t>& vertexData,
const gfx::BufferUsageType usage,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) {
AttributeBindingArray bindings;
bindings.reserve(defaults.size());
std::vector<std::uint8_t> 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<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
// Pad to 16 bytes
allData.insert(allData.end(), 16 - allData.size() % 16, 0);
pad(allData, 16);
const auto offset = static_cast<uint8_t>(allData.size());
@@ -164,10 +175,8 @@ std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>
// Assign to each element
std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); });
gfx::AttributeBindingArray& a = bindings;
std::unique_ptr<gfx::VertexBufferResource>& 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) {

View File

@@ -34,10 +34,13 @@ public:
gfx::BufferUsageType) override;
void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override;
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>>
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<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) override;
public:
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,

View File

@@ -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<gfx::VertexBufferResource> vertexBuffer;
std::size_t attrOffset = 0;
auto bindings = uploadPass->buildAttributeBindings(defaults, overrides, vertexData, usage,
vertexBuffer, attrOffset);
auto& glContext = static_cast<gl::Context&>(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"));