From 625ad1efe2f5113d69eedc363368256741d80780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 6 Aug 2014 12:36:19 +0200 Subject: [PATCH] fix icon rendering --- include/mbgl/shader/icon_shader.hpp | 4 ++ src/renderer/painter_symbol.cpp | 75 ++++++++++++++++------------- src/shader/icon.vertex.glsl | 4 +- src/shader/icon_shader.cpp | 8 +++ src/shader/text_shader.cpp | 1 + 5 files changed, 57 insertions(+), 35 deletions(-) diff --git a/include/mbgl/shader/icon_shader.hpp b/include/mbgl/shader/icon_shader.hpp index eab484387..54869fe48 100644 --- a/include/mbgl/shader/icon_shader.hpp +++ b/include/mbgl/shader/icon_shader.hpp @@ -20,6 +20,7 @@ public: void setMaxFadeZoom(float maxfadezoom); void setFadeZoom(float fadezoom); void setOpacity(float opacity); + void setTextureSize(const std::array &texsize); private: int32_t a_pos = -1; @@ -58,6 +59,9 @@ private: float opacity = 0; int32_t u_opacity = -1; + + std::array texsize = {{}}; + int32_t u_texsize = -1; }; } diff --git a/src/renderer/painter_symbol.cpp b/src/renderer/painter_symbol.cpp index 6358d26c4..a53c73f76 100644 --- a/src/renderer/painter_symbol.cpp +++ b/src/renderer/painter_symbol.cpp @@ -16,9 +16,10 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr lay return; } - if (bucket.hasTextData()) { - const SymbolProperties &properties = layer_desc->getProperties(); + const SymbolProperties &properties = layer_desc->getProperties(); + + if (bucket.hasTextData()) { mat4 exMatrix; matrix::copy(exMatrix, projMatrix); if (bucket.properties.placement == PlacementType::Line) { @@ -29,12 +30,6 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr lay float fontSize = std::fmin(properties.text.size, bucket.properties.text.max_size); matrix::scale(exMatrix, exMatrix, fontSize / 24.0f, fontSize / 24.0f, 1.0f); - // TODO: figure out whether we actually need to account for this while painting; we might - // already have - // done this during label placement. - // const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, - // properties.translateAnchor); - useProgram(textShader->program); textShader->setMatrix(matrix); textShader->setExtrudeMatrix(exMatrix); @@ -172,31 +167,45 @@ void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr lay } if (bucket.hasIconData()) { -// SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); -// -// useProgram(iconShader->program); -// iconShader->setMatrix(matrix); -// -// // TODO: update -// iconShader->setColor({{1, 1, 1, 1}}); -// iconShader->setImage(0); -// iconShader->setRatio(map.getState().getPixelRatio()); -// iconShader->setDimension({{ -// spriteAtlas.getTextureWidth(), spriteAtlas.getTextureHeight(), -// }}); -// -// spriteAtlas.bind(map.getState().isChanging()); -// -// // TODO: remove hardcoded icon size. -// const float iconSize = 12 * map.getState().getPixelRatio(); -// iconShader->setSize(iconSize); -//#ifndef GL_ES_VERSION_2_0 -// glPointSize(iconSize); -// glEnable(GL_POINT_SPRITE); -//#endif -// -// glDepthRange(strata, 1.0f); -// bucket.drawIcons(*iconShader); + mat4 exMatrix; + matrix::copy(exMatrix, projMatrix); + if (bucket.properties.icon.rotation_alignment == RotationAlignmentType::Map) { + matrix::rotate_z(exMatrix, exMatrix, map.getState().getAngle()); + } + + // If layerStyle.size > bucket.info.fontSize then labels may collide + const float fontSize = properties.icon.size != 0 ? properties.icon.size : bucket.properties.icon.max_size; + const float fontScale = fontSize / 1.0f; + matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f); + + useProgram(iconShader->program); + iconShader->setMatrix(matrix); + iconShader->setExtrudeMatrix(exMatrix); + + SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); + spriteAtlas.bind(map.getState().isChanging()); + iconShader->setTextureSize( + {{static_cast(spriteAtlas.getTextureWidth()), static_cast(spriteAtlas.getTextureHeight())}}); + + // Convert the -pi..pi to an int8 range. + float angle = std::round((map.getState().getAngle()) / M_PI * 128); + + // adjust min/max zooms for variable font sies + float zoomAdjust = log(fontSize / bucket.properties.icon.max_size) / log(2); + + iconShader->setAngle((int32_t)(angle + 256) % 256); + iconShader->setFlip(bucket.properties.placement == PlacementType::Line ? 1 : 0); + iconShader->setZoom((map.getState().getNormalizedZoom() - zoomAdjust) * + 10); // current zoom level + + iconShader->setFadeDist(0 * 10); + iconShader->setMinFadeZoom(map.getState().getNormalizedZoom() * 10); + iconShader->setMaxFadeZoom(map.getState().getNormalizedZoom() * 10); + iconShader->setFadeZoom(map.getState().getNormalizedZoom() * 10); + iconShader->setOpacity(properties.icon.opacity); + + glDepthRange(strata, 1.0f); + bucket.drawIcons(*iconShader); } } } diff --git a/src/shader/icon.vertex.glsl b/src/shader/icon.vertex.glsl index d273b733d..f8d94a263 100644 --- a/src/shader/icon.vertex.glsl +++ b/src/shader/icon.vertex.glsl @@ -11,7 +11,7 @@ attribute float a_labelminzoom; // posmatrix is for the vertex position, exmatrix is for rotating and projecting // the extrusion vector. -uniform mat4 u_posmatrix; +uniform mat4 u_matrix; uniform mat4 u_exmatrix; uniform float u_angle; uniform float u_zoom; @@ -66,7 +66,7 @@ void main() { // hide if (angle >= a_rangeend && angle < rangestart) z += step(a_rangeend, u_angle) * (1.0 - step(a_rangestart, u_angle)); - gl_Position = u_posmatrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0); + gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0); v_tex = a_tex / u_texsize; v_alpha *= u_opacity; diff --git a/src/shader/icon_shader.cpp b/src/shader/icon_shader.cpp index 435b813fa..6455d870a 100644 --- a/src/shader/icon_shader.cpp +++ b/src/shader/icon_shader.cpp @@ -36,6 +36,7 @@ IconShader::IconShader() u_maxfadezoom = glGetUniformLocation(program, "u_maxfadezoom"); u_fadezoom = glGetUniformLocation(program, "u_fadezoom"); u_opacity = glGetUniformLocation(program, "u_opacity"); + u_texsize = glGetUniformLocation(program, "u_texsize"); // fprintf(stderr, "IconShader:\n"); // fprintf(stderr, " - u_matrix: %d\n", u_matrix); @@ -144,3 +145,10 @@ void IconShader::setOpacity(float new_opacity) { } } +void IconShader::setTextureSize(const std::array &new_texsize) { + if (texsize != new_texsize) { + glUniform2fv(u_texsize, 1, new_texsize.data()); + texsize = new_texsize; + } +} + diff --git a/src/shader/text_shader.cpp b/src/shader/text_shader.cpp index c7cbbf560..c9e70825c 100644 --- a/src/shader/text_shader.cpp +++ b/src/shader/text_shader.cpp @@ -52,6 +52,7 @@ TextShader::TextShader() // fprintf(stderr, " - u_maxfadezoom: %d\n", u_maxfadezoom); // fprintf(stderr, " - u_fadezoom: %d\n", u_fadezoom); // fprintf(stderr, " - u_texsize: %d\n", u_texsize); + // fprintf(stderr, " - u_opacity: %d\n", u_opacity); } void TextShader::bind(char *offset) {