OpenGL - BackCulling - Depth Buffer Values - opengl

Here are 2 images of the same 3D scene, from the same point of view (virtual camera), with and without backCulling. The images don't depict the final mesh, but the contents of the depth buffer.
Without BackCulling
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
With BackCulling
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
Question
Why is there such a difference Between the 2 images? Of course, one would expect difference, but I don't get why without BackCulling the depth map is so smooth, while with BackCulling the depth values don't seem so continuous.
In the case without BackCulling , for a certain pixel, what is the value of the depth buffer? Is it the one closer to the camera (the smooth image looks like this), or since many things project to the same 2d point/pixel I should expect something else?
Reference - 3D Scene - 2D Frame

They're difference because you're culling the wrong faces. Your mesh data is clearly oriented so that the front face is different from OpenGL's defaults. OpenGL defaults to counter-clockwise being front. Your mesh data puts the clockwise face front (or you're inverting your mesh at some point).
So, in lieu of rearranging your vertex data, change your front face with the aptly named glFrontFace(GL_CW).

Related

In OpenGL, is it possible to draw the edges of the unoccluded triangles only?

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.

How to avoid z-fighting in OpenGL when drawing both the mesh surface and the polygon edges?

Consider the following image:
It has both the mesh surface and the polygon edges visualized. What's more, even though the edges and the faces should have the same z-coordinates on the places where they are drawn and cause z-fighting, in this image, the polygon edges are always visible as long as they are not covered by a (non-adjacent) polygon, and there is no visible z-fighting. How can this be achieved in OpenGL?
I usually just enable some MSAA on the frame buffer I'm rendering to, and then just do:
glDepthFunc(GL_LESS);
drawShadededMesh();
glDepthFunc(GL_LEQUAL);
drawWireMesh();
That usually works well enough in most cases. Failing that(as mentioned in the comments) you can experiment with glPolygonOffset.
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0); ///< may need adjustment for your use case
glDepthFunc(GL_LESS);
drawShadededMesh();
glDisable(GL_POLYGON_OFFSET_FILL);
glDepthFunc(GL_LEQUAL);
drawWireMesh();

OpenGL: Able to see inside of an object despite the fact that transparency is set to 1.0

I am trying to check transparency and how it works.
I have created a solidsphere and a solidcube in it.
I have enabled
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
The transparency works as expected using color4f.
The problem is that when I am setting the transparency of the sphere to 1.0, the cube still appears.
I am also using these:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
How can I make the cube visible only when the transparency of the sphere is != 1.0 ?
Is there a reason you've set glFrontFace(GL_CW); ? The default is GL_CCW, so you'll be culling front faces, and rendering back faces. With the front of the sphere missing, you'll see inside it.
To elaborate:
When rendering translucent objects using a normal (src_alpha , 1-src_alpha) blend, the translucent surfaces need to be rendered in depth order, back to front.
If you render only the back-surfaces of an object, it may (if it's more or less symmetrical) appear normal, but it is in fact inside-out, and thus cannot occlude objects correctly which are actually inside it.
So for this to work, it is important both that the front-surfaces are not culled, and that the opaque or more distant objects are rendered first.
If you want both front and back of the sphere to render translucently, and correctly, you would need to render the back before the front. This could be done with polygon sorting, but for a convex object it would suffice to render it twice, with the backface culling inverted - so render back faces first, and then the front faces, in two seperate passes.

OpenGL cube not rendering properly

I have a problem when rendering cubes in OpenGL.I am drawing two cubes, one is a wire cube and is centered around the origin, while the other is offset from the origin and is solid. I have mapped some keys to rotate the objects by some degrees wrt to the origin, so the whole scene can rotate around the origin.
The problem is, when I render the scene, when the wire cube is supposed to be infront of the other solid cube, it does not display itself correctly.
In the image above, the colored cube is supposed to be behind the wire cube. i.e. the green wire cube should be on top.
Also the cube is not behaving properly.
After I rotate it a little bit around the x axis (current horizontal line).
The cube has missing faces and is not rendering correctly.
What am I doing wrong?
I have coded the following
Note that rotateX,rotateY,rotateZ are mapped to keys, and are my global rotation variables.
//The Initialize function, called once:
void Init(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Depth Buffer Setup // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHTING);
}
void draw(){
//The main draw function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45, 640/480.0, .5, 100);
glMatrixMode(GL_MODELVIEW); //select the modelview matrix.
glLoadIdentity ();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
glRotatef(rotateX,1,0,0);
glRotatef(rotateY,0,1,0);
glRotatef(rotateZ,0,0,1);
drawScene(); // this just draws the main axis lines,
glutWireCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-2,1,0);
drawNiceCube();
glPopMatrix();
glutSwapBuffers();
}
The code for the drawNiceCube() is just using GL_QUADS, while the drawWireCube is built in in GLUT.
EDIT:
I have posted the full code at http://pastebin.com/p1kwPjEM, sorry if it is not well documented.
Did you also request a window with a depth buffer?
glutInitDisplayMode( ... | GLUT_DEPTH | ...);
Update:
Did you somewhere enable face culling?
glEnable(GL_CULL_FACE);
This is may be cause of clockwise
10.090 How does face culling work? Why doesn't it use the surface normal?
OpenGL face culling calculates the signed area of the filled primitive in window coordinate space. The signed area is positive when the window coordinates are in a counter-clockwise order and negative when clockwise. An app can use glFrontFace() to specify the ordering, counter-clockwise or clockwise, to be interpreted as a front-facing or back-facing primitive. An application can specify culling either front or back faces by calling glCullFace(). Finally, face culling must be enabled with a call to glEnable(GL_CULL_FACE); .
OpenGL uses your primitive's window space projection to determine face culling for two reasons. To create interesting lighting effects, it's often desirable to specify normals that aren't orthogonal to the surface being approximated. If these normals were used for face culling, it might cause some primitives to be culled erroneously. Also, a dot-product culling scheme could require a matrix inversion, which isn't always possible (i.e., in the case where the matrix is singular), whereas the signed area in DC space is always defined.
However, some OpenGL implementations support the GL_EXT_ cull_vertex extension. If this extension is present, an application may specify a homogeneous eye position in object space. Vertices are flagged as culled, based on the dot product of the current normal with a vector from the vertex to the eye. If all vertices of a primitive are culled, the primitive isn't rendered. In many circumstances, using this extension
from here
Also you can read here
datenwolf solved my problem. I quote him:
"#JonathanSimbahan: Parts of your code are redundant, but something is missing: You forgot to call Init(); after creating your GLUT window, hence depth testing and all the other state never get enabled. I for one suggest you don't use Init at all and move it's code into the drawing code, where it actually belongs."

OpenGL : How can I put the skybox in the infinity

I need to know how can I make the skybox appears as it's in the infinity??
I know that it's something related to depth, but I don't know the exact thing to disable or to enable??
First, turn off depth writes/testing (you don't need to bother with turning off depth testing if you draw the skybox first and clear your depth buffer):
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
Then, move the camera to the origin and rotate it the inverse of the modelview matrix:
// assume we're working with the modelview
glPushMatrix();
// inverseModelView is a 4x4 matrix with no translation and a transposed
// upper 3x3 portion from the regular modelview
glLoadMatrix(&inverseModelView);
Now, draw your sky box and turn depth writes back on:
DrawSkybox();
glPopMatrix();
glDepthMask(true);
glEnable(GL_DEPTH_TEST);
You'll probably want to use glPush/PopAttrib() to ensure your other states get correctly set after you draw the skybox too (make sure to turn off things like lighting or blending if necessary).
You should do this before drawing anything so all color buffer writes happen on top of your sky box.
First, Clear the buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Then, save your current modelview matrix and load the identity.
glPushMatrix();
glLoadIdentity();
Then render your skybox.
Skybox.render();
Then, clear the depth buffer and continue normally with rendering
glClear(GL_DEPTH_BUFFER_BIT);
OtherStuff.render();
glutSwapBuffers();
The only problem with drawing the sky box is first is that your pixel shader will execute for every pixel in the sky box. Just to be overwritten by other object in your world later on. Your best bet is to render all opaque object first then render your sky box. That way the pixel shader for the sky box only gets executed for the pixel who pass the z buffer test.
There is no infinity. A skybox is just a textured box, with normaly 0,0,0 in the middle.
Here is a short tut: link text
The best approach I can think of is to draw it on a first pass(or layer), then clear only the depth buffer. After that just draw the rest of the scene in another pass. This way the skybox will always remain "behind" the scene. Just remember to use the same camera for both passes and somehow snap the skybox to the camera.