add lines
This commit is contained in:
@@ -35,25 +35,25 @@ FillBucket::FillBucket(const std::shared_ptr<FillVertexBuffer>& vertexBuffer,
|
||||
const std::shared_ptr<LineElementsBuffer>& lineElementsBuffer,
|
||||
const BucketDescription& bucket_desc)
|
||||
: geom_desc(bucket_desc.geometry),
|
||||
allocator(new TESSalloc {
|
||||
&alloc,
|
||||
&realloc,
|
||||
&free,
|
||||
nullptr, // userData
|
||||
64, // meshEdgeBucketSize
|
||||
64, // meshVertexBucketSize
|
||||
32, // meshFaceBucketSize
|
||||
64, // dictNodeBucketSize
|
||||
8, // regionBucketSize
|
||||
128, // extraVertices allocated for the priority queue.
|
||||
}),
|
||||
tesselator(tessNewTess(allocator)),
|
||||
vertexBuffer(vertexBuffer),
|
||||
triangleElementsBuffer(triangleElementsBuffer),
|
||||
lineElementsBuffer(lineElementsBuffer),
|
||||
vertex_start(vertexBuffer->index()),
|
||||
triangle_elements_start(triangleElementsBuffer->index()),
|
||||
line_elements_start(lineElementsBuffer->index()) {
|
||||
allocator(new TESSalloc {
|
||||
&alloc,
|
||||
&realloc,
|
||||
&free,
|
||||
nullptr, // userData
|
||||
64, // meshEdgeBucketSize
|
||||
64, // meshVertexBucketSize
|
||||
32, // meshFaceBucketSize
|
||||
64, // dictNodeBucketSize
|
||||
8, // regionBucketSize
|
||||
128, // extraVertices allocated for the priority queue.
|
||||
}),
|
||||
tesselator(tessNewTess(allocator)),
|
||||
vertexBuffer(vertexBuffer),
|
||||
triangleElementsBuffer(triangleElementsBuffer),
|
||||
lineElementsBuffer(lineElementsBuffer),
|
||||
vertex_start(vertexBuffer->index()),
|
||||
triangle_elements_start(triangleElementsBuffer->index()),
|
||||
line_elements_start(lineElementsBuffer->index()) {
|
||||
assert(tesselator);
|
||||
}
|
||||
|
||||
@@ -101,65 +101,78 @@ void FillBucket::tessellate() {
|
||||
// First combine contours and then triangulate, this removes unnecessary inner vertices.
|
||||
if (tessTesselate(tesselator, TESS_WINDING_POSITIVE, TESS_BOUNDARY_CONTOURS, 0, 0, 0)) {
|
||||
const TESSreal *vertices = tessGetVertices(tesselator);
|
||||
const int contour_element_count = tessGetElementCount(tesselator);
|
||||
const TESSindex *contour_elements_p = tessGetElements(tesselator);
|
||||
std::vector<TESSindex> contour_elements = { contour_elements_p, contour_elements_p + contour_element_count * 2 };
|
||||
const int vertex_count = tessGetVertexCount(tesselator);
|
||||
const int element_count = tessGetElementCount(tesselator);
|
||||
const TESSindex *elements = tessGetElements(tesselator);
|
||||
|
||||
for (int i = 0; i < contour_element_count; ++i) {
|
||||
const TESSindex group_start = contour_elements[i * 2];
|
||||
const TESSindex group_count = contour_elements[i * 2 + 1];
|
||||
if (vertex_count > 65536) {
|
||||
throw geometry_too_long_exception();
|
||||
}
|
||||
|
||||
for (int i = 0; i < vertex_count; ++i) {
|
||||
vertexBuffer->add(vertices[i * 2], vertices[i * 2 + 1]);
|
||||
}
|
||||
|
||||
|
||||
if (!lineGroups.size() || (lineGroups.back().vertex_length + vertex_count > 65535)) {
|
||||
// Move to a new group because the old one can't hold the geometry.
|
||||
lineGroups.emplace_back();
|
||||
}
|
||||
|
||||
// We're generating triangle fans, so we always start with the first
|
||||
// coordinate in this polygon.
|
||||
line_group_type& group = lineGroups.back();
|
||||
uint32_t index = group.vertex_length;
|
||||
|
||||
|
||||
for (int i = 0; i < element_count; ++i) {
|
||||
const TESSindex group_start = elements[i * 2];
|
||||
const TESSindex group_end = group_start + elements[i * 2 + 1];
|
||||
|
||||
for (int i = group_start; i < group_end; ++i) {
|
||||
const TESSindex prevI = (i == group_start ? group_end : i) - 1;
|
||||
lineElementsBuffer->add(index + prevI, index + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a line from the last vertex to the first vertex.
|
||||
// lineElementsBuffer->add(index + vertex_count - 1, index);
|
||||
|
||||
group.vertex_length += vertex_count;
|
||||
group.elements_length += vertex_count;
|
||||
|
||||
for (int i = 0; i < element_count; ++i) {
|
||||
const TESSindex group_start = elements[i * 2];
|
||||
const TESSindex group_count = elements[i * 2 + 1];
|
||||
const TESSreal *group_vertices = &vertices[group_start * 2];
|
||||
tessAddContour(tesselator, 2, group_vertices, stride, group_count);
|
||||
}
|
||||
|
||||
if (tessTesselate(tesselator, TESS_WINDING_POSITIVE, TESS_POLYGONS, vertices_per_group, 2, 0)) {
|
||||
const TESSreal *vertices = tessGetVertices(tesselator);
|
||||
const TESSindex *vertex_indices = tessGetVertexIndices(tesselator);
|
||||
const int vertex_count = tessGetVertexCount(tesselator);
|
||||
const TESSindex *elements = tessGetElements(tesselator);
|
||||
const int element_count = tessGetElementCount(tesselator);
|
||||
|
||||
|
||||
if (vertex_count > 65536) {
|
||||
throw geometry_too_long_exception();
|
||||
if (!triangleGroups.size() || (triangleGroups.back().vertex_length + vertex_count > 65535)) {
|
||||
// Move to a new group because the old one can't hold the geometry.
|
||||
triangleGroups.emplace_back();
|
||||
}
|
||||
|
||||
// Add vertices and create reverse index mapping for drawing the outline.
|
||||
// std::map<TESSindex, int> contour_vertices;
|
||||
for (int i = 0; i < vertex_count; ++i) {
|
||||
// contour_vertices[vertex_indices[i]] = i;
|
||||
vertexBuffer->add(vertices[i * 2], vertices[i * 2 + 1]);
|
||||
// We're generating triangle fans, so we always start with the first
|
||||
// coordinate in this polygon.
|
||||
triangle_group_type& group = triangleGroups.back();
|
||||
uint32_t index = group.vertex_length;
|
||||
|
||||
for (int i = 0; i < element_count; ++i) {
|
||||
const TESSindex *element_group = &elements[i * vertices_per_group];
|
||||
const TESSindex a = vertex_indices[element_group[0]];
|
||||
const TESSindex b = vertex_indices[element_group[1]];
|
||||
const TESSindex c = vertex_indices[element_group[2]];
|
||||
triangleElementsBuffer->add(index + a, index + b, index + c);
|
||||
}
|
||||
|
||||
{
|
||||
if (!triangleGroups.size() || (triangleGroups.back().vertex_length + vertex_count > 65535)) {
|
||||
// Move to a new group because the old one can't hold the geometry.
|
||||
triangleGroups.emplace_back();
|
||||
}
|
||||
|
||||
// We're generating triangle fans, so we always start with the first
|
||||
// coordinate in this polygon.
|
||||
triangle_group_type& group = triangleGroups.back();
|
||||
uint32_t index = group.vertex_length;
|
||||
|
||||
|
||||
for (int i = 0; i < element_count; ++i) {
|
||||
const TESSindex *element_group = &elements[i * vertices_per_group];
|
||||
|
||||
if (element_group[0] == TESS_UNDEF || element_group[1] == TESS_UNDEF || element_group[2] == TESS_UNDEF) {
|
||||
throw std::runtime_error("element group is not a triangle");
|
||||
}
|
||||
|
||||
triangleElementsBuffer->add(
|
||||
index + element_group[0],
|
||||
index + element_group[1],
|
||||
index + element_group[2]
|
||||
);
|
||||
}
|
||||
|
||||
group.vertex_length += vertex_count;
|
||||
group.elements_length += element_count;
|
||||
}
|
||||
group.vertex_length += vertex_count;
|
||||
group.elements_length += element_count;
|
||||
|
||||
} else {
|
||||
assert(false && "tesselation failed");
|
||||
|
||||
@@ -180,50 +180,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
fill_color[2] *= properties.opacity;
|
||||
fill_color[3] *= properties.opacity;
|
||||
|
||||
// // 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 (properties.winding == 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.
|
||||
// useProgram(plainShader->program);
|
||||
// plainShader->setMatrix(matrix);
|
||||
|
||||
// // Draw all groups
|
||||
// bucket.drawElements(*plainShader);
|
||||
|
||||
// // Now that we have the stencil mask in the stencil buffer, we can start
|
||||
// // writing to the color buffer.
|
||||
// glColorMask(true, true, true, true);
|
||||
// }
|
||||
|
||||
// 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 (properties.antialias) {
|
||||
@@ -252,9 +208,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
bucket.drawVertices(*outlineShader);
|
||||
}
|
||||
|
||||
// // Only draw regions that we marked
|
||||
// glStencilFunc(GL_NOTEQUAL, 0x0, 0x3F);
|
||||
|
||||
if (false && properties.image.size() && *style.sprite) {
|
||||
// Draw texture fill
|
||||
ImagePosition imagePos = style.sprite->getPosition(properties.image, true);
|
||||
@@ -285,7 +238,6 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
// Draw a rectangle that covers the entire viewport.
|
||||
coveringPatternArray.bind(*patternShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
|
||||
|
||||
} else {
|
||||
// Draw filling rectangle.
|
||||
useProgram(plainShader->program);
|
||||
@@ -294,13 +246,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
|
||||
// Draw the actual triangle fan into the stencil buffer.
|
||||
bucket.drawElements(*plainShader);
|
||||
|
||||
// Draw a rectangle that covers the entire viewport.
|
||||
// coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
|
||||
// glDrawArrays(GL_TRIANGLES, 0, tileStencilBuffer.index());
|
||||
}
|
||||
|
||||
// glStencilFunc(GL_EQUAL, 0x80, 0x80);
|
||||
}
|
||||
|
||||
void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, const Tile::ID& id) {
|
||||
|
||||
Reference in New Issue
Block a user