summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-18 19:11:30 +0300
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-06-20 13:24:20 +0300
commitdf5a39570819abc6e083bee8bc1fc9da8d92b68c (patch)
treeef323e670ec3768f577e9b1f57cd0d102bd8e9b2 /src
parent7e549b90202655ca0de9f503178f42012c534dbc (diff)
downloadqtlocation-mapboxgl-df5a39570819abc6e083bee8bc1fc9da8d92b68c.tar.gz
[core] Refactor wireframe to match JS overdraw mode
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/map.cpp2
-rw-r--r--src/mbgl/renderer/painter.cpp13
-rw-r--r--src/mbgl/renderer/painter.hpp2
-rw-r--r--src/mbgl/renderer/painter_background.cpp16
-rw-r--r--src/mbgl/renderer/painter_circle.cpp2
-rw-r--r--src/mbgl/renderer/painter_fill.cpp22
-rw-r--r--src/mbgl/renderer/painter_line.cpp17
-rw-r--r--src/mbgl/renderer/painter_raster.cpp2
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp4
-rw-r--r--src/mbgl/shader/shader.cpp61
-rw-r--r--src/mbgl/shader/shader.hpp11
-rw-r--r--src/mbgl/style/style.cpp7
-rw-r--r--src/mbgl/style/style.hpp2
13 files changed, 91 insertions, 70 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 11bc89a1a0..f4cca3b2b5 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -794,7 +794,7 @@ void Map::cycleDebugOptions() {
impl->debugOptions = MapDebugOptions::NoDebug;
#endif // GL_ES_VERSION_2_0
else if (impl->debugOptions & MapDebugOptions::Collision)
- impl->debugOptions = MapDebugOptions::Collision | MapDebugOptions::Wireframe;
+ impl->debugOptions = MapDebugOptions::Wireframe;
else if (impl->debugOptions & MapDebugOptions::Timestamps)
impl->debugOptions = impl->debugOptions | MapDebugOptions::Collision;
else if (impl->debugOptions & MapDebugOptions::ParseStatus)
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index ca536f6671..fae5c74d7b 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -92,7 +92,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
spriteAtlas = style.spriteAtlas.get();
lineAtlas = style.lineAtlas.get();
- RenderData renderData = style.getRenderData();
+ RenderData renderData = style.getRenderData(frame.debugOptions);
const std::vector<RenderItem>& order = renderData.order;
const std::set<Source*>& sources = renderData.sources;
const Color& background = renderData.backgroundColor;
@@ -144,7 +144,12 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
config.depthTest = GL_FALSE;
config.depthMask = GL_TRUE;
config.colorMask = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE };
- if (frame.debugOptions & MapDebugOptions::Wireframe) {
+
+ if (isWireframe()) {
+ config.blend = GL_TRUE;
+ config.blendFunc = { GL_CONSTANT_COLOR, GL_ONE };
+ const float overdraw = 1.0f / 8.0f;
+ config.blendColor = { overdraw, overdraw, overdraw, 0.0f };
config.clearColor = Color::black();
} else {
config.clearColor = background;
@@ -243,7 +248,9 @@ void Painter::renderPass(RenderPass pass_,
if (!layer.baseImpl->hasRenderPass(pass))
continue;
- if (pass == RenderPass::Translucent) {
+ if (isWireframe()) {
+ config.blend = GL_TRUE;
+ } else if (pass == RenderPass::Translucent) {
config.blendFunc.reset();
config.blend = GL_TRUE;
} else {
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 4c51543bde..d2d722ef7f 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -156,6 +156,8 @@ private:
void setDepthSublayer(int n);
+ bool isWireframe() const { return frame.debugOptions & MapDebugOptions::Wireframe; }
+
mat4 projMatrix;
mat4 nativeMatrix;
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 022d3dd7ab..f9a67ee59c 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -21,9 +21,6 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
optional<SpriteAtlasPosition> imagePosA;
optional<SpriteAtlasPosition> imagePosB;
- bool wireframe = frame.debugOptions & MapDebugOptions::Wireframe;
- isPatterned &= !wireframe;
-
if (isPatterned) {
imagePosA = spriteAtlas->getPosition(properties.backgroundPattern.value.from, true);
imagePosB = spriteAtlas->getPosition(properties.backgroundPattern.value.to, true);
@@ -31,7 +28,7 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
if (!imagePosA || !imagePosB)
return;
- config.program = patternShader->getID();
+ config.program = isWireframe() ? patternShader->getOverdrawID() : patternShader->getID();
patternShader->u_matrix = identityMatrix;
patternShader->u_pattern_tl_a = imagePosA->tl;
patternShader->u_pattern_br_a = imagePosA->br;
@@ -44,15 +41,10 @@ void Painter::renderBackground(const BackgroundLayer& layer) {
backgroundPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0), store);
} else {
- if (wireframe) {
- plainShader->u_color = Color::black();
- plainShader->u_opacity = 1.0f;
- } else {
- plainShader->u_color = properties.backgroundColor;
- plainShader->u_opacity = properties.backgroundOpacity;
- }
+ plainShader->u_color = properties.backgroundColor;
+ plainShader->u_opacity = properties.backgroundOpacity;
- config.program = plainShader->getID();
+ config.program = isWireframe() ? plainShader->getOverdrawID() : plainShader->getID();
backgroundArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0), store);
}
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 24cc9806e9..d92ca1ae9b 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -27,7 +27,7 @@ void Painter::renderCircle(CircleBucket& bucket,
mat4 vtxMatrix = translatedMatrix(matrix, properties.circleTranslate, tileID,
properties.circleTranslateAnchor);
- config.program = circleShader->getID();
+ config.program = isWireframe() ? circleShader->getOverdrawID() : circleShader->getID();
circleShader->u_matrix = vtxMatrix;
circleShader->u_extrude_scale = extrudeScale;
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 710fa444e2..62e808614e 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -36,16 +36,6 @@ void Painter::renderFill(FillBucket& bucket,
bool outline = properties.fillAntialias && !pattern && isOutlineColorDefined;
bool fringeline = properties.fillAntialias && !pattern && !isOutlineColorDefined;
- bool wireframe = frame.debugOptions & MapDebugOptions::Wireframe;
- if (wireframe) {
- fillColor = Color::white();
- strokeColor = Color::white();
- opacity = 1.0f;
- pattern = false;
- outline = true;
- fringeline = true;
- }
-
config.stencilOp.reset();
config.stencilTest = GL_TRUE;
config.depthFunc.reset();
@@ -56,7 +46,7 @@ void Painter::renderFill(FillBucket& bucket,
// Because we're drawing top-to-bottom, and we update the stencil mask
// befrom, we have to draw the outline first (!)
if (outline && pass == RenderPass::Translucent) {
- config.program = outlineShader->getID();
+ config.program = isWireframe() ? outlineShader->getOverdrawID() : outlineShader->getID();
outlineShader->u_matrix = vertexMatrix;
outlineShader->u_outline_color = strokeColor;
@@ -86,7 +76,7 @@ void Painter::renderFill(FillBucket& bucket,
// Image fill.
if (pass == RenderPass::Translucent && imagePosA && imagePosB) {
- config.program = patternShader->getID();
+ config.program = isWireframe() ? patternShader->getOverdrawID() : patternShader->getID();
patternShader->u_matrix = vertexMatrix;
patternShader->u_pattern_tl_a = imagePosA->tl;
patternShader->u_pattern_br_a = imagePosA->br;
@@ -115,7 +105,7 @@ void Painter::renderFill(FillBucket& bucket,
bucket.drawElements(*patternShader, store);
if (properties.fillAntialias && !isOutlineColorDefined) {
- config.program = outlinePatternShader->getID();
+ config.program = isWireframe() ? outlinePatternShader->getOverdrawID() : outlinePatternShader->getID();
outlinePatternShader->u_matrix = vertexMatrix;
// Draw the entire line
@@ -143,14 +133,14 @@ void Painter::renderFill(FillBucket& bucket,
bucket.drawVertices(*outlinePatternShader, store);
}
}
- } else if (!wireframe) {
+ } else {
// No image fill.
if ((fillColor.a >= 1.0f && opacity >= 1.0f) == (pass == RenderPass::Opaque)) {
// Only draw the fill when it's either opaque and we're drawing opaque
// fragments or when it's translucent and we're drawing translucent
// fragments
// Draw filling rectangle.
- config.program = plainShader->getID();
+ config.program = isWireframe() ? plainShader->getOverdrawID() : plainShader->getID();
plainShader->u_matrix = vertexMatrix;
plainShader->u_color = fillColor;
plainShader->u_opacity = opacity;
@@ -164,7 +154,7 @@ void Painter::renderFill(FillBucket& bucket,
// Because we're drawing top-to-bottom, and we update the stencil mask
// below, we have to draw the outline first (!)
if (fringeline && pass == RenderPass::Translucent) {
- config.program = outlineShader->getID();
+ config.program = isWireframe() ? outlineShader->getOverdrawID() : outlineShader->getID();
outlineShader->u_matrix = vertexMatrix;
outlineShader->u_outline_color = fillColor;
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index bb759abc5f..447e3f7400 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -33,17 +33,10 @@ void Painter::renderLine(LineBucket& bucket,
// Retina devices need a smaller distance to avoid aliasing.
float antialiasing = 1.0 / frame.pixelRatio;
- bool wireframe = frame.debugOptions & MapDebugOptions::Wireframe;
-
float blur = properties.lineBlur + antialiasing;
- Color color = Color::white();
- float opacity = 1.0f;
- if (!wireframe) {
- color = properties.lineColor;
- opacity = properties.lineOpacity;
- }
-
+ const Color color = properties.lineColor;
+ const float opacity = properties.lineOpacity;
const float ratio = 1.0 / tileID.pixelsToTileUnits(1.0, state.getZoom());
mat2 antialiasingMatrix;
@@ -64,7 +57,7 @@ void Painter::renderLine(LineBucket& bucket,
if (!properties.lineDasharray.value.from.empty()) {
- config.program = linesdfShader->getID();
+ config.program = isWireframe() ? linesdfShader->getOverdrawID() : linesdfShader->getID();
linesdfShader->u_matrix = vtxMatrix;
linesdfShader->u_linewidth = properties.lineWidth / 2;
@@ -109,7 +102,7 @@ void Painter::renderLine(LineBucket& bucket,
if (!imagePosA || !imagePosB)
return;
- config.program = linepatternShader->getID();
+ config.program = isWireframe() ? linepatternShader->getOverdrawID() : linepatternShader->getID();
linepatternShader->u_matrix = vtxMatrix;
linepatternShader->u_linewidth = properties.lineWidth / 2;
@@ -145,7 +138,7 @@ void Painter::renderLine(LineBucket& bucket,
bucket.drawLinePatterns(*linepatternShader, store);
} else {
- config.program = lineShader->getID();
+ config.program = isWireframe() ? lineShader->getOverdrawID() : lineShader->getID();
lineShader->u_matrix = vtxMatrix;
lineShader->u_linewidth = properties.lineWidth / 2;
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index f3a0b720e7..6394d61dcc 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -18,7 +18,7 @@ void Painter::renderRaster(RasterBucket& bucket,
const RasterPaintProperties& properties = layer.impl->paint;
if (bucket.hasData()) {
- config.program = rasterShader->getID();
+ config.program = isWireframe() ? rasterShader->getOverdrawID() : rasterShader->getID();
rasterShader->u_matrix = matrix;
rasterShader->u_buffer = 0;
rasterShader->u_opacity = properties.rasterOpacity;
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index b65ae34a12..374500986b 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -58,7 +58,7 @@ void Painter::renderSDF(SymbolBucket &bucket,
exScale = {{ exScale[0] * scale, exScale[1] * scale }};
}
- config.program = sdfShader.getID();
+ config.program = isWireframe() ? sdfShader.getOverdrawID() : sdfShader.getID();
sdfShader.u_matrix = vtxMatrix;
sdfShader.u_extrude_scale = exScale;
sdfShader.u_texsize = texsize;
@@ -199,7 +199,7 @@ void Painter::renderSymbol(SymbolBucket& bucket,
exScale = {{ exScale[0] * scale, exScale[1] * scale }};
}
- config.program = iconShader->getID();
+ config.program = isWireframe() ? iconShader->getOverdrawID() : iconShader->getID();
iconShader->u_matrix = vtxMatrix;
iconShader->u_extrude_scale = exScale;
iconShader->u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp
index e2c7776e4d..80c4c33efc 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/shader/shader.cpp
@@ -8,6 +8,7 @@
#include <cstring>
#include <cassert>
#include <iostream>
+#include <string>
#include <fstream>
#include <cstdio>
@@ -21,12 +22,12 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment
{
util::stopwatch stopwatch("shader compilation", Event::Shader);
- if (!compileShader(vertexShader, &vertexSource)) {
+ if (!compileShader(vertexShader, vertexSource)) {
Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertexSource);
throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile");
}
- if (!compileShader(fragmentShader, &fragmentSource)) {
+ if (!compileShader(fragmentShader, fragmentSource)) {
Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragmentSource);
throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile");
}
@@ -35,32 +36,50 @@ Shader::Shader(const char* name_, const char* vertexSource, const char* fragment
MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));
- {
- // Link program
- GLint status;
- MBGL_CHECK_ERROR(glLinkProgram(program.get()));
+ linkProgram(program);
- MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status));
- if (status == 0) {
- GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength));
- const auto log = std::make_unique<GLchar[]>(logLength);
- if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get()));
- Log::Error(Event::Shader, "Program failed to link: %s", log.get());
- }
- throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
+ std::string overdrawSource(fragmentSource);
+ if (overdrawSource.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos) {
+ programOverdraw = store.createProgram();
+ overdrawShader = store.createShader(GL_FRAGMENT_SHADER);
+
+ overdrawSource.replace(overdrawSource.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n");
+ if (!compileShader(*overdrawShader, overdrawSource.c_str())) {
+ Log::Error(Event::Shader, "Overdraw shader %s failed to compile: %s", name, overdrawSource.c_str());
+ throw util::ShaderException(std::string { "Overdraw shader " } + name + " failed to compile");
}
+
+ MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, vertexShader.get()));
+ MBGL_CHECK_ERROR(glAttachShader(*programOverdraw, *overdrawShader));
+ linkProgram(*programOverdraw);
}
a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), "a_pos"));
}
-bool Shader::compileShader(gl::UniqueShader& shader, const GLchar *source[]) {
+void Shader::linkProgram(gl::UniqueProgram& program_) {
+ // Link program
+ GLint status;
+ MBGL_CHECK_ERROR(glLinkProgram(program_.get()));
+
+ MBGL_CHECK_ERROR(glGetProgramiv(program_.get(), GL_LINK_STATUS, &status));
+ if (status == 0) {
+ GLint logLength;
+ MBGL_CHECK_ERROR(glGetProgramiv(program_.get(), GL_INFO_LOG_LENGTH, &logLength));
+ const auto log = std::make_unique<GLchar[]>(logLength);
+ if (logLength > 0) {
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program_.get(), logLength, &logLength, log.get()));
+ Log::Error(Event::Shader, "Program failed to link: %s", log.get());
+ }
+ throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
+ }
+}
+
+bool Shader::compileShader(gl::UniqueShader& shader, const GLchar *source) {
GLint status = 0;
- const GLsizei lengths = static_cast<GLsizei>(std::strlen(*source));
- MBGL_CHECK_ERROR(glShaderSource(shader.get(), 1, source, &lengths));
+ const GLsizei lengths = static_cast<GLsizei>(std::strlen(source));
+ MBGL_CHECK_ERROR(glShaderSource(shader.get(), 1, &source, &lengths));
MBGL_CHECK_ERROR(glCompileShader(shader.get()));
@@ -90,6 +109,10 @@ Shader::~Shader() {
MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get()));
MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get()));
}
+ if (programOverdraw) {
+ MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, vertexShader.get()));
+ MBGL_CHECK_ERROR(glDetachShader(*programOverdraw, *overdrawShader));
+ }
}
} // namespace mbgl
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
index 3ba1e044c7..4289b83a77 100644
--- a/src/mbgl/shader/shader.hpp
+++ b/src/mbgl/shader/shader.hpp
@@ -3,6 +3,7 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/optional.hpp>
namespace mbgl {
@@ -15,6 +16,10 @@ public:
return program.get();
}
+ GLuint getOverdrawID() const {
+ return programOverdraw ? *programOverdraw : 0;
+ }
+
virtual void bind(GLbyte *offset) = 0;
protected:
@@ -22,11 +27,15 @@ protected:
GLint a_pos = -1;
private:
- bool compileShader(gl::UniqueShader&, const GLchar *source[]);
+ bool compileShader(gl::UniqueShader&, const GLchar *source);
+ void linkProgram(gl::UniqueProgram&);
gl::UniqueProgram program;
gl::UniqueShader vertexShader;
gl::UniqueShader fragmentShader;
+
+ mbgl::optional<gl::UniqueProgram> programOverdraw;
+ mbgl::optional<gl::UniqueShader> overdrawShader;
};
} // namespace mbgl
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index cfeff6d400..c3bc5d73a0 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -258,7 +258,7 @@ bool Style::isLoaded() const {
return true;
}
-RenderData Style::getRenderData() const {
+RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
RenderData result;
for (const auto& source : sources) {
@@ -272,6 +272,11 @@ RenderData Style::getRenderData() const {
continue;
if (const BackgroundLayer* background = layer->as<BackgroundLayer>()) {
+ if (debugOptions & MapDebugOptions::Wireframe) {
+ // We want to skip glClear optimization in wireframe mode.
+ result.order.emplace_back(*layer);
+ continue;
+ }
const BackgroundPaintProperties& paint = background->impl->paint;
if (layer.get() == layers[0].get() && paint.backgroundPattern.value.from.empty()) {
// This is a solid background. We can use glClear().
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 1a41c4ce40..35369ffca3 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -74,7 +74,7 @@ public:
void setClasses(const std::vector<std::string>&, const TransitionOptions& = {});
std::vector<std::string> getClasses() const;
- RenderData getRenderData() const;
+ RenderData getRenderData(MapDebugOptions) const;
std::vector<Feature> queryRenderedFeatures(const QueryParameters&) const;