linepattern in progress
This commit is contained in:
committed by
John Firebaugh
parent
c1280f0b38
commit
71c31cee24
@@ -17,10 +17,11 @@ class LineVertexBuffer;
|
||||
class TriangleElementsBuffer;
|
||||
class LineShader;
|
||||
class LinejoinShader;
|
||||
class LinepatternShader;
|
||||
struct pbf;
|
||||
|
||||
class LineBucket : public Bucket {
|
||||
typedef ElementGroup<1> triangle_group_type;
|
||||
typedef ElementGroup<2> triangle_group_type;
|
||||
typedef ElementGroup<1> point_group_type;
|
||||
|
||||
public:
|
||||
@@ -38,6 +39,7 @@ public:
|
||||
bool hasPoints() const;
|
||||
|
||||
void drawLines(LineShader& shader);
|
||||
void drawLinePatterns(LinepatternShader& shader);
|
||||
void drawPoints(LinejoinShader& shader);
|
||||
|
||||
public:
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <mbgl/shader/pattern_shader.hpp>
|
||||
#include <mbgl/shader/line_shader.hpp>
|
||||
#include <mbgl/shader/linejoin_shader.hpp>
|
||||
#include <mbgl/shader/linepattern_shader.hpp>
|
||||
#include <mbgl/shader/icon_shader.hpp>
|
||||
#include <mbgl/shader/raster_shader.hpp>
|
||||
#include <mbgl/shader/text_shader.hpp>
|
||||
@@ -169,6 +170,7 @@ public:
|
||||
std::unique_ptr<OutlineShader> outlineShader;
|
||||
std::unique_ptr<LineShader> lineShader;
|
||||
std::unique_ptr<LinejoinShader> linejoinShader;
|
||||
std::unique_ptr<LinepatternShader> linepatternShader;
|
||||
std::unique_ptr<PatternShader> patternShader;
|
||||
std::unique_ptr<IconShader> iconShader;
|
||||
std::unique_ptr<RasterShader> rasterShader;
|
||||
|
||||
59
include/mbgl/shader/linepattern_shader.hpp
Normal file
59
include/mbgl/shader/linepattern_shader.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef MBGL_SHADER_SHADER_LINEPATTERN
|
||||
#define MBGL_SHADER_SHADER_LINEPATTERN
|
||||
|
||||
#include <mbgl/shader/shader.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class LinepatternShader : public Shader {
|
||||
public:
|
||||
LinepatternShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
void setExtrudeMatrix(const std::array<float, 16>& exmatrix);
|
||||
void setLineWidth(const std::array<float, 2>& linewidth);
|
||||
void setRatio(float ratio);
|
||||
void setDebug(float debug);
|
||||
void setPatternSize(const std::array<float, 2>& new_pattern_size);
|
||||
void setPatternTopLeft(const std::array<float, 2>& new_pattern_tl);
|
||||
void setPatternBottomRight(const std::array<float, 2>& new_pattern_br);
|
||||
void setOffset(const std::array<float, 2>& offset);
|
||||
void setGamma(float new_gamma);
|
||||
void setFade(float new_fade);
|
||||
|
||||
private:
|
||||
int32_t a_pos = -1;
|
||||
int32_t a_extrude = -1;
|
||||
int32_t a_linesofar = -1;
|
||||
|
||||
std::array<float, 16> exmatrix = {{}};
|
||||
int32_t u_exmatrix = -1;
|
||||
|
||||
std::array<float, 2> linewidth = {{}};
|
||||
int32_t u_linewidth = -1;
|
||||
|
||||
float ratio = 0;
|
||||
int32_t u_ratio = -1;
|
||||
|
||||
std::array<float, 2> pattern_size = {{}};
|
||||
int32_t u_pattern_size = -1;
|
||||
|
||||
std::array<float, 2> pattern_tl = {{}};
|
||||
int32_t u_pattern_tl = -1;
|
||||
|
||||
std::array<float, 2> pattern_br = {{}};
|
||||
int32_t u_pattern_br = -1;
|
||||
|
||||
std::array<float, 2> offset = {{}};
|
||||
int32_t u_offset = -1;
|
||||
|
||||
float gamma = 0.0f;
|
||||
int32_t u_gamma = -1;
|
||||
|
||||
float fade = 0;
|
||||
int32_t u_fade = -1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -374,6 +374,20 @@ void LineBucket::drawLines(LineShader& shader) {
|
||||
}
|
||||
}
|
||||
|
||||
void LineBucket::drawLinePatterns(LinepatternShader& shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
|
||||
char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize);
|
||||
for (triangle_group_type& group : triangleGroups) {
|
||||
if (!group.elements_length) {
|
||||
continue;
|
||||
}
|
||||
group.array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index);
|
||||
glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index);
|
||||
vertex_index += group.vertex_length * vertexBuffer.itemSize;
|
||||
elements_index += group.elements_length * triangleElementsBuffer.itemSize;
|
||||
}
|
||||
}
|
||||
|
||||
void LineBucket::drawPoints(LinejoinShader& shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize);
|
||||
char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer.itemSize);
|
||||
|
||||
@@ -41,6 +41,7 @@ void Painter::setup() {
|
||||
assert(outlineShader);
|
||||
assert(lineShader);
|
||||
assert(linejoinShader);
|
||||
assert(linepatternShader);
|
||||
assert(patternShader);
|
||||
assert(rasterShader);
|
||||
assert(textShader);
|
||||
@@ -70,6 +71,7 @@ void Painter::setupShaders() {
|
||||
if (!outlineShader) outlineShader = std::make_unique<OutlineShader>();
|
||||
if (!lineShader) lineShader = std::make_unique<LineShader>();
|
||||
if (!linejoinShader) linejoinShader = std::make_unique<LinejoinShader>();
|
||||
if (!linepatternShader) linepatternShader = std::make_unique<LinepatternShader>();
|
||||
if (!patternShader) patternShader = std::make_unique<PatternShader>();
|
||||
if (!iconShader) iconShader = std::make_unique<IconShader>();
|
||||
if (!rasterShader) rasterShader = std::make_unique<RasterShader>();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include <mbgl/renderer/painter.hpp>
|
||||
#include <mbgl/renderer/line_bucket.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
@@ -60,20 +63,50 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d
|
||||
bucket.drawPoints(*linejoinShader);
|
||||
}
|
||||
|
||||
// var imagePos = properties.image && imageSprite.getPosition(properties.image);
|
||||
bool imagePos = false;
|
||||
if (imagePos) {
|
||||
// var factor = 8 / Math.pow(2, painter.transform.zoom - params.z);
|
||||
const std::shared_ptr<Sprite> &sprite = map.getSprite();
|
||||
if (properties.image.size() && sprite) {
|
||||
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
|
||||
Rect<uint16_t> imagePos = spriteAtlas.getImage(properties.image, *sprite);
|
||||
|
||||
float factor = 8.0 / std::pow(2, map.getState().getIntegerZoom() - id.z);
|
||||
|
||||
float fade = std::fmod(map.getState().getZoom(), 1.0);
|
||||
|
||||
// imageSprite.bind(gl, true);
|
||||
std::array<float, 2> imageSize = {{
|
||||
imagePos.w * factor,
|
||||
imagePos.h * factor
|
||||
}
|
||||
};
|
||||
|
||||
// //factor = Math.pow(2, 4 - painter.transform.zoom + params.z);
|
||||
// gl.switchShader(painter.linepatternShader, painter.translatedMatrix || painter.posMatrix, painter.extrudeMatrix);
|
||||
// shader = painter.linepatternShader;
|
||||
// glUniform2fv(painter.linepatternShader.u_pattern_size, [imagePos.size[0] * factor, imagePos.size[1] ]);
|
||||
// glUniform2fv(painter.linepatternShader.u_pattern_tl, imagePos.tl);
|
||||
// glUniform2fv(painter.linepatternShader.u_pattern_br, imagePos.br);
|
||||
// glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
|
||||
std::array<float, 2> offset = {{
|
||||
(float)std::fmod(id.x * 4096, imageSize[0]),
|
||||
(float)std::fmod(id.y * 4096, imageSize[1])
|
||||
}
|
||||
};
|
||||
useProgram(linepatternShader->program);
|
||||
linepatternShader->setMatrix(vtxMatrix);
|
||||
linepatternShader->setExtrudeMatrix(extrudeMatrix);
|
||||
lineShader->setDashArray({{ dash_length, dash_gap }});
|
||||
linepatternShader->setLineWidth({{ outset, inset }});
|
||||
linepatternShader->setRatio(map.getState().getPixelRatio());
|
||||
|
||||
linepatternShader->setPatternSize(imageSize);
|
||||
linepatternShader->setPatternTopLeft({{
|
||||
float(imagePos.x) / spriteAtlas.getWidth(),
|
||||
float(imagePos.y) / spriteAtlas.getHeight(),
|
||||
}});
|
||||
linepatternShader->setPatternBottomRight({{
|
||||
float(imagePos.x + imagePos.w) / spriteAtlas.getWidth(),
|
||||
float(imagePos.y + imagePos.h) / spriteAtlas.getHeight(),
|
||||
}});
|
||||
linepatternShader->setOffset(offset);
|
||||
linepatternShader->setGamma(map.getState().getPixelRatio());
|
||||
linepatternShader->setFade(fade);
|
||||
|
||||
spriteAtlas.bind(true);
|
||||
glDepthRange(strata + strata_epsilon, 1.0f); // may or may not matter
|
||||
|
||||
bucket.drawLinePatterns(*linepatternShader);
|
||||
|
||||
} else {
|
||||
useProgram(lineShader->program);
|
||||
|
||||
34
src/shader/linepattern.fragment.glsl
Normal file
34
src/shader/linepattern.fragment.glsl
Normal file
@@ -0,0 +1,34 @@
|
||||
uniform vec2 u_linewidth;
|
||||
uniform float u_gamma;
|
||||
uniform float u_fade;
|
||||
|
||||
uniform vec2 u_pattern_size;
|
||||
uniform vec2 u_pattern_tl;
|
||||
uniform vec2 u_pattern_br;
|
||||
|
||||
uniform sampler2D u_image;
|
||||
|
||||
varying vec2 v_normal;
|
||||
varying float v_linesofar;
|
||||
|
||||
void main() {
|
||||
// Calculate the distance of the pixel from the line in pixels.
|
||||
float dist = length(v_normal) * length(gl_PointCoord * 2.0 - 1.0);
|
||||
|
||||
// Calculate the antialiasing fade factor. This is either when fading in
|
||||
// the line in case of an offset line (v_linewidth.t) or when fading out
|
||||
// (v_linewidth.s)
|
||||
float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist) * u_gamma, 0.0, 1.0);
|
||||
|
||||
float x = mod(v_linesofar / u_pattern_size.x, 1.0);
|
||||
float y = 0.5 + (v_normal.y * u_linewidth.s / u_pattern_size.y);
|
||||
vec2 pos = mix(u_pattern_tl, u_pattern_br, vec2(x, y));
|
||||
float x2 = mod(x * 2.0, 1.0);
|
||||
vec2 pos2 = mix(u_pattern_tl, u_pattern_br, vec2(x2, y));
|
||||
|
||||
vec4 color = texture2D(u_image, pos) * (1.0 - u_fade) + u_fade * texture2D(u_image, pos2);
|
||||
|
||||
color.rgb *= color.a;
|
||||
|
||||
gl_FragColor = color * alpha;
|
||||
}
|
||||
53
src/shader/linepattern.vertex.glsl
Normal file
53
src/shader/linepattern.vertex.glsl
Normal file
@@ -0,0 +1,53 @@
|
||||
// floor(127 / 2) == 63.0
|
||||
// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
|
||||
// stored in a byte (-128..127). we scale regular normals up to length 63, but
|
||||
// there are also "special" normals that have a bigger length (of up to 126 in
|
||||
// this case).
|
||||
#define scale 63.0
|
||||
|
||||
attribute vec2 a_pos;
|
||||
attribute vec2 a_extrude;
|
||||
attribute float a_linesofar;
|
||||
|
||||
// posmatrix is for the vertex position, exmatrix is for rotating and projecting
|
||||
// the extrusion vector.
|
||||
uniform mat4 u_matrix;
|
||||
uniform mat4 u_exmatrix;
|
||||
|
||||
// shared
|
||||
uniform float u_ratio;
|
||||
uniform vec2 u_linewidth;
|
||||
uniform vec4 u_color;
|
||||
|
||||
varying vec2 v_normal;
|
||||
varying float v_linesofar;
|
||||
|
||||
void main() {
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
// In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
|
||||
// y is 1 if the normal points up, and -1 if it points down
|
||||
vec2 normal = mod(a_pos, 2.0);
|
||||
normal.y = sign(normal.y - 0.5);
|
||||
v_normal = normal;
|
||||
|
||||
// Scale the extrusion vector down to a normal and then up by the line width
|
||||
// of this vertex.
|
||||
vec2 extrude = a_extrude / scale;
|
||||
vec4 dist = vec4(u_linewidth.s * extrude, 0.0, 0.0);
|
||||
|
||||
// If the x coordinate is the maximum integer, we move the z coordinates out
|
||||
// of the view plane so that the triangle gets clipped. This makes it easier
|
||||
// for us to create degenerate triangle strips.
|
||||
float z = step(32767.0, a_pos.x);
|
||||
|
||||
z += step(1.0, v_normal.y);
|
||||
|
||||
// Remove the texture normal bit of the position before scaling it with the
|
||||
// model/view matrix. Add the extrusion vector *after* the model/view matrix
|
||||
// because we're extruding the line in pixel space, regardless of the current
|
||||
// tile's zoom level.
|
||||
|
||||
gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0) + u_exmatrix * dist;
|
||||
v_linesofar = a_linesofar; // * u_ratio;
|
||||
}
|
||||
121
src/shader/linepattern_shader.cpp
Normal file
121
src/shader/linepattern_shader.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <mbgl/shader/linepattern_shader.hpp>
|
||||
#include <mbgl/shader/shaders.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
LinepatternShader::LinepatternShader()
|
||||
: Shader(
|
||||
"linepattern",
|
||||
shaders[LINEPATTERN_SHADER].vertex,
|
||||
shaders[LINEPATTERN_SHADER].fragment
|
||||
) {
|
||||
if (!valid) {
|
||||
fprintf(stderr, "invalid line pattern shader\n");
|
||||
return;
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
a_extrude = glGetAttribLocation(program, "a_extrude");
|
||||
a_linesofar = glGetAttribLocation(program, "a_linesofar");
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
|
||||
u_linewidth = glGetUniformLocation(program, "u_linewidth");
|
||||
u_ratio = glGetUniformLocation(program, "u_ratio");
|
||||
u_pattern_size = glGetUniformLocation(program, "u_pattern_size");
|
||||
|
||||
u_pattern_tl = glGetUniformLocation(program, "u_pattern_tl");
|
||||
u_pattern_br = glGetUniformLocation(program, "u_pattern_br");
|
||||
u_offset = glGetUniformLocation(program, "u_offset");
|
||||
u_gamma = glGetUniformLocation(program, "u_gamma");
|
||||
u_fade = glGetUniformLocation(program, "u_fade");
|
||||
|
||||
//fprintf(stderr, "LinepatternShader:\n");
|
||||
//fprintf(stderr, " - u_matrix: %d\n", u_matrix);
|
||||
//fprintf(stderr, " - u_exmatrix: %d\n", u_exmatrix);
|
||||
//fprintf(stderr, " - u_linewidth: %d\n", u_linewidth);
|
||||
//fprintf(stderr, " - u_ratio: %d\n", u_ratio);
|
||||
//fprintf(stderr, " - u_pattern_size: %d\n", u_pattern_size);
|
||||
//fprintf(stderr, " - u_pattern_tl: %d\n", u_pattern_tl);
|
||||
//fprintf(stderr, " - u_pattern_br: %d\n", u_pattern_br);
|
||||
//fprintf(stderr, " - u_offset: %d\n", u_offset);
|
||||
//fprintf(stderr, " - u_gamma: %d\n", u_gamma);
|
||||
}
|
||||
|
||||
void LinepatternShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0);
|
||||
|
||||
glEnableVertexAttribArray(a_extrude);
|
||||
glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 4);
|
||||
|
||||
glEnableVertexAttribArray(a_linesofar);
|
||||
glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 6);
|
||||
}
|
||||
|
||||
void LinepatternShader::setExtrudeMatrix(const std::array<float, 16>& new_exmatrix) {
|
||||
if (exmatrix != new_exmatrix) {
|
||||
glUniformMatrix4fv(u_exmatrix, 1, GL_FALSE, new_exmatrix.data());
|
||||
exmatrix = new_exmatrix;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setPatternSize(const std::array<float, 2>& new_pattern_size) {
|
||||
if (pattern_size != new_pattern_size) {
|
||||
glUniform2fv(u_pattern_size, 1, new_pattern_size.data());
|
||||
pattern_size = new_pattern_size;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setLineWidth(const std::array<float, 2>& new_linewidth) {
|
||||
if (linewidth != new_linewidth) {
|
||||
glUniform2fv(u_linewidth, 1, new_linewidth.data());
|
||||
linewidth = new_linewidth;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setRatio(float new_ratio) {
|
||||
if (ratio != new_ratio) {
|
||||
glUniform1f(u_ratio, new_ratio);
|
||||
ratio = new_ratio;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setPatternTopLeft(const std::array<float, 2>& new_pattern_tl) {
|
||||
if (pattern_tl != new_pattern_tl) {
|
||||
glUniform2fv(u_pattern_tl, 1, new_pattern_tl.data());
|
||||
pattern_tl = new_pattern_tl;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setPatternBottomRight(const std::array<float, 2>& new_pattern_br) {
|
||||
if (pattern_br != new_pattern_br) {
|
||||
glUniform2fv(u_pattern_br, 1, new_pattern_br.data());
|
||||
pattern_br = new_pattern_br;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setOffset(const std::array<float, 2>& new_offset) {
|
||||
if (offset != new_offset) {
|
||||
glUniform2fv(u_offset, 1, new_offset.data());
|
||||
offset = new_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setGamma(float new_gamma) {
|
||||
if (gamma != new_gamma) {
|
||||
glUniform1f(u_gamma, new_gamma);
|
||||
gamma = new_gamma;
|
||||
}
|
||||
}
|
||||
|
||||
void LinepatternShader::setFade(float new_fade) {
|
||||
if (fade != new_fade) {
|
||||
glUniform1f(u_fade, new_fade);
|
||||
fade = new_fade;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user