Depth-Buffering

One of the simplest visibility algorithms involves storing a depth value at every pixel of the raster. This technique is called depth-buffering or z-buffering.

To accomplish this we need only add a few small modifications to our Raster object.


class Raster implements ImageObserver {
    public final static int MAXZ = 1 << 16;
    public int width, height;
    public int pixel[];
    public int zbuff[];
    private ImageProducer producer;

    ///////////////////////// Constructors //////////////////////

    /**
     *  This constructor which takes no arguments
     *  allows for future extension.
     */
    public Raster()
    {
    }

    /**
     *  This constructor creates an uninitialized
     *  Raster Object of a given size (w x h).
     */
    public Raster(int w, int h)
    {
        width = w;
        height = h;
        pixel = new int[w*h];
        zbuff = new int[w*h];
    }

								.
								.
								.
		/**
     *    Set all z values in the zbuffer
     *    to the maximum value
     */
    public final void resetz()
    {
        for (int i = 0; i < zbuff.length; i++)
            zbuff[i] = MAXZ;
    }
A few simple modifications to the Triangle routine:

    public void Draw(Raster r)
    {
        int zPlane[] = new int[3];

        if (!triangleSetup(r)) return;
        scale = (1 << EdgeEqn.FRACBITS) / ((double) area);
        PlaneEqn(zPlane, (int) vlist[v[0]].z, (int) vlist[v[1]].z, (int) vlist[v[2]].z);

        int x, y;
        int A0 = edge[0].A;
        int A1 = edge[1].A;
        int A2 = edge[2].A;

        int B0 = edge[0].B;
        int B1 = edge[1].B;
        int B2 = edge[2].B;

        int t0 = A0*xMin + B0*yMin + edge[0].C;
        int t1 = A1*xMin + B1*yMin + edge[1].C;
        int t2 = A2*xMin + B2*yMin + edge[2].C;
        int Az = zPlane[0];
        int Bz = zPlane[1];
        int tz = zPlane[2];

        yMin *= r.width;
        yMax *= r.width;

        /*
             .... scan convert triangle ....
        */
        for (y = yMin; y <= yMax; y += r.width) {
	        int e0 = t0;
	        int e1 = t1;
	        int e2 = t2;
	        int z = tz;
	        boolean beenInside = false;
	        for (x = xMin; x <= xMax; x++) {
	            if ((e0|e1|e2) >= 0) {       // all 3 edges must be >= 0
	                int iz = z >> EdgeEqn.FRACBITS;
	                if (iz <= r.zbuff[y+x]) {
	                    r.pixel[y+x] = color;
	                    r.zbuff[y+x] = iz;
	                }
		            beenInside = true;
	            } else if (beenInside) break;
	            e0 += A0;
	            e1 += A1;
	            e2 += A2;
	            z += Az;
	        }
	        t0 += B0;
	        t1 += B1;
	        t2 += B2;
	        tz += Bz;
        }
    }
And we just use it!

    void DrawScene()
    {
        view.transform(vertList, tranList, vertices);
        ((FlatTri) triList[0]).setVertexList(tranList);
        raster.fill(getBackground());
        raster.resetz();
        for (int i = 0; i < triangles; i++) {
            triList[i].Draw(raster);
        }
    }

This page last modified on Wednesday, November 06, 1996