Skip to main content
gamedev.net
🔒 Locked

z-buffer backwards

Started by Shannon Barber Dec 1, 2004 at 9:38 AM 14 replies 3k views
Original Post
Shannon Barber
Shannon Barber
For rendering normal opaque triangles, what should the z-buffer be cleared to and what depth test should be used? It seems virtually all the example code I see sets the clear value to 1.0f and the depth test to GL_LEQUAL (sometimes GL_LESS), however for the scene I'm rendering I have to set the clear value to 0.0f and the test to GL_GREATER in order for the triangles to shade correctly (I get wierd overlapps that directly indicate a z-buffer issue with 1.0f/less). What could I have setup differently that would cause a flip in the z/w values?
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Tree Penguin
Tree Penguin
I guess you could try GL_GEQUAL for depth test so triangles at the same location can overdraw eachother.
mikeman
mikeman
I can't imagine why you want to use anything else that less/lequal. You don't really describe the problem, however I'm sure it wouldn't be solved with flipping the z-values, even if that was possible. If you get z-fighting, try pushing your near clip plane as far as acceptable or increasing the depth precision.
Shannon Barber
Shannon Barber
It's not z-fighting, triangles that are in back of others are completely drawn on top. GL_GEQUAL/GL_GREATER essentially produce the same results here (again no z-fighting).
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
mikeman
mikeman
Quote:
Original post by Magmai Kai Holmlor
...triangles that are in back of others are completely drawn on top.


Have you forgot to turn on depth testing? I can't really think of something else.
_the_phantom_
_the_phantom_
yeah, that would have been my first question [smile]

I've just had a thought, ok the z-buffer stores z-values in a log. format (iirc) 0 being near, 1 being far.
Now, normally you set to 1 and use GL_LEQUAL/GL_LESS to make sure that all objects closer to you get drawn (firstly replacing the value 1.0f then whatever is closer to 1.0f for each fragment).

Now, in this case the value is set to 0.0f and you tell it "anything further away you have to draw"... I hope you can see where I'm going with this [grin] anything with a z-value close to 1.0f is going to pass the test and overwrite anything close to the near plane (z-value approching 0.0f), thus your problem.

So, based on that the question now becomes (a) can you reverse this mapping? and (b) what are the issues with 1.0f and lequal/less?
benjamin bunny
benjamin bunny
It sounds like a problem with your projection matrix. How are you setting up the projection?

Also, have you touched glDepthRange at all? It could cause the problem you describe. I assume when you said you set the clear value to 1.0 you meant with glClearDepth rather than glDepthRange?
Shannon Barber
Shannon Barber
Fair enough, I checked and I do a ::glEnable(GL_DEPTH_TEST)

It's almost like my near & far clipping planes are backwards - and indeed swapping the clipping planes allows me to use 1.0f/less, I use gluPerspective though and the docs say I have them right near,far (i.e. 0.25,50.0) which looks correct with 0.0f/greater.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Shannon Barber
Shannon Barber
Quote:
Original post by benjamin bunny
It sounds like a problem with your projection matrix. How are you setting up the projection?

Also, have you touched glDepthRange at all? It could cause the problem you describe. I assume when you said you set the clear value to 1.0 you meant with glClearDepth rather than glDepthRange?


I read a blurb about glDepthRange not working right on older hardware, and am just getting this thing started so I am using glDepthClear for now.


//Scene Clear code
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();


//Camera positioning code
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::gluPerspective(45.0, GLdouble(width/height), 0.25, 50.0);

::glMatrixMode(GL_MODELVIEW)
::glMultMatrix(camera->Orientation());


I currently am only using one camera so that code is only called once (per frame).
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
mikeman
mikeman
Quote:

::gluPerspective(45.0, GLdouble(width/height), 0.25, 50.0);


This should be GLdouble(width)/height, but other than that I don't see anything else wrong. Weird. Try swapping the order in which triangles are drawn. Do you see any difference(triangles that were drawn on top now being hided and vice versa)?
Shannon Barber
Shannon Barber
Oops, it is GLdouble(width)/height (transcoding error).
I flipped the order I render the two meshes and they still overlapp incorrectly with 1.0f/less.


I'm thinking it doesn't have anything to do with the z-buffer - but something more with the transform matrices. Can you "confuse" OGL and have the camera looking at the scene from a different angle than what it renders it for? It's like the camera is looking at the scene from the wrong side - when the objects approach the far clipping plane, triangles closer to the viewer disappear first!
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Enigma
Enigma
Quote:
Original post by Magmai Kai Holmlor
//Scene Clear code
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();


//Camera positioning code
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::gluPerspective(45.0, GLdouble(width/height), 0.25, 50.0);

::glMatrixMode(GL_MODELVIEW)
::glMultMatrix(camera->Orientation());


I currently am only using one camera so that code is only called once (per frame).


Although this is not the cause of your problem, the scene clear code should be called once per frame and should include your camera transform, while gluPerspective need only be called if there is a window size or display mode change, i.e.:
void reshape(int width, int height){	if (height == 0)	{		height = 1;	}	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glViewport(0, 0, width, height);	gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 50.0f);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity(); // this line is not strictly necessary}void display(){	glClear(buffersToClear);	glLoadIdentity();	glMultMatrix(camera->orientation()); // or just glLoadMatrix and do away with the glLoadIdentity	// rendering stuff}


As to your actual problem, can you cut your program down to a minimal example, just including all OpenGL calls, and post it?

Enigma
mikeman
mikeman
Quote:
Original post by Magmai Kai Holmlor
Oops, it is GLdouble(width)/height (transcoding error).
I flipped the order I render the two meshes and they still overlapp incorrectly with 1.0f/less.


Of course, but do they overlap the same way? For example, if one mesh is a tree and the other a car, does always the tree ovelap the car no matter the order?
Shannon Barber
Shannon Barber
Yes, sorry, the visual artifact is the same regardless of rendering order. Primatives composing the top of a hull are drawn on top of primatives composing the side of a turret.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Shannon Barber
Shannon Barber
Quote:
Original post by Enigma
Although this is not the cause of your problem, the scene clear code should be called once per frame and should include your camera transform, while gluPerspective need only be called if there is a window size or display mode change, i.e.:
*** Source Snippet Removed ***

Right, thanks, I was already checking to see if width or height had changed to call glViewport, so I moved the perspective code into that block.

Quote:

As to your actual problem, can you cut your program down to a minimal example, just including all OpenGL calls, and post it?


Is there a linux ogl debug tool I could use for this (not just for now, but for the undoubted future problems I'll have)? I have a minimal engine together and the models submit shader/mesh/material/transform blocks to the graphics enigne, so the OGL calls made and thier order are not exactly deterministic anymore.


OK, I have a little more information, if I disable culling everything looks correct, and if I enable culling and also set the cull face to front (or set the front face to CW), everything looks correct. This means my triangle vertices are in the wrong order right? I guess I don't understand why they were visible at all with back-face culling enabled - why did they draw incorrectly? I would expect them not to draw at all.
Except every single triangle is backwards, so the scene draws very strangely; thanks for your help guys it got me thinking about what was really wrong.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
_the_phantom_
_the_phantom_
it means your winding order is backwards to normal, yes, so i'm guessing what you are seeing are the backfacing polys not the front facing ones like you would expect

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.