add textshader
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <llmr/shader/linejoin_shader.hpp>
|
||||
#include <llmr/shader/point_shader.hpp>
|
||||
#include <llmr/shader/raster_shader.hpp>
|
||||
#include <llmr/shader/text_shader.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
@@ -84,6 +85,7 @@ private:
|
||||
std::unique_ptr<PatternShader> patternShader;
|
||||
std::unique_ptr<PointShader> pointShader;
|
||||
std::unique_ptr<RasterShader> rasterShader;
|
||||
std::unique_ptr<TextShader> textShader;
|
||||
|
||||
// Set up the stencil quad we're using to generate the stencil mask.
|
||||
VertexBuffer tileStencilBuffer = {
|
||||
|
||||
@@ -12,15 +12,66 @@ public:
|
||||
void bind(char *offset);
|
||||
|
||||
void setColor(float r, float g, float b, float a);
|
||||
void setColor(const std::array<float, 4>& color);
|
||||
void setColor(const std::array<float, 4> &color);
|
||||
void setBuffer(float buffer);
|
||||
void setGamma(float gamma);
|
||||
void setExmatrix(const std::array<float, 16> &exmatrix);
|
||||
void setAngle(float angle);
|
||||
void setZoom(float zoom);
|
||||
void setFlip(float flip);
|
||||
void setFadedist(float fadedist);
|
||||
void setMinfadezoom(float minfadezoom);
|
||||
void setMaxfadezoom(float maxfadezoom);
|
||||
void setFadezoom(float fadezoom);
|
||||
void setTexsize(const std::array<float, 2> &texsize);
|
||||
|
||||
private:
|
||||
int32_t a_pos = -1;
|
||||
int32_t a_offset = -1;
|
||||
int32_t a_tex = -1;
|
||||
int32_t a_angle = -1;
|
||||
int32_t a_minzoom = -1;
|
||||
int32_t a_maxzoom = -1;
|
||||
int32_t a_rangeend = -1;
|
||||
int32_t a_rangestart = -1;
|
||||
int32_t a_labelminzoom = -1;
|
||||
|
||||
std::array<float, 4> color = {{}};
|
||||
int32_t u_color = -1;
|
||||
};
|
||||
|
||||
float buffer = 0.0f;
|
||||
int32_t u_buffer = -1;
|
||||
|
||||
float gamma = 0.0f;
|
||||
int32_t u_gamma = -1;
|
||||
|
||||
std::array<float, 16> exmatrix = {{}};
|
||||
int32_t u_exmatrix = -1;
|
||||
|
||||
float angle = 0.0f;
|
||||
int32_t u_angle = -1;
|
||||
|
||||
float zoom = 0.0f;
|
||||
int32_t u_zoom = -1;
|
||||
|
||||
float flip = 0.0f;
|
||||
int32_t u_flip = -1;
|
||||
|
||||
float fadedist = 0.0f;
|
||||
int32_t u_fadedist = -1;
|
||||
|
||||
float minfadezoom = 0.0f;
|
||||
int32_t u_minfadezoom = -1;
|
||||
|
||||
float maxfadezoom = 0.0f;
|
||||
int32_t u_maxfadezoom = -1;
|
||||
|
||||
float fadezoom = 0.0f;
|
||||
int32_t u_fadezoom = -1;
|
||||
|
||||
std::array<float, 2> texsize = {{}};
|
||||
int32_t u_texsize = -1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@ void Painter::setup() {
|
||||
assert(linejoinShader);
|
||||
assert(patternShader);
|
||||
assert(rasterShader);
|
||||
assert(textShader);
|
||||
|
||||
|
||||
// Blending
|
||||
@@ -65,6 +66,7 @@ void Painter::setupShaders() {
|
||||
patternShader = std::make_unique<PatternShader>();
|
||||
pointShader = std::make_unique<PointShader>();
|
||||
rasterShader = std::make_unique<RasterShader>();
|
||||
textShader = std::make_unique<TextShader>();
|
||||
}
|
||||
|
||||
void Painter::resize(int width, int height) {
|
||||
@@ -476,6 +478,8 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co
|
||||
|
||||
void Painter::renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id) {
|
||||
// noop
|
||||
useProgram(textShader->program);
|
||||
textShader->setMatrix(matrix);
|
||||
}
|
||||
|
||||
void Painter::renderDebug(const TileData::Ptr& tile_data) {
|
||||
|
||||
@@ -33,7 +33,7 @@ const shader_source llmr::shaders[SHADER_COUNT] = {
|
||||
"uniform sampler2D u_image;\nuniform float u_opacity;\n\nvarying vec2 v_pos;\n\nvoid main() {\n gl_FragColor = texture2D(u_image, v_pos) * u_opacity;\n}\n",
|
||||
},
|
||||
{
|
||||
"attribute vec2 a_pos;\n\nuniform mat4 u_matrix;\n\nvoid main() {\n gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n",
|
||||
"uniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n",
|
||||
"attribute vec2 a_pos;\nattribute vec2 a_offset;\nattribute vec2 a_tex;\nattribute float a_angle;\nattribute float a_minzoom;\nattribute float a_maxzoom;\nattribute float a_rangeend;\nattribute float a_rangestart;\nattribute float a_labelminzoom;\n\n\n// posmatrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\nuniform float u_angle;\nuniform float u_zoom;\nuniform float u_flip;\nuniform float u_fadedist;\nuniform float u_minfadezoom;\nuniform float u_maxfadezoom;\nuniform float u_fadezoom;\n\nuniform vec2 u_texsize;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n\n float a_fadedist = 10.0;\n float rev = 0.0;\n\n // u_angle is angle of the map, -128..128 representing 0..2PI\n // a_angle is angle of the label, 0..256 representing 0..2PI, where 0 is horizontal text\n float rotated = mod(a_angle + u_angle, 256.0);\n // if the label rotates with the map, and if the rotated label is upside down, hide it\n if (u_flip > 0.0 && rotated >= 64.0 && rotated < 192.0) rev = 1.0;\n\n // If the label should be invisible, we move the vertex outside\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n // u_zoom is the current zoom level adjusted for the change in font size\n float z = 2.0 - step(a_minzoom, u_zoom) - (1.0 - step(a_maxzoom, u_zoom)) + rev;\n\n // fade out labels\n float alpha = clamp((u_fadezoom - a_labelminzoom) / u_fadedist, 0.0, 1.0);\n\n if (u_fadedist >= 0.0) {\n v_alpha = alpha;\n } else {\n v_alpha = 1.0 - alpha;\n }\n if (u_maxfadezoom < a_labelminzoom) {\n v_alpha = 0.0;\n }\n if (u_minfadezoom >= a_labelminzoom) {\n v_alpha = 1.0;\n }\n\n // if label has been faded out, clip it\n z += step(v_alpha, 0.0);\n\n // all the angles are 0..256 representing 0..2PI\n // hide if (angle >= a_rangeend && angle < rangestart)\n z += step(a_rangeend, u_angle) * (1.0 - step(a_rangestart, u_angle));\n\n gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0);\n v_tex = a_tex * 4.0 / u_texsize;\n}\n",
|
||||
"uniform sampler2D u_texture;\nuniform vec4 u_color;\nuniform float u_buffer;\nuniform float u_gamma;\n\nvarying vec2 v_tex;\nvarying float v_alpha;\n\nvoid main() {\n float dist = texture2D(u_texture, v_tex).a;\n float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist) * v_alpha;\n gl_FragColor = u_color * alpha;\n}\n",
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
uniform sampler2D u_texture;
|
||||
uniform vec4 u_color;
|
||||
uniform float u_buffer;
|
||||
uniform float u_gamma;
|
||||
|
||||
varying vec2 v_tex;
|
||||
varying float v_alpha;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = u_color;
|
||||
float dist = texture2D(u_texture, v_tex).a;
|
||||
float alpha = smoothstep(u_buffer - u_gamma, u_buffer + u_gamma, dist) * v_alpha;
|
||||
gl_FragColor = u_color * alpha;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,70 @@
|
||||
attribute vec2 a_pos;
|
||||
attribute vec2 a_offset;
|
||||
attribute vec2 a_tex;
|
||||
attribute float a_angle;
|
||||
attribute float a_minzoom;
|
||||
attribute float a_maxzoom;
|
||||
attribute float a_rangeend;
|
||||
attribute float a_rangestart;
|
||||
attribute float a_labelminzoom;
|
||||
|
||||
|
||||
// posmatrix is for the vertex position, exmatrix is for rotating and projecting
|
||||
// the extrusion vector.
|
||||
uniform mat4 u_matrix;
|
||||
uniform mat4 u_exmatrix;
|
||||
uniform float u_angle;
|
||||
uniform float u_zoom;
|
||||
uniform float u_flip;
|
||||
uniform float u_fadedist;
|
||||
uniform float u_minfadezoom;
|
||||
uniform float u_maxfadezoom;
|
||||
uniform float u_fadezoom;
|
||||
|
||||
uniform vec2 u_texsize;
|
||||
|
||||
varying vec2 v_tex;
|
||||
varying float v_alpha;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_matrix * vec4(a_pos, 0, 1);
|
||||
|
||||
float a_fadedist = 10.0;
|
||||
float rev = 0.0;
|
||||
|
||||
// u_angle is angle of the map, -128..128 representing 0..2PI
|
||||
// a_angle is angle of the label, 0..256 representing 0..2PI, where 0 is horizontal text
|
||||
float rotated = mod(a_angle + u_angle, 256.0);
|
||||
// if the label rotates with the map, and if the rotated label is upside down, hide it
|
||||
if (u_flip > 0.0 && rotated >= 64.0 && rotated < 192.0) rev = 1.0;
|
||||
|
||||
// If the label should be invisible, we move the vertex outside
|
||||
// of the view plane so that the triangle gets clipped. This makes it easier
|
||||
// for us to create degenerate triangle strips.
|
||||
// u_zoom is the current zoom level adjusted for the change in font size
|
||||
float z = 2.0 - step(a_minzoom, u_zoom) - (1.0 - step(a_maxzoom, u_zoom)) + rev;
|
||||
|
||||
// fade out labels
|
||||
float alpha = clamp((u_fadezoom - a_labelminzoom) / u_fadedist, 0.0, 1.0);
|
||||
|
||||
if (u_fadedist >= 0.0) {
|
||||
v_alpha = alpha;
|
||||
} else {
|
||||
v_alpha = 1.0 - alpha;
|
||||
}
|
||||
if (u_maxfadezoom < a_labelminzoom) {
|
||||
v_alpha = 0.0;
|
||||
}
|
||||
if (u_minfadezoom >= a_labelminzoom) {
|
||||
v_alpha = 1.0;
|
||||
}
|
||||
|
||||
// if label has been faded out, clip it
|
||||
z += step(v_alpha, 0.0);
|
||||
|
||||
// all the angles are 0..256 representing 0..2PI
|
||||
// hide if (angle >= a_rangeend && angle < rangestart)
|
||||
z += step(a_rangeend, u_angle) * (1.0 - step(a_rangestart, u_angle));
|
||||
|
||||
gl_Position = u_matrix * vec4(a_pos, 0, 1) + u_exmatrix * vec4(a_offset / 64.0, z, 0);
|
||||
v_tex = a_tex * 4.0 / u_texsize;
|
||||
}
|
||||
|
||||
@@ -17,19 +17,85 @@ TextShader::TextShader()
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
a_offset = glGetAttribLocation(program, "a_offset");
|
||||
a_tex = glGetAttribLocation(program, "a_tex");
|
||||
a_angle = glGetAttribLocation(program, "a_angle");
|
||||
a_minzoom = glGetAttribLocation(program, "a_minzoom");
|
||||
a_maxzoom = glGetAttribLocation(program, "a_maxzoom");
|
||||
a_rangeend = glGetAttribLocation(program, "a_rangeend");
|
||||
a_rangestart = glGetAttribLocation(program, "a_rangestart");
|
||||
a_labelminzoom = glGetAttribLocation(program, "a_labelminzoom");
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
u_buffer = glGetUniformLocation(program, "u_buffer");
|
||||
u_gamma = glGetUniformLocation(program, "u_gamma");
|
||||
u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
|
||||
u_angle = glGetUniformLocation(program, "u_angle");
|
||||
u_zoom = glGetUniformLocation(program, "u_zoom");
|
||||
u_flip = glGetUniformLocation(program, "u_flip");
|
||||
u_fadedist = glGetUniformLocation(program, "u_fadedist");
|
||||
u_minfadezoom = glGetUniformLocation(program, "u_minfadezoom");
|
||||
u_maxfadezoom = glGetUniformLocation(program, "u_maxfadezoom");
|
||||
u_fadezoom = glGetUniformLocation(program, "u_fadezoom");
|
||||
u_texsize = glGetUniformLocation(program, "u_texsize");
|
||||
|
||||
// fprintf(stderr, "TextShader:\n");
|
||||
// fprintf(stderr, " - a_pos: %d\n", a_pos);
|
||||
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
|
||||
// fprintf(stderr, " - a_offset: %d\n", a_offset);
|
||||
// fprintf(stderr, " - a_tex: %d\n", a_tex);
|
||||
// fprintf(stderr, " - a_angle: %d\n", a_angle);
|
||||
// fprintf(stderr, " - a_minzoom: %d\n", a_minzoom);
|
||||
// fprintf(stderr, " - a_maxzoom: %d\n", a_maxzoom);
|
||||
// fprintf(stderr, " - a_rangeend: %d\n", a_rangeend);
|
||||
// fprintf(stderr, " - a_rangestart: %d\n", a_rangestart);
|
||||
// fprintf(stderr, " - a_labelminzoom: %d\n", a_labelminzoom);
|
||||
// fprintf(stderr, " - u_color: %d\n", u_color);
|
||||
// fprintf(stderr, " - u_buffer: %d\n", u_buffer);
|
||||
// fprintf(stderr, " - u_gamma: %d\n", u_gamma);
|
||||
// fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
|
||||
// fprintf(stderr, " - u_angle: %d\n", u_angle);
|
||||
// fprintf(stderr, " - u_zoom: %d\n", u_zoom);
|
||||
// fprintf(stderr, " - u_flip: %d\n", u_flip);
|
||||
// fprintf(stderr, " - u_fadedist: %d\n", u_fadedist);
|
||||
// fprintf(stderr, " - u_minfadezoom: %d\n", u_minfadezoom);
|
||||
// fprintf(stderr, " - u_maxfadezoom: %d\n", u_maxfadezoom);
|
||||
// fprintf(stderr, " - u_fadezoom: %d\n", u_fadezoom);
|
||||
// fprintf(stderr, " - u_texsize: %d\n", u_texsize);
|
||||
}
|
||||
|
||||
void TextShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 16, offset + 0);
|
||||
|
||||
glEnableVertexAttribArray(a_offset);
|
||||
glVertexAttribPointer(a_offset, 2, GL_SHORT, false, 16, offset + 4);
|
||||
|
||||
glEnableVertexAttribArray(a_tex);
|
||||
glVertexAttribPointer(a_tex, 2, GL_UNSIGNED_BYTE, false, 16, offset + 8);
|
||||
|
||||
glEnableVertexAttribArray(a_labelminzoom);
|
||||
glVertexAttribPointer(a_labelminzoom, 1, GL_UNSIGNED_BYTE, false, 16,
|
||||
offset + 10);
|
||||
|
||||
glEnableVertexAttribArray(a_minzoom);
|
||||
glVertexAttribPointer(a_minzoom, 1, GL_UNSIGNED_BYTE, false, 16,
|
||||
offset + 11);
|
||||
|
||||
glEnableVertexAttribArray(a_maxzoom);
|
||||
glVertexAttribPointer(a_maxzoom, 1, GL_UNSIGNED_BYTE, false, 16,
|
||||
offset + 12);
|
||||
|
||||
glEnableVertexAttribArray(a_angle);
|
||||
glVertexAttribPointer(a_angle, 1, GL_UNSIGNED_BYTE, false, 16, offset + 13);
|
||||
|
||||
glEnableVertexAttribArray(a_rangeend);
|
||||
glVertexAttribPointer(a_rangeend, 1, GL_UNSIGNED_BYTE, false, 16,
|
||||
offset + 14);
|
||||
|
||||
glEnableVertexAttribArray(a_rangestart);
|
||||
glVertexAttribPointer(a_rangestart, 1, GL_UNSIGNED_BYTE, false, 16,
|
||||
offset + 15);
|
||||
}
|
||||
|
||||
void TextShader::setColor(const std::array<float, 4>& new_color) {
|
||||
@@ -42,3 +108,80 @@ void TextShader::setColor(const std::array<float, 4>& new_color) {
|
||||
void TextShader::setColor(float r, float g, float b, float a) {
|
||||
setColor({{ r, g, b, a }});
|
||||
}
|
||||
|
||||
void TextShader::setBuffer(float new_buffer) {
|
||||
if (buffer != new_buffer) {
|
||||
glUniform1f(u_buffer, new_buffer);
|
||||
buffer = new_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setGamma(float new_gamma) {
|
||||
if (gamma != new_gamma) {
|
||||
glUniform1f(u_gamma, new_gamma);
|
||||
gamma = new_gamma;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setExmatrix(const std::array<float, 16> &new_exmatrix) {
|
||||
if (exmatrix != new_exmatrix) {
|
||||
glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data());
|
||||
exmatrix = new_exmatrix;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setAngle(float new_angle) {
|
||||
if (angle != new_angle) {
|
||||
glUniform1f(u_angle, new_angle);
|
||||
angle = new_angle;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setZoom(float new_zoom) {
|
||||
if (zoom != new_zoom) {
|
||||
glUniform1f(u_zoom, new_zoom);
|
||||
zoom = new_zoom;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setFlip(float new_flip) {
|
||||
if (flip != new_flip) {
|
||||
glUniform1f(u_flip, new_flip);
|
||||
flip = new_flip;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setFadedist(float new_fadedist) {
|
||||
if (fadedist != new_fadedist) {
|
||||
glUniform1f(u_fadedist, new_fadedist);
|
||||
fadedist = new_fadedist;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setMinfadezoom(float new_minfadezoom) {
|
||||
if (minfadezoom != new_minfadezoom) {
|
||||
glUniform1f(u_minfadezoom, new_minfadezoom);
|
||||
minfadezoom = new_minfadezoom;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setMaxfadezoom(float new_maxfadezoom) {
|
||||
if (maxfadezoom != new_maxfadezoom) {
|
||||
glUniform1f(u_maxfadezoom, new_maxfadezoom);
|
||||
maxfadezoom = new_maxfadezoom;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setFadezoom(float new_fadezoom) {
|
||||
if (fadezoom != new_fadezoom) {
|
||||
glUniform1f(u_fadezoom, new_fadezoom);
|
||||
fadezoom = new_fadezoom;
|
||||
}
|
||||
}
|
||||
|
||||
void TextShader::setTexsize(const std::array<float, 2> &new_texsize) {
|
||||
if (texsize != new_texsize) {
|
||||
glUniform2fv(u_texsize, 1, new_texsize.data());
|
||||
texsize = new_texsize;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user