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:
committed by
Bart Louwers
parent
e2bc75289c
commit
aceb0394ba
@@ -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)); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -106,8 +106,6 @@ public:
|
||||
|
||||
void setupDraw(const gfx::Drawable&) override;
|
||||
|
||||
void setCurrentShader(gfx::ShaderProgramBasePtr) override;
|
||||
|
||||
private:
|
||||
RendererBackend& backend;
|
||||
bool cleanupOnDestruction = true;
|
||||
|
||||
@@ -16,25 +16,35 @@ void DrawableGL::draw(const PaintParameters ¶meters) 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_);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"));
|
||||
|
||||
Reference in New Issue
Block a user