diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-01-23 14:20:22 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-01-23 14:20:22 +0100 |
commit | 50021b730c6615d21aefa99f2f553640b43ff231 (patch) | |
tree | 0b23d06b12c2923881251cabdbe13c45f279e463 /src | |
parent | b4a95be0b217ac8a73bdc57a0488865b2289d5f5 (diff) | |
download | qtlocation-mapboxgl-50021b730c6615d21aefa99f2f553640b43ff231.tar.gz |
move to layer system
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/geometry/fill_buffer.cpp | 16 | ||||
-rw-r--r-- | src/map/layer.cpp | 3 | ||||
-rw-r--r-- | src/map/tile.cpp | 192 | ||||
-rw-r--r-- | src/renderer/fill_bucket.cpp | 103 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 257 |
6 files changed, 282 insertions, 290 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e3aed9b2e..b4e3557643 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ SET(llmr_SOURCES renderer/shader-line.cpp renderer/shader-outline.cpp renderer/shader.cpp + renderer/fill_bucket.cpp shader/shaders.cpp util/animation.cpp util/mat4.cpp diff --git a/src/geometry/fill_buffer.cpp b/src/geometry/fill_buffer.cpp index 2f71bedc1d..4894361c36 100644 --- a/src/geometry/fill_buffer.cpp +++ b/src/geometry/fill_buffer.cpp @@ -4,14 +4,14 @@ using namespace llmr; -fill_buffer::fill_buffer() +FillBuffer::FillBuffer() : vertex_buffer(0), element_buffer(0), dirty(true) { } -fill_buffer::~fill_buffer() { +FillBuffer::~FillBuffer() { if (vertex_buffer != 0) { glDeleteBuffers(1, &vertex_buffer); vertex_buffer = 0; @@ -22,33 +22,33 @@ fill_buffer::~fill_buffer() { } } -uint32_t fill_buffer::vertex_length() const { +uint32_t FillBuffer::vertex_length() const { // We store 2 coordinates per vertex return vertices.size() / 2; } -uint32_t fill_buffer::elements_length() const { +uint32_t FillBuffer::elements_length() const { // A triangle has 3 indices return elements.size() / 3; } -void fill_buffer::addDegenerate() { +void FillBuffer::addDegenerate() { vertices.push_back(32767); vertices.push_back(0); } -void fill_buffer::addCoordinate(int16_t x, int16_t y) { +void FillBuffer::addCoordinate(int16_t x, int16_t y) { vertices.push_back(x); vertices.push_back(y); } -void fill_buffer::addElements(uint16_t a, uint16_t b, uint16_t c) { +void FillBuffer::addElements(uint16_t a, uint16_t b, uint16_t c) { elements.push_back(a); elements.push_back(b); elements.push_back(c); } -void fill_buffer::bind() { +void FillBuffer::bind() { if (vertex_buffer == 0) { glGenBuffers(1, &vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); diff --git a/src/map/layer.cpp b/src/map/layer.cpp new file mode 100644 index 0000000000..56e907c0af --- /dev/null +++ b/src/map/layer.cpp @@ -0,0 +1,3 @@ +#include <llmr/map/layer.hpp> + +using namespace llmr; diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 4d744cb971..983ccff947 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -8,6 +8,7 @@ #include <llmr/util/pbf.hpp> #include <llmr/util/string.hpp> #include <llmr/geometry/geometry.hpp> +#include <llmr/renderer/fill_bucket.hpp> #include <cmath> using namespace llmr; @@ -41,6 +42,7 @@ std::forward_list<Tile::ID> Tile::children(const ID& id, int32_t z) { Tile::Tile(ID id) : id(id), state(initial), + fillBuffer(std::make_shared<FillBuffer>()), data(0), bytes(0) { @@ -92,23 +94,13 @@ bool Tile::parse() { try { while (tile.next()) { if (tile.tag == 3) { // layer - uint32_t bytes = (uint32_t)tile.varint(); - parseLayer(tile.data, bytes); - tile.skipBytes(bytes); + parseLayer(tile.message()); } else { tile.skip(); } } - } catch (const pbf::exception& ex) { - fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); - cancel(); - return false; - } catch (const Tile::exception& ex) { - fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); - cancel(); - return false; } catch (const std::exception& ex) { - fprintf(stderr, "[%p] general exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); + fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what()); cancel(); return false; } @@ -119,39 +111,23 @@ bool Tile::parse() { state = ready; } - // int i = 0; - // for (const fill_index& index : fillIndices) { - // fprintf(stderr, "[%p] %d: vertex % 8d / % 8d\n", this, i, index.vertex_start, index.vertex_length); - // fprintf(stderr, "[%p] %d: elements % 8d / % 8d\n", this, i, index.elements_start, index.elements_length); - // i++; - // } - return true; } -void Tile::parseLayer(const uint8_t *data, uint32_t bytes) { - pbf layer(data, bytes); - std::string name; - - uint32_t vertex_start = fillBuffer.vertex_length(); - uint32_t elements_start = fillBuffer.elements_length(); - fillIndices.emplace_back(vertex_start, elements_start); - +void Tile::parseLayer(const pbf data) { + pbf layer(data); while (layer.next()) { if (layer.tag == 1) { - name = layer.string(); - fillIndices.back().name = name; - } else if (layer.tag == 2) { - uint32_t bytes = (uint32_t)layer.varint(); - parseFeature(layer.data, bytes); - layer.skipBytes(bytes); + std::string name = layer.string(); + if (name == "water") { + layers.emplace_front(name, createFillBucket(data)); + } } else { layer.skip(); } } } - enum geom_type { Unknown = 0, Point = 1, @@ -159,126 +135,46 @@ enum geom_type { Polygon = 3 }; +std::shared_ptr<Bucket> Tile::createFillBucket(const pbf data) { + pbf layer(data); + std::shared_ptr<FillBucket> bucket = std::make_shared<FillBucket>(fillBuffer); -void Tile::parseFeature(const uint8_t *data, uint32_t bytes) { - pbf feature(data, bytes); - - geom_type type = Unknown; - pbf geom; - - while (feature.next()) { - if (feature.tag == 1) { - /*uint32_t id =*/ feature.varint(); - } else if (feature.tag == 2) { - const uint8_t *tag_end = feature.data + feature.varint(); - while (feature.data < tag_end) { - /*uint32_t key =*/ feature.varint(); - /*uint32_t value =*/ feature.varint(); + while (layer.next()) { + if (layer.tag == 2) { // feature + pbf feature = layer.message(); + pbf geometry; + geom_type type = Unknown; + + while (feature.next()) { + if (feature.tag == 3) { // geometry type + type = (geom_type)feature.varint(); + } else if (feature.tag == 4) { // geometry + geometry = feature.message(); + } else { + feature.skip(); + } } - } else if (feature.tag == 3) { - type = (geom_type)feature.varint(); - } else if (feature.tag == 4) { - geom = feature.message(); - } else { - feature.skip(); - } - } - - if (geom) { - if (type == LineString) { - addLineGeometry(geom); - } else if (type == Polygon) { - addFillGeometry(geom); - } - } -} - -void Tile::addFillGeometry(pbf& geom) { - - std::vector<std::vector<std::pair<int16_t, int16_t>>> lines; - { - std::vector<std::pair<int16_t, int16_t>> line; - Geometry::command cmd; - int32_t x, y; - Geometry geometry(geom); - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (cmd == Geometry::move_to) { - if (line.size()) { - lines.push_back(line); - line.clear(); - } + if (type == Polygon && geometry) { + bucket->addGeometry(geometry); } - line.emplace_back(x, y); - } - if (line.size()) { - lines.push_back(line); + } else { + layer.skip(); } } - for (const std::vector<std::pair<int16_t, int16_t>>& line : lines) { - uint32_t vertex_start = fillBuffer.vertex_length(); - - fillBuffer.addDegenerate(); - for (const std::pair<int16_t, int16_t>& coord : line) { - fillBuffer.addCoordinate(coord.first, coord.second); - } - - uint32_t vertex_end = fillBuffer.vertex_length(); - - if (vertex_end - vertex_start > 65535) { - throw geometry_too_long_exception(); - } - - if (!fillIndices.size()) { - // Create a new index because there is none yet. - throw std::runtime_error("no index yet"); - } - - fill_index& index = fillIndices.back(); - if (!index.groups.size()) { - throw std::runtime_error("no group yet"); - } - - uint32_t vertex_count = vertex_end - vertex_start; - index.length += vertex_count; - - if (index.groups.back().vertex_length + vertex_count > 65535) { - // Move to a new group because the old one can't hold the geometry. - index.groups.emplace_back(); - } - - fill_index::group& group = index.groups.back(); - - // We're generating triangle fans, so we always start with the first - // coordinate in this polygon. - // The first valid index that is not a degenerate. - uint16_t firstIndex = group.vertex_length + 1; - - assert(firstIndex + vertex_count - 1 < 65536); - - uint32_t elements_start = fillBuffer.elements_length(); - - for (uint32_t i = 2; i < vertex_count; i++) { - fillBuffer.addElements(firstIndex, firstIndex + i - 1, firstIndex + i); - } - - uint32_t elements_end = fillBuffer.elements_length(); - uint32_t elements_count = elements_end - elements_start; - group.vertex_length += vertex_count; - group.elements_length += elements_count; - } + return bucket; } -void Tile::addLineGeometry(pbf& geom) { - Geometry geometry(geom); - - Geometry::command cmd; - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (cmd == Geometry::move_to) { - lineVertex.addDegenerate(); - } - lineVertex.addCoordinate(x, y); - } -} +// void Tile::addLineGeometry(pbf& geom) { +// Geometry geometry(geom); + +// Geometry::command cmd; +// int32_t x, y; +// while ((cmd = geometry.next(x, y)) != Geometry::end) { +// if (cmd == Geometry::move_to) { +// lineVertex.addDegenerate(); +// } +// lineVertex.addCoordinate(x, y); +// } +// } diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp new file mode 100644 index 0000000000..73e6d8d029 --- /dev/null +++ b/src/renderer/fill_bucket.cpp @@ -0,0 +1,103 @@ +#include <llmr/renderer/fill_bucket.hpp> +#include <llmr/geometry/fill_buffer.hpp> +#include <llmr/geometry/geometry.hpp> + +#include <llmr/renderer/painter.hpp> +#include <llmr/style/style.hpp> + +#include <cassert> + +struct geometry_too_long_exception : std::exception {}; + +using namespace llmr; + +FillBucket::FillBucket(const std::shared_ptr<FillBuffer>& buffer) + : buffer(buffer), + vertex_start(buffer->vertex_length()), + elements_start(buffer->elements_length()), + length(0) { +} + +void FillBucket::addGeometry(pbf& geom) { + std::vector<std::vector<std::pair<int16_t, int16_t>>> lines; + + { + std::vector<std::pair<int16_t, int16_t>> line; + Geometry::command cmd; + int32_t x, y; + Geometry geometry(geom); + while ((cmd = geometry.next(x, y)) != Geometry::end) { + if (cmd == Geometry::move_to) { + if (line.size()) { + lines.push_back(line); + line.clear(); + } + } + line.emplace_back(x, y); + } + if (line.size()) { + lines.push_back(line); + } + } + + for (const std::vector<std::pair<int16_t, int16_t>>& line : lines) { + uint32_t vertex_start = buffer->vertex_length(); + + buffer->addDegenerate(); + for (const std::pair<int16_t, int16_t>& coord : line) { + buffer->addCoordinate(coord.first, coord.second); + } + + uint32_t vertex_end = buffer->vertex_length(); + + if (vertex_end - vertex_start > 65535) { + throw geometry_too_long_exception(); + } + + FillBucket& index = *this; + if (!index.groups.size()) { + index.groups.emplace_back(); + } + + uint32_t vertex_count = vertex_end - vertex_start; + index.length += vertex_count; + + if (index.groups.back().vertex_length + vertex_count > 65535) { + // Move to a new group because the old one can't hold the geometry. + index.groups.emplace_back(); + } + + group& group = index.groups.back(); + + // We're generating triangle fans, so we always start with the first + // coordinate in this polygon. + // The first valid index that is not a degenerate. + uint16_t firstIndex = group.vertex_length + 1; + + assert(firstIndex + vertex_count - 1 < 65536); + + uint32_t elements_start = buffer->elements_length(); + + for (uint32_t i = 2; i < vertex_count; i++) { + buffer->addElements(firstIndex, firstIndex + i - 1, firstIndex + i); + } + + uint32_t elements_end = buffer->elements_length(); + uint32_t elements_count = elements_end - elements_start; + group.vertex_length += vertex_count; + group.elements_length += elements_count; + } +} + +void FillBucket::draw(const Style& style, const std::string& layerName) { + +} + +void FillBucket::render(Painter& painter) { + // TODO: obtain the correct style information for this layer + FillStyle style; + style.fill_color = {{ 0, 0, 1, 0.5 }}; + style.stroke_color = style.fill_color; + + painter.renderFill(*this, style); +} diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 53ffc79eb6..6b71b3031d 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -8,8 +8,11 @@ #include <llmr/platform/gl.hpp> #include <llmr/map/settings.hpp> -#include <cmath> +#include <llmr/renderer/fill_bucket.hpp> +#include <llmr/style/style.hpp> +#include <cmath> +#include <array> #include <numeric> using namespace llmr; @@ -17,9 +20,14 @@ using namespace llmr; #define BUFFER_OFFSET(i) ((char *)NULL + (i)) GLshort tile_stencil_vertices[] = { + // top left triangle 0, 0, 4096, 0, 0, 4096, + + // bottom right triangle + 4096, 0, + 0, 4096, 4096, 4096 }; @@ -124,7 +132,7 @@ void Painter::drawClippingMask() { 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)); + glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices)); // glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 0x80, 0x80); @@ -152,9 +160,8 @@ void Painter::render(const Tile::Ptr& tile) { switchShader(outlineShader); glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix); - glStencilFunc(GL_EQUAL, 0x80, 0x80); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - // glDisable(GL_STENCIL_TEST); + // glStencilFunc(GL_EQUAL, 0x80, 0x80); + // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // draw lines: tile->lineVertex.bind(); @@ -164,12 +171,8 @@ void Painter::render(const Tile::Ptr& tile) { glLineWidth(2.0f); glDrawArrays(GL_LINE_STRIP, 0, tile->lineVertex.length()); - // draw fills: - - // TODO: expose this to the stylesheet - - for (const Tile::fill_index& index : tile->fillIndices) { - renderFill(tile, index); + for (Layer& layer : tile->layers) { + layer.bucket->render(*this); } if (settings.debug) { @@ -179,145 +182,131 @@ void Painter::render(const Tile::Ptr& tile) { renderBackground(); } -void Painter::renderFill(const std::shared_ptr<Tile>& tile, const Tile::fill_index& index) { - float color[4] = { 1.0, 0.0, 0.0, 1.0 }; - float alpha = color[3]; - - // TODO: expose this to the stylesheet. - bool evenodd = false; - bool background = false; - bool antialiasing = true; - bool stroke = false; - - if (!background) { - // Draw the stencil mask. - { - // We're only drawing to the first seven bits (== support a maximum of - // 127 overlapping polygons in one place before we get rendering errors). - glStencilMask(0x3F); - glClear(GL_STENCIL_BUFFER_BIT); - - // Draw front facing triangles. Wherever the 0x80 bit is 1, we are - // increasing the lower 7 bits by one if the triangle is a front-facing - // triangle. This means that all visible polygons should be in CCW - // orientation, while all holes (see below) are in CW orientation. - glStencilFunc(GL_NOTEQUAL, 0x80, 0x80); - - if (evenodd) { - // When we draw an even/odd winding fill, we just invert all the bits. - glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP); - } else { - // When we do a nonzero fill, we count the number of times a pixel is - // covered by a counterclockwise polygon, and subtract the number of - // times it is "uncovered" by a clockwise polygon. - glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_KEEP, GL_KEEP); - glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_KEEP, GL_KEEP); - } +void Painter::renderFill(const FillBucket& bucket, const FillStyle& style) { + // Draw the stencil mask. + { + // We're only drawing to the first seven bits (== support a maximum of + // 127 overlapping polygons in one place before we get rendering errors). + glStencilMask(0x3F); + glClear(GL_STENCIL_BUFFER_BIT); + + // Draw front facing triangles. Wherever the 0x80 bit is 1, we are + // increasing the lower 7 bits by one if the triangle is a front-facing + // triangle. This means that all visible polygons should be in CCW + // orientation, while all holes (see below) are in CW orientation. + glStencilFunc(GL_NOTEQUAL, 0x80, 0x80); + + if (style.winding == EvenOdd) { + // When we draw an even/odd winding fill, we just invert all the bits. + glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP); + } else { + // When we do a nonzero fill, we count the number of times a pixel is + // covered by a counterclockwise polygon, and subtract the number of + // times it is "uncovered" by a clockwise polygon. + glStencilOpSeparate(GL_FRONT, GL_INCR_WRAP, GL_KEEP, GL_KEEP); + glStencilOpSeparate(GL_BACK, GL_DECR_WRAP, GL_KEEP, GL_KEEP); + } - // When drawing a shape, we first draw all shapes to the stencil buffer - // and incrementing all areas where polygons are - glColorMask(false, false, false, false); - - // Draw the actual triangle fan into the stencil buffer. - switchShader(fillShader); - glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix); - - // Draw all groups - char *vertex_index = BUFFER_OFFSET(index.vertex_start * 2 * sizeof(uint16_t)); - char *elements_index = BUFFER_OFFSET(index.elements_start * 3 * sizeof(uint16_t)); - tile->fillBuffer.bind(); - for (const Tile::fill_index::group& group : index.groups) { - glVertexAttribPointer(fillShader->a_pos, 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); - } + // When drawing a shape, we first draw all shapes to the stencil buffer + // and incrementing all areas where polygons are + glColorMask(false, false, false, false); + + // Draw the actual triangle fan into the stencil buffer. + switchShader(fillShader); + glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix); - // Now that we have the stencil mask in the stencil buffer, we can start - // writing to the color buffer. - glColorMask(true, true, true, true); + // Draw all groups + char *vertex_index = BUFFER_OFFSET(bucket.vertex_start * 2 * sizeof(uint16_t)); + char *elements_index = BUFFER_OFFSET(bucket.elements_start * 3 * sizeof(uint16_t)); + bucket.buffer->bind(); + for (const auto& group : bucket.groups) { + glVertexAttribPointer(fillShader->a_pos, 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); } - // From now on, we don't want to update the stencil buffer anymore. - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilMask(0x0); - - // Because we're drawing top-to-bottom, and we update the stencil mask - // below, we have to draw the outline first (!) - if (antialiasing) { - switchShader(outlineShader); - glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix); - glLineWidth(2); - - if (stroke) { - // If we defined a different color for the fill outline, we are - // going to ignore the bits in 0x3F and just care about the global - // clipping mask. - glStencilFunc(GL_EQUAL, 0x80, 0x80); - } else { - // Otherwise, we only want to draw the antialiased parts that are - // *outside* the current shape. This is important in case the fill - // or stroke color is translucent. If we wouldn't clip to outside - // the current shape, some pixels from the outline stroke overlapped - // the (non-antialiased) fill. - glStencilFunc(GL_EQUAL, 0x80, 0xBF); - } + // Now that we have the stencil mask in the stencil buffer, we can start + // writing to the color buffer. + glColorMask(true, true, true, true); + } - glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height); + // From now on, we don't want to update the stencil buffer anymore. + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMask(0x0); + + // Because we're drawing top-to-bottom, and we update the stencil mask + // below, we have to draw the outline first (!) + if (style.antialiasing) { + switchShader(outlineShader); + glUniformMatrix4fv(outlineShader->u_matrix, 1, GL_FALSE, matrix); + glLineWidth(2); + + if (style.stroke_color != style.fill_color) { + // If we defined a different color for the fill outline, we are + // going to ignore the bits in 0x3F and just care about the global + // clipping mask. + glStencilFunc(GL_EQUAL, 0x80, 0x80); + const Color& color = style.stroke_color; + glUniform4f(outlineShader->u_color, color[0], color[1], color[2], color[3]); + } else { + // Otherwise, we only want to draw the antialiased parts that are + // *outside* the current shape. This is important in case the fill + // or stroke color is translucent. If we wouldn't clip to outside + // the current shape, some pixels from the outline stroke overlapped + // the (non-antialiased) fill. + glStencilFunc(GL_EQUAL, 0x80, 0xBF); + const Color& color = style.fill_color; glUniform4f(outlineShader->u_color, color[0], color[1], color[2], color[3]); - - // Draw the entire line - char *vertex_index = BUFFER_OFFSET(index.vertex_start * 2 * sizeof(uint16_t)); - glVertexAttribPointer(outlineShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, vertex_index); - glLineWidth(2.0f); - glDrawArrays(GL_LINE_STRIP, 0, index.length); } - } + glUniform2f(outlineShader->u_world, transform.fb_width, transform.fb_height); - // var imagePos = layerStyle.image && imageSprite.getPosition(layerStyle.image, true); + // Draw the entire line + char *vertex_index = BUFFER_OFFSET(bucket.vertex_start * 2 * sizeof(uint16_t)); + glVertexAttribPointer(outlineShader->a_pos, 2, GL_SHORT, GL_FALSE, 0, vertex_index); + glLineWidth(2.0f); + glDrawArrays(GL_LINE_STRIP, 0, bucket.length); + } - // if (imagePos) { - // // Draw texture fill - - // var factor = 8 / Math.pow(2, painter.transform.zoom - params.z); - // var mix = painter.transform.z % 1.0; - // var imageSize = [imagePos.size[0] * factor, imagePos.size[1] * factor]; - - // var offset = [ - // (params.x * 4096) % imageSize[0], - // (params.y * 4096) % imageSize[1] - // ]; - - // glSwitchShader(painter.patternShader, painter.posMatrix, painter.exMatrix); - // glUniform1i(painter.patternShader.u_image, 0); - // glUniform2fv(painter.patternShader.u_pattern_size, imageSize); - // glUniform2fv(painter.patternShader.u_offset, offset); - // glUniform2fv(painter.patternShader.u_rotate, [1, 1]); - // glUniform2fv(painter.patternShader.u_pattern_tl, imagePos.tl); - // glUniform2fv(painter.patternShader.u_pattern_br, imagePos.br); - // glUniform4fv(painter.patternShader.u_color, color); - // glUniform1f(painter.patternShader.u_mix, mix); - // imageSprite.bind(gl, true); - - // } else { + // var imagePos = layerStyle.image && imageSprite.getPosition(layerStyle.image, true); + bool imagePos = false; + if (imagePos) { + // // Draw texture fill + + // var factor = 8 / Math.pow(2, painter.transform.zoom - params.z); + // var mix = painter.transform.z % 1.0; + // var imageSize = [imagePos.size[0] * factor, imagePos.size[1] * factor]; + + // var offset = [ + // (params.x * 4096) % imageSize[0], + // (params.y * 4096) % imageSize[1] + // ]; + + // glSwitchShader(painter.patternShader, painter.posMatrix, painter.exMatrix); + // glUniform1i(painter.patternShader.u_image, 0); + // glUniform2fv(painter.patternShader.u_pattern_size, imageSize); + // glUniform2fv(painter.patternShader.u_offset, offset); + // glUniform2fv(painter.patternShader.u_rotate, [1, 1]); + // glUniform2fv(painter.patternShader.u_pattern_tl, imagePos.tl); + // glUniform2fv(painter.patternShader.u_pattern_br, imagePos.br); + // glUniform4fv(painter.patternShader.u_color, color); + // glUniform1f(painter.patternShader.u_mix, mix); + // imageSprite.bind(gl, true); + } else { // Draw filling rectangle. switchShader(fillShader); glUniformMatrix4fv(fillShader->u_matrix, 1, GL_FALSE, matrix); - glUniform4f(fillShader->u_color, color[0], color[1], color[2], color[3]); - // } - - if (background) { - glStencilFunc(GL_EQUAL, 0x80, 0x80); - } else { - // Only draw regions that we marked - glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F); + glUniform4f(fillShader->u_color, style.fill_color[0], style.fill_color[1], style.fill_color[2], style.fill_color[3]); } + // Only draw regions that we marked + glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F); + // Draw a rectangle that covers the entire viewport. glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer); glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(tile_stencil_vertices)); + glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices)); glStencilMask(0x00); glStencilFunc(GL_EQUAL, 0x80, 0x80); @@ -359,8 +348,8 @@ void Painter::renderBackground() { // Draw the clipping mask glBindBuffer(GL_ARRAY_BUFFER, tile_stencil_buffer); glVertexAttribPointer(fillShader->a_pos, 2, GL_SHORT, false, 0, BUFFER_OFFSET(0)); - glUniform4f(fillShader->u_color, 1.0f, 1.0f, 1.0f, 1.0f); - glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(tile_stencil_vertices)); + glUniform4f(fillShader->u_color, 0.5f, 0.5f, 0.5f, 1.0f); + glDrawArrays(GL_TRIANGLES, 0, sizeof(tile_stencil_vertices)); } |