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

Solid edges drawn with glitches #379

Open
ghost opened this issue Feb 19, 2019 · 19 comments
Open

Solid edges drawn with glitches #379

ghost opened this issue Feb 19, 2019 · 19 comments

Comments

@ghost
Copy link

ghost commented Feb 19, 2019

System information

SolveSpace version: 3.0~83a0a517

Operating system: Debian 9.x Stretch

Expected behavior

All solid edges should be rendered correctly

Actual behavior

Some edges drawm with glitches.

On screenshot, edges with glitches marked by yellow oval, normally rendered edges marked by green oval. All those edges are parallel.

pic.1

Additional information

@whitequark
Copy link
Contributor

Cannot reproduce. Which renderer is this?

@ghost
Copy link
Author

ghost commented Feb 19, 2019

Which renderer is this?

How I could detect which?

@whitequark
Copy link
Contributor

glxinfo

@ghost
Copy link
Author

ghost commented Feb 19, 2019

Renderer: Gallium 0.4 on ATI RS600

BTW, I has no such glitches with solid edges (style s005-#def-solid-edge) with SolveSpace 3.0~83a0a517

Sems like in latest SolveSpace faces partially overlap solid edges.

Think, need render solid edges as top layer (on top of all faces).

@whitequark whitequark added invalid and removed Linux labels Feb 19, 2019
@whitequark
Copy link
Contributor

ATI RS600 is not a supported video card because it does not provide OpenGL 3.0. Glitches are expected. I will reopen this if it can be reproduced on an OpenGL 3 capable card.

@ghost
Copy link
Author

ghost commented Feb 19, 2019

Glitches are expected

But I has NO such glitches with SolveSpace 3.0~83a0a517, so solid edges glitches appeared after #377 fix.

@whitequark
Copy link
Contributor

whitequark commented Feb 19, 2019

Fixing a bug that hits everyone is more important than fixing a glitch that hits exactly one person with a 13 year old video card that doesn't support OpenGL 3. As I've told you before, SolveSpace should not actually run on it at all. The fact that it does start is a bug (in GTK or Mesa).

@bcmpinc
Copy link
Contributor

bcmpinc commented Feb 19, 2019

I can confirm this bug also happens for me:

image

OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GTX 950M/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 390.77
OpenGL core profile shading language version string: 4.60 NVIDIA

I believe Symban9 is correct in that it is caused by z-fighting between the lines and the invisible faces that are drawn to hide the back-edges. The usual solution to this problem is to use glPolygonOffset(1,1) for drawing the edges. This command has been removed to fix #377, which explains why this bug was introduced by that fix.

@whitequark
Copy link
Contributor

Thanks! I will look into it. There is our own implementation of Z-offset that shouldn't cause this, let me write a patch.

@whitequark whitequark reopened this Feb 19, 2019
@whitequark whitequark added bug and removed invalid labels Feb 19, 2019
@bcmpinc
Copy link
Contributor

bcmpinc commented Feb 19, 2019

Correction: glPolygonOffset(1,1) should be applied to the faces, not the edges. However, that is exactly what caused #377. I cannot think of an easy fix that solves both this bug and #377.

@whitequark
Copy link
Contributor

Hm, this should already be done here: https://github.com/solvespace/solvespace/blob/master/src/groupmesh.cpp#L574-L576.

But this ends up manipulating ssglDepthRange, which would be a different transformation from what glPolygonOffset does.

@ghost
Copy link
Author

ghost commented Feb 19, 2019

more important than fixing a glitch that hits exactly one person with a 13 year old video card that doesn't support OpenGL 3.

Please, always check my bug reports deeply. All bugs should be fixed, if possible.

@bcmpinc
Copy link
Contributor

bcmpinc commented Feb 19, 2019

That implementation is equivalent to using glPolygonOffset(0,-1) for the line segments, which does not work correctly for polygons that aren't parallel to the viewing plane. See https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonOffset.xhtml.

The solution I've come up with, is to apply glPolygonOffset(1,1) only for polygons and only when outlines or edges are drawn (which would then hide the back-faces bleeding through).

P.S. the lines are also drawn with glitches when I change the outside to be solid.

@whitequark
Copy link
Contributor

The solution I've come up with, is to apply glPolygonOffset(1,1) only for polygons and only when outlines or edges are drawn (which would then hide the back-faces bleeding through).

@bcmpinc Do you think you can implement this?

@bcmpinc
Copy link
Contributor

bcmpinc commented Apr 21, 2019

That shouldn't be problem, though I'm not sure that it will entirely fix this issue nor introduce other rendering bugs. I had already tried to implement a fix, but it didn't work, though I don't remember why.

@bcmpinc
Copy link
Contributor

bcmpinc commented Apr 22, 2019

I've come up with the following patch, but as you can see in the image below, the offset is not high enough to render properly on cylinders, yet it already causes the red back faces to bleed through.

diff --git a/src/render/rendergl3.cpp b/src/render/rendergl3.cpp
index 167ce03..7c786bf 100644
--- a/src/render/rendergl3.cpp
+++ b/src/render/rendergl3.cpp
@@ -886,11 +886,18 @@ public:
     }
 
     void Draw(OpenGl3Renderer *renderer) override {
+        // A hackish way to partially solve issues #377 and #379 simultaneously.
+        if (SS.GW.showEdges || SS.GW.showOutlines || SS.GW.showMesh) {
+            glEnable(GL_POLYGON_OFFSET_FILL);
+            // glPolygonOffset(a,b) offsets zdepth by a*fwidth + b
+            glPolygonOffset(SS.GW.showOutlines ? 2.0 : 1.0, 1.0);
+        }
         glEnable(GL_CULL_FACE);
         if(hasFillBack)
             DrawFace(renderer, GL_BACK, fillBack);
         DrawFace(renderer, GL_FRONT, fillFront);
         glDisable(GL_CULL_FACE);
+        glDisable(GL_POLYGON_OFFSET_FILL);
     }
 
     void Remove(OpenGl3Renderer *renderer) override {

image

@whitequark
Copy link
Contributor

@bcmpinc Yeah, I've had a few attempts to fix it with pretty much the same result as yours. Seems like an annoying problem.

@bcmpinc
Copy link
Contributor

bcmpinc commented Apr 23, 2019

Yeah. There's some other solutions I can think of, though none of them that I really like to pick up. For example:

  1. Disable alpha based anti-aliasing and enable multi-sampling. This is still not a perfect solution though, and I don't like the increased performance cost.
  2. Change the OpenGL shaders, such that the edges are drawn by the fragment shader as part of the triangles (I've done something like this in the past). This allows us to do without the zdepth offset trickery. However, considering we're working at edges, this might still give weird results as it requires fwidth, which is based on dfdx and dfdy.
  3. Make the back faces render after drawing the outlines, to prevent the red bleeding through the alpha-based anti-aliasing. This unfortunately requires changes outside of the renderer and does not fix the line next to the cylinder.

@Evil-Spirit
Copy link
Collaborator

Evil-Spirit commented Apr 23, 2019

  1. Will not work since boundary edges (outline) can have different width (e.g 3 or 10 pix instead of 1).
    SolveSpace - (new sketch) 2019-04-23 23 30 07
    SolveSpace - (new sketch) 2019-04-23 23 31 39

@phkahler phkahler added this to the 4.0 milestone Oct 12, 2020
@phkahler phkahler removed this from the 4.0 milestone Sep 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants