Merge pull request #39 from mapbox/ios-speed
Switch to Vertex Array Objects
This commit is contained in:
51
include/llmr/geometry/vao.hpp
Normal file
51
include/llmr/geometry/vao.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef LLMR_GEOMETRY_VAO
|
||||
#define LLMR_GEOMETRY_VAO
|
||||
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
template <typename Shader>
|
||||
class VertexArrayObject {
|
||||
public:
|
||||
template <typename Buffer>
|
||||
void bind(Shader& shader, Buffer& buffer, char *offset) {
|
||||
if (!vao) {
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
buffer.bind();
|
||||
shader.bind(offset);
|
||||
|
||||
buffer_ptr = &buffer;
|
||||
offset_ptr = offset;
|
||||
} else if (buffer_ptr != &buffer) {
|
||||
throw std::runtime_error("trying to bind VAO to another buffer");
|
||||
} else if (offset_ptr != offset) {
|
||||
throw std::runtime_error("trying to bind VAO to another offset");
|
||||
} else {
|
||||
// We have been given the correct information.
|
||||
glBindVertexArray(vao);
|
||||
}
|
||||
}
|
||||
|
||||
~VertexArrayObject() {
|
||||
if (vao) {
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint vao = 0;
|
||||
|
||||
// For debug reasons, we're storing the bind information so that we can
|
||||
// detect errors and report
|
||||
void *buffer_ptr = NULL;
|
||||
char *offset_ptr = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,8 @@
|
||||
#define LLMR_MAP_TILE
|
||||
|
||||
#include <llmr/util/vec.hpp>
|
||||
#include <llmr/geometry/debug_font_buffer.hpp>
|
||||
#include <llmr/geometry/vao.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <forward_list>
|
||||
@@ -18,9 +20,9 @@ class LayerDescription;
|
||||
class BucketDescription;
|
||||
class VectorTile;
|
||||
class VectorTileLayer;
|
||||
class DebugFontBuffer;
|
||||
class FillBuffer;
|
||||
class LineBuffer;
|
||||
class PlainShader;
|
||||
|
||||
class Tile : public std::enable_shared_from_this<Tile> {
|
||||
public:
|
||||
@@ -71,7 +73,9 @@ public:
|
||||
state state;
|
||||
|
||||
// Holds the actual geometries in this tile.
|
||||
std::shared_ptr<DebugFontBuffer> debugFontBuffer;
|
||||
DebugFontBuffer debugFontBuffer;
|
||||
VertexArrayObject<PlainShader> debugFontArray;
|
||||
|
||||
std::shared_ptr<FillBuffer> fillBuffer;
|
||||
std::shared_ptr<LineBuffer> lineBuffer;
|
||||
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
#if TARGET_OS_IPHONE
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#define glGenVertexArrays glGenVertexArraysOES
|
||||
#define glBindVertexArray glBindVertexArrayOES
|
||||
#define glDeleteVertexArrays glDeleteVertexArraysOES
|
||||
#elif TARGET_IPHONE_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#define glGenVertexArrays glGenVertexArraysAPPLE
|
||||
#define glBindVertexArray glBindVertexArrayAPPLE
|
||||
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
|
||||
#else
|
||||
#error Unsupported Apple platform
|
||||
#endif
|
||||
|
||||
@@ -3,15 +3,23 @@
|
||||
|
||||
#include "bucket.hpp"
|
||||
#include <llmr/style/bucket_description.hpp>
|
||||
#include <llmr/geometry/vao.hpp>
|
||||
#include <llmr/geometry/fill_buffer.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BUFFER_OFFSET
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
#endif
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class Style;
|
||||
class FillBuffer;
|
||||
class BucketDescription;
|
||||
class OutlineShader;
|
||||
class PlainShader;
|
||||
struct Coordinate;
|
||||
struct pbf;
|
||||
|
||||
@@ -24,8 +32,9 @@ public:
|
||||
void addGeometry(pbf& data);
|
||||
void addGeometry(const std::vector<Coordinate>& line);
|
||||
uint32_t size() const;
|
||||
void drawElements(int32_t attrib);
|
||||
void drawVertices(int32_t attrib);
|
||||
|
||||
void drawElements(PlainShader& shader);
|
||||
void drawVertices(OutlineShader& shader);
|
||||
|
||||
public:
|
||||
const BucketGeometryDescription geom_desc;
|
||||
@@ -34,6 +43,7 @@ private:
|
||||
std::shared_ptr<FillBuffer> buffer;
|
||||
|
||||
struct group {
|
||||
VertexArrayObject<PlainShader> array;
|
||||
uint32_t vertex_length;
|
||||
uint32_t elements_length;
|
||||
|
||||
@@ -48,6 +58,7 @@ private:
|
||||
uint32_t vertex_start;
|
||||
uint32_t elements_start;
|
||||
uint32_t length;
|
||||
VertexArrayObject<OutlineShader> array;
|
||||
std::vector<group> groups;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "bucket.hpp"
|
||||
#include <llmr/style/bucket_description.hpp>
|
||||
#include <llmr/geometry/vao.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -10,6 +11,7 @@ namespace llmr {
|
||||
|
||||
class Style;
|
||||
class LineBuffer;
|
||||
class LineShader;
|
||||
struct Coordinate;
|
||||
struct pbf;
|
||||
|
||||
@@ -21,10 +23,12 @@ public:
|
||||
|
||||
void addGeometry(pbf& data);
|
||||
void addGeometry(const std::vector<Coordinate>& line);
|
||||
uint32_t size() const;
|
||||
|
||||
void bind();
|
||||
char *vertexOffset() const;
|
||||
size_t size() const;
|
||||
|
||||
void bind(LineShader& shader);
|
||||
void drawLines();
|
||||
void drawPoints();
|
||||
|
||||
public:
|
||||
const BucketGeometryDescription geometry;
|
||||
@@ -33,6 +37,7 @@ private:
|
||||
std::shared_ptr<LineBuffer> buffer;
|
||||
uint32_t start;
|
||||
uint32_t length;
|
||||
VertexArrayObject<LineShader> array;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,23 +2,22 @@
|
||||
#define LLMR_RENDERER_PAINTER
|
||||
|
||||
#include <llmr/map/tile.hpp>
|
||||
#include <llmr/geometry/vao.hpp>
|
||||
#include <llmr/geometry/vertex_buffer.hpp>
|
||||
#include <llmr/util/mat4.hpp>
|
||||
|
||||
#include <llmr/renderer/shader-plain.hpp>
|
||||
#include <llmr/renderer/shader-outline.hpp>
|
||||
#include <llmr/renderer/shader-pattern.hpp>
|
||||
#include <llmr/renderer/shader-line.hpp>
|
||||
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class Transform;
|
||||
class Settings;
|
||||
class Style;
|
||||
class Tile;
|
||||
// class LayerDescription;
|
||||
|
||||
class Shader;
|
||||
class PlainShader;
|
||||
class OutlineShader;
|
||||
class FillShader;
|
||||
class LineShader;
|
||||
class PatternShader;
|
||||
|
||||
class FillBucket;
|
||||
class LineBucket;
|
||||
@@ -33,29 +32,21 @@ public:
|
||||
Painter& operator=(const Painter&) = delete;
|
||||
Painter& operator=(const Painter && ) = delete;
|
||||
|
||||
|
||||
void setup();
|
||||
|
||||
|
||||
void clear();
|
||||
void changeMatrix(const Tile::ID& id);
|
||||
void render(const std::shared_ptr<Tile>& tile);
|
||||
void renderLayers(const std::shared_ptr<Tile>& tile, const std::vector<LayerDescription>& layers);
|
||||
void renderDebug(const std::shared_ptr<Tile>& tile);
|
||||
|
||||
void renderMatte();
|
||||
void renderBackground();
|
||||
void renderFill(FillBucket& bucket, const std::string& layer_name, const Tile::ID& id);
|
||||
void renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id);
|
||||
|
||||
|
||||
void drawClippingMask();
|
||||
bool switchShader(std::shared_ptr<Shader> shader);
|
||||
|
||||
private:
|
||||
void setupShaders();
|
||||
|
||||
public:
|
||||
void drawClippingMask();
|
||||
void renderLayers(const std::shared_ptr<Tile>& tile, const std::vector<LayerDescription>& layers);
|
||||
void renderDebug(const std::shared_ptr<Tile>& tile);
|
||||
|
||||
private:
|
||||
Transform& transform;
|
||||
@@ -66,12 +57,10 @@ private:
|
||||
mat4 matrix;
|
||||
mat4 exMatrix;
|
||||
|
||||
std::shared_ptr<Shader> currentShader;
|
||||
std::shared_ptr<FillShader> fillShader;
|
||||
std::shared_ptr<PlainShader> plainShader;
|
||||
std::shared_ptr<OutlineShader> outlineShader;
|
||||
std::shared_ptr<LineShader> lineShader;
|
||||
std::shared_ptr<PatternShader> patternShader;
|
||||
std::unique_ptr<PlainShader> plainShader;
|
||||
std::unique_ptr<OutlineShader> outlineShader;
|
||||
std::unique_ptr<LineShader> lineShader;
|
||||
std::unique_ptr<PatternShader> patternShader;
|
||||
|
||||
// Set up the stencil quad we're using to generate the stencil mask.
|
||||
VertexBuffer tileStencilBuffer = {
|
||||
@@ -86,6 +75,9 @@ private:
|
||||
4096, 4096
|
||||
};
|
||||
|
||||
VertexArrayObject<PlainShader> coveringPlainArray;
|
||||
VertexArrayObject<PatternShader> coveringPatternArray;
|
||||
|
||||
// Set up the tile boundary lines we're using to draw the tile outlines.
|
||||
VertexBuffer tileBorderBuffer = {
|
||||
0, 0,
|
||||
@@ -95,6 +87,8 @@ private:
|
||||
0, 0
|
||||
};
|
||||
|
||||
VertexArrayObject<PlainShader> tileBorderArray;
|
||||
|
||||
// Set up the matte buffer we're using to draw the filling background.
|
||||
VertexBuffer matteBuffer = {
|
||||
// top left triangle
|
||||
@@ -108,6 +102,7 @@ private:
|
||||
16384, 16384
|
||||
};
|
||||
|
||||
VertexArrayObject<PlainShader> matteArray;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef LLMR_RENDERER_SHADER_FILL
|
||||
#define LLMR_RENDERER_SHADER_FILL
|
||||
|
||||
#include "shader.hpp"
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class FillShader : public Shader {
|
||||
public:
|
||||
FillShader();
|
||||
|
||||
int32_t a_pos;
|
||||
int32_t u_matrix;
|
||||
int32_t u_color;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,8 @@ class LineShader : public Shader {
|
||||
public:
|
||||
LineShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
int32_t a_pos;
|
||||
int32_t a_extrude;
|
||||
int32_t a_linesofar;
|
||||
|
||||
@@ -9,6 +9,8 @@ class OutlineShader : public Shader {
|
||||
public:
|
||||
OutlineShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
int32_t a_pos;
|
||||
int32_t u_matrix;
|
||||
int32_t u_color;
|
||||
|
||||
@@ -9,6 +9,8 @@ class PatternShader : public Shader {
|
||||
public:
|
||||
PatternShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
int32_t a_pos;
|
||||
int32_t u_matrix;
|
||||
int32_t u_color;
|
||||
|
||||
@@ -9,6 +9,8 @@ class PlainShader : public Shader {
|
||||
public:
|
||||
PlainShader();
|
||||
|
||||
void bind(char *offset);
|
||||
|
||||
int32_t a_pos;
|
||||
int32_t u_matrix;
|
||||
int32_t u_color;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef LLMR_RENDERER_SHADER
|
||||
#define LLMR_RENDERER_SHADER
|
||||
|
||||
#include <forward_list>
|
||||
#include <cstdint>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
@@ -18,7 +18,6 @@ public:
|
||||
|
||||
bool valid;
|
||||
uint32_t program;
|
||||
std::forward_list<uint32_t> attributes;
|
||||
|
||||
private:
|
||||
bool compileShader(uint32_t *shader, uint32_t type, const char *source);
|
||||
|
||||
@@ -11,7 +11,6 @@ struct shader_source {
|
||||
};
|
||||
|
||||
enum {
|
||||
FILL_SHADER,
|
||||
LINE_SHADER,
|
||||
OUTLINE_SHADER,
|
||||
PATTERN_SHADER,
|
||||
|
||||
@@ -46,20 +46,24 @@ struct pbf {
|
||||
inline void skipValue(uint32_t val);
|
||||
inline void skipBytes(uint32_t bytes);
|
||||
|
||||
const uint8_t *data;
|
||||
const uint8_t *end;
|
||||
uint32_t value;
|
||||
uint32_t tag;
|
||||
const uint8_t *data = NULL;
|
||||
const uint8_t *end = NULL;
|
||||
uint32_t value = 0;
|
||||
uint32_t tag = 0;
|
||||
};
|
||||
|
||||
pbf::pbf(const unsigned char *data, uint32_t length)
|
||||
: data(data),
|
||||
end(data + length) {
|
||||
end(data + length),
|
||||
value(0),
|
||||
tag(0) {
|
||||
}
|
||||
|
||||
pbf::pbf()
|
||||
: data(NULL),
|
||||
end(NULL) {
|
||||
end(NULL),
|
||||
value(0),
|
||||
tag(0) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
include/llmr/util/std.hpp
Normal file
16
include/llmr/util/std.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef LLMR_UTIL_STD
|
||||
#define LLMR_UTIL_STD
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace std {
|
||||
|
||||
// C++14 backfill from http://herbsutter.com/gotw/_102/
|
||||
template<typename T, typename ...Args>
|
||||
::std::unique_ptr<T> make_unique(Args&& ...args) {
|
||||
return ::std::unique_ptr<T>(new T(::std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -72,6 +72,7 @@ class MBXMapView
|
||||
GLKView *view = (GLKView *)self.view;
|
||||
view.context = self.context;
|
||||
view.drawableStencilFormat = GLKViewDrawableStencilFormat8;
|
||||
self.preferredFramesPerSecond = 60;
|
||||
[view bindDrawable];
|
||||
|
||||
[EAGLContext setCurrentContext:self.context];
|
||||
|
||||
@@ -9,7 +9,6 @@ VertexBuffer::VertexBuffer(std::initializer_list<int16_t> init) : array(init) {}
|
||||
VertexBuffer::~VertexBuffer() {
|
||||
if (buffer != 0) {
|
||||
glDeleteBuffers(1, &buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,5 +25,4 @@ void VertexBuffer::bind() {
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ void Map::setScale(double scale) {
|
||||
}
|
||||
|
||||
void Map::setAngle(double angle, double x, double y) {
|
||||
double dx, dy;
|
||||
double dx = 0, dy = 0;
|
||||
|
||||
if (x >= 0 && y >= 0) {
|
||||
dx = (transform.width / 2) - x;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/map/vector_tile.hpp>
|
||||
#include <llmr/geometry/debug_font_buffer.hpp>
|
||||
#include <llmr/geometry/fill_buffer.hpp>
|
||||
#include <llmr/geometry/line_buffer.hpp>
|
||||
#include <llmr/renderer/fill_bucket.hpp>
|
||||
@@ -43,7 +42,6 @@ std::forward_list<Tile::ID> Tile::children(const ID& id, int32_t z) {
|
||||
Tile::Tile(ID id, const Style& style)
|
||||
: id(id),
|
||||
state(initial),
|
||||
debugFontBuffer(std::make_shared<DebugFontBuffer>()),
|
||||
fillBuffer(std::make_shared<FillBuffer>()),
|
||||
lineBuffer(std::make_shared<LineBuffer>()),
|
||||
style(style) {
|
||||
@@ -51,7 +49,7 @@ Tile::Tile(ID id, const Style& style)
|
||||
// Initialize tile debug coordinates
|
||||
char coord[32];
|
||||
snprintf(coord, sizeof(coord), "%d/%d/%d", id.z, id.x, id.y);
|
||||
debugFontBuffer->addText(coord, 50, 200, 5);
|
||||
debugFontBuffer.addText(coord, 50, 200, 5);
|
||||
}
|
||||
|
||||
Tile::~Tile() {
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
#include <cassert>
|
||||
|
||||
struct geometry_too_long_exception : std::exception {};
|
||||
@@ -97,26 +95,6 @@ void FillBucket::addGeometry(const std::vector<Coordinate>& line) {
|
||||
|
||||
}
|
||||
|
||||
void FillBucket::drawElements(int32_t attrib) {
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
|
||||
char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t));
|
||||
buffer->bind();
|
||||
for (const auto& group : groups) {
|
||||
glVertexAttribPointer(attrib, 2, GL_SHORT, GL_FALSE, 0, vertex_index);
|
||||
glDrawElements(GL_TRIANGLES, group.elements_length * 3, GL_UNSIGNED_SHORT, elements_index);
|
||||
vertex_index += group.vertex_length * 2 * sizeof(uint16_t);
|
||||
elements_index += group.elements_length * 3 * sizeof(uint16_t);
|
||||
}
|
||||
}
|
||||
|
||||
void FillBucket::drawVertices(int32_t attrib) {
|
||||
// Draw the entire line
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
|
||||
buffer->bind();
|
||||
glVertexAttribPointer(attrib, 2, GL_SHORT, GL_FALSE, 0, vertex_index);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, length);
|
||||
}
|
||||
|
||||
void FillBucket::render(Painter& painter, const std::string& layer_name, const Tile::ID& id) {
|
||||
painter.renderFill(*this, layer_name, id);
|
||||
}
|
||||
@@ -125,3 +103,24 @@ uint32_t FillBucket::size() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FillBucket::drawElements(PlainShader& shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
|
||||
char *elements_index = BUFFER_OFFSET(elements_start * 3 * sizeof(int16_t));
|
||||
for (group& group : groups) {
|
||||
group.array.bind(shader, *buffer, vertex_index);
|
||||
glDrawElements(GL_TRIANGLES, group.elements_length * 3 - 3, GL_UNSIGNED_SHORT, elements_index);
|
||||
vertex_index += group.vertex_length * 2 * sizeof(uint16_t);
|
||||
elements_index += group.elements_length * 3 * sizeof(uint16_t);
|
||||
}
|
||||
}
|
||||
|
||||
void FillBucket::drawVertices(OutlineShader& shader) {
|
||||
// Draw the entire line
|
||||
char *vertex_index = BUFFER_OFFSET(vertex_start * 2 * sizeof(int16_t));
|
||||
array.bind(shader, *buffer, vertex_index);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <llmr/geometry/geometry.hpp>
|
||||
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
#include <llmr/renderer/shader-line.hpp>
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/map/vector_tile.hpp>
|
||||
|
||||
@@ -264,14 +265,19 @@ void LineBucket::render(Painter& painter, const std::string& layer_name, const T
|
||||
painter.renderLine(*this, layer_name, id);
|
||||
}
|
||||
|
||||
uint32_t LineBucket::size() const {
|
||||
size_t LineBucket::size() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
void LineBucket::bind() {
|
||||
buffer->bind();
|
||||
void LineBucket::bind(LineShader& shader) {
|
||||
char *vertex_index = BUFFER_OFFSET(start * 4 * sizeof(int16_t));
|
||||
array.bind(shader, *buffer, vertex_index);
|
||||
}
|
||||
|
||||
char *LineBucket::vertexOffset() const {
|
||||
return BUFFER_OFFSET(start * 4 * sizeof(int16_t));
|
||||
void LineBucket::drawLines() {
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, length);
|
||||
}
|
||||
|
||||
void LineBucket::drawPoints() {
|
||||
glDrawArrays(GL_POINTS, 0, length);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
|
||||
#include <llmr/renderer/shader-plain.hpp>
|
||||
#include <llmr/renderer/shader-fill.hpp>
|
||||
#include <llmr/renderer/shader-outline.hpp>
|
||||
#include <llmr/renderer/shader-pattern.hpp>
|
||||
#include <llmr/renderer/shader-line.hpp>
|
||||
#include <llmr/renderer/painter.hpp>
|
||||
#include <llmr/util/std.hpp>
|
||||
|
||||
#include <llmr/renderer/fill_bucket.hpp>
|
||||
#include <llmr/renderer/line_bucket.hpp>
|
||||
|
||||
#include <llmr/map/transform.hpp>
|
||||
#include <llmr/map/settings.hpp>
|
||||
#include <llmr/geometry/debug_font_buffer.hpp>
|
||||
@@ -24,15 +22,13 @@ using namespace llmr;
|
||||
Painter::Painter(Transform& transform, Settings& settings, Style& style)
|
||||
: transform(transform),
|
||||
settings(settings),
|
||||
style(style),
|
||||
currentShader(NULL) {
|
||||
style(style) {
|
||||
}
|
||||
|
||||
|
||||
void Painter::setup() {
|
||||
setupShaders();
|
||||
|
||||
assert(fillShader);
|
||||
assert(plainShader);
|
||||
assert(outlineShader);
|
||||
assert(lineShader);
|
||||
@@ -47,11 +43,10 @@ void Painter::setup() {
|
||||
}
|
||||
|
||||
void Painter::setupShaders() {
|
||||
fillShader = std::make_shared<FillShader>();
|
||||
plainShader = std::make_shared<PlainShader>();
|
||||
outlineShader = std::make_shared<OutlineShader>();
|
||||
lineShader = std::make_shared<LineShader>();
|
||||
patternShader = std::make_shared<PatternShader>();
|
||||
plainShader = std::make_unique<PlainShader>();
|
||||
outlineShader = std::make_unique<OutlineShader>();
|
||||
lineShader = std::make_unique<LineShader>();
|
||||
patternShader = std::make_unique<PatternShader>();
|
||||
}
|
||||
|
||||
void Painter::changeMatrix(const Tile::ID& id) {
|
||||
@@ -76,7 +71,7 @@ void Painter::changeMatrix(const Tile::ID& id) {
|
||||
}
|
||||
|
||||
void Painter::drawClippingMask() {
|
||||
switchShader(plainShader);
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
|
||||
glColorMask(false, false, false, false);
|
||||
@@ -96,9 +91,10 @@ void Painter::drawClippingMask() {
|
||||
glStencilMask(0xC0);
|
||||
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
|
||||
|
||||
|
||||
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
|
||||
// Draw the clipping mask
|
||||
tileStencilBuffer.bind();
|
||||
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
|
||||
|
||||
@@ -197,11 +193,11 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
glColorMask(false, false, false, false);
|
||||
|
||||
// Draw the actual triangle fan into the stencil buffer.
|
||||
switchShader(fillShader);
|
||||
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
|
||||
// Draw all groups
|
||||
bucket.drawElements(fillShader->a_pos);
|
||||
bucket.drawElements(*plainShader);
|
||||
|
||||
// Now that we have the stencil mask in the stencil buffer, we can start
|
||||
// writing to the color buffer.
|
||||
@@ -215,7 +211,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
// Because we're drawing top-to-bottom, and we update the stencil mask
|
||||
// below, we have to draw the outline first (!)
|
||||
if (properties.antialias) {
|
||||
switchShader(outlineShader);
|
||||
glUseProgram(outlineShader->program);
|
||||
glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glLineWidth(2);
|
||||
|
||||
@@ -238,7 +234,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
// Draw the entire line
|
||||
glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height);
|
||||
glLineWidth(2.0f);
|
||||
bucket.drawVertices(outlineShader->a_pos);
|
||||
bucket.drawVertices(*outlineShader);
|
||||
}
|
||||
|
||||
// Only draw regions that we marked
|
||||
@@ -257,7 +253,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
fmod(id.y * 4096, imageSize.y)
|
||||
};
|
||||
|
||||
switchShader(patternShader);
|
||||
glUseProgram(patternShader->program);
|
||||
glUniformMatrix4fv(patternShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glUniform2f(patternShader->u_pattern_size, imageSize.x, imageSize.y);
|
||||
glUniform2f(patternShader->u_offset, offset.x, offset.y);
|
||||
@@ -268,19 +264,17 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
style.sprite->bind(true);
|
||||
|
||||
// Draw a rectangle that covers the entire viewport.
|
||||
tileStencilBuffer.bind();
|
||||
glVertexAttribPointer(patternShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
|
||||
|
||||
} else {
|
||||
// Draw filling rectangle.
|
||||
switchShader(fillShader);
|
||||
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glUniform4fv(fillShader->u_color, 1, fill_color.data());
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glUniform4fv(plainShader->u_color, 1, fill_color.data());
|
||||
|
||||
// Draw a rectangle that covers the entire viewport.
|
||||
tileStencilBuffer.bind();
|
||||
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
|
||||
}
|
||||
|
||||
@@ -324,42 +318,37 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
|
||||
// glUniform1f(painter.linepatternShader.u_fade, painter.transform.z % 1.0);
|
||||
|
||||
} else {
|
||||
switchShader(lineShader);
|
||||
glUseProgram(lineShader->program);
|
||||
glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
glUniformMatrix4fv(lineShader->u_exmatrix, 1, GL_FALSE, exMatrix.data());
|
||||
// glUniform2fv(painter.lineShader.u_dasharray, properties.dasharray || [1, -1]);
|
||||
glUniform2f(lineShader->u_dasharray, 1, -1);
|
||||
}
|
||||
|
||||
|
||||
// TODO: Move this to transform?
|
||||
const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
|
||||
// TODO: Move this to transform?
|
||||
const double tilePixelRatio = transform.getScale() / (1 << transform.getIntegerZoom()) / 8;
|
||||
|
||||
glUniform2f(lineShader->u_linewidth, outset, inset);
|
||||
glUniform1f(lineShader->u_ratio, tilePixelRatio);
|
||||
glUniform1f(lineShader->u_gamma, transform.pixelRatio);
|
||||
glUniform2f(lineShader->u_linewidth, outset, inset);
|
||||
glUniform1f(lineShader->u_ratio, tilePixelRatio);
|
||||
glUniform1f(lineShader->u_gamma, transform.pixelRatio);
|
||||
|
||||
// const Color& color = properties.color;
|
||||
// if (!params.antialiasing) {
|
||||
// color[3] = Infinity;
|
||||
// glUniform4fv(lineShader->u_color, color);
|
||||
// } else {
|
||||
glUniform4fv(lineShader->u_color, 1, color.data());
|
||||
// }
|
||||
// const Color& color = properties.color;
|
||||
// if (!params.antialiasing) {
|
||||
// color[3] = Infinity;
|
||||
// glUniform4fv(lineShader->u_color, color);
|
||||
// } else {
|
||||
glUniform4fv(lineShader->u_color, 1, color.data());
|
||||
// }
|
||||
|
||||
|
||||
glUniform1f(lineShader->u_point, 0);
|
||||
glUniform1f(lineShader->u_point, 0);
|
||||
bucket.bind(*lineShader);
|
||||
bucket.drawLines();
|
||||
|
||||
bucket.bind();
|
||||
char *vertex_index = bucket.vertexOffset();
|
||||
glVertexAttribPointer(lineShader->a_pos, 2, GL_SHORT, false, 8, vertex_index);
|
||||
glVertexAttribPointer(lineShader->a_extrude, 2, GL_BYTE, false, 8, vertex_index + 6);
|
||||
glVertexAttribPointer(lineShader->a_linesofar, 1, GL_SHORT, false, 8, vertex_index + 4);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, bucket.size());
|
||||
|
||||
if (bucket.geometry.join == JoinType::Round) {
|
||||
glUniform1f(lineShader->u_point, 1);
|
||||
glDrawArrays(GL_POINTS, 0, bucket.size());
|
||||
if (bucket.geometry.join == JoinType::Round) {
|
||||
glUniform1f(lineShader->u_point, 1);
|
||||
bucket.drawPoints();
|
||||
}
|
||||
}
|
||||
|
||||
// statistics
|
||||
@@ -369,27 +358,23 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
|
||||
void Painter::renderDebug(const Tile::Ptr& tile) {
|
||||
// Blend to the front, not the back.
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
|
||||
// draw tile outline
|
||||
switchShader(plainShader);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
tileBorderBuffer.bind();
|
||||
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0));
|
||||
glUniform4f(plainShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glLineWidth(4.0f);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, tileBorderBuffer.length());
|
||||
|
||||
// draw debug info
|
||||
switchShader(plainShader);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
tile->debugFontBuffer->bind();
|
||||
glVertexAttribPointer(plainShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
tile->debugFontArray.bind(*plainShader, tile->debugFontBuffer, BUFFER_OFFSET(0));
|
||||
glUniform4f(plainShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glLineWidth(4.0f);
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer->length());
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length());
|
||||
glUniform4f(plainShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glLineWidth(2.0f);
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer->length());
|
||||
glDrawArrays(GL_LINES, 0, tile->debugFontBuffer.length());
|
||||
|
||||
// Revert blending mode to blend to the back.
|
||||
glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
|
||||
@@ -398,76 +383,27 @@ void Painter::renderDebug(const Tile::Ptr& tile) {
|
||||
void Painter::renderMatte() {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
switchShader(fillShader);
|
||||
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
|
||||
Color white = {{ 0.9, 0.9, 0.9, 1 }};
|
||||
|
||||
Color white = {{ 1, 1, 1, 1 }};
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, nativeMatrix.data());
|
||||
|
||||
// Draw the clipping mask
|
||||
matteBuffer.bind();
|
||||
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
glUniform4fv(fillShader->u_color, 1, white.data());
|
||||
matteArray.bind(*plainShader, matteBuffer, BUFFER_OFFSET(0));
|
||||
glUniform4fv(plainShader->u_color, 1, white.data());
|
||||
glDrawArrays(GL_TRIANGLES, 0, matteBuffer.length());
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
void Painter::renderBackground() {
|
||||
switchShader(fillShader);
|
||||
glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
|
||||
Color white = {{ 1, 1, 1, 1 }};
|
||||
|
||||
glUseProgram(plainShader->program);
|
||||
glUniformMatrix4fv(plainShader->u_matrix, 1, GL_FALSE, matrix.data());
|
||||
|
||||
// Draw the clipping mask
|
||||
tileStencilBuffer.bind();
|
||||
glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
|
||||
glUniform4fv(fillShader->u_color, 1, white.data());
|
||||
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
glUniform4fv(plainShader->u_color, 1, white.data());
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.length());
|
||||
}
|
||||
|
||||
|
||||
// Switches to a different shader program.
|
||||
/**
|
||||
* @return boolean whether the shader was actually switched
|
||||
*/
|
||||
bool Painter::switchShader(std::shared_ptr<Shader> shader) {
|
||||
if (currentShader != shader) {
|
||||
glUseProgram(shader->program);
|
||||
|
||||
// Disable all attributes from the existing shader that aren't used in
|
||||
// the new shader. Note: attribute indices are *not* program specific!
|
||||
if (currentShader) {
|
||||
const std::forward_list<uint32_t>& hitherto = currentShader->attributes;
|
||||
const std::forward_list<uint32_t>& henceforth = shader->attributes;
|
||||
|
||||
// Find all attribute indices that are used in the old shader,
|
||||
// but unused in the new one.
|
||||
for (uint32_t i : hitherto) {
|
||||
if (std::find(henceforth.begin(), henceforth.end(), i) == henceforth.end()) {
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable all attributes for the new shader that were not already in
|
||||
// use in the old one.
|
||||
for (uint32_t i : henceforth) {
|
||||
if (std::find(hitherto.begin(), hitherto.end(), i) == hitherto.end()) {
|
||||
glEnableVertexAttribArray(i);
|
||||
}
|
||||
}
|
||||
|
||||
currentShader = shader;
|
||||
} else {
|
||||
// Enable all attributes for the new shader (== first shader).
|
||||
for (GLuint index : shader->attributes) {
|
||||
glEnableVertexAttribArray(index);
|
||||
}
|
||||
}
|
||||
|
||||
currentShader = shader;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <llmr/renderer/shader-fill.hpp>
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
FillShader::FillShader()
|
||||
: Shader(
|
||||
shaders[FILL_SHADER].vertex,
|
||||
shaders[FILL_SHADER].fragment
|
||||
) {
|
||||
if (!valid) {
|
||||
fprintf(stderr, "invalid fill shader\n");
|
||||
return;
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
attributes.emplace_front(a_pos);
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
LineShader::LineShader()
|
||||
@@ -15,11 +17,8 @@ LineShader::LineShader()
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
attributes.emplace_front(a_pos);
|
||||
a_extrude = glGetAttribLocation(program, "a_extrude");
|
||||
attributes.emplace_front(a_extrude);
|
||||
a_linesofar = glGetAttribLocation(program, "a_linesofar");
|
||||
attributes.emplace_front(a_linesofar);
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_exmatrix = glGetUniformLocation(program, "u_exmatrix");
|
||||
@@ -31,3 +30,14 @@ LineShader::LineShader()
|
||||
u_point = glGetUniformLocation(program, "u_point");
|
||||
u_gamma = glGetUniformLocation(program, "u_gamma");
|
||||
}
|
||||
|
||||
void LineShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset);
|
||||
|
||||
glEnableVertexAttribArray(a_extrude);
|
||||
glVertexAttribPointer(a_extrude, 2, GL_BYTE, false, 8, offset + 6);
|
||||
|
||||
glEnableVertexAttribArray(a_linesofar);
|
||||
glVertexAttribPointer(a_linesofar, 1, GL_SHORT, false, 8, offset + 4);
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
OutlineShader::OutlineShader()
|
||||
@@ -15,9 +17,13 @@ OutlineShader::OutlineShader()
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
attributes.emplace_front(a_pos);
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
u_world = glGetUniformLocation(program, "u_world");
|
||||
}
|
||||
|
||||
void OutlineShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
PatternShader::PatternShader()
|
||||
@@ -15,7 +17,6 @@ PatternShader::PatternShader()
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
attributes.emplace_front(a_pos);
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
@@ -25,3 +26,8 @@ PatternShader::PatternShader()
|
||||
u_pattern_br = glGetUniformLocation(program, "u_pattern_br");
|
||||
u_mix = glGetUniformLocation(program, "u_mix");
|
||||
}
|
||||
|
||||
void PatternShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <llmr/shader/shaders.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
PlainShader::PlainShader()
|
||||
@@ -15,8 +17,12 @@ PlainShader::PlainShader()
|
||||
}
|
||||
|
||||
a_pos = glGetAttribLocation(program, "a_pos");
|
||||
attributes.emplace_front(a_pos);
|
||||
|
||||
u_matrix = glGetUniformLocation(program, "u_matrix");
|
||||
u_color = glGetUniformLocation(program, "u_color");
|
||||
}
|
||||
|
||||
void PlainShader::bind(char *offset) {
|
||||
glEnableVertexAttribArray(a_pos);
|
||||
glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ bool Shader::compileShader(GLuint *shader, GLenum type, const GLchar *source) {
|
||||
|
||||
#if defined(EMSCRIPTEN) || defined(GL_ES_VERSION_2_0)
|
||||
// Add WebGL GLSL / OpenGL ES precision premable
|
||||
const GLchar *preamble = "precision mediump float;\n\n";
|
||||
const GLchar *preamble = "precision highp float;\n\n";
|
||||
#else
|
||||
// Desktop GLSL
|
||||
const GLchar *preamble = "#version 120\n\n";
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = u_color;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
attribute vec2 a_pos;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_matrix * vec4(a_pos, 0, 1);
|
||||
}
|
||||
@@ -4,10 +4,6 @@
|
||||
using namespace llmr;
|
||||
|
||||
const shader_source llmr::shaders[SHADER_COUNT] = {
|
||||
{
|
||||
"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",
|
||||
},
|
||||
{
|
||||
"// these are the shaders for rendering antialiased lines\n\n// floor(127 / 2) == 63.0\n// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is\n// stored in a byte (-128..127). we scale regular normals up to length 63, but\n// there are also \"special\" normals that have a bigger length (of up to 126 in\n// this case).\n#define scale 63.0\n\nattribute vec2 a_pos;\nattribute vec2 a_extrude;\nattribute float a_linesofar;\n\n// matrix is for the vertex position, exmatrix is for rotating and projecting\n// the extrusion vector.\nuniform mat4 u_matrix;\nuniform mat4 u_exmatrix;\n\n\nuniform float u_debug;\n\n// shared\nuniform float u_ratio;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\nuniform float u_point;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // We store the texture normals in the most insignificant bit\n // transform y so that 0 => -1 and 1 => 1\n // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap\n // y is 1 if the normal points up, and -1 if it points down\n vec2 normal = mod(a_pos, 2.0);\n normal.y = sign(normal.y - 0.5);\n v_normal = normal;\n\n // Scale the extrusion vector down to a normal and then up by the line width\n // of this vertex.\n vec2 extrude = a_extrude / scale;\n vec2 dist = u_linewidth.s * extrude * (1.0 - u_point);\n\n // If the x coordinate is the maximum integer, we move the z coordinates out\n // of the view plane so that the triangle gets clipped. This makes it easier\n // for us to create degenerate triangle strips.\n float z = step(32767.0, a_pos.x);\n\n // When drawing points, skip every other vertex\n z += u_point * step(1.0, v_normal.y);\n\n // Remove the texture normal bit of the position before scaling it with the\n // model/view matrix. Add the extrusion vector *after* the model/view matrix\n // because we're extruding the line in pixel space, regardless of the current\n // tile's zoom level.\n gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0) + u_exmatrix * vec4(dist, z, 0.0);\n v_linesofar = a_linesofar * u_ratio;\n\n\n gl_PointSize = 2.0 * u_linewidth.s - 1.0;\n}\n",
|
||||
"// shared\nuniform float u_debug;\nuniform vec2 u_linewidth;\nuniform vec4 u_color;\nuniform float u_point;\nuniform float u_gamma;\n\nuniform vec2 u_dasharray;\n\nvarying vec2 v_normal;\nvarying float v_linesofar;\n\nvoid main() {\n // Calculate the distance of the pixel from the line in pixels.\n float dist = length(v_normal) * (1.0 - u_point) + u_point * length(gl_PointCoord * 2.0 - 1.0);\n\n dist *= u_linewidth.s;\n\n // Calculate the antialiasing fade factor. This is either when fading in\n // the line in case of an offset line (v_linewidth.t) or when fading out\n // (v_linewidth.s)\n float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist) * u_gamma, 0.0, 1.0);\n\n // Calculate the antialiasing fade factor based on distance to the dash.\n // Only affects alpha when line is dashed\n float pos = mod(v_linesofar, u_dasharray.x + u_dasharray.y);\n alpha *= max(step(0.0, -u_dasharray.y), clamp(min(pos, u_dasharray.x - pos), 0.0, 1.0));\n\n gl_FragColor = u_color * alpha;\n\n if (u_debug > 0.0) {\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n}\n",
|
||||
|
||||
Reference in New Issue
Block a user