Merge branch 'master' into tessellation
Conflicts: include/llmr/renderer/fill_bucket.hpp src/renderer/fill_bucket.cpp src/renderer/painter.cpp
This commit is contained in:
@@ -96,7 +96,6 @@ void FillBucket::tessellate() {
|
||||
}
|
||||
hasVertices = false;
|
||||
|
||||
|
||||
std::vector<std::vector<ClipperLib::IntPoint>> polygons;
|
||||
clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftPositive);
|
||||
clipper.Clear();
|
||||
|
||||
@@ -103,7 +103,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
nextNormal = util::normal<double>(currentVertex, lastVertex);
|
||||
}
|
||||
|
||||
size_t start_vertex = vertexBuffer->index();
|
||||
int32_t start_vertex = (int32_t)vertexBuffer->index();
|
||||
|
||||
std::vector<TriangleElement> triangle_store;
|
||||
std::vector<PointElement> point_store;
|
||||
@@ -174,7 +174,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
// Add offset square begin cap.
|
||||
if (!prevVertex && beginCap == CapType::Square) {
|
||||
// Add first vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal
|
||||
0, 0, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -182,7 +182,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
e1 = e2; e2 = e3;
|
||||
|
||||
// Add second vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal
|
||||
0, 1, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -193,7 +193,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
// Add offset square end cap.
|
||||
else if (!nextVertex && endCap == CapType::Square) {
|
||||
// Add first vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal
|
||||
0, 0, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -201,7 +201,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
e1 = e2; e2 = e3;
|
||||
|
||||
// Add second vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal
|
||||
0, 1, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -227,7 +227,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
}
|
||||
|
||||
// Add first vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
flip * joinNormal.x, flip * joinNormal.y, // extrude normal
|
||||
0, 0, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -235,7 +235,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
e1 = e2; e2 = e3;
|
||||
|
||||
// Add second vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
-flip * joinNormal.x, -flip * joinNormal.y, // extrude normal
|
||||
0, 1, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -251,7 +251,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
else {
|
||||
// Close up the previous line
|
||||
// Add first vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
flip * prevNormal.y, -flip * prevNormal.x, // extrude normal
|
||||
0, 0, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -259,7 +259,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
e1 = e2; e2 = e3;
|
||||
|
||||
// Add second vertex.
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
-flip * prevNormal.y, flip * prevNormal.x, // extrude normal
|
||||
0, 1, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -289,7 +289,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
|
||||
// Start the new quad.
|
||||
// Add first vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
-flip * nextNormal.y, flip * nextNormal.x, // extrude normal
|
||||
0, 0, distance) - start_vertex; // texture normal
|
||||
|
||||
@@ -297,7 +297,7 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) {
|
||||
e1 = e2; e2 = e3;
|
||||
|
||||
// Add second vertex
|
||||
e3 = vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
e3 = (int32_t)vertexBuffer->add(currentVertex.x, currentVertex.y, // vertex pos
|
||||
flip * nextNormal.y, -flip * nextNormal.x, // extrude normal
|
||||
0, 1, distance) - start_vertex; // texture normal
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <llmr/renderer/fill_bucket.hpp>
|
||||
#include <llmr/renderer/line_bucket.hpp>
|
||||
#include <llmr/renderer/point_bucket.hpp>
|
||||
|
||||
#include <llmr/map/transform.hpp>
|
||||
#include <llmr/map/settings.hpp>
|
||||
@@ -29,6 +30,7 @@ Painter::Painter(Transform& transform, Settings& settings, Style& style)
|
||||
void Painter::setup() {
|
||||
setupShaders();
|
||||
|
||||
assert(pointShader);
|
||||
assert(plainShader);
|
||||
assert(outlineShader);
|
||||
assert(lineShader);
|
||||
@@ -52,6 +54,7 @@ void Painter::setupShaders() {
|
||||
lineShader = std::make_unique<LineShader>();
|
||||
linejoinShader = std::make_unique<LinejoinShader>();
|
||||
patternShader = std::make_unique<PatternShader>();
|
||||
pointShader = std::make_unique<PointShader>();
|
||||
}
|
||||
|
||||
void Painter::useProgram(uint32_t program) {
|
||||
@@ -114,7 +117,7 @@ void Painter::drawClippingMask() {
|
||||
|
||||
// Draw the clipping mask
|
||||
plainShader->setColor(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
|
||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index());
|
||||
|
||||
// glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_EQUAL, 0x80, 0x80);
|
||||
@@ -360,6 +363,44 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
|
||||
}
|
||||
}
|
||||
|
||||
void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, const Tile::ID& id) {
|
||||
const PointProperties& properties = style.computed.points[layer_name];
|
||||
|
||||
// Abort early.
|
||||
if (!bucket.hasPoints()) return;
|
||||
if (properties.hidden) return;
|
||||
|
||||
Color color = properties.color;
|
||||
color[0] *= properties.opacity;
|
||||
color[1] *= properties.opacity;
|
||||
color[2] *= properties.opacity;
|
||||
color[3] *= properties.opacity;
|
||||
|
||||
std::string sized_image = properties.image;
|
||||
sized_image.append("-");
|
||||
sized_image.append(std::to_string(static_cast<int>(std::round(properties.size))));
|
||||
|
||||
ImagePosition imagePos = style.sprite->getPosition(sized_image, false);
|
||||
|
||||
// fprintf(stderr, "%f/%f => %f/%f\n", imagePos.tl.x, imagePos.tl.y, imagePos.br.x, imagePos.br.y);
|
||||
|
||||
useProgram(pointShader->program);
|
||||
pointShader->setMatrix(matrix);
|
||||
pointShader->setImage(0);
|
||||
pointShader->setColor(color);
|
||||
const float pointSize = properties.size * 1.4142135623730951 * transform.pixelRatio;
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
pointShader->setSize(pointSize);
|
||||
#else
|
||||
glPointSize(pointSize);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
#endif
|
||||
pointShader->setPointTopLeft({{ imagePos.tl.x, imagePos.tl.y }});
|
||||
pointShader->setPointBottomRight({{ imagePos.br.x, imagePos.br.y }});
|
||||
style.sprite->bind(transform.rotating || transform.scaling || transform.panning);
|
||||
bucket.drawPoints(*pointShader);
|
||||
}
|
||||
|
||||
void Painter::renderDebug(const Tile::Ptr& tile) {
|
||||
// Blend to the front, not the back.
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -370,16 +411,16 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
|
||||
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
|
||||
plainShader->setColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
lineWidth(4.0f * transform.pixelRatio);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.index());
|
||||
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index());
|
||||
|
||||
// draw debug info
|
||||
tile->debugFontArray.bind(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
|
||||
plainShader->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
lineWidth(4.0f * transform.pixelRatio);
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index());
|
||||
glDrawArrays(GL_LINES, 0, (GLsizei)tile->debugFontBuffer.index());
|
||||
plainShader->setColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
lineWidth(2.0f * transform.pixelRatio);
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.index());
|
||||
glDrawArrays(GL_LINES, 0, (GLsizei)tile->debugFontBuffer.index());
|
||||
|
||||
// Revert blending mode to blend to the back.
|
||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
|
||||
@@ -396,7 +437,7 @@ void Painter::renderMatte() {
|
||||
// Draw the clipping mask
|
||||
matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0));
|
||||
plainShader->setColor(white);
|
||||
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.index());
|
||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)matteBuffer.index());
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
}
|
||||
@@ -410,5 +451,5 @@ void Painter::renderBackground() {
|
||||
// Draw the clipping mask
|
||||
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
plainShader->setColor(white);
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
|
||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index());
|
||||
}
|
||||
|
||||
52
src/renderer/point_bucket.cpp
Normal file
52
src/renderer/point_bucket.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <llmr/renderer/point_bucket.hpp>
|
||||
#include <llmr/geometry/point_buffer.hpp>
|
||||
#include <llmr/geometry/elements_buffer.hpp>
|
||||
#include <llmr/geometry/geometry.hpp>
|
||||
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/map/vector_tile.hpp>
|
||||
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
struct geometry_too_long_exception : std::exception {};
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
PointBucket::PointBucket(const std::shared_ptr<PointVertexBuffer>& vertexBuffer,
|
||||
const BucketDescription& bucket_desc)
|
||||
: geometry(bucket_desc.geometry),
|
||||
vertexBuffer(vertexBuffer),
|
||||
vertex_start(vertexBuffer->index()) {
|
||||
}
|
||||
|
||||
void PointBucket::addGeometry(pbf& geom) {
|
||||
Geometry::command cmd;
|
||||
Geometry geometry(geom);
|
||||
int32_t x, y;
|
||||
while ((cmd = geometry.next(x, y)) != Geometry::end) {
|
||||
if (cmd == Geometry::move_to) {
|
||||
vertexBuffer->add(x, y);
|
||||
} else {
|
||||
fprintf(stderr, "other command than move_to in point geometry\n");
|
||||
}
|
||||
}
|
||||
|
||||
vertex_end = vertexBuffer->index();
|
||||
}
|
||||
|
||||
void PointBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) {
|
||||
painter.renderPoint(*this, layer_name, id);
|
||||
}
|
||||
|
||||
bool PointBucket::hasPoints() const {
|
||||
return vertex_end > 0;
|
||||
}
|
||||
|
||||
void PointBucket::drawPoints(PointShader& shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer->itemSize);
|
||||
array.bind(shader, *vertexBuffer, vertex_index);
|
||||
glDrawArrays(GL_POINTS, 0, (GLsizei)(vertex_end - vertex_start));
|
||||
}
|
||||
74
src/renderer/shader-point.cpp
Normal file
74
src/renderer/shader-point.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <llmr/renderer/shader-point.hpp>
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
PointShader::PointShader()
|
||||
: Shader(
|
||||
shaders[POINT_SHADER].vertex,
|
||||
shaders[POINT_SHADER].fragment
|
||||
) {
|
||||
if (!valid) {
|
||||
fprintf(stderr, "invalid point shader\n");
|
||||
return;
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
u_size = glGetUniformLocation(program, "u_size");
|
||||
u_point_tl = glGetUniformLocation(program, "u_tl");
|
||||
u_point_br = glGetUniformLocation(program, "u_br");
|
||||
|
||||
// fprintf(stderr, "PointShader:\n");
|
||||
// fprintf(stderr, " - u_matrix: %d\n", u_matrix);
|
||||
// fprintf(stderr, " - u_color: %d\n", u_color);
|
||||
// fprintf(stderr, " - u_size: %d\n", u_size);
|
||||
// fprintf(stderr, " - u_point_tl: %d\n", u_point_tl);
|
||||
// fprintf(stderr, " - u_point_br: %d\n", u_point_br);
|
||||
// fprintf(stderr, " - u_image: %d\n", u_image);
|
||||
}
|
||||
|
||||
void PointShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
|
||||
}
|
||||
|
||||
void PointShader::setImage(int32_t new_image) {
|
||||
if (image != new_image) {
|
||||
glUniform1i(u_image, new_image);
|
||||
image = new_image;
|
||||
}
|
||||
}
|
||||
|
||||
void PointShader::setColor(const std::array<float, 4>& new_color) {
|
||||
if (color != new_color) {
|
||||
glUniform4fv(u_color, 1, new_color.data());
|
||||
color = new_color;
|
||||
}
|
||||
}
|
||||
|
||||
void PointShader::setSize(float new_size) {
|
||||
if (size != new_size) {
|
||||
glUniform1f(u_size, new_size);
|
||||
size = new_size;
|
||||
}
|
||||
}
|
||||
|
||||
void PointShader::setPointTopLeft(const std::array<float, 2>& new_point_tl) {
|
||||
if (point_tl != new_point_tl) {
|
||||
glUniform2fv(u_point_tl, 1, new_point_tl.data());
|
||||
point_tl = new_point_tl;
|
||||
}
|
||||
}
|
||||
|
||||
void PointShader::setPointBottomRight(const std::array<float, 2>& new_point_br) {
|
||||
if (point_br != new_point_br) {
|
||||
glUniform2fv(u_point_br, 1, new_point_br.data());
|
||||
point_br = new_point_br;
|
||||
}
|
||||
}
|
||||
@@ -105,8 +105,8 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
|
||||
|
||||
*shader = glCreateShader(type);
|
||||
|
||||
#if defined(EMSCRIPTEN) || defined(GL_ES_VERSION_2_0)
|
||||
// Add WebGL GLSL / OpenGL ES precision premable
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
// Add OpenGL ES precision premable
|
||||
const GLchar *preamble = "precision highp float;\n\n";
|
||||
#else
|
||||
// Desktop GLSL
|
||||
|
||||
Reference in New Issue
Block a user