New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sw_engine: Fix one pixel blank #1342
base: main
Are you sure you want to change the base?
Conversation
@RuiwenTang thanks for your patch. I think enhancing this feature may be a bit more complex because the current TVG renderer handles closed shapes with separate drawing units, which is different from the triangle-list mesh composition in OpenGL and D3D. As a result, there may be visible anti-aliasing gaps between the shapes, especially in a rotated version (see the following figure). I've considered a proper and efficient model to handle this, but it's not clear yet. Perhaps the TVG canvas could merge the closed shapes into one paint before moving on to rendering, although this may not be efficient for general cases. Instead, I would suggest that users request a single rectangle directly, as it would be much cheaper! Any opinions? |
Yes, this problem is more complicated than I thought, I prefer merge these closed pathes. I'm going to dig a little deeper into this issue |
@RuiwenTang I mentioned earlier that we need the shapes-merge step prior to the rasterization stage(Sure, you can suggest another solution). If we include this fix, it could become redundant. I don't want to leave any dead code that will be difficult to maintain in the future. The problem is that if we change the height of the box (triangles), the patch won't work, as shown in the attached figure. This could confuse users and make them think it's a bug, which would hurt the consistency of the behavior. Currently, on the other hand, we don't support merged shapes. However, if you say that this fix is REALLY necessary for your project now, we can discuss further and compromise for the quick-fix. |
Ok,and currently I am working on merge these closed shapes. I have implemented a similar algorithm before in my local project. |
we have the merging shapes function in b26672a |
@hermet I pushed a sweep line algorithm. I used this algorithm in my own engine to do polygon triangulation and complex polygon clip. I hope this code can help to fix this case. the one pixel blank case I wish to fix:Path with intersection:Path with intersection and different filltype |
Here is a sample code: std::array<std::unique_ptr<tvg::Shape>, 2> gen_shape() {
std::array<std::unique_ptr<tvg::Shape>, 2> ret{};
// stroke
ret[0] = tvg::Shape::gen();
ret[0]->moveTo(100, 10);
ret[0]->lineTo(40, 180);
ret[0]->lineTo(190, 60);
ret[0]->lineTo(10, 60);
ret[0]->lineTo(160, 180);
ret[0]->fill(tvg::FillRule::EvenOdd);
ret[0]->close();
ret[0]->stroke(0, 255, 0, 255);
ret[0]->stroke(3.f);
// fill
ret[1] = tvg::Shape::gen();
ret[1]->moveTo(100, 10);
ret[1]->lineTo(40, 180);
ret[1]->lineTo(190, 60);
ret[1]->lineTo(10, 60);
ret[1]->lineTo(160, 180);
ret[1]->close();
ret[1]->fill(0, 255, 0, 255);
ret[1]->fill(tvg::FillRule::EvenOdd);
return ret;
};
auto paths = gen_shape();
auto outline = paths[0]->extractOutline();
outline->translate(200, 100);
outline->stroke(0, 255, 0, 255);
outline->stroke(3.f);
canvas->push(std::move(paths[0]));
paths[1]->translate(0, 200);
canvas->push(std::move(paths[1]));
canvas->push(std::move(outline)); |
Thank you, @RuiwenTang, for your contribution.
Again thanks, you did really good job. |
The basic scanline idea comes from this video: https://www.youtube.com/watch?v=qkhUNzCGDt0&t=293s . Some data struct and geometric calculation in this code is inspired by SKIA: https://github.com/google/skia/blob/main/src/gpu/ganesh/geometry/GrTriangulator.cpp I made a lot of changes to make the code simple and can do more things like extract the boundary or do advance polygon boolean operation. I can share these changes if thorvg needs these feature. |
If two sub path sharing one edge but with different direction. The winding number of this edge is not zero, but the alpha for aa may be zero. Since this edge is inside whole polygon, need to mark this edge in sweep line based on this edge's cover.
This PR fix #1329
If pixel covered by two edge with same slope with different direction. The
area
value is zero, but the winding number is not.