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:
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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)*/
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user