Render Monster support: (part 1)
Removed all limitations from render code for maximum threads. The only define for this now is in BLI_threads.h, and currently set to 8. Note that each thread renders an entire tile, and also allocates the buffers for the tiles, so; more threads might work better with smaller tiles. IMPORTANT: node system won't work yet with more than 2 threads! So, don't try material nodes or compositing with over 2 threads. That I'll commit later today. What does work (should work :) is AO and soft shadow now.
This commit is contained in:
@@ -2974,6 +2974,11 @@ void RE_Database_Free(Render *re)
|
||||
re->wrld.aosphere= NULL;
|
||||
re->scene->world->aosphere= NULL;
|
||||
}
|
||||
if(re->wrld.aotables) {
|
||||
MEM_freeN(re->wrld.aotables);
|
||||
re->wrld.aotables= NULL;
|
||||
re->scene->world->aotables= NULL;
|
||||
}
|
||||
|
||||
if(re->r.mode & R_RAYTRACE) freeoctree(re);
|
||||
|
||||
@@ -3220,11 +3225,8 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view)
|
||||
}
|
||||
|
||||
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
|
||||
if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) ) {
|
||||
re->wrld.aosphere= MEM_mallocN(2*3*re->wrld.aosamp*re->wrld.aosamp*sizeof(float), "AO sphere");
|
||||
/* we make twice the amount of samples, because only a hemisphere is used */
|
||||
init_ao_sphere(re->wrld.aosphere, 2*re->wrld.aosamp*re->wrld.aosamp, 16);
|
||||
}
|
||||
if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) )
|
||||
init_ao_sphere(&re->wrld);
|
||||
|
||||
/* still bad... doing all */
|
||||
init_render_textures(re);
|
||||
@@ -3894,11 +3896,8 @@ void RE_Database_Baking(Render *re, Scene *scene, int type)
|
||||
}
|
||||
|
||||
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
|
||||
if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) ) {
|
||||
re->wrld.aosphere= MEM_mallocN(2*3*re->wrld.aosamp*re->wrld.aosamp*sizeof(float), "AO sphere");
|
||||
/* we make twice the amount of samples, because only a hemisphere is used */
|
||||
init_ao_sphere(re->wrld.aosphere, 2*re->wrld.aosamp*re->wrld.aosamp, 16);
|
||||
}
|
||||
if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) )
|
||||
init_ao_sphere(&re->wrld);
|
||||
|
||||
/* still bad... doing all */
|
||||
init_render_textures(re);
|
||||
|
||||
@@ -1100,7 +1100,7 @@ static void threaded_tile_processor(Render *re)
|
||||
RenderPart *pa, *nextpa;
|
||||
RenderResult *rr;
|
||||
rctf viewplane= re->viewplane;
|
||||
int maxthreads, rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
|
||||
int rendering=1, counter= 1, drawtimer=0, hasdrawn, minx=0;
|
||||
|
||||
/* first step; the entire render result, or prepare exr buffer saving */
|
||||
free_render_result(re->result);
|
||||
@@ -1123,11 +1123,7 @@ static void threaded_tile_processor(Render *re)
|
||||
IMB_exrtile_begin_write(rr->exrhandle, str, rr->rectx, rr->recty, rr->rectx/re->xparts, rr->recty/re->yparts);
|
||||
}
|
||||
|
||||
if(re->r.mode & R_THREADS)
|
||||
maxthreads= RE_MAXTHREAD; /* should become button value too */
|
||||
else maxthreads= 1;
|
||||
|
||||
BLI_init_threads(&threads, do_part_thread, maxthreads);
|
||||
BLI_init_threads(&threads, do_part_thread, re->r.threads);
|
||||
|
||||
/* assuming no new data gets added to dbase... */
|
||||
R= *re;
|
||||
@@ -1154,7 +1150,7 @@ static void threaded_tile_processor(Render *re)
|
||||
nextpa= find_next_part(re, minx);
|
||||
}
|
||||
else if(re->r.mode & R_PANORAMA) {
|
||||
if(nextpa==NULL && BLI_available_threads(&threads)==maxthreads)
|
||||
if(nextpa==NULL && BLI_available_threads(&threads)==re->r.threads)
|
||||
nextpa= find_next_pano_slice(re, &minx, &viewplane);
|
||||
else {
|
||||
PIL_sleep_ms(50);
|
||||
@@ -1195,7 +1191,7 @@ static void threaded_tile_processor(Render *re)
|
||||
drawtimer= 0;
|
||||
|
||||
/* on break, wait for all slots to get freed */
|
||||
if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
|
||||
if( (g_break=re->test_break()) && BLI_available_threads(&threads)==re->r.threads)
|
||||
rendering= 0;
|
||||
|
||||
}
|
||||
@@ -1223,10 +1219,8 @@ void RE_TileProcessor(Render *re, int firsttile)
|
||||
|
||||
re->i.starttime= PIL_check_seconds_timer();
|
||||
|
||||
//if(re->r.mode & R_THREADS)
|
||||
// threaded_tile_processor(re);
|
||||
//else
|
||||
render_tile_processor(re, firsttile);
|
||||
render_tile_processor(re, firsttile);
|
||||
|
||||
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
|
||||
re->stats_draw(&re->i);
|
||||
|
||||
@@ -1762,7 +1762,10 @@ void init_jitter_plane(LampRen *lar)
|
||||
float *fp;
|
||||
int x, iter=12, tot= lar->ray_totsamp;
|
||||
|
||||
fp=lar->jitter= MEM_mallocN(4*tot*2*sizeof(float), "lamp jitter tab");
|
||||
/* at least 4, or max threads+1 tables */
|
||||
if(BLENDER_MAX_THREADS < 4) x= 4;
|
||||
else x= BLENDER_MAX_THREADS+1;
|
||||
fp= lar->jitter= MEM_mallocN(x*tot*2*sizeof(float), "lamp jitter tab");
|
||||
|
||||
/* set per-lamp fixed seed */
|
||||
BLI_srandom(tot);
|
||||
@@ -1780,7 +1783,7 @@ void init_jitter_plane(LampRen *lar)
|
||||
}
|
||||
}
|
||||
|
||||
/* create the dithered tables */
|
||||
/* create the dithered tables (could just check lamp type!) */
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.0);
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.5);
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0, 0.5);
|
||||
@@ -1795,20 +1798,13 @@ static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys)
|
||||
|
||||
if(lar->ray_samp_type & LA_SAMP_JITTER) {
|
||||
/* made it threadsafe */
|
||||
if(thread & 1) {
|
||||
if(lar->xold1!=xs || lar->yold1!=ys) {
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(1), BLI_thread_frand(1));
|
||||
lar->xold1= xs; lar->yold1= ys;
|
||||
}
|
||||
return lar->jitter+2*tot;
|
||||
}
|
||||
else {
|
||||
if(lar->xold2!=xs || lar->yold2!=ys) {
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(0), BLI_thread_frand(0));
|
||||
lar->xold2= xs; lar->yold2= ys;
|
||||
}
|
||||
return lar->jitter+4*tot;
|
||||
|
||||
if(lar->xold[thread]!=xs || lar->yold[thread]!=ys) {
|
||||
jitter_plane_offset(lar->jitter, lar->jitter+2*(thread+1)*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(thread), BLI_thread_frand(thread));
|
||||
lar->xold[thread]= xs;
|
||||
lar->yold[thread]= ys;
|
||||
}
|
||||
return lar->jitter+2*(thread+1)*tot;
|
||||
}
|
||||
if(lar->ray_samp_type & LA_SAMP_DITHER) {
|
||||
return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1));
|
||||
@@ -2029,45 +2025,52 @@ static void DS_energy(float *sphere, int tot, float *vec)
|
||||
|
||||
/* called from convertBlenderScene.c */
|
||||
/* creates an equally distributed spherical sample pattern */
|
||||
void init_ao_sphere(float *sphere, int tot, int iter)
|
||||
/* and allocates threadsafe memory */
|
||||
void init_ao_sphere(World *wrld)
|
||||
{
|
||||
float *fp;
|
||||
int a;
|
||||
int a, tot, iter= 16;
|
||||
|
||||
/* we make twice the amount of samples, because only a hemisphere is used */
|
||||
tot= 2*wrld->aosamp*wrld->aosamp;
|
||||
|
||||
wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere");
|
||||
|
||||
/* fixed random */
|
||||
BLI_srandom(tot);
|
||||
|
||||
/* init */
|
||||
fp= sphere;
|
||||
fp= wrld->aosphere;
|
||||
for(a=0; a<tot; a++, fp+= 3) {
|
||||
RandomSpherical(fp);
|
||||
}
|
||||
|
||||
while(iter--) {
|
||||
for(a=0, fp= sphere; a<tot; a++, fp+= 3) {
|
||||
DS_energy(sphere, tot, fp);
|
||||
for(a=0, fp= wrld->aosphere; a<tot; a++, fp+= 3) {
|
||||
DS_energy(wrld->aosphere, tot, fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* tables */
|
||||
wrld->aotables= MEM_mallocN(BLENDER_MAX_THREADS*3*tot*sizeof(float), "AO tables");
|
||||
}
|
||||
|
||||
|
||||
static float *threadsafe_table_sphere(int test, int thread, int xs, int ys)
|
||||
/* give per thread a table, we have to compare xs ys because of way OSA works... */
|
||||
static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int tot)
|
||||
{
|
||||
static float sphere1[2*3*256];
|
||||
static float sphere2[2*3*256];
|
||||
static int xs1=-1, xs2=-1, ys1=-1, ys2=-1;
|
||||
static int xso[BLENDER_MAX_THREADS], yso[BLENDER_MAX_THREADS];
|
||||
static int firsttime= 1;
|
||||
|
||||
if(thread & 1) {
|
||||
if(xs==xs1 && ys==ys1) return sphere1;
|
||||
if(test) return NULL;
|
||||
xs1= xs; ys1= ys;
|
||||
return sphere1;
|
||||
}
|
||||
else {
|
||||
if(xs==xs2 && ys==ys2) return sphere2;
|
||||
if(test) return NULL;
|
||||
xs2= xs; ys2= ys;
|
||||
return sphere2;
|
||||
if(firsttime) {
|
||||
memset(xso, 255, sizeof(xso));
|
||||
memset(yso, 255, sizeof(yso));
|
||||
firsttime= 0;
|
||||
}
|
||||
|
||||
if(xs==xso[thread] && ys==yso[thread]) return R.wrld.aotables+ thread*tot*3;
|
||||
if(test) return NULL;
|
||||
xso[thread]= xs; yso[thread]= ys;
|
||||
return R.wrld.aotables+ thread*tot*3;
|
||||
}
|
||||
|
||||
static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
|
||||
@@ -2097,9 +2100,9 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
|
||||
float ang, *vec1;
|
||||
int a;
|
||||
|
||||
sphere= threadsafe_table_sphere(1, thread, xs, ys); // returns table if xs and ys were equal to last call
|
||||
sphere= threadsafe_table_sphere(1, thread, xs, ys, tot); // returns table if xs and ys were equal to last call
|
||||
if(sphere==NULL) {
|
||||
sphere= threadsafe_table_sphere(0, thread, xs, ys);
|
||||
sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
|
||||
|
||||
// random rotation
|
||||
ang= BLI_thread_frand(thread);
|
||||
@@ -2239,7 +2242,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
|
||||
/* only when not mir tracing, first hit optimm */
|
||||
if(shi->depth==0)
|
||||
isec.vlr_last= lar->vlr_last[shi->thread & 1];
|
||||
isec.vlr_last= lar->vlr_last[shi->thread];
|
||||
else
|
||||
isec.vlr_last= NULL;
|
||||
|
||||
@@ -2352,7 +2355,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
|
||||
|
||||
/* for first hit optim, set last interesected shadow face */
|
||||
if(shi->depth==0)
|
||||
lar->vlr_last[shi->thread & 1]= isec.vlr_last;
|
||||
lar->vlr_last[shi->thread]= isec.vlr_last;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3315,6 +3315,7 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
/* free all */
|
||||
MEM_freeN(pa->rectp); pa->rectp= NULL;
|
||||
MEM_freeN(pa->rectz); pa->rectz= NULL;
|
||||
MEM_freeN(pa->clipflag); pa->clipflag= NULL;
|
||||
|
||||
/* display active layer */
|
||||
rr->renrect.ymin=rr->renrect.ymax= 0;
|
||||
@@ -3462,6 +3463,7 @@ void zbufshade_tile(RenderPart *pa)
|
||||
|
||||
MEM_freeN(pa->rectp); pa->rectp= NULL;
|
||||
MEM_freeN(pa->rectz); pa->rectz= NULL;
|
||||
MEM_freeN(pa->clipflag); pa->clipflag= NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -3900,10 +3902,10 @@ static void *do_bake_thread(void *bs_v)
|
||||
/* returns 0 if nothing was handled */
|
||||
int RE_bake_shade_all_selected(Render *re, int type)
|
||||
{
|
||||
BakeShade handles[RE_MAXTHREAD];
|
||||
BakeShade handles[BLENDER_MAX_THREADS];
|
||||
ListBase threads;
|
||||
Image *ima;
|
||||
int a, vdone=0, maxthreads= 1;
|
||||
int a, vdone=0;
|
||||
|
||||
/* initialize static vars */
|
||||
get_next_bake_face(NULL);
|
||||
@@ -3916,14 +3918,10 @@ int RE_bake_shade_all_selected(Render *re, int type)
|
||||
R= *re;
|
||||
R.bakebuf= NULL;
|
||||
|
||||
if(re->r.mode & R_THREADS)
|
||||
maxthreads= RE_MAXTHREAD; /* should become button value too */
|
||||
else maxthreads= 1;
|
||||
|
||||
BLI_init_threads(&threads, do_bake_thread, maxthreads);
|
||||
BLI_init_threads(&threads, do_bake_thread, re->r.threads);
|
||||
|
||||
/* get the threads running */
|
||||
for(a=0; a<maxthreads; a++) {
|
||||
for(a=0; a<re->r.threads; a++) {
|
||||
/* set defaults in handles */
|
||||
memset(&handles[a], 0, sizeof(BakeShade));
|
||||
handles[a].shi.lay= re->scene->lay;
|
||||
@@ -3935,11 +3933,11 @@ int RE_bake_shade_all_selected(Render *re, int type)
|
||||
|
||||
/* wait for everything to be done */
|
||||
a= 0;
|
||||
while(a!=maxthreads) {
|
||||
while(a!=re->r.threads) {
|
||||
|
||||
PIL_sleep_ms(50);
|
||||
|
||||
for(a=0; a<maxthreads; a++)
|
||||
for(a=0; a<re->r.threads; a++)
|
||||
if(handles[a].ready==0)
|
||||
break;
|
||||
}
|
||||
@@ -3955,7 +3953,7 @@ int RE_bake_shade_all_selected(Render *re, int type)
|
||||
}
|
||||
|
||||
/* calculate return value */
|
||||
for(a=0; a<maxthreads; a++) {
|
||||
for(a=0; a<re->r.threads; a++) {
|
||||
vdone+= handles[a].vdone;
|
||||
|
||||
zbuf_free_span(handles[a].zspan);
|
||||
|
||||
@@ -1685,68 +1685,42 @@ void set_part_zbuf_clipflag(RenderPart *pa)
|
||||
{
|
||||
VertRen *ver=NULL;
|
||||
float minx, miny, maxx, maxy, wco;
|
||||
unsigned short clipclear;
|
||||
int v;
|
||||
char *clipflag;
|
||||
|
||||
/* flags stored in part now */
|
||||
clipflag= pa->clipflag= MEM_mallocN(R.totvert+1, "part clipflags");
|
||||
|
||||
minx= (2*pa->disprect.xmin - R.winx-1)/(float)R.winx;
|
||||
maxx= (2*pa->disprect.xmax - R.winx+1)/(float)R.winx;
|
||||
miny= (2*pa->disprect.ymin - R.winy-1)/(float)R.winy;
|
||||
maxy= (2*pa->disprect.ymax - R.winy+1)/(float)R.winy;
|
||||
|
||||
/* supports up to 4 threads this way */
|
||||
clipclear= ~(15 << 4*(pa->thread & 3));
|
||||
|
||||
/* extra security to prevent access to same data */
|
||||
BLI_lock_thread(LOCK_CUSTOM1);
|
||||
|
||||
for(v=0; v<R.totvert; v++) {
|
||||
for(v=0; v<R.totvert; v++, clipflag++) {
|
||||
if((v & 255)==0)
|
||||
ver= RE_findOrAddVert(&R, v);
|
||||
else ver++;
|
||||
|
||||
wco= ver->ho[3];
|
||||
ver->flag &= clipclear;
|
||||
|
||||
switch(pa->thread & 3) {
|
||||
case 0:
|
||||
if( ver->ho[0] > maxx*wco) ver->flag |= 1;
|
||||
else if( ver->ho[0]< minx*wco) ver->flag |= 2;
|
||||
if( ver->ho[1] > maxy*wco) ver->flag |= 4;
|
||||
else if( ver->ho[1]< miny*wco) ver->flag |= 8;
|
||||
break;
|
||||
case 1:
|
||||
if( ver->ho[0] > maxx*wco) ver->flag |= 16;
|
||||
else if( ver->ho[0]< minx*wco) ver->flag |= 32;
|
||||
if( ver->ho[1] > maxy*wco) ver->flag |= 64;
|
||||
else if( ver->ho[1]< miny*wco) ver->flag |= 128;
|
||||
break;
|
||||
case 2:
|
||||
if( ver->ho[0] > maxx*wco) ver->flag |= 256;
|
||||
else if( ver->ho[0]< minx*wco) ver->flag |= 512;
|
||||
if( ver->ho[1] > maxy*wco) ver->flag |= 1024;
|
||||
else if( ver->ho[1]< miny*wco) ver->flag |= 2048;
|
||||
break;
|
||||
case 3:
|
||||
if( ver->ho[0] > maxx*wco) ver->flag |= 4096;
|
||||
else if( ver->ho[0]< minx*wco) ver->flag |= 8192;
|
||||
if( ver->ho[1] > maxy*wco) ver->flag |= 16384;
|
||||
else if( ver->ho[1]< miny*wco) ver->flag |= 32768;
|
||||
break;
|
||||
}
|
||||
|
||||
*clipflag= 0;
|
||||
if( ver->ho[0] > maxx*wco) *clipflag |= 1;
|
||||
else if( ver->ho[0]< minx*wco) *clipflag |= 2;
|
||||
if( ver->ho[1] > maxy*wco) *clipflag |= 4;
|
||||
else if( ver->ho[1]< miny*wco) *clipflag |= 8;
|
||||
}
|
||||
|
||||
BLI_unlock_thread(LOCK_CUSTOM1);
|
||||
}
|
||||
|
||||
void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
|
||||
{
|
||||
ZSpan zspan;
|
||||
VlakRen *vlr= NULL;
|
||||
VertRen *v1, *v2, *v3, *v4;
|
||||
Material *ma=0;
|
||||
int v, zvlnr;
|
||||
unsigned short clipmask;
|
||||
short nofill=0, env=0, wire=0, all_z= layflag & SCE_LAY_ALL_Z;
|
||||
|
||||
char *clipflag= pa->clipflag;
|
||||
|
||||
zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
|
||||
|
||||
/* needed for transform from hoco to zbuffer co */
|
||||
@@ -1779,9 +1753,6 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
|
||||
zspan.zbuffunc= zbuffillGL4;
|
||||
zspan.zbuflinefunc= zbufline;
|
||||
|
||||
/* part clipflag, threaded */
|
||||
clipmask= (15 << 4*(pa->thread & 3));
|
||||
|
||||
for(v=0; v<R.totvlak; v++) {
|
||||
|
||||
if((v & 255)==0) vlr= R.blovl[v>>8];
|
||||
@@ -1813,11 +1784,17 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
|
||||
if(nofill==0) {
|
||||
unsigned short partclip;
|
||||
|
||||
/* partclipping doesn't need viewplane clipping */
|
||||
if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
|
||||
else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
|
||||
v1= vlr->v1;
|
||||
v2= vlr->v2;
|
||||
v3= vlr->v3;
|
||||
v4= vlr->v4;
|
||||
|
||||
if((partclip & clipmask)==0) {
|
||||
/* partclipping doesn't need viewplane clipping */
|
||||
partclip= clipflag[v1->index] & clipflag[v2->index] & clipflag[v3->index];
|
||||
if(v4)
|
||||
partclip &= clipflag[v4->index];
|
||||
|
||||
if(partclip==0) {
|
||||
|
||||
if(env) zvlnr= -1;
|
||||
else zvlnr= v+1;
|
||||
@@ -1825,14 +1802,14 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag)
|
||||
if(wire) zbufclipwire(&zspan, zvlnr, vlr);
|
||||
else {
|
||||
/* strands allow to be filled in as quad */
|
||||
if(vlr->v4 && (vlr->flag & R_STRAND)) {
|
||||
zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
|
||||
if(v4 && (vlr->flag & R_STRAND)) {
|
||||
zbufclip4(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v4->ho, v1->clip, v2->clip, v3->clip, v4->clip);
|
||||
}
|
||||
else {
|
||||
zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
|
||||
if(vlr->v4) {
|
||||
zbufclip(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v1->clip, v2->clip, v3->clip);
|
||||
if(v4) {
|
||||
if(zvlnr>0) zvlnr+= RE_QUAD_OFFS;
|
||||
zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
|
||||
zbufclip(&zspan, zvlnr, v1->ho, v3->ho, v4->ho, v1->clip, v3->clip, v4->clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2561,9 +2538,10 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
|
||||
ZSpan zspan;
|
||||
Material *ma=NULL;
|
||||
VlakRen *vlr=NULL;
|
||||
VertRen *v1, *v2, *v3, *v4;
|
||||
float vec[3], hoco[4], mul, zval, fval;
|
||||
int v, zvlnr, zsample, dofill= 0;
|
||||
unsigned short clipmask;
|
||||
char *clipflag= pa->clipflag;
|
||||
|
||||
zbuf_alloc_span(&zspan, pa->rectx, pa->recty);
|
||||
|
||||
@@ -2580,9 +2558,6 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
|
||||
zspan.zbuffunc= zbuffillAc4;
|
||||
zspan.zbuflinefunc= zbuflineAc;
|
||||
|
||||
/* part clipflag, 4 threads */
|
||||
clipmask= (15 << 4*(pa->thread & 3));
|
||||
|
||||
for(zsample=0; zsample<R.osa || R.osa==0; zsample++) {
|
||||
|
||||
copyto_abufz(pa, zspan.arectz, zsample); /* init zbuffer */
|
||||
@@ -2618,17 +2593,23 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
|
||||
if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) {
|
||||
unsigned short partclip;
|
||||
|
||||
/* partclipping doesn't need viewplane clipping */
|
||||
if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag;
|
||||
else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag;
|
||||
v1= vlr->v1;
|
||||
v2= vlr->v2;
|
||||
v3= vlr->v3;
|
||||
v4= vlr->v4;
|
||||
|
||||
if((partclip & clipmask)==0) {
|
||||
/* partclipping doesn't need viewplane clipping */
|
||||
partclip= clipflag[v1->index] & clipflag[v2->index] & clipflag[v3->index];
|
||||
if(v4)
|
||||
partclip &= clipflag[v4->index];
|
||||
|
||||
if(partclip==0) {
|
||||
/* a little advantage for transp rendering (a z offset) */
|
||||
if( ma->zoffs != 0.0) {
|
||||
mul= 0x7FFFFFFF;
|
||||
zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]);
|
||||
zval= mul*(1.0+v1->ho[2]/v1->ho[3]);
|
||||
|
||||
VECCOPY(vec, vlr->v1->co);
|
||||
VECCOPY(vec, v1->co);
|
||||
/* z is negative, otherwise its being clipped */
|
||||
vec[2]-= ma->zoffs;
|
||||
projectverto(vec, R.winmat, hoco);
|
||||
@@ -2642,14 +2623,14 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
|
||||
|
||||
if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr);
|
||||
else {
|
||||
if(vlr->v4 && (vlr->flag & R_STRAND)) {
|
||||
zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip);
|
||||
if(v4 && (vlr->flag & R_STRAND)) {
|
||||
zbufclip4(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v4->ho, v1->clip, v2->clip, v3->clip, v4->clip);
|
||||
}
|
||||
else {
|
||||
zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip);
|
||||
if(vlr->v4) {
|
||||
zbufclip(&zspan, zvlnr, v1->ho, v2->ho, v3->ho, v1->clip, v2->clip, v3->clip);
|
||||
if(v4) {
|
||||
zvlnr+= RE_QUAD_OFFS;
|
||||
zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip);
|
||||
zbufclip(&zspan, zvlnr, v1->ho, v3->ho, v4->ho, v1->clip, v3->clip, v4->clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user