summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-01-15 11:34:41 +0100
committerKonstantin Käfer <mail@kkaefer.com>2014-01-15 11:34:41 +0100
commit44a0f98fe54a7a2954c46137b9aac3e149ad7958 (patch)
tree8eee70ecb491f629b32ed179ad7cbbdfacc7d2d8
parent60a8fdca5727bc57bd6526e5447e2cc41db1ada8 (diff)
downloadqtlocation-mapboxgl-44a0f98fe54a7a2954c46137b9aac3e149ad7958.tar.gz
retain child tiles
-rw-r--r--include/llmr/map/map.hpp17
-rw-r--r--include/llmr/map/tile.hpp24
-rw-r--r--include/llmr/map/transform.hpp3
-rw-r--r--include/llmr/renderer/painter.hpp7
-rw-r--r--include/llmr/util/vec2.hpp9
-rw-r--r--macosx/main.mm20
-rw-r--r--src/map/map.cpp113
-rw-r--r--src/map/tile.cpp74
-rw-r--r--src/map/transform.cpp7
-rw-r--r--src/renderer/painter.cpp141
-rw-r--r--src/shader/line.fragment.glsl1
11 files changed, 249 insertions, 167 deletions
diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp
index 71387c0934..e9dd9b0974 100644
--- a/include/llmr/map/map.hpp
+++ b/include/llmr/map/map.hpp
@@ -4,10 +4,11 @@
#include "../platform/platform.hpp"
#include "../renderer/painter.hpp"
#include "transform.hpp"
+#include <llmr/map/tile.hpp>
-namespace llmr {
+#include <forward_list>
-class tile;
+namespace llmr {
class map {
public:
@@ -22,20 +23,22 @@ public:
void moveBy(double dx, double dy);
void scaleBy(double ds, double cx, double cy);
void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey);
- void tileLoaded(std::shared_ptr<tile> tile);
- void tileFailed(std::shared_ptr<tile> tile);
+ void tileLoaded(tile::ptr tile);
+ void tileFailed(tile::ptr tile);
private:
void updateTiles();
+ tile::ptr addTile(tile_id id);
+ tile::ptr hasTile(tile_id id);
private:
transform *transform;
painter *painter;
- // int32_t min_zoom;
- // int32_t max_zoom;
+ int32_t min_zoom;
+ int32_t max_zoom;
- std::vector<std::shared_ptr<tile>> tiles;
+ std::forward_list<tile::ptr> tiles;
};
}
diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp
index 063e6a90bd..0e3706de7b 100644
--- a/include/llmr/map/tile.hpp
+++ b/include/llmr/map/tile.hpp
@@ -4,18 +4,26 @@
#include "../geometry/linevertexbuffer.hpp"
#include <stdint.h>
-#include <vector>
+#include <forward_list>
#include <mutex>
#include <llmr/util/vec2.hpp>
namespace llmr {
+typedef vec3<int32_t> tile_id;
+
class tile {
public:
typedef std::shared_ptr<tile> ptr;
+ enum state {
+ initial,
+ loading,
+ ready,
+ obsolete
+ };
public:
- tile(int32_t z, int32_t x, int32_t y);
+ tile(tile_id id);
~tile();
void setData(uint8_t *data, uint32_t bytes);
@@ -26,18 +34,20 @@ public:
void cancel();
+ const std::string toString() const;
+
+ static tile_id parent(const tile_id& id, int32_t z);
+ static std::forward_list<tile_id> children(const tile_id& id, int32_t z);
+
// static int64_t toID(int32_t z, int32_t x, int32_t y, int32_t w = 0);
// static vec4<int32_t> fromID(int64_t id);
public:
- const int32_t z, x, y;
- bool loaded;
- bool cancelled;
+ const tile_id id;
+ state state;
linevertexbuffer lineVertex;
private:
- std::mutex mutex;
-
// Source data
uint8_t *data;
uint32_t bytes;
diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp
index 5d81b0c202..4ff7ba7fd4 100644
--- a/include/llmr/map/transform.hpp
+++ b/include/llmr/map/transform.hpp
@@ -3,6 +3,7 @@
#include <cstdint>
+#include <llmr/util/vec2.hpp>
namespace llmr {
@@ -26,7 +27,7 @@ public:
void setLonLat(double lon, double lat);
// Getters
- void matrixFor(float matrix[16], uint32_t z, uint32_t x, uint32_t y) const;
+ void matrixFor(float matrix[16], const vec3<int32_t>& id) const;
int32_t getZoom() const;
void getLonLat(double& lon, double& lat) const;
diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp
index 83a9171aba..3f6235d8f3 100644
--- a/include/llmr/renderer/painter.hpp
+++ b/include/llmr/renderer/painter.hpp
@@ -21,7 +21,8 @@ public:
void clear();
void render(std::shared_ptr<tile> tile);
- void switchShader(Shader *shader, float matrix[16]);
+ void drawClippingMask();
+ void switchShader(Shader *shader);
private:
void setupShaders();
@@ -37,9 +38,7 @@ private:
FillShader *fillShader;
LineShader *lineShader;
- // uint32_t vertexArray;
- uint32_t triangleVertexBuffer;
- uint32_t fillVertexBuffer;
+ uint32_t tile_stencil_buffer;
};
}
diff --git a/include/llmr/util/vec2.hpp b/include/llmr/util/vec2.hpp
index 332f54f5f9..782573d7fd 100644
--- a/include/llmr/util/vec2.hpp
+++ b/include/llmr/util/vec2.hpp
@@ -7,6 +7,9 @@ template <typename T = double>
struct vec2 {
T x, y;
+ inline vec2() {}
+ inline vec2(const vec2& o) : x(o.x), y(o.y) {}
+ inline vec2(T x, T y) : x(x), y(y) {}
inline bool operator==(const vec2& rhs) const {
return x == rhs.x && y == rhs.y;
}
@@ -16,6 +19,9 @@ template <typename T = double>
struct vec3 {
T x, y, z;
+ inline vec3() {}
+ inline vec3(const vec3& o) : x(o.x), y(o.y), z(o.z) {}
+ inline vec3(T x, T y, T z) : x(x), y(y), z(z) {}
inline bool operator==(const vec3& rhs) const {
return x == rhs.x && y == rhs.y && z == rhs.z;
}
@@ -25,6 +31,9 @@ template <typename T = double>
struct vec4 {
T x, y, z, w;
+ inline vec4() {}
+ inline vec4(const vec4& o) : x(o.x), y(o.y), z(o.z), w(o.w) {}
+ inline vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
inline bool operator==(const vec4& rhs) const {
return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
}
diff --git a/macosx/main.mm b/macosx/main.mm
index 23d75b4679..15f4727700 100644
--- a/macosx/main.mm
+++ b/macosx/main.mm
@@ -20,6 +20,9 @@ public:
exit(1);
}
+ glfwWindowHint(GLFW_STENCIL_BITS, 8);
+ glfwWindowHint(GLFW_DEPTH_BITS, 16);
+
window = glfwCreateWindow(640, 480, "llmr", NULL, NULL);
if (!window) {
glfwTerminate();
@@ -29,6 +32,9 @@ public:
glfwMakeContextCurrent(window);
+ int stencil_bits = glfwGetWindowAttrib(window, GLFW_STENCIL_BITS);
+ fprintf(stderr, "stencil bits: %d\n", stencil_bits);
+
map->setup();
@@ -173,6 +179,7 @@ void restart(void *) {
}
void request(void *, tile::ptr tile) {
+ assert((bool)tile);
// fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y);
// fprintf(stderr, "requesting tile\n");
@@ -180,9 +187,9 @@ void request(void *, tile::ptr tile) {
NSString *urlTemplate = @"http://localhost:3333/gl/tiles/plain/%d-%d-%d.vector.pbf";
NSString *urlString = [NSString
stringWithFormat:urlTemplate,
- tile->z,
- tile->x,
- tile->y];
+ tile->id.z,
+ tile->id.x,
+ tile->id.y];
NSURL *url = [NSURL URLWithString:urlString];
// NSLog(@"Requesting %@", urlString);
@@ -210,12 +217,9 @@ void request(void *, tile::ptr tile) {
});
return;
}
- } else {
- fprintf(stderr, "[%s] status code %d\n", [urlString UTF8String], code);
- dispatch_async(dispatch_get_main_queue(), ^ {
- view->map->tileFailed(tile);
- });
}
+
+ fprintf(stderr, "[%s] status code %d\n", [urlString UTF8String], code);
}
dispatch_async(dispatch_get_main_queue(), ^ {
diff --git a/src/map/map.cpp b/src/map/map.cpp
index f488899939..d1392d4c9c 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -6,12 +6,15 @@
#include <thread>
#include <cmath>
+#include <cassert>
using namespace llmr;
map::map()
: transform(new class transform()),
- painter(new class painter(transform)) {
+ painter(new class painter(transform)),
+ min_zoom(0),
+ max_zoom(14) {
// transform->setLonLat(13, 50);
// transform->setZoom(3);
@@ -50,9 +53,38 @@ void map::rotateBy(double cx, double cy, double sx, double sy, double ex, double
platform::restart(this);
}
+
+tile::ptr map::hasTile(tile_id id) {
+ for (tile::ptr& tile : tiles) {
+ if (tile->id == id) {
+ return tile;
+ }
+ }
+
+ return tile::ptr();
+}
+
+tile::ptr map::addTile(tile_id id) {
+ tile::ptr tile = hasTile(id);
+
+ if (!tile.get()) {
+ // We couldn't find the tile in the list. Create a new one.
+ tile = std::make_shared<class tile>(id);
+ assert(tile);
+ std::cerr << "init " << id.z << "/" << id.x << "/" << id.y << std::endl;
+ std::cerr << "add " << tile->toString() << std::endl;
+ tiles.push_front(tile);
+ }
+
+ return tile;
+}
+
void map::updateTiles() {
// Figure out what tiles we need to load
int32_t zoom = transform->getZoom();
+ if (zoom > max_zoom) zoom = max_zoom;
+ if (zoom < min_zoom) zoom = min_zoom;
+
int32_t max_dim = pow(2, zoom);
// Map four viewport corners to pixel coordinates
@@ -65,55 +97,75 @@ void map::updateTiles() {
br.x = fmin(max_dim, ceil(fmax(box.tr.x, box.br.x)));
br.y = fmin(max_dim, ceil(fmax(box.bl.y, box.br.y)));
- typedef vec3<int32_t> tile_id;
// TODO: Discard tiles that are outside the viewport
- std::vector<tile_id> required;
+ std::forward_list<tile_id> required;
for (int32_t y = tl.y; y < br.y; y++) {
for (int32_t x = tl.x; x < br.x; x++) {
- tile_id id; id.z = zoom; id.x = x; id.y = y;
- required.push_back(id);
+ required.emplace_front(x, y, zoom);
}
}
+ std::forward_list<tile_id> retain(required);
+
// Add existing child/parent tiles if the actual tile is not yet loaded
- // TODO
+ for (const tile_id& id : required) {
+ tile::ptr tile = addTile(id);
+ assert(tile);
+
+ if (tile->state == tile::initial || tile->state == tile::loading) {
+ // The tile we require is not yet loaded. Try to find a parent or
+ // child tile that we already have.
+ std::forward_list<tile_id> covering;
+
+ // Find existing child tiles.
+ // TODO: Limit to existing tile ranges.
+ if (id.z + 1 <= max_zoom) {
+ covering = tile::children(id, id.z + 1);
+ }
+
+ // Find existing parent tile.
+ // TODO: Limit to existing tile ranges.
+ if (id.z - 1 >= min_zoom) {
+ covering.push_front(tile::parent(id, id.z - 1));
+ }
+
+ for (const tile_id& covering_id : covering) {
+ tile::ptr covering_tile = hasTile(covering_id);
+ if (covering_tile) {
+ assert(covering_tile);
+ if (covering_tile->state == tile::ready) {
+ retain.emplace_front(covering_tile->id);
+ }
+ }
+ }
+ }
+ if (tile->state == tile::initial) {
+ // If the tile is new, we have to make sure to load it.
+ tile->state = tile::loading;
+ platform::request(this, tile);
+ }
+ }
// Remove tiles that we definitely don't need, i.e. tiles that are not on
// the required list.
- for (std::vector<tile::ptr>::iterator it = tiles.begin(); it != tiles.end(); it++) {
- tile::ptr& tile = *it;
- tile_id id; id.z = tile->z; id.x = tile->x; id.y = tile->y;
- std::vector<tile_id>::const_iterator required_it = std::find(required.begin(), required.end(), id);
- bool retain = required_it != required.end();
- if (retain) {
- // We already have the tile; remove it from the list of required tiles.
- required.erase(required_it);
- } else {
- // We don't need this tile, so we can remove it entirely.
- std::vector<tile::ptr>::iterator to_remove = it - 1;
+ tiles.remove_if([&retain](const tile::ptr& tile) {
+ assert(tile);
+ bool obsolete = std::find(retain.begin(), retain.end(), tile->id) == retain.end();
+ if (obsolete) {
tile->cancel();
- tiles.erase(it);
- it = to_remove;
}
- }
-
- // Required now only contains those tiles that are not yet in the list of
- // tiles, so we should add them all.
- for (tile_id& id : required) {
- tile::ptr tile = std::make_shared<class tile>(id.z, id.x, id.y);
- tiles.push_back(tile);
- platform::request(this, tile);
- }
+ return obsolete;
+ });
}
bool map::render() {
painter->clear();
for (tile::ptr& tile : tiles) {
- // painter->viewport();
- if (tile->loaded) {
+ assert(tile);
+ if (tile->state == tile::ready) {
painter->render(tile);
}
}
@@ -122,6 +174,7 @@ bool map::render() {
}
void map::tileLoaded(tile::ptr tile) {
+ std::cerr << "loaded " << tile->toString() << std::endl;
platform::restart(this);
}
diff --git a/src/map/tile.cpp b/src/map/tile.cpp
index ab9f2fe03b..58533dc86c 100644
--- a/src/map/tile.cpp
+++ b/src/map/tile.cpp
@@ -7,6 +7,7 @@
#include "pbf.hpp"
#include <llmr/util/vec2.hpp>
+#include <llmr/util/string.hpp>
#include <cmath>
using namespace llmr;
@@ -34,48 +35,69 @@ using namespace llmr;
// return coord;
// };
-tile::tile(int32_t z, int32_t x, int32_t y)
- : z(z),
- x(x),
- y(y),
- loaded(false),
- cancelled(false),
+tile_id tile::parent(const tile_id& id, int32_t z) {
+ assert(z < id.z);
+ tile_id pos(id);
+ while (pos.z > z) {
+ pos.z--;
+ pos.x = floor(pos.x / 2);
+ pos.y = floor(pos.y / 2);
+ }
+ return pos;
+}
+
+
+std::forward_list<tile_id> tile::children(const tile_id& id, int32_t z) {
+ assert(z > id.z);
+ int32_t factor = pow(2, z - id.z);
+
+ std::forward_list<tile_id> children;
+ for (int32_t y = id.y * factor, y_max = (id.y + 1) * factor; y < y_max; y++) {
+ for (int32_t x = id.x * factor, x_max = (id.x + 1) * factor; x < x_max; x++) {
+ children.emplace_front(x, y, z);
+ }
+ }
+ return children;
+}
+
+
+tile::tile(tile_id id)
+ : id(id),
+ state(initial),
data(0),
bytes(0) {
}
tile::~tile() {
- fprintf(stderr, "[%p] deleting tile %d/%d/%d\n", this, z, x, y);
+ fprintf(stderr, "[%p] deleting tile %d/%d/%d\n", this, id.z, id.x, id.y);
if (this->data) {
free(this->data);
}
}
+const std::string tile::toString() const {
+ return util::sprintf("[tile %d/%d/%d]", id.z, id.x, id.y);
+}
+
+
void tile::setData(uint8_t *data, uint32_t bytes) {
this->data = (uint8_t *)malloc(bytes);
this->bytes = bytes;
memcpy(this->data, data, bytes);
}
-void tile::cancel()
-{
- std::lock_guard<std::mutex> lock(mutex);
-
+void tile::cancel() {
// TODO: thread safety
- if (!cancelled) {
- cancelled = true;
+ if (state != obsolete) {
+ state = obsolete;
} else {
assert((!"logic error? multiple cancelleations"));
}
}
-bool tile::parse()
-{
- {
- std::lock_guard<std::mutex> lock(mutex);
- if (cancelled) {
- return false;
- }
+bool tile::parse() {
+ if (state == obsolete) {
+ return false;
}
// fprintf(stderr, "[%p] parsing tile [%d/%d/%d]...\n", this, z, x, y);
@@ -84,7 +106,7 @@ bool tile::parse()
int code = setjmp(tile.jump_buffer);
if (code > 0) {
- fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... failed: %s\n", this, z, x, y, tile.msg.c_str());
+ fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, tile.msg.c_str());
cancel();
return false;
}
@@ -101,14 +123,12 @@ bool tile::parse()
// fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... done\n", this, z, x, y);
- {
- std::lock_guard<std::mutex> lock(mutex);
- if (cancelled) {
- return false;
- }
+ if (state == obsolete) {
+ return false;
+ } else {
+ state = ready;
}
- loaded = true;
return true;
}
diff --git a/src/map/transform.cpp b/src/map/transform.cpp
index 6c5f902c86..d7c189003b 100644
--- a/src/map/transform.cpp
+++ b/src/map/transform.cpp
@@ -1,7 +1,6 @@
#include <llmr/map/transform.hpp>
#include <llmr/util/mat4.h>
-#include <llmr/util/vec2.hpp>
#include <llmr/util/math.hpp>
#include <cmath>
#include <cstdio>
@@ -131,8 +130,8 @@ double transform::pixel_y() const {
return center + y;
}
-void transform::matrixFor(float matrix[16], uint32_t tile_z, uint32_t tile_x, uint32_t tile_y) const {
- const double tile_scale = pow(2, tile_z);
+void transform::matrixFor(float matrix[16], const vec3<int32_t>& id) const {
+ const double tile_scale = pow(2, id.z);
const double tile_size = scale * size / tile_scale;
mat4_identity(matrix);
@@ -142,7 +141,7 @@ void transform::matrixFor(float matrix[16], uint32_t tile_z, uint32_t tile_x, ui
mat4_translate(matrix, matrix, -0.5f * (float)width, -0.5f * (float)height, 0);
mat4_translate(matrix, matrix, pixel_x(), pixel_y(), 0);
- mat4_translate(matrix, matrix, tile_x * tile_size, tile_y * tile_size, 0);
+ mat4_translate(matrix, matrix, id.x * tile_size, id.y * tile_size, 0);
// TODO: Get rid of the 8 (scaling from 4096 to 512 px tile size);
mat4_scale(matrix, matrix, scale / tile_scale / 8, scale / tile_scale / 8, 1);
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index a7ee1f034a..00acb1fb40 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -11,49 +11,37 @@ using namespace llmr;
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
-GLfloat triangle_vertices[] = {
- 100, 100,
- 100, 300,
- 150, 150
-};
-
-GLfloat fill_vertices[] = {
+GLshort tile_stencil_vertices[] = {
0, 0,
- 300, 0,
- 0, 300,
- 300, 300
+ 4096, 0,
+ 0, 4096,
+ 4096, 4096
};
-
painter::painter(class transform *transform)
: transform(transform),
currentShader(NULL),
- fillShader(NULL) {
-
+ fillShader(NULL),
+ lineShader(NULL) {
}
void painter::setup() {
setupShaders();
-
assert(fillShader);
assert(lineShader);
+ // Set up the stencil quad we're using to generate the stencil mask.
+ glGenBuffers(1, &tile_stencil_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(tile_stencil_vertices), tile_stencil_vertices, GL_STATIC_DRAW);
+ glEnable(GL_STENCIL_TEST);
- glGenBuffers(1, &triangleVertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
- glGenBuffers(1, &fillVertexBuffer);
- glBindBuffer(GL_ARRAY_BUFFER, fillVertexBuffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(fill_vertices), fill_vertices, GL_STATIC_DRAW);
-
-
- // glGenVertexArraysOES(1, &vertexArray);
- // glBindVertexArrayOES(vertexArray);
- // glBindVertexArrayOES(0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void painter::setupShaders() {
@@ -62,10 +50,7 @@ void painter::setupShaders() {
}
void painter::teardown() {
- glDeleteBuffers(1, &triangleVertexBuffer);
- glDeleteBuffers(1, &fillVertexBuffer);
-
- // glDeleteVertexArraysOES(1, &vertexArray);
+ glDeleteBuffers(1, &tile_stencil_buffer);
if (fillShader) {
delete fillShader;
@@ -87,74 +72,74 @@ void painter::changeMatrix(std::shared_ptr<tile> tile) {
mat4_ortho(projMatrix, 0, transform->width, transform->height, 0, 1, 10);
float mvMatrix[16];
- transform->matrixFor(mvMatrix, tile->z, tile->x, tile->y);
+ transform->matrixFor(mvMatrix, tile->id);
mat4_multiply(matrix, projMatrix, mvMatrix);
}
+void painter::drawClippingMask() {
+ switchShader(lineShader);
+ glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix);
+
+ glColorMask(false, false, false, false);
+
+ // Clear the entire stencil buffer, except for the 7th bit, which stores
+ // the global clipping mask that allows us to avoid drawing in regions of
+ // tiles we've already painted in.
+ glClearStencil(0x0);
+ glStencilMask(0xBF);
+ glClear(GL_STENCIL_BUFFER_BIT);
+
+ // The stencil test will fail always, meaning we set all pixels covered
+ // by this geometry to 0x80. We use the highest bit 0x80 to mark the regions
+ // we want to draw in. All pixels that have this bit *not* set will never be
+ // drawn in.
+ glStencilFunc(GL_EQUAL, 0xC0, 0x40);
+ glStencilMask(0xC0);
+ glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
+
+ // Draw the clipping mask
+ glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer);
+ glVertexAttribPointer(lineShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0));
+ glUniform4f(lineShader->u_color, 1.0f, 0.0f, 1.0f, 1.0f);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(tile_stencil_vertices));
+
+ // glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_EQUAL, 0x80, 0x80);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilMask(0x00);
+ glColorMask(true, true, true, true);
+}
+
void painter::clear() {
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
+ glClearStencil(0x0);
+ glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
-void painter::render(std::shared_ptr<tile> tile) {
+void painter::render(tile::ptr tile) {
+ if (tile->state != tile::ready) {
+ return;
+ }
+
changeMatrix(tile);
- glDisable(GL_STENCIL_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ drawClippingMask();
- // fprintf(stderr, "render tile\n");
- switchShader(lineShader, matrix);
+ switchShader(lineShader);
glUniformMatrix4fv(lineShader->u_matrix, 1, GL_FALSE, matrix);
- // glEnable(GL_BLEND);
- // glVertexAttribPointer(fillShader->a_pos, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
- // glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0));
- // glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBuffer);
+ glStencilFunc(GL_EQUAL, 0x80, 0x80);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ // glDisable(GL_STENCIL_TEST);
+
tile->lineVertex.bind();
glVertexAttribPointer(lineShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, BUFFER_OFFSET(0));
glUniform4f(lineShader->u_color, 0.0f, 0.0f, 0.0f, 1.0f);
glLineWidth(1.0f);
glDrawArrays(GL_LINE_STRIP, 0, tile->lineVertex.length());
-
- // switchShader(fillShader, matrix);
- // glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBuffer);
- // glVertexAttribPointer(fillShader->a_pos, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
- // glUniform4f(fillShader->u_color, 0.0f, 1.0f, 0.0f, 1.0f);
- // glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-
-
-
-
- // glBindVertexArrayOES(vertexArray);
- // switchShader(fillShader, matrix);
- // glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix);
-
- // glEnable(GL_STENCIL_TEST);
-
- // Draw stencil mask.
- // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- // glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
- // glStencilFunc(GL_EQUAL, 0xFF, 0xFF);
- // glStencilMask(0xFF);
-
- // glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBuffer);
- // glVertexAttribPointer(fillShader->a_pos, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
- // glUniform4f(fillShader->u_color, 0.0f, 1.0f, 0.0f, 1.0f);
- // glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-
-
- // // Draw covering fill.
- // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- // glStencilFunc(GL_EQUAL, 0xFF, 0xFF);
-
- // glBindBuffer(GL_ARRAY_BUFFER, fillVertexBuffer);
- // glVertexAttribPointer(fillShader->a_pos, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
- // glUniform4f(fillShader->u_color, 1.0f, 0.0f, 0.0f, 1.0f);
- // glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
void painter::viewport() {
@@ -162,7 +147,7 @@ void painter::viewport() {
}
// Switches to a different shader program.
-void painter::switchShader(Shader *shader, float matrix[16]) {
+void painter::switchShader(Shader *shader) {
if (currentShader != shader) {
glUseProgram(shader->program);
diff --git a/src/shader/line.fragment.glsl b/src/shader/line.fragment.glsl
index 0656051313..8df552c171 100644
--- a/src/shader/line.fragment.glsl
+++ b/src/shader/line.fragment.glsl
@@ -1,4 +1,3 @@
-
uniform vec4 u_color;
void main() {