Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/source/zbuf.c')
-rw-r--r--source/blender/render/intern/source/zbuf.c166
1 files changed, 105 insertions, 61 deletions
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 3b3a8568933..a7b9867715f 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -271,7 +271,7 @@ static APixstr *addpsmainA(ListBase *lb)
return psm->ps;
}
-static void freepsA(ListBase *lb)
+void freepsA(ListBase *lb)
{
APixstrMain *psm, *psmnext;
@@ -1760,12 +1760,12 @@ static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[
}
}
-static void zbuffer_part_bounds(Render *re, RenderPart *pa, float *bounds)
+static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bounds)
{
- bounds[0]= (2*pa->disprect.xmin - re->winx-1)/(float)re->winx;
- bounds[1]= (2*pa->disprect.xmax - re->winx+1)/(float)re->winx;
- bounds[2]= (2*pa->disprect.ymin - re->winy-1)/(float)re->winy;
- bounds[3]= (2*pa->disprect.ymax - re->winy+1)/(float)re->winy;
+ bounds[0]= (2*pa->disprect.xmin - winx-1)/(float)winx;
+ bounds[1]= (2*pa->disprect.xmax - winx+1)/(float)winx;
+ bounds[2]= (2*pa->disprect.ymin - winy-1)/(float)winy;
+ bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy;
}
static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho)
@@ -1803,7 +1803,7 @@ void zbuf_render_project(float winmat[][4], float *co, float *ho)
projectvert(vec, winmat, ho);
}
-void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4])
+void zbuf_make_winmat(Render *re, float winmat[][4])
{
float panomat[4][4];
@@ -1814,13 +1814,8 @@ void zbuf_make_winmat(Render *re, float duplimat[][4], float winmat[][4])
panomat[2][0]= -re->panosi;
panomat[2][2]= re->panoco;
- if(duplimat)
- Mat4MulSerie(winmat, re->winmat, panomat, duplimat, 0, 0, 0, 0, 0);
- else
- Mat4MulMat4(winmat, panomat, re->winmat);
+ Mat4MulMat4(winmat, panomat, re->winmat);
}
- else if(duplimat)
- Mat4MulMat4(winmat, duplimat, re->winmat);
else
Mat4CpyMat4(winmat, re->winmat);
}
@@ -2047,12 +2042,15 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
Material *ma=0;
ObjectInstanceRen *obi;
ObjectRen *obr;
- float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ float obwinmat[4][4], winmat[4][4], bounds[4];
+ float ho1[4], ho2[4], ho3[4], ho4[4]={0};
unsigned int lay= rl->lay, lay_zmask= rl->lay_zmask;
int i, v, zvlnr, zsample, samples, c1, c2, c3, c4=0;
short nofill=0, env=0, wire=0, zmaskpass=0;
short all_z= (rl->layflag & SCE_LAY_ALL_Z) && !(rl->layflag & SCE_LAY_ZMASK);
short neg_zmask= (rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK);
+
+ zbuf_make_winmat(&R, winmat);
samples= (R.osa? R.osa: 1);
samples= MIN2(4, samples-pa->sample);
@@ -2060,7 +2058,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
for(zsample=0; zsample<samples; zsample++) {
zspan= &zspans[zsample];
- zbuffer_part_bounds(&R, pa, bounds);
+ zbuffer_part_bounds(R.winx, R.winy, pa, bounds);
zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop);
/* needed for transform from hoco to zbuffer co */
@@ -2135,9 +2133,9 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
continue;
if(obi->flag & R_TRANSFORMED)
- zbuf_make_winmat(&R, obi->mat, winmat);
+ Mat4MulMat4(obwinmat, obi->mat, winmat);
else
- zbuf_make_winmat(&R, NULL, winmat);
+ Mat4CpyMat4(obwinmat, winmat);
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
continue;
@@ -2182,14 +2180,14 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*,
v3= vlr->v3;
v4= vlr->v4;
- c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
- c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
- c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+ c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3);
/* partclipping doesn't need viewplane clipping */
partclip= c1 & c2 & c3;
if(v4) {
- c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4);
partclip &= c4;
}
@@ -2511,11 +2509,13 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
VlakRen *vlr= NULL;
VertRen *v1, *v2, *v3, *v4;
Material *ma=0, *sss_ma= R.sss_mat;
- float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ float obwinmat[4][4], winmat[4][4], bounds[4];
+ float ho1[4], ho2[4], ho3[4], ho4[4]={0};
int i, v, zvlnr, c1, c2, c3, c4=0;
short nofill=0, env=0, wire=0;
- zbuffer_part_bounds(&R, pa, bounds);
+ zbuf_make_winmat(&R, winmat);
+ zbuffer_part_bounds(R.winx, R.winy, pa, bounds);
zbuf_alloc_span(&zspan, pa->rectx, pa->recty, R.clipcrop);
zspan.sss_handle= handle;
@@ -2551,9 +2551,9 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
continue;
if(obi->flag & R_TRANSFORMED)
- zbuf_make_winmat(&R, obi->mat, winmat);
+ Mat4MulMat4(obwinmat, obi->mat, winmat);
else
- zbuf_make_winmat(&R, NULL, winmat);
+ Mat4CpyMat4(obwinmat, winmat);
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
continue;
@@ -3181,6 +3181,11 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
int x, y, *rza, *rma;
intptr_t *rd;
+ if((R.osa==0 && !pa->rectz) || !pa->rectdaps) {
+ fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFE);
+ return;
+ }
+
if(R.osa==0) {
memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty);
if(rectmask && pa->rectmask)
@@ -3222,7 +3227,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
* Do accumulation z buffering.
*/
-static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, RenderLayer *rl, unsigned int lay)
+static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspans[16], *zspan; /* MAX_OSA */
@@ -3232,28 +3237,27 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
VlakRen *vlr=NULL;
VertRen *v1, *v2, *v3, *v4;
float vec[3], hoco[4], mul, zval, fval;
- float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ float obwinmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
int i, v, zvlnr, c1, c2, c3, c4=0, dofill= 0;
- int zsample, samples, polygon_offset;
+ int zsample, polygon_offset;
- zbuffer_part_bounds(&R, pa, bounds);
- samples= (R.osa? R.osa: 1);
+ zbuffer_part_bounds(winx, winy, pa, bounds);
for(zsample=0; zsample<samples; zsample++) {
zspan= &zspans[zsample];
- zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop);
+ zbuf_alloc_span(zspan, pa->rectx, pa->recty, re->clipcrop);
/* needed for transform from hoco to zbuffer co */
- zspan->zmulx= ((float)R.winx)/2.0;
- zspan->zmuly= ((float)R.winy)/2.0;
+ zspan->zmulx= ((float)winx)/2.0;
+ zspan->zmuly= ((float)winy)/2.0;
/* the buffers */
zspan->arectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz");
zspan->apixbuf= APixbuf;
zspan->apsmbase= apsmbase;
- if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
+ if(negzmask)
zspan->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectmask");
/* filling methods */
@@ -3263,36 +3267,35 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
copyto_abufz(pa, zspan->arectz, zspan->rectmask, zsample); /* init zbuffer */
zspan->mask= 1<<zsample;
- if(R.osa) {
- zspan->zofsx= -pa->disprect.xmin - R.jit[zsample][0];
- zspan->zofsy= -pa->disprect.ymin - R.jit[zsample][1];
- }
- else if(R.i.curblur) {
- zspan->zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0];
- zspan->zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1];
+ if(jit) {
+ zspan->zofsx= -pa->disprect.xmin + jit[zsample][0];
+ zspan->zofsy= -pa->disprect.ymin + jit[zsample][1];
}
else {
zspan->zofsx= -pa->disprect.xmin;
zspan->zofsy= -pa->disprect.ymin;
}
- /* to center the sample position */
- zspan->zofsx -= 0.5f;
- zspan->zofsy -= 0.5f;
+
+ if(!shadow) {
+ /* to center the sample position */
+ zspan->zofsx -= 0.5f;
+ zspan->zofsy -= 0.5f;
+ }
}
/* we use this to test if nothing was filled in */
zvlnr= 0;
- for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
+ for(i=0, obi=re->instancetable.first; obi; i++, obi=obi->next) {
obr= obi->obr;
if(!(obi->lay & lay))
continue;
if(obi->flag & R_TRANSFORMED)
- zbuf_make_winmat(&R, obi->mat, winmat);
+ Mat4MulMat4(obwinmat, obi->mat, winmat);
else
- zbuf_make_winmat(&R, NULL, winmat);
+ Mat4CpyMat4(obwinmat, winmat);
if(clip_render_object(obi->obr->boundbox, bounds, winmat))
continue;
@@ -3306,7 +3309,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
if(vlr->mat!=ma) {
ma= vlr->mat;
- dofill= ((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST);
+ dofill= shadow || (((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP)) && !(ma->mode & MA_ONLYCAST));
}
if(dofill) {
@@ -3318,27 +3321,27 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
v3= vlr->v3;
v4= vlr->v4;
- c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
- c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
- c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+ c1= zbuf_part_project(cache, v1->index, obwinmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, obwinmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, obwinmat, bounds, v3->co, ho3);
/* partclipping doesn't need viewplane clipping */
partclip= c1 & c2 & c3;
if(v4) {
- c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ c4= zbuf_part_project(cache, v4->index, obwinmat, bounds, v4->co, ho4);
partclip &= c4;
}
if(partclip==0) {
/* a little advantage for transp rendering (a z offset) */
- if( ma->zoffs != 0.0) {
+ if(!shadow && ma->zoffs != 0.0) {
mul= 0x7FFFFFFF;
zval= mul*(1.0+ho1[2]/ho1[3]);
VECCOPY(vec, v1->co);
/* z is negative, otherwise its being clipped */
vec[2]-= ma->zoffs;
- projectverto(vec, R.winmat, hoco);
+ projectverto(vec, obwinmat, hoco);
fval= mul*(1.0+hoco[2]/hoco[3]);
polygon_offset= (int) fabs(zval - fval );
@@ -3376,13 +3379,13 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
}
}
if((v & 255)==255)
- if(R.test_break(R.tbh))
+ if(re->test_break(re->tbh))
break;
}
}
}
- if(R.test_break(R.tbh)) break;
+ if(re->test_break(re->tbh)) break;
}
for(zsample=0; zsample<samples; zsample++) {
@@ -3396,6 +3399,51 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
return zvlnr;
}
+static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, RenderLayer *rl, StrandShadeCache *sscache)
+{
+ float winmat[4][4], (*jit)[2];
+ int samples, negzmask, doztra= 0;
+
+ samples= (R.osa)? R.osa: 1;
+ negzmask= ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK));
+
+ if(R.osa)
+ jit= R.jit;
+ else if(R.i.curblur)
+ jit= &R.jit[R.i.curblur-1];
+ else
+ jit= NULL;
+
+ zbuf_make_winmat(&R, winmat);
+
+ if(rl->layflag & SCE_LAY_ZTRA)
+ doztra+= zbuffer_abuf(&R, pa, APixbuf, apsmbase, rl->lay, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0);
+ if((rl->layflag & SCE_LAY_STRAND) && APixbufstrand)
+ doztra+= zbuffer_strands_abuf(&R, pa, APixbufstrand, apsmbase, rl->lay, negzmask, winmat, R.winx, R.winy, samples, jit, R.clipcrop, 0, sscache);
+
+ return doztra;
+}
+
+void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2])
+{
+ RenderPart pa;
+ int lay= -1;
+
+ if(lar->mode & LA_LAYER) lay= lar->lay;
+
+ memset(&pa, 0, sizeof(RenderPart));
+ pa.rectx= size;
+ pa.recty= size;
+ pa.disprect.xmin= 0;
+ pa.disprect.ymin= 0;
+ pa.disprect.xmax= size;
+ pa.disprect.ymax= size;
+
+ zbuffer_abuf(re, &pa, APixbuf, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1);
+ if(APixbufstrand)
+ zbuffer_strands_abuf(re, &pa, APixbufstrand, apsmbase, lay, 0, winmat, size, size, samples, jit, 1.0f, 1, NULL);
+}
+
/* different rules for speed in transparent pass... */
/* speed pointer NULL = sky, we clear */
/* else if either alpha is full or no solid was filled in: copy speed */
@@ -3902,11 +3950,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
sampalpha= 1.0f;
/* fill the Apixbuf */
- doztra= 0;
- if(rl->layflag & SCE_LAY_ZTRA)
- doztra+= zbuffer_abuf(pa, APixbuf, &apsmbase, rl, rl->lay);
- if((rl->layflag & SCE_LAY_STRAND) && APixbufstrand)
- doztra+= zbuffer_strands_abuf(&R, pa, rl, APixbufstrand, &apsmbase, sscache);
+ doztra= zbuffer_abuf_render(pa, APixbuf, APixbufstrand, &apsmbase, rl, sscache);
if(doztra == 0) {
/* nothing filled in */