1

I have three basic functions that draw a surface, the first one is drawing the surface;

    def deflected_3d_surface(self, array):
        glBegin(GL_QUADS)
        for d in range(int(array.shape[0] / 2 - 1)):
            glColor4f(1, 1, 1, 1)
            glVertex3fv(array[2 * d + 2, :])
            glVertex3fv(array[2 * d, :])
            glVertex3fv(array[2 * d + 1, :])
            glVertex3fv(array[2 * d + 3, :])
        glEnd()

the second one drawing the outer edges of that surface;

def deflected_3d_edges(self, array2):
    glBegin(GL_LINES)
    for i in range(array2.shape[0] - 1):
        glColor3fv((0, 0, 0))
        glVertex3fv(array2[i, :])
        glVertex3fv(array2[i + 1, :])
    glEnd()

the third one is drawing lines on that surface; (note that the line vertices and the surface vertices are not the same)

def deflected_3d_inner_edges(self, x_array, y_array, z_array): 
   glBegin(GL_LINES)
    for i in range(x_array.shape[0]):
        glColor3fv((0, 0, 0))
        glVertex3fv([x_array[i, 0], y_array[i, 0], z_array[i, 0]])
        glVertex3fv([x_array[i, 1], y_array[i, 1], z_array[i, 1]])
        if x_array.shape[1] != 2:
            glVertex3fv([x_array[i, 1], y_array[i, 1], z_array[i, 1]])
            glVertex3fv([x_array[i, 2], y_array[i, 2], z_array[i, 2]])
    glEnd()

When I call these functions with the following order;

`glWidget.deflected_3d_edges(self, self.tf1_edges_array)
 glWidget.deflected_3d_edges(self, self.tf2_edges_array)
 glWidget.deflected_3d_edges(self, self.bf1_edges_array)
 glWidget.deflected_3d_edges(self, self.bf2_edges_array)
 glWidget.deflected_3d_inner_edges(self, self.xbcr_, self.ybcr_, 
      self.zbcr_)
     glWidget.deflected_3d_inner_edges(self, self.xwcr_, self.ywcr_,
          self.zwcr_)
 glWidget.deflected_3d_inner_edges(self, self.xtcr_, self.ytcr_, 
      self.ztcr_)`

resultant shape on the link

Any ideas how I can fix the black lines appearing on the white surface?

Atlanta's
  • 11
  • 3
  • Seems a "z-fight" case. Try giving a tiny increment to those lines coordinates, so that they get closer (or further way), to the camera. Or change depth-compare function before rendering them, – Ripi2 Aug 01 '18 at 15:15
  • That solves, but when I rotate the scene I cannot see the lines on the other side now. – Atlanta's Aug 01 '18 at 15:24
  • Set a [Depth offset](https://stackoverflow.com/questions/45314290/depth-offset-in-opengl). Do `glEnable( GL_POLYGON_OFFSET_FILL );` [`glPolygonOffset( 1.0, 1.0 );`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonOffset.xhtml) before drawing the entire geometry. Of course you can set a negative depth offset for `GL_POLYGON_OFFSET_LINE` istead. – Rabbid76 Aug 01 '18 at 15:24
  • That helps but still having z-fight on some part of the surfaces. – Atlanta's Aug 01 '18 at 16:25
  • @Atlanta's The default depth function is `GL_LESS` use [`glDepthFunc(GL_LEQUAL)`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDepthFunc.xhtml) instead. – Rabbid76 Aug 01 '18 at 16:47
  • [example](https://ibb.co/kxNHqe) this is how it looks after `glDepthFunc(GL_LEQUAL)` – Atlanta's Aug 01 '18 at 16:59

1 Answers1

0

When a fragment (think of it as a pixel) is going to be set in the frame buffer FB (previous step to the window) OpenGL compares its Z-coordinate with the current one for the same X,Y NDC coordinates (those of the FB).

By default, if the incomming Z is less than the current one (it's nearer to the camera), then it wins and it replaces the old color in the FB. This way, a fragment behind another one is discarded.

When to fragments have a similar Z-coordinate, it's not clear who gets ahead. Sometimes, due to numerical float imprecisions, the nearest fragment "loses" and wrongly gets discarded. This is called "z-fighting".

If you want to see something, despite it's at the front or the back of other primitive, you can change the glDepthFunc to GL_ALWAYS.

So:

  1. Draw your surface
  2. Set glDepthFunc(GL_ALWAYS)
  3. Draw your always-seen objects
  4. Restore glDepthFunc to normal 'GL_LESS`
Ripi2
  • 7,031
  • 1
  • 17
  • 33
  • Thanks. Actually this solves the problem in terms of the lines are not rendering, but it also causes the surfaces behaving like transparent. Is that possible to avoid that at the same time? [example problem](https://ibb.co/iKWktz) – Atlanta's Aug 01 '18 at 16:06
  • @Atlanta's As Rabbid76 suggested, use `glPolygonOffset`. For better control, forget *fixed pipeline*, move to OpenGL >= 3.2 and do the correction in the *fragment shader*. – Ripi2 Aug 01 '18 at 16:13
  • That helps but still having z-fight on some part of the surfaces. And unfortunately, i don't have any experience with fragment shader. – Atlanta's Aug 01 '18 at 16:25
  • @Atlanta's If you stick to OGL<3 then you can sort your triangles and lines by distance to camera (not easy, they may overlap) and render them in that order. – Ripi2 Aug 01 '18 at 16:28