From 14690e6e422d1d8a49fd5ec3c57c094f3f37400f Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 22 Mar 2015 16:39:12 +0300 Subject: [PATCH] Work around poor line rendering with Intel Mesa-based drivers. However, don't use ssglLineWidth for UI drawing operations. These only draw horizontal or vertical lines that don't need to be antialiased, and thus don't require the workaround. In fact the workaround would make them thicker than needed. --- src/bsp.cpp | 4 ++-- src/draw.cpp | 16 ++++++++-------- src/drawconstraint.cpp | 4 ++-- src/drawentity.cpp | 8 ++++---- src/generate.cpp | 2 +- src/glhelper.cpp | 24 +++++++++++++++++++++--- src/groupmesh.cpp | 4 ++-- src/solvespace.h | 1 + src/style.cpp | 2 +- 9 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/bsp.cpp b/src/bsp.cpp index ac1c3dc..d6da49c 100644 --- a/src/bsp.cpp +++ b/src/bsp.cpp @@ -667,7 +667,7 @@ void SBsp2::DebugDraw(Vector n, double d) { if(fabs((edge.a).Dot(n) - d) > LENGTH_EPS) oops(); if(fabs((edge.b).Dot(n) - d) > LENGTH_EPS) oops(); - glLineWidth(10); + ssglLineWidth(10); glBegin(GL_LINES); ssglVertex3v(edge.a); ssglVertex3v(edge.b); @@ -675,6 +675,6 @@ void SBsp2::DebugDraw(Vector n, double d) { pos->DebugDraw(n, d); neg->DebugDraw(n, d); more->DebugDraw(n, d); - glLineWidth(1); + ssglLineWidth(1); } diff --git a/src/draw.cpp b/src/draw.cpp index fc4f822..9923d66 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -60,14 +60,14 @@ void GraphicsWindow::Selection::Draw(void) { topLeft = topLeft.Plus(SS.GW.projUp.ScaledBy(SS.GW.height*s)); topLeft = topLeft.Minus(SS.GW.offset); - glLineWidth(40); + ssglLineWidth(40); RgbColor rgb = Style::Color(Style::HOVERED); glColor4d(rgb.redF(), rgb.greenF(), rgb.blueF(), 0.2); glBegin(GL_LINES); ssglVertex3v(topLeft); ssglVertex3v(refp); glEnd(); - glLineWidth(1); + ssglLineWidth(1); } } @@ -673,7 +673,7 @@ void GraphicsWindow::Paint(void) { if(i0 > i1 || i1 - i0 > 400) goto nogrid; if(j0 > j1 || j1 - j0 > 400) goto nogrid; - glLineWidth(1); + ssglLineWidth(1); ssglColorRGBa(Style::Color(Style::DATUM), 0.3); glBegin(GL_LINES); for(i = i0 + 1; i < i1; i++) { @@ -717,7 +717,7 @@ nogrid:; } // Draw the traced path, if one exists - glLineWidth(Style::Width(Style::ANALYZE)); + ssglLineWidth(Style::Width(Style::ANALYZE)); ssglColorRGB(Style::Color(Style::ANALYZE)); SContour *sc = &(SS.traced.path); glBegin(GL_LINE_STRIP); @@ -727,7 +727,7 @@ nogrid:; glEnd(); // And the naked edges, if the user did Analyze -> Show Naked Edges. - glLineWidth(Style::Width(Style::DRAW_ERROR)); + ssglLineWidth(Style::Width(Style::DRAW_ERROR)); ssglColorRGB(Style::Color(Style::DRAW_ERROR)); ssglDrawEdges(&(SS.nakedEdges), true); @@ -758,7 +758,7 @@ nogrid:; br = UnProjectPoint(Point2d::From(xmax, ymax)), bl = UnProjectPoint(Point2d::From(xmin, ymax)); - glLineWidth((GLfloat)1.3); + ssglLineWidth((GLfloat)1.3); ssglColorRGB(Style::Color(Style::HOVERED)); glBegin(GL_LINE_LOOP); ssglVertex3v(tl); @@ -778,7 +778,7 @@ nogrid:; // An extra line, used to indicate the origin when rotating within the // plane of the monitor. if(SS.extraLine.draw) { - glLineWidth(1); + ssglLineWidth(1); ssglLockColorTo(Style::Color(Style::DATUM)); glBegin(GL_LINES); ssglVertex3v(SS.extraLine.ptA); @@ -793,7 +793,7 @@ nogrid:; u = SS.justExportedInfo.u, v = SS.justExportedInfo.v; - glLineWidth(1.5); + ssglLineWidth(1.5); glBegin(GL_LINES); ssglVertex3v(p.Plus(u.WithMagnitude(-15/scale))); ssglVertex3v(p.Plus(u.WithMagnitude(30/scale))); diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp index 3610e3a..bffd2d5 100644 --- a/src/drawconstraint.cpp +++ b/src/drawconstraint.cpp @@ -1030,7 +1030,7 @@ s: case COMMENT: { if(disp.style.v) { - glLineWidth(Style::Width(disp.style)); + ssglLineWidth(Style::Width(disp.style)); ssglColorRGB(Style::Color(disp.style)); } Vector u, v; @@ -1054,7 +1054,7 @@ void Constraint::Draw(void) { dogd.drawing = true; dogd.sel = NULL; - glLineWidth(Style::Width(Style::CONSTRAINT)); + ssglLineWidth(Style::Width(Style::CONSTRAINT)); ssglColorRGB(Style::Color(Style::CONSTRAINT)); DrawOrGetDistance(NULL); diff --git a/src/drawentity.cpp b/src/drawentity.cpp index 8879290..a0149b9 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -114,7 +114,7 @@ void Entity::DrawAll(void) { void Entity::Draw(void) { hStyle hs = Style::ForEntity(h); dogd.lineWidth = Style::Width(hs); - glLineWidth((float)dogd.lineWidth); + ssglLineWidth((float)dogd.lineWidth); ssglColorRGB(Style::Color(hs)); dogd.drawing = true; @@ -534,7 +534,7 @@ void Entity::DrawOrGetDistance(void) { Vector tail; if(i == 0) { tail = SK.GetEntity(point[0])->PointGetNum(); - glLineWidth(1); + ssglLineWidth(1); } else { // Draw an extra copy of the x, y, and z axes, that's // always in the corner of the view and at the front. @@ -545,7 +545,7 @@ void Entity::DrawOrGetDistance(void) { tail = SS.GW.projRight.ScaledBy(w/s).Plus( SS.GW.projUp. ScaledBy(h/s)).Minus(SS.GW.offset); ssglDepthRangeLockToFront(true); - glLineWidth(2); + ssglLineWidth(2); } Vector v = (q.RotationN()).WithMagnitude(50/SS.GW.scale); @@ -583,7 +583,7 @@ void Entity::DrawOrGetDistance(void) { Vector mm = p.Minus(us).Minus(vs), mm2 = mm; Vector mp = p.Minus(us).Plus (vs); - glLineWidth(1); + ssglLineWidth(1); ssglColorRGB(Style::Color(Style::NORMALS)); glEnable(GL_LINE_STIPPLE); glLineStipple(3, 0x1111); diff --git a/src/generate.cpp b/src/generate.cpp index 92ef72c..b54c56a 100644 --- a/src/generate.cpp +++ b/src/generate.cpp @@ -209,7 +209,7 @@ void SolveSpace::GenerateAll(int first, int last, bool andFindFree) { double left = 80, top = -20, width = 240, height = 24; glColor3d(0.9, 0.8, 0.8); ssglAxisAlignedQuad(left, left+width, top, top-height); - glLineWidth(1); + ssglLineWidth(1); glColor3d(0.0, 0.0, 0.0); ssglAxisAlignedLineLoop(left, left+width, top, top-height); diff --git a/src/glhelper.cpp b/src/glhelper.cpp index 52aab0f..9a08c5d 100644 --- a/src/glhelper.cpp +++ b/src/glhelper.cpp @@ -52,9 +52,27 @@ void ssglWriteTextRefCenter(const char *str, double h, Vector t, Vector u, Vecto ssglWriteText(str, h, t, u, v, fn, fndata); } +void ssglLineWidth(GLfloat width) { + // Intel GPUs with Mesa on *nix render thin lines poorly. + static bool workaroundChecked, workaroundEnabled; + if(!workaroundChecked) { + // ssglLineWidth can be called before GL is initialized + if(glGetString(GL_VENDOR)) { + workaroundChecked = true; + if(!strcmp((char*)glGetString(GL_VENDOR), "Intel Open Source Technology Center")) + workaroundEnabled = true; + } + } + + if(workaroundEnabled && width < 1.6) + width = 1.6; + + glLineWidth(width); +} + static void LineDrawCallback(void *fndata, Vector a, Vector b) { - glLineWidth(1); + ssglLineWidth(1); glBegin(GL_LINES); ssglVertex3v(a); ssglVertex3v(b); @@ -362,7 +380,7 @@ void ssglTesselatePolygon(GLUtesselator *gt, SPolygon *p) void ssglDebugPolygon(SPolygon *p) { int i, j; - glLineWidth(2); + ssglLineWidth(2); glPointSize(7); glDisable(GL_DEPTH_TEST); for(i = 0; i < p->l.n; i++) { @@ -410,7 +428,7 @@ void ssglDrawEdges(SEdgeList *el, bool endpointsToo) void ssglDebugMesh(SMesh *m) { int i; - glLineWidth(1); + ssglLineWidth(1); glPointSize(7); ssglDepthRangeOffset(1); ssglUnlockColor(); diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index 906d6af..081167f 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -465,7 +465,7 @@ void Group::DrawDisplayItems(int t) { if(SS.GW.showEdges) { ssglDepthRangeOffset(2); ssglColorRGB(Style::Color(Style::SOLID_EDGE)); - glLineWidth(Style::Width(Style::SOLID_EDGE)); + ssglLineWidth(Style::Width(Style::SOLID_EDGE)); ssglDrawEdges(&displayEdges, false); } @@ -490,7 +490,7 @@ void Group::Draw(void) { if(type == DRAWING_WORKPLANE) { glDisable(GL_DEPTH_TEST); ssglColorRGBa(Style::Color(Style::DRAW_ERROR), 0.2); - glLineWidth (Style::Width(Style::DRAW_ERROR)); + ssglLineWidth (Style::Width(Style::DRAW_ERROR)); glBegin(GL_LINES); ssglVertex3v(polyError.notClosedAt.a); ssglVertex3v(polyError.notClosedAt.b); diff --git a/src/solvespace.h b/src/solvespace.h index 7182225..9d6a674 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -273,6 +273,7 @@ typedef IdList ParamList; // Utility functions that are provided in the platform-independent code. +void ssglLineWidth(GLfloat width); void ssglVertex3v(Vector u); void ssglAxisAlignedQuad(double l, double r, double t, double b, bool lone = true); void ssglAxisAlignedLineLoop(double l, double r, double t, double b); diff --git a/src/style.cpp b/src/style.cpp index 3a69374..bc7da63 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -259,7 +259,7 @@ float Style::Width(hStyle h) { } else if(s->widthAs == UNITS_AS_PIXELS) { r = s->width; } - // This returns a float because glLineWidth expects a float, avoid casts. + // This returns a float because ssglLineWidth expects a float, avoid casts. return (float)r; }