Re: [Plib-devel] Ancient history....depth buffer queries
Brought to you by:
sjbaker
From: Scott M. <mcm...@ca...> - 2000-05-22 15:30:17
|
In answer to a previous question: This is an OpenGL question and not a Performer one. I have been having problems with the approach below on one piece (so far) of NT/PC hardware: the AccelGalaxy card and/or its OpenGL driver. The culprit is the following piece of code that I am not sure is valid OpenGL code: glGetIntegerv( GL_DEPTH_RANGE, z_vals ) ; The OpenGL 1.1 manual says to use glGetFloatv for this enum, and AccelGalaxy drive truncates the floating point values to ints and reports 0 and 1 for near far (where as an SGI O2 would report 0 and something close to MAX_INT). The way I did get this to work is to sample the depth buffer as GL_FLOAT (instead of int) and use the results of glGetFloatv(GL_DEPTH_RANGE, z_vals); I still need to do timing to see if sampling the depth buffer as GL_FLOATs incurs an extreme penalty (not sure I have much choice though as I need not only a cross platform solution but a cross OpenGL driver solution). scott Stephen J Baker wrote: > > > I have a question. Here's what you wrote (I think...as formatting > > has garbled the equation): > > > > > This comes up about every 6 months....here is the stock reply... > > > > > > The 'official' SGI solution to this is... > > > > > > z = value in z buffer after rendering (input) > > > range = distance to pixel in database units (output) > > > > > > np = distance to near clipping plane > > > fp = distance far clipping plane > > > > > > nz = near-clip z value > > > fz = far-clip z value > > > (as read from glGetIntegerv ( GL_DEPTH_RANGE,...) for OpenGL) > > > > > > For each Z-buffer value: > > > > > > fp*np(fz-nz) > > > ------------ > > > fp-np > > > - range = -------------------------- > > > (fp+np)(fz-nz) fz+nz > > > z - -------------- - ----- > > > 2(fp-np) 2 > > > > > > > My questions are: > > 1) has this formatting been restored correctly? > > Yes. That's correct. > > > > 2) Could you explain the nz/fz equations more clearly... > > Here is what I use in an actual Performer application: > > --------------------------- CUT HERE --------------------------- > /* > This routine calculates the terms: > > fp*np(fz-nz) > z_top = ------------ > fp-np > > and > (fp+np)(fz-nz) fz+nz > z_bot = -------------- + ----- > 2(fp-np) 2 > > So the actual per-pixel z-to-range math can be boiled down to: z_top / ( z - z_bot ) > */ > > void read_z ( pfChannel *chan ) > { > float z_top ; > float z_bot ; > float np, fp ; > float nz, fz ; > int width = ...whatever... ; > int height = ...whatever... ; > int top, bot, left, right = ...whatever... ; > unsigned long z_result [ height * width ] ; > float result [ height * width ] ; > GLint z_vals[ 2 ] ; > > /* Set up the math... */ > > pfGetChanNearFar ( chan, & np, & fp ); > glGetIntegerv ( GL_DEPTH_RANGE, z_vals ) ; > > nz = (float) z_vals [ 0 ] ; > fz = (float) z_vals [ 1 ] ; > > z_top = -fp*np *(fz-nz) / (fp-np) ; > z_bot = (fp+np)*(fz-nz) / ((fp-np) * 2.0 ) + (fz+nz) / 2.0 ; > > /* Read the Z buffer... */ > > glReadBuffer ( GL_BACK ) ; > glReadPixels ( left, bot, right-left+1, top-bot+1, > GL_DEPTH_COMPONENT, GL_INT, z_result ) ; > > /* Convert to real-world units... */ > > for ( ...each Z value to convert... ) > result[...whatever...] = z_top / ( (float) z_result[...whatever...] - z_bot ) ; > } > ---------------------- CUT HERE ------------------------------ > > Steve Baker (817)619-2657 (Vox/Vox-Mail) > L3Com/Link Simulation & Training (817)619-2466 (Fax) > Work: sj...@ht... http://www.hti.com > Home: sjb...@ai... http://web2.airmail.net/sjbaker1 > > _______________________________________________ > plib-devel mailing list > pli...@li... > http://lists.sourceforge.net/mailman/listinfo/plib-devel -- Scott McMillan mailto:mcm...@ca... Cambridge Research Associates http://www.cambridge.com 1430 Spring Hill Road, Ste. 200 Voice: (703) 790-0505 x7235 McLean, VA 22102 Fax: (703) 790-0370 |