[comp.sys.sgi] zbuffer lrectread

mpapp@ (Mike Papper) (06/11/91)

I have been trying to read the contents (of a small area) of the 
zbuffer using lrectread. All I seem to get is a smattering of
16777216s (i.e. almost 2 * 8388607 i.e. 2 * 0x7FFFFF), sometimes
mixed in with other values.


For instance after a zclear() i do the following:

/* l,r,b,t are the left,right,bottom,and top points of a rectangle,
in window coords. */
static long get_z_data( long l, long r, long b, long t)
{
long oldmode;
unsigned long *ztemp;

  ztemp = (unsigned long *)ALLOC (sizeof(unsigned long) * (r-l+1)*(t-b+1));

  oldmode = getdrawmode();
  drawmode(NORMALDRAW);
  readsource(SRC_ZBUFFER);
  lrectread((Screencoord)l,(Screencoord)b,(Screencoord)r,(Screencoord)t,ztemp);
  readsource(SRC_AUTO);
  drawmode(oldmode);
}

On this particular machine (a GTX) getgdesc(GD_ZMAX) returns
8388607 i.e. 0x7FFFFF. Why does a zclear seem to fill 
the zbuffer with values twice this size (plus other values???)?

I believe that since I'm using unsigned longs the "top" (or is it bottom)
8 bits of the word are zeros (since the zbuffer contains 24 bit values
and I assume that unsigned longs are 32 bits), thus I should not
need to use pixmode.

Note: I have also tried writing to the zbuffer then reading it.
I use zbuffer(1) followed by a lrectwrite, I bel;ieve zdraw()
and the use of pixmode is uness. as zbuffer(1) will allow a subsequent
write to go directly into the zbuffer -- in this case I write zbuffer values,
not color indices.


However, I still get the wrong results (I write different values
and after a subsequent read, the values are the same).

Does anyone have some strightforward code that reads the numeric zbuffer values
from the current zbuffer? (These values shouyld always
be in the range used in lsetdepth(near, far)).

Email responses would be preffered.

Mike Papper
mpapp@godzilla.cgl.rmit.oz.au

peta@McRCIM.McGill.EDU (Peter Whaite) (06/18/91)

In article <acas.676654349@godzilla>, mpapp@ (Mike Papper) writes:
> I have been trying to read the contents (of a small area) of the 
> zbuffer using lrectread. All I seem to get is a smattering of
> 16777216s (i.e. almost 2 * 8388607 i.e. 2 * 0x7FFFFF), sometimes
> mixed in with other values.
> ...
> ... deleted
> ...
> Does anyone have some strightforward code that reads the numeric zbuffer values
> from the current zbuffer? (These values shouyld always
> be in the range used in lsetdepth(near, far)).
> 
> Email responses would be preffered.

I'd like to know the answer to this as well.  I'm using the z-buffer to simulate
laser range scanner data from the surface of superellipsoid models.  My hack was
to read both the color and the z-buffers.  I render shaded white models onto a
black background so I use the colour to tell whether I am looking at background
or at the model's surface.  I found that the z buffer values in the backgound
were garbage, and not z-far as one would expect.  The values on the model are
correct.  

I was under the impression that the z buffer value at a screen coord changed
only if something was rendered there.  If not it remained at the previous value.
zclear() doesnt seem to write z-far values into the buffer.  I suspect it sets a
flag somewhere that effectively does this for the graphics engine, but,
unfortunately, not for lrectread.

The machine is a Personal IRIS w. turbo graphics, running IRIX 3.3.2.  It'd be
nice if someone at SGI could clear this one up.  I wasted an embarassing amount
of time on it.


Peter Whaite,
McGILL Research Centre for Intelligent Machines
McGILL UNIVERSITY
Montreal

ringrose@femur.ai.mit.edu (Robert Ringrose) (06/18/91)

In article <1991Jun18.000218.5825@thunder.mcrcim.mcgill.edu> peta@McRCIM.McGill.EDU (Peter Whaite) writes:
>In article <acas.676654349@godzilla>, mpapp@ (Mike Papper) writes:
>> I have been trying to read the contents (of a small area) of the 
>> zbuffer using lrectread. All I seem to get is a smattering of
>> 16777216s (i.e. almost 2 * 8388607 i.e. 2 * 0x7FFFFF), sometimes
>> mixed in with other values.

... most of situation deleted ...

>I'd like to know the answer to this as well.

I'm not with SGI, but I'll give it a try (having done something similar
trying to generate global shadows for video).  We have a PI 4D/25.

>zclear() doesnt seem to write z-far values into the buffer.
>flag somewhere that effectively does this for the graphics engine, but,
>unfortunately, not for lrectread.

I haven't had a problem with this delay (although you aren't alone - our
PI does it too :-) )  since we draw enough polygons that it has time
to complete the clear asynchronously.  You might try the finish() command
or even a delay statement to check this out.

The reason for "garbage" in the zbuffer:

One the PI, the zbuffer is _signed_ 24 bits.  Check GD_ZMAX and GD_ZMIN.
Since C doesn't have a 24-bit signed integer which really takes 32 bits,
here's what I did to "decode" the z buffer:

1) read the z buffer
2) for every point which will actually be used I sign-extended it with
	if (zval & 0x800000)
	  zval - zval | 0xff000000;
   where zval is a (signed) long set equal to the zbuffer value.

This has worked on a VGX and an IBM RS6000 (although the RS6000 had a problem
with clear not finishing before the drawing started).



Anyone found a better way?


BTW, I found snoop (in demos) a very handy tool for debugging this problem.



SGI : how about a pixmode option which works on the PI and causes it to
do the sign-extend as it loads from the zbuffer?


Robert Ringrose
ringrose@ai.mit.edu

"There's always one more bu6."

mpapp@ (Mike Papper) (06/20/91)

I fixed my zbuffer problem. The reason I was getting the "far" values was
because I was "writing" to the zbuffer inadvertently, while drawing
in the POPUP planes with the zbuffer on. (I had been using
a "square magnifying glass" in the POPUP planes of my window
to decide what area of the zbuffer to read.
The initial zclear put in the far values, and as I moved
the magnifying glass, the zbuffer was written to
(there is no zbuffer mode in these planes, so results
are unpredictable).

Note that I did not have to convert my 24 bit integers to 32
(z buffer lrectread values should always have 0s in top 8 bits --
the manual also says this -- haven't tried on a VGX though).
I did not have to use zdraw, only readsource.

The only question I have now iss why zclear doesn't set the zbuffer
to the highest lsetdepth value (it ALWAYS sets it to 16000000 or so).
I ,suspect this is for efficiency, zclear deals with bitplanes
and doesn't look at the rest of the GL state.
Thus even on a GTX with z buffer range 8,000,000 to -8,000,000
zclear gives 16,000,000 (all values approximate).
Subsequent writes to zbuffer (via drawing routines)
does give values within the lsetdepth range.

Mike Papper
mpapp@godzilla.cgl.rmit.oz.au