Skip to content

Commit

Permalink
Merge pull request #585 from openmobilemaps/feature/fading-pattern
Browse files Browse the repository at this point in the history
Add scale-in option for vector layer polygons
  • Loading branch information
maurhofer-ubique authored Feb 5, 2024
2 parents df94302 + dad152a commit 771f29d
Show file tree
Hide file tree
Showing 53 changed files with 520 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ void PolygonPatternGroup2dOpenGl::render(const std::shared_ptr<::RenderingContex
auto scalingFactorHandle = glGetUniformLocation(program, "uScalingFactor");
glUniform2f(scalingFactorHandle, scalingFactor.x, scalingFactor.y);

auto screenPixelAsRealMeterFactorHandle = glGetUniformLocation(program, "uScreenPixelAsRealMeterFactor");
if (screenPixelAsRealMeterFactorHandle >= 0) {
glUniform1f(screenPixelAsRealMeterFactorHandle, screenPixelAsRealMeterFactor);
}

int textureCoordinatesHandle = glGetUniformLocation(program, "textureCoordinates");
glUniform1fv(textureCoordinatesHandle, sizeTextureCoordinatesValuesArray, &textureCoordinates[0]);
int opacitiesHandle = glGetUniformLocation(program, "opacities");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
#include "OpenGlContext.h"
#include "OpenGlHelper.h"

const std::string PolygonPatternGroup2dShaderOpenGl::programName = "UBMAP_PolygonPatternGroup2dShaderOpenGl";
#include <algorithm>
#include <string>
#include <iostream>

PolygonPatternGroup2dShaderOpenGl::PolygonPatternGroup2dShaderOpenGl(bool fadeInPattern)
: fadeInPattern(fadeInPattern),
programName(std::string("UBMAP_PolygonPatternGroup2dShaderOpenGl_") + (fadeInPattern ? "std" : "fade")) {}

std::string PolygonPatternGroup2dShaderOpenGl::getProgramName() { return programName; }

Expand Down Expand Up @@ -45,14 +51,22 @@ std::string PolygonPatternGroup2dShaderOpenGl::getVertexShader() {

uniform mat4 uMVPMatrix;
uniform vec2 uScalingFactor;
) + (fadeInPattern ? OMMShaderCode(uniform float uScreenPixelAsRealMeterFactor;) : "")
+ OMMShaderCode(

out vec2 pixelPosition;
out flat uint styleIndex;

void main() {
pixelPosition = vPosition.xy * vec2(1.0 / uScalingFactor.x, 1.0 / uScalingFactor.y);
styleIndex = uint(floor(vStyleIndex + 0.5));
gl_Position = uMVPMatrix * vec4(vPosition, 0.0, 1.0);
) + (fadeInPattern ? OMMShaderCode(
// fadeInPattern
pixelPosition = vPosition.xy / vec2(uScreenPixelAsRealMeterFactor);
) : OMMShaderCode(
// DefaultBehavior
pixelPosition = vPosition.xy / uScalingFactor;
)) + OMMShaderCode(
styleIndex = uint(floor(vStyleIndex + 0.5));
gl_Position = uMVPMatrix * vec4(vPosition, 0.0, 1.0);
}
);
}
Expand All @@ -65,6 +79,10 @@ std::string PolygonPatternGroup2dShaderOpenGl::getFragmentShader() {
uniform vec2 uTextureFactor;
uniform float textureCoordinates[5 * 16];
uniform float opacities[16];
) + (fadeInPattern ? OMMShaderCode(
uniform float uScreenPixelAsRealMeterFactor;
uniform vec2 uScalingFactor;) : "")
+ OMMShaderCode(

in vec2 pixelPosition;
in flat uint styleIndex;
Expand All @@ -78,21 +96,85 @@ std::string PolygonPatternGroup2dShaderOpenGl::getFragmentShader() {
}

int styleOffset = min(int(styleIndex) * 5, 16 * 5);
vec2 uvSize = vec2(textureCoordinates[styleOffset + 2], textureCoordinates[styleOffset + 3]) * uTextureFactor;
vec2 uvSize =
vec2(textureCoordinates[styleOffset + 2], textureCoordinates[styleOffset + 3]) *
uTextureFactor;
if (uvSize.x == 0.0 && uvSize.y == 0.0) {
discard;
}
vec2 uvOrig = vec2(textureCoordinates[styleOffset], textureCoordinates[styleOffset + 1]) * uTextureFactor;
vec2 uvOrig = vec2(textureCoordinates[styleOffset], textureCoordinates[styleOffset + 1]) *
uTextureFactor;
float combined = textureCoordinates[styleOffset + 4];
vec2 pixelSize = vec2(mod(combined, 65536.0), combined / 65536.0);
) + (fadeInPattern ? OMMShaderCode(
// fadeInPattern
vec4 resultColor = vec4(0.0, 0.0, 0.0, 0.0);
float scalingFactorFactor = (uScalingFactor.x / uScreenPixelAsRealMeterFactor) - 1.0;
vec2 spacing = pixelSize * scalingFactorFactor;
vec2 totalSize = pixelSize + spacing;
vec2 adjustedPixelPosition = pixelPosition + pixelSize * 0.5;
vec2 uvTot = mod(adjustedPixelPosition, totalSize);

int yIndex = int(mod(adjustedPixelPosition.y / totalSize.y, 2.0));

if (yIndex != 0 && uvTot.y <= pixelSize.y) {
uvTot.x = mod(adjustedPixelPosition.x + totalSize.x * 0.5, totalSize.x);
}

vec2 uv = mod(vec2(mod(pixelPosition.x, pixelSize.x), mod(pixelPosition.y, pixelSize.y)) / pixelSize + vec2(1.0, 1.0), vec2(1.0, 1.0));
vec2 texUv = uvOrig + uvSize * uv;
vec4 color = texture(uTextureSampler, texUv);

float a = color.a * opacity;
fragmentColor = vec4(color.rgb * a, a);
if (uvTot.x > pixelSize.x || uvTot.y > pixelSize.y) {
if (uvTot.x > pixelSize.x && uvTot.y < pixelSize.y) {
// top right
vec2 spacingTexSize = vec2(spacing.x, spacing.x);
float relative = uvTot.y - (pixelSize.y - spacing.x) / 2.0;
if (relative > 0.0 && relative < spacing.x) {
float xPos = uvTot.x - pixelSize.x;
vec2 uv = mod(vec2(xPos, relative) / spacingTexSize + vec2(1.0, 1.0),
vec2(1.0, 1.0));

vec2 texUv = uvOrig + uvSize * vec2(uv.x, uv.y);
vec4 texColor = texture(uTextureSampler, texUv);
resultColor = texColor;
}
} else {
uvTot.x = mod(adjustedPixelPosition.x + spacing.x * 0.5, totalSize.x);
if (uvTot.x > pixelSize.x && uvTot.y > pixelSize.y) {
// bottom right
vec2 uv = mod((uvTot - pixelSize) / spacing + vec2(1.0, 1.0), vec2(1.0, 1.0));

vec2 texUv = uvOrig + uvSize * vec2(uv.x, uv.y);
vec4 texColor = texture(uTextureSampler, texUv);
resultColor = texColor;
} else {
// bottom left
vec2 spacingTexSize = vec2(spacing.y, spacing.y);
float relativeX = uvTot.x - (pixelSize.x - spacing.x) / 2.0;

if (relativeX > 0.0 && relativeX < spacing.y) {
vec2 uv = mod(vec2(relativeX, uvTot.y - pixelSize.y) / spacingTexSize +
vec2(1.0, 1.0), vec2(1.0, 1.0));
vec2 texUv = uvOrig + uvSize * vec2(uv.x, uv.y);
vec4 texColor = texture(uTextureSampler, texUv);
resultColor = texColor;
}
}
}
} else {
vec2 uv = mod(uvTot / pixelSize + vec2(1.0, 1.0), vec2(1.0, 1.0));
vec2 texUv = uvOrig + uvSize * vec2(uv.x, uv.y);
vec4 texColor = texture(uTextureSampler, texUv);
resultColor = texColor;
}
fragmentColor = resultColor;
}
) : OMMShaderCode(
// Default pattern behavior
vec2 uv = mod(vec2(mod(pixelPosition.x, pixelSize.x), mod(pixelPosition.y, pixelSize.y)) / pixelSize + vec2(1.0, 1.0), vec2(1.0, 1.0));
vec2 texUv = uvOrig + uvSize * uv;
vec4 color = texture(uTextureSampler, texUv);

float a = color.a * opacity;
fragmentColor = vec4(color.rgb * a, a);
}
);
));
}
std::shared_ptr<ShaderProgramInterface> PolygonPatternGroup2dShaderOpenGl::asShaderProgramInterface() { return shared_from_this(); }
std::shared_ptr<ShaderProgramInterface> PolygonPatternGroup2dShaderOpenGl::asShaderProgramInterface() { return shared_from_this(); }
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class PolygonPatternGroup2dShaderOpenGl : public BaseShaderProgramOpenGl,
public std::enable_shared_from_this<ShaderProgramInterface> {

public:
PolygonPatternGroup2dShaderOpenGl(bool fadeInPattern);

virtual std::string getProgramName() override;

virtual void setupProgram(const std::shared_ptr<::RenderingContextInterface> &context) override;
Expand All @@ -30,7 +32,8 @@ class PolygonPatternGroup2dShaderOpenGl : public BaseShaderProgramOpenGl,
virtual std::shared_ptr<ShaderProgramInterface> asShaderProgramInterface() override;

protected:
const static std::string programName;
const bool fadeInPattern;
const std::string programName;

virtual std::string getFragmentShader() override;

Expand Down
4 changes: 2 additions & 2 deletions android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ std::shared_ptr<PolygonGroupShaderInterface> ShaderFactoryOpenGl::createPolygonG
return std::make_shared<ColorPolygonGroup2dShaderOpenGl>();
}

std::shared_ptr<PolygonPatternGroupShaderInterface> ShaderFactoryOpenGl::createPolygonPatternGroupShader() {
return std::make_shared<PolygonPatternGroup2dShaderOpenGl>();
std::shared_ptr<PolygonPatternGroupShaderInterface> ShaderFactoryOpenGl::createPolygonPatternGroupShader(bool fadeInPattern) {
return std::make_shared<PolygonPatternGroup2dShaderOpenGl>(fadeInPattern);
}

std::shared_ptr<TextShaderInterface> ShaderFactoryOpenGl::createTextShader() {
Expand Down
2 changes: 1 addition & 1 deletion android/src/main/cpp/graphics/shader/ShaderFactoryOpenGl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ShaderFactoryOpenGl : public ShaderFactoryInterface {

std::shared_ptr<PolygonGroupShaderInterface> createPolygonGroupShader() override;

std::shared_ptr<PolygonPatternGroupShaderInterface> createPolygonPatternGroupShader() override;
std::shared_ptr<PolygonPatternGroupShaderInterface> createPolygonPatternGroupShader(bool fadeInPattern) override;

std::shared_ptr<TextShaderInterface> createTextShader() override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ class GLThread constructor(
width = w
height = h
sizeChanged = true
requestRender()
}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 771f29d

Please sign in to comment.