home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <zsort.h>
-
-
-
- void xform_pointcollection
- (pointcollection *p,
- affine *xform,
- pipe_point *xpoints)
- {
- long x,y,z;
-
-
- for(x=0;x<p->numpoints;x++) /* for each point... */
- {
- /* transform it */
- affine_xform(xform,p->vertex[x].location,
- xpoints[x].point.location);
-
- #ifdef __vertexnormals__
- mat_mul_vec(xpoints[x].point.normal,
- xform->m,
- p->vertex[x].normal);
- /* rotate vertex normals */
- #endif
-
- xpoints[x].point.clipping=p->vertex[x].clipping;
- /* copy clipping information which could be required in
- a later part of the pipeline */
- if(xpoints[x].point.location[2]>0)
- {
- xpoints[x].scr_X=div(xpoints[x].point.location[0],
- xpoints[x].point.location[2]);
- xpoints[x].scr_Y=div(xpoints[x].point.location[1],
- xpoints[x].point.location[2]);
- }
- }
- }
-
-
-
-
-
-
- pipeline *alloc_pipeline(int numpoints, int numfaces, int numindex)
- {
- pipeline *p;
-
- p=malloc(sizeof(pipeline));
-
- if(!p)
- return 0;
-
- p->numfaces=numfaces;
- p->numindex=numindex;
- p->numpoints=numpoints;
- p->pbase=malloc(sizeof(pipe_point)*numpoints);
- p->fbase=malloc(sizeof(face)*numfaces);
- p->ibase=malloc(sizeof(long)*numindex);
- p->index1=malloc(sizeof(long)*numfaces);
- p->index2=malloc(sizeof(long)*numfaces);
- p->minZ=malloc(sizeof(long)*numfaces);
- p->maxZ=malloc(sizeof(long)*numfaces);
-
- if(!p->pbase||
- !p->fbase||
- !p->ibase||
- !p->index1||
- !p->index2||
- !p->minZ||
- !p->maxZ
- )
- {
- free_pipeline(p);
- return 0;
- }
-
- reset_pipeline(p);
-
- return p;
- }
-
-
-
- void free_pipeline(pipeline *p)
- {
- if(p)
- {
- if(p->pbase)
- {
- free(p->pbase);
- p->pbase=0;
- }
- if(p->fbase)
- {
- free(p->fbase);
- p->fbase=0;
- }
- if(p->ibase)
- {
- free(p->ibase);
- p->ibase=0;
- }
- if(p->index1)
- {
- free(p->index1);
- p->index1=0;
- }
- if(p->index2)
- {
- free(p->index2);
- p->index1=0;
- }
- if(p->minZ)
- {
- free(p->minZ);
- p->index1=0;
- }
- if(p->maxZ)
- {
- free(p->maxZ);
- p->index1=0;
- }
-
- p->numindex=0;
- p->numpoints=0;
- p->numfaces=0;
- free(p);
- }
- }
-
-
-
- void reset_pipeline(pipeline *p)
- {
- p->pptr=0;
- p->fptr=0;
- p->iptr=0;
- }
-
-
-
-
- void cull_object(object *o, pipeline *p, affine *xform)
- {
- long a,b,c,x,y,z;
- face *f,*g;
- pipe_point *pt;
- vector u;
- REAL D;
-
- pt=p->pbase+p->pptr;
-
- xform_pointcollection(o->pts_data,xform,pt);
-
- for(a=0;a<o->pts_data->numpoints;a++)
- {
- pt[a].point.clipping=
- o->pts_data->vertex[a].clipping;
- }
- f=o->face_data->face;
- for(a=0;a<o->face_data->numfaces;a++,f++)
- {
- /* backface cull. dot product of vector from eye to a point in
- face with normal vector of face */
- mat_mul_vec(u,xform->m,f->normal);
- D=vec_dot(u, pt[*f->index].point.location);
- if(D>=floattoreal(0.0))
- {
- /* clip */
- for(b=0;b<f->numpoints;b++)
- pt[f->index[b]].point.clipping--;
- }
- else
- {
- /* output face to pipeline */
- g=p->fbase+p->fptr;
-
-
- g->index=p->ibase+p->iptr;
- g->numpoints=f->numpoints;
- copyvector(g->normal,u);
- g->D=D;
-
- for(b=0;b<f->numpoints;b++)
- g->index[b]=f->index[b]+p->pptr;
-
- /* update pointers */
- p->iptr+=f->numpoints;
- p->fptr++;
- }
- }
-
- /* now all faces are properly output and culled. we need only do
- vertices now */
-
- p->pptr+=o->pts_data->numpoints;
- }
-
-
-
-
- long *sort_pipeline(pipeline *p)
- {
- long a,b,c;
- REAL A,B;
- face *f;
- pipe_point *pt;
-
- f=p->fbase;
- pt=p->pbase;
- for(a=0;a<p->fptr;a++,f++)
- {
- A=pt[f->index[0]].point.location[2];
- B=A;
- for(b=1;b<f->numpoints;b++)
- {
- c=f->index[b];
- if(pt[c].point.location[2]<A)
- A=pt[c].point.location[2];
- else if(pt[c].point.location[2]>B)
- B=pt[c].point.location[2];
- }
-
- p->index1[a]=a;
- p->minZ[a]=realtofixed(A);
- p->maxZ[a]=realtofixed(B);
- }
-
- bytesort(p->maxZ,p->index1,p->index2,p->fptr,0);
- bytesort(p->maxZ,p->index2,p->index1,p->fptr,1);
- bytesort(p->maxZ,p->index1,p->index2,p->fptr,2);
- bytesort(p->maxZ,p->index2,p->index1,p->fptr,3);
-
- return p->index1;
- }
-
-
-
-
-
-
-
- #define getbyte(x,bitshift) (((x)>>(bitshift))&0xff)
-
- void bytesort(long *data, long *indexin, long *indexout, long itemcount,
- int bytenumber)
- {
- long count[257];
- long a,b,c;
-
- for(a=0;a<=256;a++)
- count[a]=0;
-
- bytenumber*=8;
-
- for(a=0;a<itemcount;a++)
- {
- b=getbyte(data[indexin[a]],bytenumber);
- count[b+1]++;
- }
-
- for(a=1;a<256;a++)
- count[a]+=count[a-1];
-
- for(a=0;a<itemcount;a++)
- {
- b=getbyte(data[indexin[a]],bytenumber);
- indexout[count[b]]=indexin[a];
- count[b]++;
- }
- }
-