Topic/drawable 2 (#1029)
This commit is contained in:
committed by
Bart Louwers
parent
14b53e54ec
commit
e2bc75289c
@@ -15,7 +15,12 @@ class ProgramParameters;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
class Drawable;
|
||||
class OffscreenTexture;
|
||||
class ShaderProgramBase;
|
||||
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
|
||||
|
||||
class Context {
|
||||
protected:
|
||||
@@ -81,6 +86,17 @@ public:
|
||||
#endif
|
||||
|
||||
virtual void clearStencilBuffer(int32_t) = 0;
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -28,7 +28,7 @@ void DrawableBuilder::flush() {
|
||||
if (!impl->vertices.empty()) {
|
||||
auto draw = getCurrentDrawable(/*create=*/true);
|
||||
currentDrawable->setDrawPriority(drawPriority);
|
||||
currentDrawable->setShaderID(shaderID);
|
||||
currentDrawable->setShader(shader);
|
||||
currentDrawable->setVertexAttributes(getVertexAttributes());
|
||||
currentDrawable->addTweakers(tweakers.begin(), tweakers.end());
|
||||
init();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/gl/renderer_backend.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
@@ -9,6 +10,7 @@
|
||||
#include <mbgl/gl/command_encoder.hpp>
|
||||
#include <mbgl/gl/debugging_extension.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
@@ -445,7 +447,34 @@ void Context::setDirtyState() {
|
||||
globalVertexArrayState.setDirty();
|
||||
}
|
||||
|
||||
void Context::clear(std::optional<mbgl::Color> color, std::optional<float> depth, std::optional<int32_t> stencil) {
|
||||
void Context::setupDraw(const gfx::Drawable& drawable) {
|
||||
if (auto &shader = drawable.getShader()) {
|
||||
if (shader != currentShader) {
|
||||
setCurrentShader(shader);
|
||||
}
|
||||
}
|
||||
|
||||
auto& drawableGL = static_cast<const DrawableGL&>(drawable);
|
||||
auto& vao = drawableGL.getVertexArray();
|
||||
if (vao.isValid()) {
|
||||
bindVertexArray = vao.getID(); // glBindVertexArray
|
||||
} else {
|
||||
bindVertexArray = value::BindVertexArray::Default;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
GLbitfield mask = 0;
|
||||
|
||||
if (color) {
|
||||
|
||||
@@ -104,6 +104,10 @@ public:
|
||||
|
||||
void setCleanupOnDestruction(bool cleanup) { cleanupOnDestruction = cleanup; }
|
||||
|
||||
void setupDraw(const gfx::Drawable&) override;
|
||||
|
||||
void setCurrentShader(gfx::ShaderProgramBasePtr) override;
|
||||
|
||||
private:
|
||||
RendererBackend& backend;
|
||||
bool cleanupOnDestruction = true;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#include <mbgl/gl/renderer_backend.hpp>
|
||||
#include <mbgl/gfx/backend_scope.hpp>
|
||||
#include <mbgl/gfx/shader_registry.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/extension.hpp>
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
@@ -62,5 +65,67 @@ void RendererBackend::setScissorTest(bool enabled) {
|
||||
|
||||
RendererBackend::~RendererBackend() = default;
|
||||
|
||||
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
|
||||
constexpr auto shaderName = "background_generic";
|
||||
|
||||
gl::Context& glContext = static_cast<gl::Context&>(*context);
|
||||
|
||||
auto shader = shaders.get<gl::ShaderProgramGL>(shaderName);
|
||||
if (!shader) {
|
||||
constexpr auto vert = R"(
|
||||
#version 300 es
|
||||
precision highp float;
|
||||
uniform float a;
|
||||
uniform int b;
|
||||
uniform mat4 c;
|
||||
layout (location = 0) in vec3 pos;
|
||||
in float d;
|
||||
in int e;
|
||||
in mat2 f;
|
||||
in mat4 g;
|
||||
void main() {
|
||||
gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12;
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
})";
|
||||
constexpr auto frag = R"(
|
||||
#version 300 es
|
||||
precision highp float;
|
||||
in vec4 pos;
|
||||
out vec4 color;
|
||||
void main() {
|
||||
color = vec4(1.0,0.0,0.0,1.0);
|
||||
})";
|
||||
|
||||
try {
|
||||
// Compile
|
||||
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
|
||||
if (shader) {
|
||||
// Set default values
|
||||
if (auto *attr = shader->getVertexAttributes().get("d")) {
|
||||
attr->set(0, 12.3f);
|
||||
}
|
||||
if (auto *attr = shader->getVertexAttributes().get("e")) {
|
||||
attr->set(0, 123);
|
||||
}
|
||||
if (auto *attr = shader->getVertexAttributes().get("f")) {
|
||||
attr->set(0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f });
|
||||
}
|
||||
|
||||
// Add to the registry
|
||||
if (!shaders.registerShader(shader, shaderName)) {
|
||||
Log::Warning(Event::General, "Shader conflict - " + std::string(shaderName));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::General, "Shader create failed - " + std::string(shaderName));
|
||||
return;
|
||||
}
|
||||
} catch (const std::runtime_error& ex) {
|
||||
Log::Warning(Event::General, "Shader create exception - " + std::string(ex.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
|
||||
bool isValid() const { return state.operator bool(); }
|
||||
|
||||
VertexArrayID getID() const { return state->vertexArray; }
|
||||
|
||||
private:
|
||||
UniqueVertexArrayState state;
|
||||
};
|
||||
|
||||
@@ -61,6 +61,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
|
||||
auto& context = backend.getContext();
|
||||
|
||||
// Now that the shader registry is set up, do one-time shader init.
|
||||
// TODO: Both should be done earlier.
|
||||
backend.initShaders(*staticData->shaders);
|
||||
|
||||
// Blocks execution until the renderable is available.
|
||||
backend.getDefaultRenderable().wait();
|
||||
|
||||
@@ -109,34 +113,32 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
|
||||
// Generate a vertex array object for the drawable state, if necessary
|
||||
auto& drawableGL = static_cast<gl::DrawableGL&>(drawable);
|
||||
if (!drawableGL.getVertexArray().isValid() && !drawable.getShaderID().empty()) {
|
||||
// TODO: avoid having to do this lookup twice
|
||||
if (auto shader = parameters.shaders.get<gl::ShaderProgramGL>(drawable.getShaderID())) {
|
||||
const auto usage = gfx::BufferUsageType::StaticDraw;
|
||||
const auto& shader = drawable.getShader();
|
||||
if (shader && !drawableGL.getVertexArray().isValid()) {
|
||||
const auto usage = gfx::BufferUsageType::StaticDraw;
|
||||
|
||||
// Build index buffer
|
||||
const auto& indexData = drawable.getIndexData();
|
||||
auto indexBuffer = gfx::IndexBuffer {
|
||||
indexData.size(),
|
||||
uploadPass->createIndexBufferResource(
|
||||
&indexData[0],
|
||||
indexData.size() * sizeof(indexData[0]),
|
||||
usage)
|
||||
};
|
||||
// Build index buffer
|
||||
const auto& indexData = drawable.getIndexData();
|
||||
auto indexBuffer = gfx::IndexBuffer {
|
||||
indexData.size(),
|
||||
uploadPass->createIndexBufferResource(
|
||||
&indexData[0],
|
||||
indexData.size() * sizeof(indexData[0]),
|
||||
usage)
|
||||
};
|
||||
|
||||
// Apply drawable values to shader defaults
|
||||
const auto& defaults = shader->getVertexAttributes();
|
||||
const auto& overrides = drawable.getVertexAttributes();
|
||||
auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage);
|
||||
// Apply drawable values to shader defaults
|
||||
const auto& defaults = shader->getVertexAttributes();
|
||||
const auto& overrides = drawable.getVertexAttributes();
|
||||
auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage);
|
||||
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
auto vertexArray = glContext.createVertexArray();
|
||||
vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first);
|
||||
|
||||
drawableGL.setVertexArray(std::move(vertexArray),
|
||||
std::move(bindingsAndBuffer.second),
|
||||
std::move(indexBuffer));
|
||||
}
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
auto vertexArray = glContext.createVertexArray();
|
||||
vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first);
|
||||
|
||||
drawableGL.setVertexArray(std::move(vertexArray),
|
||||
std::move(bindingsAndBuffer.second),
|
||||
std::move(indexBuffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,15 +198,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
{
|
||||
for (const auto &pair : orchestrator.getDrawables()) {
|
||||
const auto& drawable = *pair.second;
|
||||
|
||||
if (!drawable.getShaderID().empty()) {
|
||||
// if shader != currentShader
|
||||
if (auto shader = parameters.shaders.get<gl::ShaderProgramGL>(drawable.getShaderID())) {
|
||||
// Context.activate(shader)
|
||||
}
|
||||
}
|
||||
|
||||
// Context.bind(drawable vao)
|
||||
context.setupDraw(drawable);
|
||||
|
||||
drawable.draw(parameters);
|
||||
}
|
||||
|
||||
@@ -57,9 +57,17 @@ ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_)
|
||||
glProgram(std::move(glProgram_)) {
|
||||
}
|
||||
|
||||
ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_,
|
||||
VertexAttributeArrayGL&& attributes)
|
||||
: ShaderProgramBase(),
|
||||
glProgram(std::move(glProgram_)),
|
||||
vertexAttributes(std::move(attributes)) {
|
||||
}
|
||||
|
||||
ShaderProgramGL::ShaderProgramGL(ShaderProgramGL&& other)
|
||||
: ShaderProgramBase(std::forward<ShaderProgramBase&&>(other)),
|
||||
glProgram(std::move(other.glProgram)) {
|
||||
glProgram(std::move(other.glProgram)),
|
||||
vertexAttributes(std::move(other.vertexAttributes)) {
|
||||
}
|
||||
|
||||
std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
|
||||
@@ -111,7 +119,7 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<ShaderProgramGL>(std::move(program));
|
||||
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(attrs));
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -19,62 +19,8 @@ bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
|
||||
constexpr auto shaderName = "background_generic";
|
||||
|
||||
void BackgroundLayer::Impl::layerAdded(PaintParameters& parameters, UniqueChangeRequestVec& changes) const {
|
||||
// TODO: this should happen a GL-specific part of map initialization
|
||||
auto &glContext = static_cast<gl::Context&>(parameters.context);
|
||||
auto shader = parameters.shaders.get<gl::ShaderProgramGL>(shaderName);
|
||||
if (!shader) {
|
||||
constexpr auto vert = R"(
|
||||
//#version 300 es
|
||||
precision highp float;
|
||||
uniform float a;
|
||||
uniform int b;
|
||||
uniform mat4 c;
|
||||
attribute vec3 pos; //layout (location = 0) in vec3 pos;
|
||||
attribute float d;
|
||||
//attribute int e;
|
||||
attribute mat2 f;
|
||||
attribute mat4 g;
|
||||
void main() {
|
||||
gl_Position = vec4(a, g[0][0], f[0][0], d);
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
})";
|
||||
constexpr auto frag = R"(
|
||||
//#version 300 es
|
||||
precision highp float;
|
||||
//out vec4 color;
|
||||
void main() {
|
||||
//color = vec4(1.0,0.0,0.0,1.0);
|
||||
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
|
||||
})";
|
||||
|
||||
try {
|
||||
// Compile
|
||||
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
|
||||
if (shader) {
|
||||
// Set default values
|
||||
if (auto *attr = shader->getVertexAttributes().get("a")) {
|
||||
attr->set(0, 12.3f);
|
||||
}
|
||||
if (auto *attr = shader->getVertexAttributes().get("b")) {
|
||||
attr->set(0, 123);
|
||||
}
|
||||
if (auto *attr = shader->getVertexAttributes().get("f")) {
|
||||
attr->set(0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f });
|
||||
}
|
||||
|
||||
// Add to the registry
|
||||
if (!parameters.shaders.registerShader(shader, shaderName)) {
|
||||
Log::Warning(Event::General, "Shader conflict - " + std::string(shaderName));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::General, "Shader create failed - " + std::string(shaderName));
|
||||
return;
|
||||
}
|
||||
} catch (const std::runtime_error& ex) {
|
||||
Log::Warning(Event::General, "Shader create exception - " + std::string(ex.what()));
|
||||
return;
|
||||
}
|
||||
shader = parameters.shaders.get<gl::ShaderProgramGL>(shaderName);
|
||||
}
|
||||
|
||||
buildDrawables(changes);
|
||||
@@ -88,8 +34,13 @@ void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVe
|
||||
}
|
||||
|
||||
void BackgroundLayer::Impl::buildDrawables(UniqueChangeRequestVec& changes) const {
|
||||
|
||||
if (!shader) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method?
|
||||
builder->setShaderID(shaderName);
|
||||
builder->setShader(shader);
|
||||
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables
|
||||
builder->addQuad(0, 0, util::EXTENT, util::EXTENT);
|
||||
builder->flush();
|
||||
|
||||
@@ -10,7 +10,9 @@ namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class Drawable;
|
||||
class ShaderProgramBase;
|
||||
using DrawablePtr = std::shared_ptr<Drawable>;
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -27,7 +29,7 @@ public:
|
||||
void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const override;
|
||||
|
||||
/// Generate any changes needed by the layer
|
||||
void update(UniqueChangeRequestVec& changes) const override;
|
||||
void update(UniqueChangeRequestVec&) const override;
|
||||
|
||||
private:
|
||||
void buildDrawables(UniqueChangeRequestVec&) const;
|
||||
@@ -35,6 +37,7 @@ private:
|
||||
public:
|
||||
BackgroundPaintProperties::Transitionable paint;
|
||||
|
||||
mutable gfx::ShaderProgramBasePtr shader;
|
||||
mutable gfx::DrawablePtr drawable;
|
||||
|
||||
DECLARE_LAYER_TYPE_INFO;
|
||||
|
||||
Reference in New Issue
Block a user