Skip to content

Commit

Permalink
Merge pull request #641 from openmobilemaps/release/2.5.0
Browse files Browse the repository at this point in the history
Release 2.5.0
  • Loading branch information
maurhofer-ubique authored Sep 17, 2024
2 parents b2e8a8d + 77580f7 commit fb5cbdc
Show file tree
Hide file tree
Showing 140 changed files with 1,838 additions and 441 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog for Open Mobile Maps

## Version 2.5.0
- Initial version of the integration of compute shaders into the render pipeline
- Fix of an issue for OpenGl that could lead to unnecessary buffer creations
- Fix logging of OpenGl Shader compilation/linking errors
- Fix of an invalid usage of clamp in the MapCamera2D
- Add support for a "raster-brightness-shift" attribute in the metadata clause of raster layers in vector style.jsons
- Add support for "text-halo-blur" in vector layers
- Fix of a superfluous alpha multiplication in the Metal RasterShader

## Version 2.4.0
- Add pass masking for single polygons
- Fixing pass masking in non-tile-masked contexts for OpenGl
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ let package = Package(
.target(
name: "MapCoreSharedModule",
dependencies: [
"MapCoreSharedModuleCpp"
"MapCoreSharedModuleCpp",
],
path: "bridging/ios",
publicHeadersPath: ""
Expand Down
4 changes: 2 additions & 2 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots/

GROUP=io.openmobilemaps
POM_ARTIFACT_ID=mapscore
VERSION_NAME=2.4.0
VERSION_CODE=2040000
VERSION_NAME=2.5.0
VERSION_CODE=2050000

POM_NAME=mapscore
POM_PACKAGING=aar
Expand Down
2 changes: 1 addition & 1 deletion android/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ This library is available on MavenCentral. To add it to your Android project, ad

```
dependencies {
implementation 'io.openmobilemaps:mapscore:2.4.0'
implementation 'io.openmobilemaps:mapscore:2.5.0'
}
```

Expand Down
2 changes: 2 additions & 0 deletions android/src/main/cpp/graphics/objects/Polygon2dOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ void Polygon2dOpenGl::prepareGlData(int program) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

mvpMatrixHandle = glGetUniformLocation(program, "uMVPMatrix");

glDataBuffersGenerated = true;
}

void Polygon2dOpenGl::clear() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ void PolygonPatternGroup2dOpenGl::prepareGlData(int program) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

mvpMatrixHandle = glGetUniformLocation(program, "uMVPMatrix");

glDataBuffersGenerated = true;
}

void PolygonPatternGroup2dOpenGl::clear() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ void Quad2dStretchedInstancedOpenGl::prepareGlData(int program) {
instStretchYsHandle = glGetAttribLocation(program, "aStretchY");

mvpMatrixHandle = glGetUniformLocation(program, "uMVPMatrix");

glDataBuffersGenerated = true;
}

void Quad2dStretchedInstancedOpenGl::prepareTextureCoordsGlData(int program) {
Expand Down
10 changes: 10 additions & 0 deletions android/src/main/cpp/graphics/objects/Text2dInstancedOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ void Text2dInstancedOpenGl::prepareGlData(int program) {
glBindBuffer(GL_ARRAY_BUFFER, 0);

mvpMatrixHandle = glGetUniformLocation(program, "uMVPMatrix");

glDataBuffersGenerated = true;
}

void Text2dInstancedOpenGl::prepareTextureCoordsGlData(int program) {
Expand Down Expand Up @@ -261,6 +263,14 @@ void Text2dInstancedOpenGl::render(const std::shared_ptr<::RenderingContextInter

// Draw the triangles
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

// Draw halos first
auto isHaloHandle = glGetUniformLocation(program, "isHalo");
glUniform1f(isHaloHandle, 1.0);
glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_BYTE, nullptr, instanceCount);

// Draw non-halos second
glUniform1f(isHaloHandle, 0.0);
glDrawElementsInstanced(GL_TRIANGLES,6, GL_UNSIGNED_BYTE, nullptr, instanceCount);

glBindBuffer(GL_ARRAY_BUFFER, 0);
Expand Down
10 changes: 6 additions & 4 deletions android/src/main/cpp/graphics/shader/BaseShaderProgramOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
int BaseShaderProgramOpenGl::loadShader(int type, std::string shaderCode) {
// create a vertex shader type (GL_VERTEX_SHADER)
// or a fragment shader type (GL_FRAGMENT_SHADER)
// or a compute shader type (GL_COMPUTE_SHADER)
int shader = glCreateShader(type);

// add the source code to the shader and compile it
Expand All @@ -33,7 +34,7 @@ int BaseShaderProgramOpenGl::loadShader(int type, std::string shaderCode) {
glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);

std::stringstream errorSS;
errorSS << "Shader " << shader << " (" << getProgramName() << ") failed:\n";
errorSS << "Shader " << shader << " failed:\n";

for (auto a : errorLog) {
errorSS << a;
Expand All @@ -56,13 +57,14 @@ void BaseShaderProgramOpenGl::checkGlProgramLinking(GLuint program) {
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);

LogError << "OpenGL Program Linking failed:";
std::stringstream errorSS;
errorSS << "OpenGL Program Linking failed:\n";

for (auto a : infoLog) {
LogError << a;
errorSS << a;
}

LogError <<= ".";
LogError << errorSS.str() <<= ".";
}
}

Expand Down
10 changes: 5 additions & 5 deletions android/src/main/cpp/graphics/shader/BaseShaderProgramOpenGl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@

class BaseShaderProgramOpenGl: public ShaderProgramInterface {
protected:
int loadShader(int type, std::string shaderCode);

void checkGlProgramLinking(GLuint program);

virtual std::string getVertexShader();

virtual std::string getFragmentShader();

public:
void preRender(const std::shared_ptr<::RenderingContextInterface> &context) override;
static int loadShader(int type, std::string shaderCode);

static void checkGlProgramLinking(GLuint program);

virtual void preRender(const std::shared_ptr<::RenderingContextInterface> &context) override;

protected:

Expand Down
16 changes: 9 additions & 7 deletions android/src/main/cpp/graphics/shader/RasterShaderOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ void RasterShaderOpenGl::setStyle(const RasterShaderStyle &style) {
styleValues[3] = style.brightnessMin;
styleValues[4] = style.brightnessMax;
styleValues[5] = style.gamma;
styleValues[6] = style.brightnessShift;
}

std::string RasterShaderOpenGl::getFragmentShader() {
return OMMVersionedGlesShaderCode(320 es,
precision mediump float;
precision highp float;
uniform sampler2D textureSampler;
// [0] opacity, 0-1 | [1] contrast, 0-1 | [2] saturation, 1-0 | [3] brightnessMin, 0-1 | [4] brightnessMax, 0-1 | [5] gamma, 0.1-10
uniform highp float styleValues[6];
// [0] opacity, 0-1 | [1] contrast, 0-1 | [2] saturation, 1-0 | [3] brightnessMin, 0-1 | [4] brightnessMax, 0-1 | [5] gamma, 0.1-10 | [6] brightnessShift, -1-1
uniform highp float styleValues[7];
in vec2 v_texcoord;
out vec4 fragmentColor;

Expand All @@ -73,15 +74,16 @@ std::string RasterShaderOpenGl::getFragmentShader() {
if (styleValues[0] == 0.0 || color.a == 0.0) {
discard;
}
color.rgb = clamp(color.rgb + styleValues[6], 0.0, 1.0); // brighntess shift
float average = (color.r + color.g + color.b) / 3.0;
vec3 rgb = color.rgb + (vec3(average) - color.rgb) * styleValues[2];
rgb = (rgb - vec3(0.5)) * styleValues[1] + 0.5;
vec3 rgb = color.rgb + (vec3(average) - color.rgb) * styleValues[2]; // saturation
rgb = clamp((rgb - vec3(0.5)) * styleValues[1] + 0.5, 0.0, 1.0); // contrast (notice range 0-1)

vec3 brightnessMin = vec3(styleValues[3]);
vec3 brightnessMax = vec3(styleValues[4]);

rgb = pow(rgb, vec3(1.0 / styleValues[5]));
rgb = mix(brightnessMin, brightnessMax, min(rgb / color.a, vec3(1.0)));
rgb = pow(rgb, vec3(1.0 / styleValues[5])); // gamma
rgb = mix(brightnessMin, brightnessMax, min(rgb / color.a, vec3(1.0))); // brightness min/max mix
fragmentColor = vec4(rgb * color.a, color.a) * styleValues[0];
});
}
2 changes: 1 addition & 1 deletion android/src/main/cpp/graphics/shader/RasterShaderOpenGl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ class RasterShaderOpenGl : public BaseShaderProgramOpenGl,
const static std::string programName;

std::mutex dataMutex;
std::vector<GLfloat> styleValues = {1.0, 1.0, 1.0, 0.0, 1.0, 1.0};
std::vector<GLfloat> styleValues = {1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0};
};

54 changes: 35 additions & 19 deletions android/src/main/cpp/graphics/shader/TextInstancedShaderOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ std::string TextInstancedShaderOpenGl::getFragmentShader() {
return OMMVersionedGlesShaderCode(320 es,
precision highp float;
layout(std430, binding = 0) buffer textInstancedStyleBuffer {
float styles[]; // vec4 color; vec4 haloColor; float haloWidth;
float styles[]; // vec4 color; vec4 haloColor; float haloWidth; float haloBlur;
};

uniform sampler2D textureSampler;
uniform vec2 textureFactor;
uniform float isHalo; // 0.0 = false, 1.0 = true

in vec2 v_texCoord;
in vec4 v_texCoordInstance;
Expand All @@ -92,12 +93,13 @@ std::string TextInstancedShaderOpenGl::getFragmentShader() {
out vec4 fragmentColor;

void main() {
int styleOffset = int(vStyleIndex) * 9;
vec4 color = vec4(styles[styleOffset + 0], styles[styleOffset + 1], styles[styleOffset + 2], styles[styleOffset + 3]);
vec4 haloColor = vec4(styles[styleOffset + 4], styles[styleOffset + 5], styles[styleOffset + 6], styles[styleOffset + 7]);
float haloWidth = styles[styleOffset + 8];
int styleOffset = int(vStyleIndex) * 10;

if (color.a == 0.0 && haloColor.a == 0.0) {
int colorOffset = int(isHalo) * 4 + styleOffset; // fill/halo color switch
vec4 color = vec4(styles[colorOffset + 0], styles[colorOffset + 1],
styles[colorOffset + 2], styles[colorOffset + 3]);

if (color.a == 0.0) {
discard;
}

Expand All @@ -106,23 +108,37 @@ std::string TextInstancedShaderOpenGl::getFragmentShader() {

float median = max(min(dist.r, dist.g), min(max(dist.r, dist.g), dist.b)) / dist.a;
float w = fwidth(median);
float alpha = smoothstep(0.5 - w, 0.5 + w, median);

vec4 mixed = mix(haloColor, color, alpha);
float fillStart = 0.5 - w;
float fillEnd = 0.5 + w;

float innerFallOff = smoothstep(fillStart, fillEnd, median);

float edgeAlpha = 0.0;

if(bool(isHalo)) {
float haloWidth = styles[styleOffset + 8];
float halfHaloBlur = 0.5 * styles[styleOffset + 9];

if(haloWidth > 0.0) {
float start = (0.0 + 0.5 * (1.0 - haloWidth)) - w;
float end = start + w;
float a2 = smoothstep(start, end, median) * color.a;
fragmentColor = mixed;
fragmentColor.a = 1.0;
fragmentColor *= a2;
if (haloWidth == 0.0 && halfHaloBlur == 0.0) {
discard;
}

float start = max(0.0, fillStart - (haloWidth + halfHaloBlur));
float end = fillStart - max(0.0, haloWidth - halfHaloBlur);

float sideSwitch = step(median, end);
float outerFallOff = smoothstep(start, end, median);

// Combination of blurred outer falloff and inverse inner fill falloff
edgeAlpha = (sideSwitch * outerFallOff + (1.0 - sideSwitch) * (1.0 - innerFallOff)) * color.a;
} else {
float a2 = alpha * color.a;
fragmentColor = mixed;
fragmentColor.a = 1.0;
fragmentColor *= a2;
edgeAlpha = innerFallOff * color.a;
}

fragmentColor = color;
fragmentColor.a = 1.0;
fragmentColor *= edgeAlpha;
}
);
}
Expand Down
48 changes: 34 additions & 14 deletions android/src/main/cpp/graphics/shader/TextShaderOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ void TextShaderOpenGl::setColor(const ::Color & c) {
color[3] = c.a;
}

void TextShaderOpenGl::setHaloColor(const ::Color & color, double width) {
void TextShaderOpenGl::setHaloColor(const ::Color & color, float width, float blur) {
std::lock_guard<std::mutex> lock(dataMutex);
haloColor[0] = color.r;
haloColor[1] = color.g;
haloColor[2] = color.b;
haloColor[3] = color.a;
haloWidth = width;
haloBlur = blur;
}

void TextShaderOpenGl::setOpacity(float opacity) { this->opacity = opacity; }
Expand Down Expand Up @@ -61,12 +62,14 @@ void TextShaderOpenGl::preRender(const std::shared_ptr<::RenderingContextInterfa
int colorHandle = glGetUniformLocation(program, "color");
int haloColorHandle = glGetUniformLocation(program, "haloColor");
int haloWidthHandle = glGetUniformLocation(program, "haloWidth");
int haloBlurHandle = glGetUniformLocation(program, "haloBlur");
int opacityHandle = glGetUniformLocation(program, "opacity");
{
std::lock_guard<std::mutex> lock(dataMutex);
glUniform4fv(colorHandle, 1, &color[0]);
glUniform4fv(haloColorHandle, 1, &haloColor[0]);
glUniform1f(haloWidthHandle, haloWidth);
glUniform1f(haloBlurHandle, haloBlur);
glUniform1f(opacityHandle, opacity);
}

Expand Down Expand Up @@ -96,33 +99,50 @@ std::string TextShaderOpenGl::getFragmentShader() {
uniform vec4 haloColor;
uniform float opacity;
uniform float haloWidth;
uniform float haloBlur;
uniform float isHalo; // 0.0 = false, 1.0 = true
in vec2 vTextCoord;
out vec4 fragmentColor;

void main() {
vec4 dist = texture(textureSampler, vTextCoord);
vec4 finalColor = isHalo * haloColor + (1.0 - isHalo) * color; // fill/halo color switch

if(opacity == 0.0) {
if (opacity == 0.0 || finalColor.a == 0.0) {
discard;
}

float median = max(min(dist.r, dist.g), min(max(dist.r, dist.g), dist.b)) / dist.a;
vec4 dist = texture(textureSampler, vTextCoord);

float median = max(min(dist.r, dist.g), min(max(dist.r, dist.g), dist.b)) / dist.a;
float w = fwidth(median);
float alpha = smoothstep(0.5 - w, 0.5 + w, median);

vec4 mixed = mix(haloColor, color, alpha);
float fillStart = 0.5 - w;
float fillEnd = 0.5 + w;

float innerFallOff = smoothstep(fillStart, fillEnd, median);

if(haloWidth > 0.0) {
float start = (0.0 + 0.5 * (1.0 - haloWidth)) - w;
float end = start + w;
float a2 = smoothstep(start, end, median) * opacity;
fragmentColor = mixed;
fragmentColor.a = 1.0;
fragmentColor *= a2;
float edgeAlpha = 0.0;

if(bool(isHalo)) {
if (haloWidth == 0.0 && haloBlur == 0.0) {
discard;
}

float start = max(0.0, fillStart - (haloWidth + 0.5 * haloBlur));
float end = fillStart - max(0.0, haloWidth - 0.5 * haloBlur);

float sideSwitch = step(median, end);
float outerFallOff = smoothstep(start, end, median);

// Combination of blurred outer falloff and inverse inner fill falloff
edgeAlpha = (sideSwitch * outerFallOff + (1.0 - sideSwitch) * (1.0 - innerFallOff)) * finalColor.a;
} else {
fragmentColor = mixed;
edgeAlpha = innerFallOff * finalColor.a;
}

fragmentColor = finalColor;
fragmentColor.a = 1.0;
fragmentColor *= edgeAlpha;
});
}

Expand Down
3 changes: 2 additions & 1 deletion android/src/main/cpp/graphics/shader/TextShaderOpenGl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TextShaderOpenGl : public BaseShaderProgramOpenGl,

virtual void setColor(const ::Color & color) override;

virtual void setHaloColor(const ::Color & color, double width) override;
virtual void setHaloColor(const ::Color & color, float width, float blur) override;

virtual void setOpacity(float opacity) override;

Expand All @@ -48,4 +48,5 @@ class TextShaderOpenGl : public BaseShaderProgramOpenGl,
std::vector<float> haloColor = {0.0, 0.0, 0.0, 0.0};
float opacity = 0.0;
float haloWidth = 0.0f;
float haloBlur = 0.0f;
};
Loading

0 comments on commit fb5cbdc

Please sign in to comment.