From c3ed2ee0312d163685e3e8c4d9bbeb3654c27ca7 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 26 Sep 2002 10:07:15 +0000 Subject: * (ZnRenderPolyline, ZnRenderPolygonRelief): line_width doit �tre flottant. Corrige un bug erratique de curve trop �paisse quand on met 0.5 comme �paisseur. * (ZnRenderPolyline): Corrig� (contourn�) le probl�me des cracks dans le raccordement des segments d'un curve, arc, etc qui apparaissaient dans le dessin openGL depuis les GeForce 3 et 4. C'est li� au rendu des lignes antialias�e et d�pendant de la quantit� de couverture des pixels de bordures. Pour �tre safe on antialiase que les lignes compl�tement opaques, celles avec de l'alpha ne sont plus antialias�e (conflit entre le code garantissant un alpha homog�ne et un raccordement ok). * (ZnRenderPolyline): Corrig� un bug dans le code garantissant un alpha homog�ne, qui conduit dans certains cas � une surcharge de couleur aux joints des segments de lignes (F.Decrock). --- generic/Draw.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 13 deletions(-) (limited to 'generic/Draw.c') diff --git a/generic/Draw.c b/generic/Draw.c index 92b22b5..b408446 100644 --- a/generic/Draw.c +++ b/generic/Draw.c @@ -993,7 +993,7 @@ ZnRenderPolygonRelief(WidgetInfo *wi, ZnBool smooth, ZnPoint *points, int num_points, - int line_width) + ZnReal line_width) { PolygonData pd; @@ -1013,7 +1013,7 @@ void ZnRenderPolyline(WidgetInfo *wi, ZnPoint *points, int num_points, - int line_width, + ZnReal line_width, LineStyle line_style, int cap_style, int join_style, @@ -1024,7 +1024,7 @@ ZnRenderPolyline(WidgetInfo *wi, int num_clips = ZnListSize(wi->clip_stack); ZnPoint end_points[LINE_END_POINTS]; ZnBool need_rcaps, thin, closed; - int pass, i, k, m; + int pass, num_passes, i, k, m; ZnPoint c1, c2; XColor *color; int alpha; @@ -1045,14 +1045,41 @@ ZnRenderPolyline(WidgetInfo *wi, glColor4us(color->red, color->green, color->blue, alpha); ZnSetLineStyle(wi, line_style); glLineWidth(line_width); - glPointSize(line_width); + if (thin && (alpha != 65535)) { + /* + * This makes a special case for transparent lines. + * In this case we need to avoid drawing twice a + * single pixel. To achieve this we use the stencil + * buffer to protect already drawn pixels, unfortunately + * using antialiasing write in the stencil even if + * the pixel area is not fully covered resulting in + * a crack that can't be covered by points later on. + * To handle this case we need to disable the stencil + * which in turn result in erroneous alpha coverage. + * + * We have chosen to drawn transparent lines with a + * correct coverage but NOT antialiased. + */ + glPointSize(line_width>1?line_width-1:line_width); + glDisable(GL_LINE_SMOOTH); + } + else { + glPointSize(line_width); + } - for (pass = 0; pass < 2; pass++) { - if (pass == 0) { - GLX_START_CLIP(num_clips, True); - } - else { - GLX_RESTORE_STENCIL(num_clips, False); + num_passes = 1; + if (alpha != 65535) { + num_passes = 2; + } + + for (pass = 0; pass < num_passes; pass++) { + if (alpha != 65535) { + if (pass == 0) { + GLX_START_CLIP(num_clips, True); + } + else { + GLX_RESTORE_STENCIL(num_clips, False); + } } if (first_end) { GetLineEnd(&points[0], &points[1], line_width, cap_style, @@ -1092,13 +1119,13 @@ ZnRenderPolyline(WidgetInfo *wi, glEnd(); } - if (pass == 0) { + /* if (pass == 0) { GLX_RENDER_CLIPPED(); } else { GLX_END_CLIP(num_clips); - return; - } + break; + }*/ need_rcaps = ((line_width > 1) && (cap_style == CapRound)); i = 0; k = num_points; @@ -1111,6 +1138,7 @@ ZnRenderPolyline(WidgetInfo *wi, if ((!need_rcaps && !closed) || last_end) { k--; } + if (thin) { glBegin(GL_POINTS); for ( ; i < k; i++) { @@ -1135,6 +1163,11 @@ ZnRenderPolyline(WidgetInfo *wi, } } } + + GLX_END_CLIP(num_clips); + if (thin) { + glEnable(GL_LINE_SMOOTH); + } } -- cgit v1.1