Skip to content
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

nvgArc does some ugly overdraw #659

Open
mulle-nat opened this issue Jul 30, 2023 · 2 comments
Open

nvgArc does some ugly overdraw #659

mulle-nat opened this issue Jul 30, 2023 · 2 comments

Comments

@mulle-nat
Copy link
Contributor

I suspect, that when the area to fill gets less than a pixel, something goes awry at the very top of the circle hole:

image

In this special case, it can be mitigated with nvgIntersectScissor.

For reference this is how it's drawn (it uses a few "UIKit"isms, that should be easy to understand)

void drawSplitRectWithHole(NVGcontext* vg, CGRect rect, CGFloat x, CGFloat radius)
{
    CGFloat y = CGRectGetMidY( rect);
    CGFloat angle = asinf( rect.size.height / (2 * radius));

    nvgSave( vg);
    //nvgIntersectScissor( vg, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);

    // Draw the left part
    nvgBeginPath(vg);
    nvgMoveTo(vg, CGRectGetMinX( rect), CGRectGetMinY( rect));
    nvgLineTo(vg, x - radius * cosf(angle), CGRectGetMinY( rect));
    nvgArc(vg, x, y, radius, M_PI_f + angle, M_PI_f - angle, NVG_CCW);
    nvgLineTo(vg, CGRectGetMinX( rect), CGRectGetMaxY( rect));
    nvgClosePath(vg);
    nvgFillColor( vg, CGColorMakeIndigo());
    nvgFill(vg);

    // Draw the right part 
    nvgBeginPath(vg);
    nvgMoveTo(vg, x + radius * cosf(angle), CGRectGetMinY( rect));
    nvgLineTo(vg, CGRectGetMaxX( rect), CGRectGetMinY( rect));
    nvgLineTo(vg, CGRectGetMaxX( rect), CGRectGetMaxY( rect));
    nvgLineTo(vg, x + radius * cosf(angle), CGRectGetMaxY( rect));
    nvgArc(vg, x, y, radius, angle, -angle, NVG_CCW);
    nvgClosePath(vg);
    nvgFillColor( vg, CGColorMakeOrange());
    nvgFill(vg);

    nvgRestore( vg);
}
@memononen
Copy link
Owner

This is unfortunately due to the antialiasing algorithm used by nanovg.

An alternative is to use MSAA, one of the examples shows how to set that up.

@mulle-nat
Copy link
Contributor Author

Thanks, I wasn't aware that I could use MSAA to replace nanovg edge antialiasing. I am trying to use MSAA (4) as the default now and EdgeAntialiasing as a fallback option.

It seems though, that there is more to do than just adding glfwWindowHint( GLFW_SAMPLES, 4). For example at my current understanding (being mostly this stackoverflow.) nvgluCreateFramebuffer doesn't seem to be coded to be MSAA aware. I am also not sure how this will pertain to textures, so I have no real feel for how much more work this will be.

Just to get a better understanding of things:

  • Is the anti aliasing algorithm used by nanovg "fixable" in any shape or form ?
  • Would I expect that MSAA is available on major mobile and desktop platforms ?
  • Does MSAA really take up 4 times the GPU memory for everything, it feels like this might get too expensive for mobile platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants