I am rendering lines at the same position as a mesh and when the lines are right on top of the mesh I get an effect where the lines start to clip and parts of them disappear, especially when moving around.
What I eventually have to do is something like the screenshot below, move the lines off the mesh a little bit in order to get rid of that effect. Does anyone have any ideas on how I can render the lines so that they are right on the mesh without parts of it disappearing?
First of all, are these lines really lines? Or are they the mesh drawn a second time with glPolygonMode (GL_FRONT_AND_BACK, GL_LINES)? In either case, the problem is that the filled polygons and your lines are generating (roughly) the same depths and passing/failing the depth test is not working like you want.
The solution is to add a very slight depth offset to one of the primitives, and the easiest way to do this is to use glPolygonOffset (...). But it is worth mentioning that this only works for filled primitives (e.g. GL_POLYGON, GL_QUADS, GL_TRIANGLES) and not GL_LINES or GL_POINTS.
If it is the same mesh drawn twice, on the second pass you can do something like this:
glPolygonOffset (-0.1f, -1.0f);
glEnable (GL_POLYGON_OFFSET_LINE);
... Draw Mesh Second Time
glDisable (GL_POLYGON_OFFSET_LINE);
Otherwise, you will need to apply the depth offset when you draw the (solid) mesh the first time:
glPolygonOffset (0.1f, 1.0f);
glEnable (GL_POLYGON_OFFSET_FILL);
... Draw Mesh
glDisable (GL_POLYGON_OFFSET_FILL);
... Draw Lines
You may need to tweak the values used for glPolygonOffset (...), it depends on a number of factors including depth buffer precision and the implementation. Generally the second parameter is going to be more important, it is a constant offset applied to the depth. The first factor varies according to the change in depth (e.g. angle).
Related
I'm able to draw a simple cube with modern opengl, but I would like to be able to draw a line cube from the same data I draw my current cube with (vertices):
currently I'm drawing a cube and using glPolygonMode to draw the lines, but I would like to get rid of the lines going though each quad face (essentially just drawing the edges of the cube)
I wasn't able to get any further than this, I don't know how to tackle this topic (shaders, or some other opengl method)
how can I draw a cube in such a way?
Easiest way is to still use glPolygonMOde(...) while rendering QUADS instead of TRIANGLES. This however requires change in your data ...
In case your meshes will be always composed from QUADS and triangulated so the 2 consequent triangles always form a QUAD but you are unwilling to switch to QUADS then you can write a Geometry shader taking in 6 Vertexes and outputting 4 lines which will be still more or less "fast" however note that Geometry shaders where not very reliable in past...
If those are not an option you can modify this:
Silhouette-Outlined shader
To render fragments near sharp normal changes. However this will hide back sides so in order to have them too you have to do this in 2 passes one with glFrontFace(GL_CW); and the other with glFrontFace(GL_CCW); combining their outputs. This also allows you to set different color to the hidden edges ...
So I see it like this:
glFrontFace(GL_CW);
render_mesh_to_trexture(); // using normal instead of color
render_siluete_from_texture(); // using texture from previous line
glFrontFace(GL_CCW);
render_mesh_to_trexture(); // using normal instead of color
render_siluete_from_texture(); // using texture from previous line
However this will be a lot slower and requires consistent winding rule...
Another option is to just compile list of edges from your mesh on CPU side and remove all that have duplicates. Its simple and fast however will create new VBO/VAO data and no longer complies with your requirement to use the same data (however the new VBO might be just integer indices so 2 ints per edge).
I have a mesh to render with OpenGL. What I want is to render its edges, but only the ones of the un-occluded faces. However, I realize that this is not possible with only:
glEnable(GL_DEPTH_TEST); // Enable depth test
glDepthFunc(GL_LEQUAL); // Accept fragment if it closer to the camera than the former one
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
since there is no depth information in-between the edges, so the edges of the occluded triangles are still rendered.
A work around is to draw the triangles with GL_FILL first in background color (in my case, white), and then draw the edges separately. But doing so results in artifacts similar to the z-fighting phenomenon, i.e., some edges seem thinner than others or even vanish, as shown below
On the left is what I have, and on the right is what I desire (viewed in MeshLab). Since depth test of triangles seems to be unavoidable in this case, I guess I am also asking:
How can I draw edges over triangles without the z-fighting artifacts?
Note that face culling is not useful, as it only eliminates faces facing backward, but cannot deal with occlusion.
Set a polygon offset for the first pass with glPolygonOffset:
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1, 1);
Disable the polygon offset for the 2nd pass:
glDisable(GL_POLYGON_OFFSET_FILL);
Polygon fill offset manipulates the depth of a fragment by a minimum amount. This results in the depth of the fragments in the first pass being a small amount greater than the depth of the same fragments in the second pass. This is how you get rid of the deep conflict.
I am drawing a cube and a line grid in 3D in OpenGL:
glBegin(GL_QUADS);
...
glEnd();
glBegin(GL_LINES);
...
glEnd();
Now, independent of the order (if I draw the lines first or the quads first) and independent of the position it always happens that the lines are draw over the cube. I thought OpenGL draws front to back.
What I tried is to use:
glEnable(GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
which does work but part of the cube is transparent now.
I also tried glDepthFunc(GL_NEVER) with disabling glEnable (GL_DEPTH_TEST) but I get the same problem that the cube appears transparent.
Does anyone have a hint to overcome this problem?
If you want to draw the lines in the background, just draw them (and the rest of the background) first, clear the depth buffer, then render the rest of the scene.
Or you can just give the lines a depth such that they will always be behind everything else, but then you have to make sure that none of your gameworld objects go behind it.
Now, independent of the order (if I draw the lines first or the quads first) and independent of the position it always happens that the lines are draw over the cube.
IF your lines have proper depth, then you forgot to enable depth buffer. If you enabled depth buffer, then you must make sure that your library used for initializing OpenGL requested depth buffer.
I thought OpenGL draws front to back.
It does not. OpenGL draws polygons in the same order you specify them. There is no automatic sorting of any kind.
Does anyone have a hint to overcome this problem?
Well, you could clear depth buffer, but this will be slow and inefficient. Technically, you should almost never do that.
glDepthMask(GL_FALSE) will disable writing to depth buffer. i.e. any object drawn after that call will not update depth buffer but will use data that is already stored. It is frequently used for particle systems. So call glDepthMask(GL_FALSE), draw "lines", call glDepthMask(GL_TRUE), then draw cube.
If you combine glDepthMask(GL_FALSE) with glDepthFunc(GL_ALWAYS) then object will be always drawn, completely ignoring depth buffer (but depth buffer won't be changed).
I wanted to see the wireframe of my triangle mesh, so rather than constructing a whole new VBO I'm trying to use glPolygonMode and draw it again with the exact same draw call. This is because I can't find a draw command that will let me make GL_LINE_LOOP primitives out of every 3 indices from my IBO.
But when I draw the wireframe, the insides of the triangles become black again. Is this because when a fragment is discarded, its color value is set to zero (black)? How could I set it so that a discarded fragment does not get written or blended? Are the fragments actually getting discarded?
I solved it. I set glPolygonMode(GL_FRONT_AND_BACK,GL_LINE) then neglected to set it back to GL_FILL, so all subsequent draws in my loop were wireframe. So it's obvious why the polygons ended up not filled.
I've drawn a simple quad with glBegin and glEnd. With a for-loop I create copies of the quad and rotate it around my y-Axis in 3D space.
Now the problem is that I only see the quads in the front. These in the back are not displayed. I assume that the problem lies within the normal vector, which direction is towards me. Is there a possibility to define two normal vectors for one quad.
Sounds like you need to disable backface culling:
glDisable(GL_CULL_FACE);
These in the back are not displayed. I assume that th problem lies within the normal-vector,
The problem is not the normal vector, but what OpenGL considers front side and backside. What's what is determined by the winding of the vertices on the screen. If the vertices are on screen in counterclockwise order, then by default OpenGL assumes the front face. If back face culling is enables, back faces will not be drawn. You can disable culling, but then you'll get odd lighting results.
The best way is to draw the back side explicitly with it's own set of quads; windings and normals adjusted.