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:
authorTon Roosendaal <ton@blender.org>2005-12-04 17:32:21 +0300
committerTon Roosendaal <ton@blender.org>2005-12-04 17:32:21 +0300
commitaa939b859904fcfad5c6782e14621da74bbf8118 (patch)
treeccf58f615f767fea93ddcfc01988244efdc0c643 /source/blender/src/previewrender.c
parentc2cff1cbcf71634de3aca184c70cc4bd23fe35a8 (diff)
Orange branch feature; Material Layering
(WIP, don't bugs for this in tracker yet please!) - New Panel "Layers" in Material buttons, allows to add unlimited amount of materials on top of each other. - Every Layer is actually just another Material, which gets rendered/shaded (including texture), and then added on top of previous layer with an operation like Mix, Add, Mult, etc. - Layers render fully independent, so bumpmaps are not passed on to next layers. - Per Layer you can set if it influences Diffuse, Specular or Alpha - If a Material returns alpha (like from texture), the alpha value is used for adding the layers too. - New texture "Map To" channel allows to have a texture work on a Layer - Each layer, including basis Material, can be turned on/off individually Notes: - at this moment, the full shading pass happens for each layer, including shadow, AO and raytraced mirror or transparency... - I had to remove old hacks from preview render, which corrected reflected normals for preview texturing. - still needs loadsa testing!
Diffstat (limited to 'source/blender/src/previewrender.c')
-rw-r--r--source/blender/src/previewrender.c583
1 files changed, 305 insertions, 278 deletions
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index 5761d0af36c..759baa72e5c 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -1,7 +1,4 @@
-/* previewrender.c GRAPHICS
- *
- * maart 95
- *
+/*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
@@ -130,26 +127,26 @@ static short snijpunt(float *v1, float *v2, float *v3, float *rtlabda, float
x2= t10*t21-t11*t20;
deeldet= t00*x0+t01*x1+t02*x2;
- if(deeldet!=0.0) {
+ if(deeldet!=0.0f) {
m0= ray1[0]-v3[0];
m1= ray1[1]-v3[1];
m2= ray1[2]-v3[2];
det1= m0*x0+m1*x1+m2*x2;
rtu= det1/deeldet;
- if(rtu<=0.0) {
+ if(rtu<=0.0f) {
det2= t00*(m1*t22-m2*t21);
det2+= t01*(m2*t20-m0*t22);
det2+= t02*(m0*t21-m1*t20);
rtv= det2/deeldet;
- if(rtv<=0.0) {
- if(rtu+rtv>= -1.0) {
+ if(rtv<=0.0f) {
+ if(rtu+rtv>= -1.0f) {
det3= m0*(t12*t01-t11*t02);
det3+= m1*(t10*t02-t12*t00);
det3+= m2*(t11*t00-t10*t01);
*rtlabda= det3/deeldet;
- if(*rtlabda>=0.0 && *rtlabda<=1.0) {
+ if(*rtlabda>=0.0f && *rtlabda<=1.0f) {
return 1;
}
}
@@ -176,7 +173,7 @@ static int rcubi[3][4]= {
static int ray_previewrender(int x, int y, float *vec, float *vn)
{
- float scalef= 10.0/100.0;
+ float scalef= 10.0f/100.0f;
float ray1[3], ray2[3];
float minlabda, labda;
int totface= 3, hitface= -1;
@@ -184,10 +181,10 @@ static int ray_previewrender(int x, int y, float *vec, float *vn)
ray1[0]= ray2[0]= x*scalef;
ray1[1]= ray2[1]= y*scalef;
- ray1[2]= -10.0;
- ray2[2]= 10.0;
+ ray1[2]= -10.0f;
+ ray2[2]= 10.0f;
- minlabda= 1.0;
+ minlabda= 1.0f;
for(a=0; a<totface; a++) {
if(snijpunt( rcubev[rcubi[a][0]], rcubev[rcubi[a][1]], rcubev[rcubi[a][2]], &labda, ray1, ray2)) {
if( labda < minlabda) {
@@ -252,8 +249,8 @@ static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax)
pr_sizex= (prerect.xmax-prerect.xmin);
pr_sizey= (prerect.ymax-prerect.ymin);
- pr_facx= ( pr_sizex-1.0)/PR_RECTX;
- pr_facy= ( pr_sizey-1.0)/PR_RECTY;
+ pr_facx= ( pr_sizex-1.0f)/PR_RECTX;
+ pr_facy= ( pr_sizey-1.0f)/PR_RECTY;
/* correction for gla draw */
prerect.xmin-= curarea->winrct.xmin;
@@ -277,7 +274,7 @@ static void end_previewrect(void)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
- glPixelZoom(1.0, 1.0);
+ glPixelZoom(1.0f, 1.0f);
// restore viewport / scissor which was set by glaDefine2DArea
glViewport(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy);
@@ -309,10 +306,10 @@ static void draw_tex_crop(Tex *tex)
if(tex==0) return;
if(tex->type==TEX_IMAGE) {
- if(tex->cropxmin==0.0) ret++;
- if(tex->cropymin==0.0) ret++;
- if(tex->cropxmax==1.0) ret++;
- if(tex->cropymax==1.0) ret++;
+ if(tex->cropxmin==0.0f) ret++;
+ if(tex->cropymin==0.0f) ret++;
+ if(tex->cropxmax==1.0f) ret++;
+ if(tex->cropymax==1.0f) ret++;
if(ret==4) return;
rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4);
@@ -405,7 +402,7 @@ static void sky_preview_pixel(float lens, int x, int y, char *rect)
if(R.wrld.skytype & WO_SKYPAPER) {
view[0]= (2*x)/(float)PR_RECTX;
view[1]= (2*y)/(float)PR_RECTY;
- view[2]= 0.0;
+ view[2]= 0.0f;
}
else {
view[0]= x;
@@ -425,9 +422,9 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char
shi->co[1]= (float)y/(PR_RECTX/4);
shi->co[2]= 0;
- vec[0]= 0.02*x;
- vec[1]= 0.02*y;
- vec[2]= 0.005*PR_RECTX;
+ vec[0]= 0.02f*x;
+ vec[1]= 0.02f*y;
+ vec[2]= 0.005f*PR_RECTX;
VECCOPY(shi->view, vec);
dist= Normalise(shi->view);
@@ -438,16 +435,16 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char
if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi, lacol);
if(la->type==LA_SUN || la->type==LA_HEMI) {
- dist= 1.0;
+ dist= 1.0f;
}
else {
if(la->mode & LA_QUAD) {
- t= 1.0;
- if(la->ld1>0.0)
+ t= 1.0f;
+ if(la->ld1>0.0f)
t= la->dist/(la->dist+la->ld1*dist);
- if(la->ld2>0.0) {
+ if(la->ld2>0.0f) {
distkw= la->dist*la->dist;
t= t*distkw/(t*distkw+la->ld2*dist*dist);
}
@@ -471,10 +468,10 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char
}
t= la->spotsi;
- if(inpr<t) dist= 0.0;
+ if(inpr<t) dist= 0.0f;
else {
t= inpr-t;
- if(t<la->spotbl && la->spotbl!=0.0) {
+ if(t<la->spotbl && la->spotbl!=0.0f) {
/* soft area */
i= t/la->spotbl;
t= i*i;
@@ -577,9 +574,9 @@ static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect)
afmy= R.afmy;
rectot= R.rectot;
- R.r.postmul= R.r.postgamma= R.r.postsat= 1.0;
- R.r.posthue= R.r.postadd= 0.0;
- R.ycor= 1.0;
+ R.r.postmul= R.r.postgamma= R.r.postsat= 1.0f;
+ R.r.posthue= R.r.postadd= 0.0f;
+ R.ycor= 1.0f;
R.rectx= PR_RECTX;
R.recty= PR_RECTY;
R.afmx= PR_RECTX/2;
@@ -609,11 +606,11 @@ static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect)
static void texture_preview_pixel(Tex *tex, int x, int y, char *rect)
{
float i, v1, xsq, ysq, texvec[3];
- float tin=1.0, tr, tg, tb, ta;
+ float tin=1.0f, tr, tg, tb, ta;
int rgbnor, tracol, skip=0;
if(tex->type==TEX_IMAGE) {
- v1= 1.0/PR_RECTX;
+ v1= 1.0f/PR_RECTX;
texvec[0]= 0.5+v1*x;
texvec[1]= 0.5+v1*y;
@@ -622,11 +619,11 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect)
if(tex->extend==TEX_REPEAT) {
if(tex->xrepeat>1) {
texvec[0] *= tex->xrepeat;
- if(texvec[0]>1.0) texvec[0] -= (int)(texvec[0]);
+ if(texvec[0]>1.0f) texvec[0] -= (int)(texvec[0]);
}
if(tex->yrepeat>1) {
texvec[1] *= tex->yrepeat;
- if(texvec[1]>1.0) texvec[1] -= (int)(texvec[1]);
+ if(texvec[1]>1.0f) texvec[1] -= (int)(texvec[1]);
}
}
else if(tex->extend==TEX_CHECKER) {
@@ -647,17 +644,17 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect)
i= 2.0*(texvec[2]);
texvec[0]= (i*texvec[0]);
texvec[1]= (i*texvec[1]);
- texvec[2]= (-1.0+i*texvec[2]);
+ texvec[2]= (-1.0f+i*texvec[2]);
}
else {
skip= 1;
- tr= tg= tb= ta= 0.0;
+ tr= tg= tb= ta= 0.0f;
}
}
else {
skip= 1;
- tr= tg= tb= ta= 0.0;
+ tr= tg= tb= ta= 0.0f;
}
}
else {
@@ -665,7 +662,7 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect)
texvec[0]= v1*x;
texvec[1]= v1*y;
- texvec[2]= 0.0;
+ texvec[2]= 0.0f;
}
if(skip==0) rgbnor= multitex_ext(tex, texvec, &tin, &tr, &tg, &tb, &ta);
@@ -680,9 +677,9 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect)
v1= 255.0*tb;
rect[2]= CLAMPIS(v1, 0, 255);
- if(ta!=1.0) {
+ if(ta!=1.0f) {
tracol= 64+100*(abs(x)>abs(y));
- tracol= (1.0-ta)*tracol;
+ tracol= (1.0f-ta)*tracol;
rect[0]= tracol+ (rect[0]*ta) ;
rect[1]= tracol+ (rect[1]*ta) ;
@@ -706,24 +703,24 @@ static void refraction_prv(int *x, int *y, float *n, float index)
{
float dot, fac, view[3], len;
- index= 1.0/index;
+ index= 1.0f/index;
view[0]= index*(float)*x;
view[1]= ((float)*y)/index;
- view[2]= 20.0;
+ view[2]= 20.0f;
len= Normalise(view);
dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2];
- if(dot>0.0) {
- fac= 1.0 - (1.0 - dot*dot)*index*index;
- if(fac<= 0.0) return;
+ if(dot>0.0f) {
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if(fac<= 0.0f) return;
fac= -dot*index + sqrt(fac);
}
else {
- index = 1.0/index;
- fac= 1.0 - (1.0 - dot*dot)*index*index;
- if(fac<= 0.0) return;
+ index = 1.0f/index;
+ fac= 1.0f - (1.0f - dot*dot)*index*index;
+ if(fac<= 0.0f) return;
fac= -dot*index - sqrt(fac);
}
@@ -731,157 +728,62 @@ static void refraction_prv(int *x, int *y, float *n, float index)
*y= (int)(len*(index*view[1] + fac*n[1]));
}
-
-static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *rect, int smooth)
+static void shade_lamp_loop_preview(ShadeInput *shi, ShadeResult *shr, int pr_lamp)
{
extern float fresnel_fac(float *view, float *vn, float ior, float fac);
- Material *mat;
- float v1,inp, is, inprspec=0, isr=0.0, isb=0.0, isg=0.0;
- float diff[3]={0.0, 0.0, 0.0};
- float lv[3], *la, alpha;
- float eul[3], tmat[3][3], imat[3][3];
- int temp, a;
- char tracol;
-
- mat= shi->mat;
-
+ Material *mat= shi->mat;
+ float inp, is, inprspec=0;
+ float lv[3], *la;
+ int a;
+
// copy all relevant material vars, note, keep this synced with render_types.h
memcpy(&shi->r, &mat->r, 23*sizeof(float));
// set special cases:
shi->har= mat->har;
- if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
- v1= 1.0/PR_RECTX;
- shi->view[0]= v1*x;
- shi->view[1]= v1*y;
- shi->view[2]= 1.0;
- Normalise(shi->view);
+ if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0f;
+ memset(shr, 0, sizeof(ShadeResult));
- shi->xs= (float)x;
- shi->ys= (float)y;
+ /* normals flipped in render for smooth... */
+ if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0f);
- shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0;
-
- /* texture handling */
- if(mat->texco) {
-
- VECCOPY(shi->lo, vec);
-
- if(mat->pr_type==MA_CUBE) {
-
- eul[0]= (297)*M_PI/180.0;
- eul[1]= 0.0;
- eul[2]= (45)*M_PI/180.0;
- EulToMat3(eul, tmat);
-
- MTC_Mat3MulVecfl(tmat, shi->lo);
- MTC_Mat3MulVecfl(tmat, shi->vn);
- /* hack for cubemap, why!!! */
- SWAP(float, shi->vn[0], shi->vn[1]);
- }
- /* textures otherwise upside down */
- if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE)
- shi->lo[2]= -shi->lo[2];
-
- if(mat->texco & TEXCO_GLOB) {
- VECCOPY(shi->gl, shi->lo);
- }
- if(mat->texco & TEXCO_WINDOW) {
- VECCOPY(shi->winco, shi->lo);
- }
- if(mat->texco & TEXCO_STICKY) {
- VECCOPY(shi->sticky, shi->lo);
- }
- if(mat->texco & TEXCO_UV) {
- VECCOPY(shi->uv, shi->lo);
- }
- if(mat->texco & TEXCO_STRAND) {
- shi->strand= shi->lo[0];
- }
- if(mat->texco & TEXCO_OBJECT) {
- VECCOPY(shi->co, shi->lo);
- }
- if(mat->texco & (TEXCO_NORM)) {
- shi->orn[0]= shi->vn[0];
- shi->orn[1]= shi->vn[1];
- shi->orn[2]= shi->vn[2];
- }
- if(mat->texco & TEXCO_REFL) {
-
- inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]);
- shi->ref[0]= (shi->view[0]+inp*shi->vn[0]);
- shi->ref[1]= (shi->view[1]+inp*shi->vn[1]);
- shi->ref[2]= (shi->view[2]+inp*shi->vn[2]);
- }
-
- /* Clear displase vec for preview */
- shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
-
- /* normals flipped in render for smooth... */
- if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0);
-
- do_material_tex(shi);
-
- /* normals flipped in render... */
- if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0);
+ do_material_tex(shi);
+
+ /* normals flipped in render... */
+ if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0f);
+
+ shr->alpha= shi->alpha;
- if(mat->texco & TEXCO_REFL) {
- /* normals in render are pointing different... rhm */
- if(smooth) shi->ref[1]= -shi->ref[1];
- }
-
- if(mat->pr_type==MA_CUBE) {
- /* rotate normal back for normals texture */
- SWAP(float, shi->vn[0], shi->vn[1]);
- MTC_Mat3Inv(imat, tmat);
- MTC_Mat3MulVecfl(imat, shi->vn);
- }
-
- }
- /* set it here, because ray_mirror will affect it */
- alpha= shi->alpha;
-
- if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */
- shi->vn[0]-=2.0*shi->displace[2];
- shi->vn[1]-=2.0*shi->displace[0];
- shi->vn[2]+=2.0*shi->displace[1];
- Normalise(shi->vn);
- }
-
if(mat->mode & (MA_ZTRA|MA_RAYTRANSP))
- if(mat->fresnel_tra!=0.0)
- alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra);
-
+ if(mat->fresnel_tra!=0.0f)
+ shr->alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra);
+
if(mat->mode & MA_SHLESS) {
- temp= 255.0*(shi->r);
- if(temp>255) rect[0]= 255; else if(temp<0) rect[0]= 0; else rect[0]= temp;
-
- temp= 255.0*(shi->g);
- if(temp>255) rect[1]= 255; else if(temp<0) rect[1]= 0; else rect[1]= temp;
-
- temp= 255.0*(shi->b);
- if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp;
+ shr->diff[0]= shi->r;
+ shr->diff[1]= shi->g;
+ shr->diff[2]= shi->b;
+
}
else {
for(a=0; a<2; a++) {
- if((mat->pr_lamp & (1<<a))==0) continue;
+ if((pr_lamp & (1<<a))==0) continue;
if(a==0) la= pr1_lamp;
else la= pr2_lamp;
- lv[0]= vec[0]-la[0];
- lv[1]= vec[1]-la[1];
- lv[2]= vec[2]-la[2];
+ lv[0]= shi->co[0]-la[0];
+ lv[1]= shi->co[1]-la[1];
+ lv[2]= shi->co[2]-la[2];
Normalise(lv);
is= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2];
- if(is<0.0) is= 0.0;
+ if(is<0.0f) is= 0.0f;
- if(shi->spec>0.0) {
+ if(shi->spec>0.0f) {
- if(is>0.0) {
+ if(is>0.0f) {
/* specular shaders */
float specfac;
@@ -895,20 +797,20 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *
specfac= WardIso_Spec(shi->vn, lv, shi->view, mat->rms, 0);
else
specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3], 0);
-
+
inprspec= specfac*shi->spec;
if(mat->mode & MA_RAMP_SPEC) {
float spec[3];
do_specular_ramp(shi, specfac, inprspec, spec);
- isr+= inprspec*spec[0];
- isg+= inprspec*spec[1];
- isb+= inprspec*spec[2];
+ shr->spec[0]+= inprspec*spec[0];
+ shr->spec[1]+= inprspec*spec[1];
+ shr->spec[2]+= inprspec*spec[2];
}
else {
- isr+= inprspec*shi->specr;
- isg+= inprspec*shi->specg;
- isb+= inprspec*shi->specb;
+ shr->spec[0]+= inprspec*shi->specr;
+ shr->spec[1]+= inprspec*shi->specg;
+ shr->spec[2]+= inprspec*shi->specb;
}
}
}
@@ -922,12 +824,10 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *
if(a==0) la= pr1_col;
else la= pr2_col;
-
- add_to_diffuse(diff, shi, is, inp*la[0], inp*la[1], inp*la[2]);
- //ir+= inp*la[0];
- //ig+= inp*la[1];
- //ib+= inp*la[2];
+
+ add_to_diffuse(shr->diff, shi, is, inp*la[0], inp*la[1], inp*la[2]);
}
+ /* end lamp loop */
/* drawing checkerboard and sky */
if(mat->mode & MA_RAYMIRROR) {
@@ -940,93 +840,240 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *
shi->ref[2]= 0.17*y + 0.98*z;
/* scale */
- div= (0.85*shi->ref[1]);
+ div= (0.85f*shi->ref[1]);
shi->refcol[0]= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir);
/* not real 'alpha', but mirror overriding transparency */
if(mat->mode & MA_RAYTRANSP) {
float fac= sqrt(shi->refcol[0]);
- alpha= alpha*(1.0-fac) + fac;
+ shr->alpha= shr->alpha*(1.0f-fac) + fac;
}
- else alpha= alpha*(1.0-shi->refcol[0]) + shi->refcol[0];
+ else shr->alpha= shr->alpha*(1.0f-shi->refcol[0]) + shi->refcol[0];
- if(div<0.0) {
+ if(div<0.0f) {
/* minus 0.5 prevents too many small tiles in distance */
- fac= (int)(shi->ref[0]/(div-0.1) ) + (int)(shi->ref[2]/(div-0.1) );
- if(fac & 1) col= 0.8;
- else col= 0.3;
-
+ fac= (int)(shi->ref[0]/(div-0.1f) ) + (int)(shi->ref[2]/(div-0.1f) );
+ if(fac & 1) col= 0.8f;
+ else col= 0.3f;
+
shi->refcol[1]= shi->refcol[0]*col;
shi->refcol[2]= shi->refcol[1];
shi->refcol[3]= shi->refcol[2];
}
else {
- shi->refcol[1]= 0.0;
- shi->refcol[2]= shi->refcol[0]*0.3*div;
- shi->refcol[3]= shi->refcol[0]*0.8*div;
+ shi->refcol[1]= 0.0f;
+ shi->refcol[2]= shi->refcol[0]*0.3f*div;
+ shi->refcol[3]= shi->refcol[0]*0.8f*div;
}
}
- if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(diff, shi);
- if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, shi);
+ shr->diff[0]+= shi->ambr;
+ shr->diff[1]+= shi->ambg;
+ shr->diff[2]+= shi->ambb;
+
+ if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi);
+ if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi);
- if(shi->refcol[0]==0.0) {
- a= 255.0*(diff[0] +shi->ambr +isr);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[0]= a;
- a= 255.0*(diff[1] +shi->ambg +isg);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[1]= a;
- a= 255*(diff[2] +shi->ambb +isb);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[2]= a;
+ /* refcol */
+ if(shi->refcol[0]!=0.0f) {
+ shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->diff[0];
+ shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->diff[1];
+ shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->diff[2];
}
- else {
- a= 255.0*( shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*(diff[0] +shi->ambr) +isr);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[0]= a;
- a= 255.0*( shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*(diff[1] +shi->ambg) +isg);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[1]= a;
- a= 255.0*( shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*(diff[2] +shi->ambb) +isb);
- if(a>255) a=255; else if(a<0) a= 0;
- rect[2]= a;
+
+ /* ztra shade */
+ if(shi->spectra!=0.0f) {
+ inp = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
+ inp *= shi->spectra;
+ if(inp>1.0f) inp= 1.0f;
+ shr->alpha= (1.0f-inp)*shr->alpha+inp;
}
+ }
+}
+
+static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y, char *rect, int smooth)
+{
+ Material *mat;
+ MaterialLayer *ml;
+ ShadeResult shr;
+ float v1, inp;
+ float eul[3], tmat[3][3], imat[3][3], col[3];
+ char tracol;
+
+ mat= shi->mat;
+
+ v1= 1.0/PR_RECTX;
+ shi->view[0]= v1*x;
+ shi->view[1]= v1*y;
+ shi->view[2]= 1.0f;
+ Normalise(shi->view);
+
+ shi->xs= (float)x;
+ shi->ys= (float)y;
+
+ shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f;
+ VECCOPY(shi->co, vec);
+
+ /* texture handling */
+ if(mat->texco) {
+
+ VECCOPY(shi->lo, vec);
+
+ if(mat->pr_type==MA_CUBE) {
+
+ eul[0]= (297)*M_PI/180.0;
+ eul[1]= 0.0;
+ eul[2]= (45)*M_PI/180.0;
+ EulToMat3(eul, tmat);
+
+ MTC_Mat3MulVecfl(tmat, shi->lo);
+ MTC_Mat3MulVecfl(tmat, shi->vn);
+ /* hack for cubemap, why!!! */
+ SWAP(float, shi->vn[0], shi->vn[1]);
+ }
+ /* textures otherwise upside down */
+ if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE)
+ shi->lo[2]= -shi->lo[2];
+
+ if(mat->texco & TEXCO_GLOB) {
+ VECCOPY(shi->gl, shi->lo);
+ }
+ if(mat->texco & TEXCO_WINDOW) {
+ VECCOPY(shi->winco, shi->lo);
+ }
+ if(mat->texco & TEXCO_STICKY) {
+ VECCOPY(shi->sticky, shi->lo);
+ }
+ if(mat->texco & TEXCO_UV) {
+ VECCOPY(shi->uv, shi->lo);
+ }
+ if(mat->texco & TEXCO_STRAND) {
+ shi->strand= shi->lo[0];
+ }
+ if(mat->texco & TEXCO_OBJECT) {
+ /* nothing */
+ }
+ if(mat->texco & (TEXCO_NORM)) {
+ shi->orn[0]= shi->vn[0];
+ shi->orn[1]= shi->vn[1];
+ shi->orn[2]= shi->vn[2];
+ }
+ if(mat->texco & TEXCO_REFL) {
+
+ inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]);
+ shi->ref[0]= (shi->view[0]+inp*shi->vn[0]);
+ shi->ref[1]= (shi->view[1]+inp*shi->vn[1]);
+ shi->ref[2]= (shi->view[2]+inp*shi->vn[2]);
+ }
+
+ /* Clear displase vec for preview */
+ shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0;
+
+ if(mat->texco & TEXCO_REFL) {
+ /* normals in render are pointing different... rhm */
+ if(smooth) shi->ref[1]= -shi->ref[1];
+ }
+
+ if(mat->pr_type==MA_CUBE) {
+ /* rotate normal back for normals texture */
+ SWAP(float, shi->vn[0], shi->vn[1]);
+ MTC_Mat3Inv(imat, tmat);
+ MTC_Mat3MulVecfl(imat, shi->vn);
+ }
+
}
- /* ztra shade */
- if(shi->spectra!=0.0) {
- inp = MAX3(isr, isg, isb);
- inp *= shi->spectra;
- if(inp>1.0) inp= 1.0;
- alpha= (1.0-inp)*alpha+inp;
+ if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */
+// shi->vn[0]-=2.0*shi->displace[2];
+// shi->vn[1]-=2.0*shi->displace[0];
+// shi->vn[2]+=2.0*shi->displace[1];
+// Normalise(shi->vn);
+ }
+
+ /* ------ main shading loop with material layers */
+ VECCOPY(shi->vno, shi->vn);
+ if(mat->ml_flag & ML_RENDER)
+ shade_lamp_loop_preview(shi, &shr, mat->pr_lamp);
+ else {
+ memset(&shr, 0, sizeof(ShadeResult));
+ shr.alpha= 1.0f;
}
- if(alpha!=1.0) {
+ for(ml= mat->layers.first; ml; ml= ml->next) {
+ if(ml->mat && (ml->flag & ML_RENDER)) {
+ ShadeResult shrlay;
+
+ shi->mat= ml->mat;
+ shi->layerfac= ml->blendfac;
+ VECCOPY(shi->vn, shi->vno);
+ if(ml->flag & ML_NEG_NORMAL)
+ VecMulf(shi->vn, -1.0);
+
+ shade_lamp_loop_preview(shi, &shrlay, mat->pr_lamp);
+ matlayer_blend(ml, shi->layerfac, &shr, &shrlay);
+ }
+ }
+
+ shi->mat= mat; /* restore, shade input is re-used! */
+
+ /* after shading and composit layers */
+ if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f;
+ if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f;
+ if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f;
+
+ if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f;
+ if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f;
+ if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f;
+
+ VECADD(col, shr.diff, shr.spec);
+ if(col[0]<=0.0f) rect[0]= 0; else if(col[0]>=1.0f) rect[0]= 255; else rect[0]= (char)(255.0*col[0]);
+ if(col[1]<=0.0f) rect[1]= 0; else if(col[1]>=1.0f) rect[1]= 255; else rect[1]= (char)(255.0*col[1]);
+ if(col[2]<=0.0f) rect[2]= 0; else if(col[2]>=1.0f) rect[2]= 255; else rect[2]= (char)(255.0*col[2]);
+
+ if(shr.alpha!=1.0f) {
if(mat->mode & MA_RAYTRANSP) {
refraction_prv(&x, &y, shi->vn, shi->ang);
}
tracol= previewback(mat->pr_back, x, y) & 255;
- tracol= (1.0-alpha)*tracol;
+ tracol= (1.0f-shr.alpha)*tracol;
if((mat->mode & MA_RAYTRANSP) && mat->filter!=0.0) {
- float fr= 1.0+ mat->filter*(shi->r-1.0);
- rect[0]= fr*tracol+ (rect[0]*alpha) ;
- fr= 1.0+ mat->filter*(shi->g-1.0);
- rect[1]= fr*tracol+ (rect[1]*alpha) ;
- fr= 1.0+ mat->filter*(shi->b-1.0);
- rect[2]= fr*tracol+ (rect[2]*alpha) ;
+ float fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f);
+ rect[0]= fr*tracol+ (rect[0]*shr.alpha) ;
+ fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f);
+ rect[1]= fr*tracol+ (rect[1]*shr.alpha) ;
+ fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f);
+ rect[2]= fr*tracol+ (rect[2]*shr.alpha) ;
}
else {
- rect[0]= tracol+ (rect[0]*alpha) ;
- rect[1]= tracol+ (rect[1]*alpha) ;
- rect[2]= tracol+ (rect[2]*alpha) ;
+ rect[0]= tracol+ (rect[0]*shr.alpha) ;
+ rect[1]= tracol+ (rect[1]*shr.alpha) ;
+ rect[2]= tracol+ (rect[2]*shr.alpha) ;
}
}
}
+static void preview_init_render_textures(MTex **mtex)
+{
+ int x;
+
+ for(x=0; x<MAX_MTEX; x++) {
+ if(mtex[x]) {
+ if(mtex[x]->tex) {
+ init_render_texture(mtex[x]->tex);
+
+ if(mtex[x]->tex->env && mtex[x]->tex->env->object)
+ MTC_Mat4One(mtex[x]->tex->env->object->imat);
+
+ }
+ if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat);
+ if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat);
+ }
+ }
+
+}
void BIF_previewrender(SpaceButs *sbuts)
{
@@ -1100,27 +1147,23 @@ void BIF_previewrender(SpaceButs *sbuts)
shi.osatex= 0;
if(mat) {
+ MaterialLayer *ml;
+
/* rendervars */
init_render_world();
init_render_material(mat);
+ /* also clears imats */
+ preview_init_render_textures(mat->mtex);
- /* clear imats, flip normal... (hack because everything is inverted here) */
- for(x=0; x<MAX_MTEX; x++) {
- if(mat->mtex[x]) {
- if(mat->mtex[x]->tex) {
- init_render_texture(mat->mtex[x]->tex);
-
- if(mat->mtex[x]->tex->env && mat->mtex[x]->tex->env->object)
- MTC_Mat4One(mat->mtex[x]->tex->env->object->imat);
-
- mat->mtex[x]->maptoneg ^= MAP_NORM;
- }
- if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat);
- if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat);
+ for(ml= mat->layers.first; ml; ml= ml->next) {
+ if(ml->mat && (ml->flag & ML_RENDER)) {
+ init_render_material(ml->mat);
+ preview_init_render_textures(ml->mat->mtex);
+ mat->texco |= ml->mat->texco;
}
}
- shi.vlr= 0;
+ shi.vlr= NULL;
shi.mat= mat;
if(mat->mode & MA_HALO) init_previewhalo(&har, mat);
@@ -1141,15 +1184,15 @@ void BIF_previewrender(SpaceButs *sbuts)
else if(la) {
init_render_world();
- init_render_textures(); /* do not do it twice!! (brightness) */
+ preview_init_render_textures(la->mtex);
R.totlamp= 0;
RE_add_render_lamp(ob, 0); /* 0=no shadbuf or tables */
lar= R.la[0];
/* exceptions: */
- lar->spottexfac= 1.0;
- lar->spotsi= cos( M_PI/3.0 );
- lar->spotbl= (1.0-lar->spotsi)*la->spotblend;
+ lar->spottexfac= 1.0f;
+ lar->spotsi= cos( M_PI/3.0f );
+ lar->spotbl= (1.0f-lar->spotsi)*la->spotblend;
MTC_Mat3One(lar->imat);
}
@@ -1165,7 +1208,7 @@ void BIF_previewrender(SpaceButs *sbuts)
MTC_Mat4Invert(R.viewmat, R.viewinv);
}
init_render_world();
- init_render_textures(); /* dont do it twice!! (brightness) */
+ preview_init_render_textures(wrld->mtex);
}
uiPanelPush(block); // sets UImat
@@ -1258,12 +1301,12 @@ void BIF_previewrender(SpaceButs *sbuts)
}
}
else {
- vec[0]= x*(2.0/PR_RECTX);
- vec[1]= y*(2.0/PR_RECTX);
+ vec[0]= x*(2.0f/PR_RECTX);
+ vec[1]= y*(2.0f/PR_RECTX);
vec[2]= 0.0;
- shi.vn[0]= shi.vn[1]= 0.0;
- shi.vn[2]= 1.0;
+ shi.vn[0]= shi.vn[1]= 0.0f;
+ shi.vn[2]= 1.0f;
shade_preview_pixel(&shi, vec, x, y, (char *)rect, 0);
}
@@ -1317,27 +1360,11 @@ void BIF_previewrender(SpaceButs *sbuts)
uiPanelPop(block);
- if(mat) {
- end_render_material(mat);
- for(x=0; x<MAX_MTEX; x++) {
- if(mat->mtex[x] && mat->mtex[x]->tex) {
- end_render_texture(mat->mtex[x]->tex);
- mat->mtex[x]->maptoneg ^= MAP_NORM;
- }
- }
- }
- else if(tex) {
- end_render_texture(tex);
- }
- else if(la) {
+ if(la) {
if(R.totlamp) {
MEM_freeN(R.la[0]);
}
R.totlamp= 0;
- end_render_textures();
- }
- else if(wrld) {
- end_render_textures();
}
}