Fixed several annoyances with halo render + unified render (bug 1989+2382)

- Maximum faces/halos per pixel was 500, which wasn't correctly applied in
  all cases, causing errors in AA
- Moved maximum up to 1000 now
- made halos become clipped away from filling in buffers when behind a
  solid face. That saves a lot of rendertime!

Unified remains weak with halos...
This commit is contained in:
Ton Roosendaal
2005-04-18 19:36:34 +00:00
parent 5d31c72020
commit 99ee891596
5 changed files with 67 additions and 93 deletions

View File

@@ -37,7 +37,7 @@
/* Render defines */
#define RE_MAX_OSA_COUNT 16 /* The max. number of possible oversamples */
#define RE_MAX_FACES_PER_PIXEL 500 /* max. nr of faces rendered behind one */
#define RE_MAX_FACES_PER_PIXEL 1000 /* max. nr of faces rendered behind one */
/* pixel */
enum RE_SkyAlphaBlendingType {

View File

@@ -71,7 +71,6 @@ RE_APixstrExt *addpseA(void);
* Add an object to a zbuffer entry.
*/
void insertObject(int teller,
/* int opaque, */
int obindex,
int obtype,
int dist,

View File

@@ -55,10 +55,12 @@ typedef struct RE_APixstrExt {
/* but this should definitely be done in a better way. An enum may */
/* be some help, but masking is still a nice feature... */
/* object types to buffer in the z buffer */
#define RE_NONE 0
#define RE_POLY 1
#define RE_HALO 2
#define RE_SKY 4
/* RE_SOLID is flag for RE_POLY, as speedup */
#define RE_NONE 0
#define RE_POLY 1
#define RE_HALO 2
#define RE_SKY 4
#define RE_SOLID 8
/* unique indices for each field */
#define RE_ZMIN 0

View File

@@ -197,6 +197,7 @@ static void freeRenderBuffers(void) {
static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3)
{
/* Coordinates of the vertices are specified in ZCS */
VlakRen *vlr;
int apteller, apoffsetteller;
double z0; /* used as temp var*/
double xx1;
@@ -205,13 +206,17 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3)
register int zverg,zvlak,x;
int my0,my2,sn1,sn2,rectx,zd;
int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask;
int obtype;
/* These used to be doubles. We may want to change them back if the */
/* loss of accuracy proves to be a problem? There does not seem to be */
/* any performance issues here, so I'll just keep the doubles. */
/* float vec0[3], vec1[3], vec2[3]; */
double vec0[3], vec1[3], vec2[3];
vlr= RE_findOrAddVlak( (zvlnr-1) & 0x7FFFFF);
if(vlr->mat->mode & MA_ZTRA) obtype= RE_POLY;
else obtype= RE_POLY|RE_SOLID;
/* MIN MAX */
/* sort vertices for min mid max y value */
if(v1[1]<v2[1]) {
@@ -351,7 +356,7 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3)
zverg-= Azvoordeel;
while(x>=0) {
insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask);
insertObject(apteller, zvlnr, obtype, zverg, mask);
zverg+= zd;
apteller++;
x--;
@@ -392,7 +397,7 @@ static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3)
zverg-= Azvoordeel;
while(x>=0) {
insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask);
insertObject(apteller, zvlnr, obtype, zverg, mask);
zverg+= zd;
apteller++;
x--;
@@ -455,7 +460,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2)
}
if(x>=0 && y>=Aminy && y<=Amaxy) {
insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask);
insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
}
v1[1]+= dy;
@@ -507,7 +512,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2)
}
if(x>=0 && y>=Aminy && (x < zBufferWidth)) {
insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask);
insertObject(apteller, zvlnr, RE_POLY, vergz, mask);
}
v1[0]+= dx;
@@ -522,7 +527,7 @@ static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2)
* Count and sort the list behind ap into buf. Sorts on min. distance.
* Low index <=> high z
*/
static int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE],
static int countAndSortPixelFaces(int zrow[][RE_PIXELFIELDSIZE],
RE_APixstrExt *ap)
{
int totvlak; /* face counter */
@@ -582,7 +587,7 @@ static int VR_cbuf[RE_MAX_FACES_PER_PIXEL][2];
/**
* Analyze the z-buffer, and pre-sample the colours.
*/
static int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector,
static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector,
struct RE_faceField* stack, int ptr,
int totvlak, float x, float y, int osaNr)
{
@@ -974,10 +979,18 @@ static void integratePerSubStack(float *sampcol, struct RE_faceField* stack,
/* an RE_APixstrExt* array */
/* - redo the numbering to something more logical */
/* threadsafe global arrays, too large for stack */
typedef struct zbufline {
int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE];
struct RE_faceField osastack[RE_MAX_FACES_PER_PIXEL + 1];
} zbufline;
static zbufline zb1, zb2;
static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3)
{
int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE];
RE_APixstrExt *ap; /* iterator for the face-lists */
RE_APixstrExt *ap; /* iterator for the face-lists */
RE_COLBUFTYPE collector[4];
RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4];
RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */
@@ -985,9 +998,12 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2
int x; /* pixel counter */
int i; /* yet another counter */
int stackDepth; /* faces-behind-this-pixel counter */
struct RE_faceField RE_OSAstack[RE_MAX_FACES_PER_PIXEL + 1];
int RE_OSAstack_ptr; /* Points to the lowest empty field. The indexed */
/* field is NOT readable. */
int osastack_ptr; /* Points to the lowest empty field. The indexed */
zbufline *zbl;
/* thread safe row buffers */
if(y & 1) zbl= &zb1;
else zbl= &zb2;
/* Prepare iterators */
ap = APixbufExt + (zBufferWidth * (y - Aminy));
@@ -1004,15 +1020,13 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2
};
/* a. count and sort number of faces */
stackDepth = countAndSortPixelFaces(zrow, ap);
stackDepth = countAndSortPixelFaces( zbl->zrow, ap);
/* b,c. oversample all subpixels, then integrate */
RE_OSAstack_ptr = 0;
RE_OSAstack_ptr = composeStack(zrow, collector,
RE_OSAstack, RE_OSAstack_ptr,
stackDepth, x, y, osaNr);
integratePerSubStack(sampcol, RE_OSAstack, RE_OSAstack_ptr,
x, y, osaNr);
osastack_ptr = 0;
osastack_ptr = composeStack(zbl->zrow, collector, zbl->osastack, osastack_ptr,
stackDepth, x, y, osaNr);
integratePerSubStack(sampcol, zbl->osastack, osastack_ptr, x, y, osaNr);
/* d. Gamma corrected blending and Gaussian */
sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
@@ -1436,6 +1450,7 @@ static void calcZBufLine(int y)
/* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */
if( (y < Aminy) || (y > Amaxy)) {
/* prepare buffer */
part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */
Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */
@@ -1458,7 +1473,7 @@ static void calcZBufLine(int y)
if(RE_local_test_break()) keepLooping = 0;
Zsample++;
}
};
}
}

View File

@@ -61,6 +61,7 @@
#include "MEM_guardedalloc.h"
#include "zbufferdatastruct.h"
#include "vanillaRenderPipe_types.h"
#include "render.h"
#ifdef HAVE_CONFIG_H
@@ -174,7 +175,6 @@ RE_APixstrExt *addpseA(void)
/* ------------------------------------------------------------------------- */
void insertObject(int apteller,
/* int opaque, */
int obindex,
int obtype,
int dist,
@@ -182,21 +182,17 @@ void insertObject(int apteller,
{
/* Guard the insertion if needed? */
RE_APixstrExt* apn = &APixbufExt[apteller];
int all_subpixels= 0;
//if(obtype==RE_POLY) {
// VlakRen *vlr= RE_findOrAddVlak( (obindex-1) & 0x7FFFFF);
// if(vlr->flag & R_FULL_OSA) all_subpixels= 1;
//}
int all_subpixels= 0; // not used now... (ton)
while(apn) {
if(apn->t[0] == RE_NONE) {
apn->p[0] = obindex; apn->t[0] = obtype;
apn->zmin[0] = dist; apn->zmax[0] = dist;
apn->mask[0] = mask;
break;
}
if(all_subpixels==0) {
else if(all_subpixels==0) {
if((apn->p[0] == obindex) && (apn->t[0] & obtype)) {
if(dist < apn->zmin[0]) apn->zmin[0] = dist;
else if(dist > apn->zmax[0]) apn->zmax[0] = dist;
@@ -204,13 +200,14 @@ void insertObject(int apteller,
break;
}
}
if(apn->t[1] == RE_NONE) {
apn->p[1] = obindex; apn->t[1] = obtype;
apn->zmin[1] = dist; apn->zmax[1] = dist;
apn->mask[1] = mask;
break;
}
if(all_subpixels==0) {
else if(all_subpixels==0) {
if((apn->p[1] == obindex) && (apn->t[1] & obtype)) {
if(dist < apn->zmin[1]) apn->zmin[1] = dist;
else if(dist > apn->zmax[1]) apn->zmax[1] = dist;
@@ -218,13 +215,14 @@ void insertObject(int apteller,
break;
}
}
if(apn->t[2] == RE_NONE) {
apn->p[2] = obindex; apn->t[2] = obtype;
apn->zmin[2] = dist; apn->zmax[2] = dist;
apn->mask[2] = mask;
break;
}
if(all_subpixels==0) {
else if(all_subpixels==0) {
if((apn->p[2] == obindex) && (apn->t[2] & obtype)) {
if(dist < apn->zmin[2]) apn->zmin[2] = dist;
else if(dist > apn->zmax[2]) apn->zmax[2] = dist;
@@ -232,13 +230,14 @@ void insertObject(int apteller,
break;
}
}
if(apn->t[3] == RE_NONE) {
apn->p[3] = obindex; apn->t[3] = obtype;
apn->zmin[3] = dist; apn->zmax[3] = dist;
apn->mask[3] = mask;
break;
}
if(all_subpixels==0) {
else if(all_subpixels==0) {
if((apn->p[3] == obindex) && (apn->t[3] & obtype)) {
if(dist < apn->zmin[3]) apn->zmin[3] = dist;
else if(dist > apn->zmax[3]) apn->zmax[3] = dist;
@@ -246,66 +245,16 @@ void insertObject(int apteller,
break;
}
}
if(apn->next==0) apn->next= addpseA();
apn= apn->next;
}
} /* end of insertObject(RE_APixstrExt*, int, int, int, int) */
}
/* ------------------------------------------------------------------------- */
void insertFlatObject(RE_APixstrExt *apn, int obindex, int obtype, int dist, int mask)
{
while(apn) {
if(apn->t[0] == RE_NONE) {
apn->p[0] = obindex; apn->zmin[0] = dist;
apn->zmax[0] = dist; apn->mask[0] = mask;
apn->t[0] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[0] & obtype) && (apn->p[0] == obindex)) {
apn->mask[0]|= mask; break;
}
#endif
if(apn->t[1] == RE_NONE) {
apn->p[1] = obindex; apn->zmin[1] = dist;
apn->zmax[1] = dist; apn->mask[1] = mask;
apn->t[1] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[1] & obtype) && (apn->p[1] == obindex)) {
apn->mask[1]|= mask; break;
}
#endif
if(apn->t[2] == RE_NONE) {
apn->p[2] = obindex; apn->zmin[2] = dist;
apn->zmax[2] = dist; apn->mask[2] = mask;
apn->t[2] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[2] & obtype) && (apn->p[2] == obindex)) {
apn->mask[2]|= mask; break;
}
#endif
if(apn->t[3] == RE_NONE) {
apn->p[3] = obindex; apn->zmin[3] = dist;
apn->zmax[3] = dist; apn->mask[3] = mask;
apn->t[3] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[3] & obtype) && (apn->p[3] == obindex)) {
apn->mask[3]|= mask; break;
}
#endif
if(apn->next==0) apn->next= addpseA();
apn= apn->next;
};
} /* end of void insertFlatObject(RE_APixstrExt, int, int, int, int)*/
/* ------------------------------------------------------------------------- */
/* This function might be helped by an end-of-list marker */
void insertFlatObjectNoOsa(RE_APixstrExt *ap,
int obindex,
@@ -313,6 +262,8 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap,
int dist,
int mask)
{
int counter;
while(ap) {
if(ap->t[0] == RE_NONE) {
ap->p[0] = obindex; ap->zmin[0] = dist;
@@ -320,6 +271,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap,
ap->t[0] = obtype;
break;
}
else if(ap->t[0] & RE_SOLID) if( dist > ap->zmin[0] ) break;
if(ap->t[1] == RE_NONE) {
ap->p[1] = obindex; ap->zmin[1] = dist;
@@ -327,6 +279,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap,
ap->t[1] = obtype;
break;
}
else if(ap->t[1] & RE_SOLID) if( dist > ap->zmin[1] ) break;
if(ap->t[2] == RE_NONE) {
ap->p[2] = obindex; ap->zmin[2] = dist;
@@ -334,6 +287,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap,
ap->t[2] = obtype;
break;
}
else if(ap->t[2] & RE_SOLID) if( dist > ap->zmin[2] ) break;
if(ap->t[3] == RE_NONE) {
ap->p[3] = obindex; ap->zmin[3] = dist;
@@ -341,11 +295,15 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap,
ap->t[3] = obtype;
break;
}
else if(ap->t[3] & RE_SOLID) if( dist > ap->zmin[3] ) break;
counter+= 4;
if(counter > RE_MAX_FACES_PER_PIXEL) break;
if(ap->next==0) ap->next= addpseA();
ap= ap->next;
};
} /* end of void insertFlatObjectNoOsa(RE_APixstrExt, int, int, int, int)*/
}
/* ------------------------------------------------------------------------- */