Failed to fill self-crossing polygon
Opened this issue · 3 comments
I rendered a sandglass-like shape with following code:
nvgBeginPath(nvg);
nvgMoveTo(nvg, 0, 0);
nvgLineTo(nvg, 100, 75);
nvgLineTo(nvg, 100, 25);
nvgLineTo(nvg, 0, 100);
nvgFillColor( nvg, nvgRGB(255, 0, 0) );
nvgFill(nvg);
It filled the area of whole square bounding box.
In addition, if I render such kind of thing with non-full alpha, it would also show a very dim stroked path of that shape.
Does nanovg allow to draw polygons like that? Or I have to manually separate it into more "healthy" polygons?
I made some more tests on different computers, and it looks like a platform-specific issue.
Incorrect filling:
- AMD R9 390, Windows 10, newest driver.
- Integrated Intel HD 4000, Windows 10.
Correct filling: - Integrated Intel HD 3000, Debian Stretch.
Using GL2 or GL3 backend seems unrelated.
I made a more straightforward test. It also failed to fill non-convex shapes. The whole code is pasted below, it could be compiled with nanovg, SDL2 and glew:
#include <GL/glew.h>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <nanovg.h>
#define NANOVG_GL3_IMPLEMENTATION
#include <nanovg_gl.h>
#ifdef _WIN32
int WinMain()
#else
int main()
#endif
{
SDL_Init( SDL_INIT_EVERYTHING );
auto win = SDL_CreateWindow( "nanovg sdl test", 100, 100, 600, 400, SDL_WINDOW_OPENGL );
auto gl = SDL_GL_CreateContext( win );
glewInit();
auto nvg = nvgCreateGL3( NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG );
while ( true )
{
int w, h;
SDL_GetWindowSize(win, &w, &h);
glClearColor( 1, 1, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT );
nvgBeginFrame(nvg, w, h, 1);
// a timeglass-shape fill
nvgBeginPath( nvg );
nvgMoveTo( nvg, 50, 50 );
nvgLineTo( nvg, 200, 200 );
nvgLineTo( nvg, 200, 50 );
nvgLineTo( nvg, 50, 200 );
nvgFillColor( nvg, nvgRGBA( 255, 0, 0, 64 ) );
nvgFill( nvg );
// a non-convex fill
nvgBeginPath(nvg);
nvgMoveTo(nvg, 220, 50);
nvgLineTo(nvg, 230, 40);
nvgLineTo(nvg, 240, 45);
nvgLineTo(nvg, 250, 70);
nvgLineTo(nvg, 260, 20);
nvgLineTo(nvg, 270, 100);
nvgLineTo(nvg, 280, 80);
nvgLineTo(nvg, 290, 30);
nvgLineTo(nvg, 300, 60);
nvgLineTo(nvg, 270, 250);
nvgLineTo(nvg, 230, 250);
nvgFillColor( nvg, nvgRGBA( 255, 0, 255, 64 ) );
nvgFill( nvg );
// simple triangle
nvgBeginPath(nvg);
nvgMoveTo(nvg, 330, 150);
nvgLineTo(nvg, 450, 200);
nvgLineTo(nvg, 320, 350);
nvgFillColor( nvg, nvgRGBA( 0, 0, 255, 64 ) );
nvgFill(nvg);
nvgEndFrame(nvg);
SDL_GL_SwapWindow( win );
SDL_Event e;
bool should_break = false;
while ( SDL_PollEvent( &e ) )
{
if (e.type == SDL_WINDOWEVENT)
{
if (e.window.event == SDL_WINDOWEVENT_CLOSE)
should_break = true;
}
}
if (should_break)
break;
}
nvgDeleteGL3( nvg );
SDL_GL_DeleteContext( gl );
SDL_DestroyWindow( win );
}
Ok I've found the problem. Stencil buffer is not turned on by default, in both SDL and the actual environment I use (JUCE).