summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/layers/render_raster_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/layers/render_raster_layer.cpp')
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.cpp127
1 files changed, 116 insertions, 11 deletions
diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp
index 84e27a3895..06616d90e5 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.cpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.cpp
@@ -1,14 +1,18 @@
#include <mbgl/renderer/layers/render_raster_layer.hpp>
-#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/style/layers/raster_layer_impl.hpp>
-#include <mbgl/gl/context.hpp>
+#include <mbgl/renderer/buckets/raster_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/tile/tile.hpp>
+#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/sources/render_image_source.hpp>
-#include <mbgl/renderer/painter.hpp>
+#include <mbgl/renderer/render_static_data.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/raster_program.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/style/layers/raster_layer_impl.hpp>
namespace mbgl {
+using namespace style;
+
RenderRasterLayer::RenderRasterLayer(Immutable<style::RasterLayer::Impl> _impl)
: RenderLayer(style::LayerType::Raster, _impl),
unevaluated(impl().paint.untransitioned()) {
@@ -37,12 +41,113 @@ bool RenderRasterLayer::hasTransition() const {
return unevaluated.hasTransition();
}
-void RenderRasterLayer::render(Painter& painter, PaintParameters& parameters, RenderSource* source) {
- RenderLayer::render(painter, parameters, source);
- if (renderTiles.empty()) {
- RenderImageSource* imageSource = source->as<RenderImageSource>();
- if (imageSource) {
- imageSource->render(painter, parameters, *this);
+static float saturationFactor(float saturation) {
+ if (saturation > 0) {
+ return 1 - 1 / (1.001 - saturation);
+ } else {
+ return -saturation;
+ }
+}
+
+static float contrastFactor(float contrast) {
+ if (contrast > 0) {
+ return 1 / (1 - contrast);
+ } else {
+ return 1 + contrast;
+ }
+}
+
+static std::array<float, 3> spinWeights(float spin) {
+ spin *= util::DEG2RAD;
+ float s = std::sin(spin);
+ float c = std::cos(spin);
+ std::array<float, 3> spin_weights = {{
+ (2 * c + 1) / 3,
+ (-std::sqrt(3.0f) * s - c + 1) / 3,
+ (std::sqrt(3.0f) * s - c + 1) / 3
+ }};
+ return spin_weights;
+}
+
+void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source) {
+ if (parameters.pass != RenderPass::Translucent)
+ return;
+
+ auto draw = [&] (const mat4& matrix,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments) {
+ parameters.programs.raster.draw(
+ parameters.context,
+ gl::Triangles(),
+ parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ RasterProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_image0::Value{ 0 },
+ uniforms::u_image1::Value{ 1 },
+ uniforms::u_opacity::Value{ evaluated.get<RasterOpacity>() },
+ uniforms::u_fade_t::Value{ 1 },
+ uniforms::u_brightness_low::Value{ evaluated.get<RasterBrightnessMin>() },
+ uniforms::u_brightness_high::Value{ evaluated.get<RasterBrightnessMax>() },
+ uniforms::u_saturation_factor::Value{ saturationFactor(evaluated.get<RasterSaturation>()) },
+ uniforms::u_contrast_factor::Value{ contrastFactor(evaluated.get<RasterContrast>()) },
+ uniforms::u_spin_weights::Value{ spinWeights(evaluated.get<RasterHueRotate>()) },
+ uniforms::u_buffer_scale::Value{ 1.0f },
+ uniforms::u_scale_parent::Value{ 1.0f },
+ uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} },
+ },
+ vertexBuffer,
+ indexBuffer,
+ segments,
+ RasterProgram::PaintPropertyBinders { evaluated, 0 },
+ evaluated,
+ parameters.state.getZoom(),
+ getID()
+ );
+ };
+
+ if (RenderImageSource* imageSource = source->as<RenderImageSource>()) {
+ if (imageSource->isEnabled() && imageSource->isLoaded() && !imageSource->bucket->needsUpload()) {
+ RasterBucket& bucket = *imageSource->bucket;
+
+ assert(bucket.texture);
+ parameters.context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
+ parameters.context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
+
+ for (auto matrix_ : imageSource->matrices) {
+ draw(matrix_,
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments);
+ }
+ }
+ } else {
+ for (const RenderTile& tile : renderTiles) {
+ assert(dynamic_cast<RasterBucket*>(tile.tile.getBucket(*baseImpl)));
+ RasterBucket& bucket = *reinterpret_cast<RasterBucket*>(tile.tile.getBucket(*baseImpl));
+
+ if (!bucket.hasData())
+ continue;
+
+ assert(bucket.texture);
+ parameters.context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
+ parameters.context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
+
+ if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
+ // Draw only the parts of the tile that aren't drawn by another tile in the layer.
+ draw(tile.matrix,
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments);
+ } else {
+ // Draw the full tile.
+ draw(tile.matrix,
+ parameters.staticData.rasterVertexBuffer,
+ parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments);
+ }
}
}
}