diff options
Diffstat (limited to 'source/blender/src/previewrender.c')
-rw-r--r-- | source/blender/src/previewrender.c | 1074 |
1 files changed, 1074 insertions, 0 deletions
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c new file mode 100644 index 00000000000..1180248c16e --- /dev/null +++ b/source/blender/src/previewrender.c @@ -0,0 +1,1074 @@ +/* previewrender.c GRAPHICS + * + * maart 95 + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* global includes */ + +#include <stdlib.h> +#include <math.h> + +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif +#include "MEM_guardedalloc.h" +#include "BLI_arithb.h" +#include "BKE_utildefines.h" + +#include "MTC_matrixops.h" + +#include "render.h" +#include "mydevice.h" + +#include "DNA_texture_types.h" +#include "DNA_world_types.h" +#include "DNA_camera_types.h" +#include "DNA_image_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_texture.h" +#include "BKE_material.h" +#include "BKE_world.h" +#include "BKE_texture.h" + +#include "BIF_gl.h" +#include "BIF_screen.h" +#include "BIF_space.h" /* allqueue */ +#include "BIF_drawimage.h" /* rectwrite_part */ +//#include "BIF_previewrender.h" +#include "BIF_mywindow.h" + +#include "RE_renderconverter.h" + +//#include "mydevice.h" + +#define PR_RECTX 101 +#define PR_RECTY 101 +#define PR_XMIN 10 +#define PR_YMIN 10 +#define PR_XMAX 190 +#define PR_YMAX 190 + +#define PR_FACY (PR_YMAX-PR_YMIN-4)/(PR_RECTY) + +static rcti prerect; +static int pr_sizex, pr_sizey; +static float pr_facx, pr_facy; + + +/* implementation */ + +static short snijpunt(float *v1, + float *v2, + float *v3, + float *rtlabda, + float *ray1, + float *ray2) +{ + float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; + float m0,m1,m2,deeldet,det1,det2,det3; + float rtu, rtv; + + t00= v3[0]-v1[0]; + t01= v3[1]-v1[1]; + t02= v3[2]-v1[2]; + t10= v3[0]-v2[0]; + t11= v3[1]-v2[1]; + t12= v3[2]-v2[2]; + t20= ray1[0]-ray2[0]; + t21= ray1[1]-ray2[1]; + t22= ray1[2]-ray2[2]; + + x0= t11*t22-t12*t21; + x1= t12*t20-t10*t22; + x2= t10*t21-t11*t20; + + deeldet= t00*x0+t01*x1+t02*x2; + if(deeldet!=0.0) { + 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) { + 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) { + + 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) { + return 1; + } + } + } + } + } + return 0; +} + +static float rcubev[7][3]= { + {-0.002055, 6.627364, -3.369742}, + {-6.031684, -3.750204, -1.992980}, + {-6.049086, 3.817431, 1.969788}, + { 6.031685, 3.833064, 1.992979}, + { 6.049086, -3.734571, -1.969787}, + { 0.002054, -6.544502, 3.369744}, + {-0.015348, 1.023131, 7.332510} }; + +static int rcubi[3][4]= { + {3, 6, 5, 4}, + {1, 5, 6, 2}, + {3, 0, 2, 6} }; + + +static int ray_previewrender(int x, + int y, + float *vec) +{ + float scalef= 12.8/100.0; + float ray1[3], ray2[3]; + float minlabda, labda; + int totface= 3, hitface= -1; + int a; + + ray1[0]= ray2[0]= x*scalef; + ray1[1]= ray2[1]= y*scalef; + ray1[2]= -10.0; + ray2[2]= 10.0; + + minlabda= 1.0; + 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) { + minlabda= labda; + hitface= a; + } + } + if(snijpunt( rcubev[rcubi[a][0]], rcubev[rcubi[a][2]], rcubev[rcubi[a][3]], &labda, ray1, ray2)) { + if( labda < minlabda) { + minlabda= labda; + hitface= a; + } + } + } + + if(hitface > -1) { + + CalcNormFloat(rcubev[rcubi[hitface][0]], rcubev[rcubi[hitface][1]], rcubev[rcubi[hitface][2]], R.vn); + + vec[0]= (minlabda*(ray1[0]-ray2[0])+ray2[0])/3.7; + vec[1]= (minlabda*(ray1[1]-ray2[1])+ray2[1])/3.7; + vec[2]= (minlabda*(ray1[2]-ray2[2])+ray2[2])/3.7; + + return 1; + } + return 0; +} + + +static unsigned int previewback(int type, int x, int y) +{ + if(type & MA_DARK) { + if(abs(x)>abs(y)) return 0; + else return 0x40404040; + } + else { + if(abs(x)>abs(y)) return 0x40404040; + else return 0xa0a0a0a0; + } +} + +static void view2d_to_window(int win, int *x_r, int *y_r) +{ + int x= *x_r, y= *y_r; + int size[2], origin[2]; + float winmat[4][4]; + + bwin_getsinglematrix(win, winmat); + bwin_getsize(win, &size[0], &size[1]); + bwin_getsuborigin(win, &origin[0], &origin[1]); + + *x_r= origin[0] + (size[0]*(0.5 + 0.5*(x*winmat[0][0] + y*winmat[1][0] + winmat[3][0]))); + *y_r= origin[1] + (size[1]*(0.5 + 0.5*(x*winmat[0][1] + y*winmat[1][1] + winmat[3][1]))); +} + +static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax) +{ + prerect.xmin= xmin; + prerect.ymin= ymin; + prerect.xmax= xmax; + prerect.ymax= ymax; + + view2d_to_window(win, &prerect.xmin, &prerect.ymin); + view2d_to_window(win, &prerect.xmax, &prerect.ymax); + + pr_sizex= (prerect.xmax-prerect.xmin); + pr_sizey= (prerect.ymax-prerect.ymin); + + pr_facx= ( (float)pr_sizex-1)/PR_RECTX; + pr_facy= ( (float)pr_sizey-1)/PR_RECTY; +} + +static void display_pr_scanline(unsigned int *rect, int recty) +{ + /* we display 3 new scanlines, one old */ + + if(recty % 2) return; + if(recty<2) return; + + rect+= (recty-2)*PR_RECTX; + + /* iets meer uitvergroten in y om GL/mesa bugje te verhelpen */ + glPixelZoom(pr_facx, pr_facy); + + glRasterPos2f( (float)PR_XMIN+0.5, 1.0+(float)PR_YMIN + (recty*PR_FACY) ); + glDrawPixels(PR_RECTX, 3, GL_RGBA, GL_UNSIGNED_BYTE, rect); + + glPixelZoom(1.0, 1.0); +} + +static void draw_tex_crop(Tex *tex) +{ + rcti rct; + int ret= 0; + + 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(ret==4) return; + + rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4); + rct.xmax= PR_XMIN+2+tex->cropxmax*(PR_XMAX-PR_XMIN-4); + rct.ymin= PR_YMIN+2+tex->cropymin*(PR_YMAX-PR_YMIN-4); + rct.ymax= PR_YMIN+2+tex->cropymax*(PR_YMAX-PR_YMIN-4); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor3ub(0, 0, 0); + glRecti(rct.xmin+1, rct.ymin-1, rct.xmax+1, rct.ymax-1); + + glColor3ub(255, 255, 255); + glRecti(rct.xmin, rct.ymin, rct.xmax, rct.ymax); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + +} + +void BIF_preview_changed(SpaceButs *sbuts) +{ + sbuts->cury= 0; + addafterqueue(sbuts->area->win, RENDERPREVIEW, 1); +} + +void BIF_previewdraw(SpaceButs *sbuts) +{ + set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); + + if (sbuts->rect==0 || sbuts->cury==0) { + BIF_preview_changed(sbuts); + } else { + int y; + + for (y=0; y<PR_RECTY; y++) { + display_pr_scanline(sbuts->rect, y); + } + + if (sbuts->mainb==BUTS_TEX) { + draw_tex_crop(sbuts->lockpoin); + } + } +} + +static void sky_preview_pixel(float lens, int x, int y, char *rect) +{ + + if(R.wrld.skytype & WO_SKYPAPER) { + R.view[0]= (2*x)/(float)PR_RECTX; + R.view[1]= (2*y)/(float)PR_RECTY; + R.view[2]= 0.0; + } + else { + R.view[0]= x; + R.view[1]= y; + R.view[2]= -lens*PR_RECTX/32.0; + Normalise(R.view); + } + RE_sky(rect); +} + +static void lamp_preview_pixel(LampRen *la, int x, int y, char *rect) +{ + float inpr, i, t, dist, distkw, vec[3]; + int col; + + R.co[0]= (float)x/(PR_RECTX/4); + R.co[1]= (float)y/(PR_RECTX/4); + R.co[2]= 0; + + vec[0]= 0.02*x; + vec[1]= 0.02*y; + vec[2]= 0.005*PR_RECTX; + VECCOPY(R.view, vec); + dist= Normalise(R.view); + + if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec); + + if(la->type==LA_SUN || la->type==LA_HEMI) { + dist= 1.0; + } + else { + + if(la->mode & LA_QUAD) { + + t= 1.0; + if(la->ld1>0.0) + t= la->dist/(la->dist+la->ld1*dist); + if(la->ld2>0.0) { + distkw= la->dist*la->dist; + t= t*distkw/(t*distkw+la->ld2*dist*dist); + } + dist= t; + } + else { + dist= (la->dist/(la->dist+dist)); + } + } + + if(la->type==LA_SPOT) { + + + if(la->mode & LA_SQUARE) { + /* slightly smaller... */ + inpr= 1.7*cos(MAX2(fabs(R.view[0]/R.view[2]) , fabs(R.view[1]/R.view[2]) )); + } + else { + inpr= R.view[2]; + } + + t= la->spotsi; + if(inpr<t) dist= 0.0; + else { + t= inpr-t; + if(t<la->spotbl && la->spotbl!=0.0) { + /* zachte gebied */ + i= t/la->spotbl; + t= i*i; + i= t*i; + inpr*=(3.0*t-2.0*i); + } + } + dist*=inpr; + } + else if(la->type==LA_LOCAL) dist*= R.view[2]; + + col= 255.0*dist*la->r; + if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col; + + col= 255.0*dist*la->g; + if(col<=0) rect[1]= 0; else if(col>=255) rect[1]= 255; else rect[1]= col; + + col= 255.0*dist*la->b; + if(col<=0) rect[2]= 0; else if(col>=255) rect[2]= 255; else rect[2]= col; +} + +static void init_previewhalo(HaloRen *har, Material *mat) +{ + + har->type= 0; + if(mat->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; + har->mat= mat; + har->hard= mat->har; + har->rad= PR_RECTX/2.0; + har->radsq= PR_RECTX*PR_RECTX/4.0; + har->alfa= mat->alpha; + har->add= 255.0*mat->add; + har->r= 255.0*mat->r; + har->g= 255.0*mat->g; + har->b= 255.0*mat->b; + har->xs= PR_RECTX/2.0; + har->ys= PR_RECTX/2.0; + har->zs= har->zd= 0; + har->seed= (mat->seed1 % 256); + + if( (mat->mode & MA_HALOTEX) && mat->mtex[0] ) har->tex= 1; else har->tex=0; + + if(mat->mode & MA_STAR) har->starpoints= mat->starc; else har->starpoints= 0; + if(mat->mode & MA_HALO_LINES) har->linec= mat->linec; else har->linec= 0; + if(mat->mode & MA_HALO_RINGS) har->ringc= mat->ringc; else har->ringc= 0; + if(mat->mode & MA_HALO_FLARE) har->flarec= mat->flarec; else har->flarec= 0; + + if(har->flarec) { + har->xs-= PR_RECTX/3; + har->ys+= PR_RECTX/3; + + har->rad*= 0.3; + har->radsq= har->rad*har->rad; + + har->pixels= har->rad*har->rad*har->rad; + } +} + +static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char *rect) +{ + float dist, xn, yn, xsq, ysq; + int x; + char front[4]; + + if(har->flarec) yn= y-PR_RECTX/3; + else yn= y; + ysq= yn*yn; + + for(x=startx; x<endx; x++) { + + if(har->flarec) xn= x+PR_RECTX/3; + else xn= x; + + xsq= xn*xn; + dist= xsq+ysq; + + + + if(dist<har->radsq) { + RE_shadehalo(har, front, 0, dist, xn, yn, har->flarec); + RE_addalphaAddfac(rect, front, har->add); + } + rect+= 4; + } +} + +static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) +{ + float ycor; + unsigned int *rectot; + int afmx, afmy, rectx, recty; + + /* temps */ + ycor= R.ycor; + rectx= R.rectx; + recty= R.recty; + afmx= R.afmx; + afmy= R.afmy; + rectot= R.rectot; + + R.ycor= 1.0; + R.rectx= PR_RECTX; + R.recty= PR_RECTY; + R.afmx= PR_RECTX/2; + R.afmy= PR_RECTY/2; + R.rectot= rect; + + waitcursor(1); + + RE_renderflare(har); + + BIF_previewdraw(sbuts); + + waitcursor(0); + + /* temps */ + R.ycor= ycor; + R.rectx= rectx; + R.recty= recty; + R.afmx= afmx; + R.afmy= afmy; + R.rectot= rectot; +} + +extern float Tin, Tr, Tg, Tb, Ta; /* texture.c */ +static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) +{ + float i, v1, xsq, ysq, texvec[3]; + int rgbnor, tracol, skip=0; + + if(tex->type==TEX_IMAGE) { + v1= 1.0/PR_RECTX; + + texvec[0]= 0.5+v1*x; + texvec[1]= 0.5+v1*y; + + /* geen coordmapping, uitzondering: repeat */ + if(tex->xrepeat>1) { + texvec[0] *= tex->xrepeat; + if(texvec[0]>1.0) texvec[0] -= (int)(texvec[0]); + } + if(tex->yrepeat>1) { + texvec[1] *= tex->yrepeat; + if(texvec[1]>1.0) texvec[1] -= (int)(texvec[1]); + } + + } + else if(tex->type==TEX_ENVMAP) { + if(tex->env) { + ysq= y*y; + xsq= x*x; + if(xsq+ysq < (PR_RECTX/2)*(PR_RECTY/2)) { + texvec[2]= sqrt( (float)((PR_RECTX/2)*(PR_RECTY/2)-xsq-ysq) ); + texvec[0]= -x; + texvec[1]= -y; + Normalise(texvec); + + i= 2.0*(texvec[2]); + texvec[0]= (i*texvec[0]); + texvec[1]= (i*texvec[1]); + texvec[2]= (-1.0+i*texvec[2]); + + } + else { + skip= 1; + Ta= 0.0; + } + } + else { + skip= 1; + Ta= 0.0; + } + } + else { + v1= 2.0/PR_RECTX; + + texvec[0]= v1*x; + texvec[1]= v1*y; + texvec[2]= 0.0; + } + + /* geeft geen Tin terug */ + if(tex->type==TEX_STUCCI) { + tex->nor= R.vn; + R.vn[0]= 1.0; + R.vn[1]= R.vn[2]= 0.0; + } + + if(skip==0) rgbnor= multitex(tex, texvec, 0, 0); + else rgbnor= 1; + + if(rgbnor & 1) { + + rect[0]= 255.0*Tr; + rect[1]= 255.0*Tg; + rect[2]= 255.0*Tb; + + if(Ta!=1.0) { + tracol= 64+100*(abs(x)>abs(y)); + tracol= (1.0-Ta)*tracol; + + rect[0]= tracol+ (rect[0]*Ta) ; + rect[1]= tracol+ (rect[1]*Ta) ; + rect[2]= tracol+ (rect[2]*Ta) ; + + } + } + else { + + if(tex->type==TEX_STUCCI) { + Tin= 0.5 + 0.7*tex->nor[0]; + CLAMP(Tin, 0.0, 1.0); + } + rect[0]= 255.0*Tin; + rect[1]= 255.0*Tin; + rect[2]= 255.0*Tin; + } +} + +static float pr1_lamp[3]= {2.3, -2.4, -4.6}; +static float pr2_lamp[3]= {-8.8, -5.6, -1.5}; +static float pr1_col[3]= {0.8, 0.8, 0.8}; +static float pr2_col[3]= {0.5, 0.6, 0.7}; + +static void shade_preview_pixel(float *vec, + int x, + int y, + char *rect, + int smooth) +{ + Material *mat; + float v1,inp, inprspec=0, isr=0.0, isb=0.0, isg=0.0; + float ir=0.0, ib=0.0, ig=0.0; + float view[3], lv[3], *la, alpha; + float eul[3], tmat[3][3], imat[3][3]; + int temp, a; + char tracol; + + mat= R.matren; + /* pr1_lamp[0]= mat->mtex[0]->ofs[0]; */ + /* pr1_lamp[1]= mat->mtex[0]->ofs[1]; */ + /* pr1_lamp[2]= mat->mtex[0]->ofs[2]; */ + + /* pr2_lamp[0]= mat->mtex[0]->size[0]; */ + /* pr2_lamp[1]= mat->mtex[0]->size[1]; */ + /* pr2_lamp[2]= mat->mtex[0]->size[2]; */ + + v1= 1.0/PR_RECTX; + view[0]= v1*x; + view[1]= v1*y; + view[2]= 1.0; + Normalise(view); + + R.refcol[0]= R.refcol[1]= R.refcol[2]= R.refcol[3]= 0.0; + + /* texture afhandeling */ + if(mat->texco) { + + VECCOPY(R.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, R.lo); + MTC_Mat3MulVecfl(tmat, R.vn); + /* hack for cubemap, why!!! */ + SWAP(float, R.vn[0], R.vn[1]); + } + + if(mat->texco & TEXCO_GLOB) { + VECCOPY(R.gl, R.lo); + } + if(mat->texco & TEXCO_WINDOW) { + VECCOPY(R.winco, R.lo); + } + if(mat->texco & TEXCO_STICKY) { + VECCOPY(R.sticky, R.lo); + } + if(mat->texco & TEXCO_UV) { + VECCOPY(R.uv, R.lo); + } + if(mat->texco & TEXCO_OBJECT) { + VECCOPY(R.co, R.lo); + } + if(mat->texco & TEXCO_NORM) { + R.orn[0]= R.vn[0]; + R.orn[1]= -R.vn[1]; + R.orn[2]= R.vn[2]; + } + if(mat->texco & TEXCO_REFL) { + /* for bump texture */ + VECCOPY(R.view, view); + + inp= -2.0*(R.vn[0]*view[0]+R.vn[1]*view[1]+R.vn[2]*view[2]); + R.ref[0]= (view[0]+inp*R.vn[0]); + R.ref[1]= -(view[1]+inp*R.vn[1]); + R.ref[2]= (view[2]+inp*R.vn[2]); + } + + do_material_tex(); + + if(mat->pr_type==MA_CUBE) { + /* rotate normal back for normals texture */ + SWAP(float, R.vn[0], R.vn[1]); + MTC_Mat3Inv(imat, tmat); + MTC_Mat3MulVecfl(imat, R.vn); + } + + } + + if(mat->mode & MA_SHLESS) { + temp= 255.0*(mat->r); + if(temp>255) rect[0]= 255; else if(temp<0) rect[0]= 0; else rect[0]= temp; + + temp= 255.0*(mat->g); + if(temp>255) rect[1]= 255; else if(temp<0) rect[1]= 0; else rect[1]= temp; + + temp= 255.0*(mat->b); + if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp; + } + else { + + for(a=0; a<2; a++) { + + 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]; + Normalise(lv); + + inp= R.vn[0]*lv[0]+R.vn[1]*lv[1]+R.vn[2]*lv[2]; + if(inp<0.0) inp= 0.0; + + if(mat->spec) { + + lv[0]+= view[0]; + lv[1]+= view[1]; + lv[2]+= view[2]; + Normalise(lv); + + if(inp>0.0) { + v1= lv[0]*R.vn[0]+lv[1]*R.vn[1]+lv[2]*R.vn[2]; + if(v1>0.0) { + v1= RE_Spec(v1, mat->har); + inprspec= v1*mat->spec; + isr+= inprspec*mat->specr; + isg+= inprspec*mat->specg; + isb+= inprspec*mat->specb; + } + } + } + inp= (mat->ref*inp + mat->emit); + + if(a==0) la= pr1_col; + else la= pr2_col; + + ir+= inp*la[0]; + ig+= inp*la[1]; + ib+= inp*la[2]; + } + + if(R.refcol[0]==0.0) { + a= 255.0*( mat->r*ir +mat->ambr +isr); + if(a>255) a=255; else if(a<0) a= 0; + rect[0]= a; + a= 255.0*(mat->g*ig +mat->ambg +isg); + if(a>255) a=255; else if(a<0) a= 0; + rect[1]= a; + a= 255*(mat->b*ib +mat->ambb +isb); + if(a>255) a=255; else if(a<0) a= 0; + rect[2]= a; + } + else { + a= 255.0*( mat->mirr*R.refcol[1] + (1.0 - mat->mirr*R.refcol[0])*(mat->r*ir +mat->ambr) +isr); + if(a>255) a=255; else if(a<0) a= 0; + rect[0]= a; + a= 255.0*( mat->mirg*R.refcol[2] + (1.0 - mat->mirg*R.refcol[0])*(mat->g*ig +mat->ambg) +isg); + if(a>255) a=255; else if(a<0) a= 0; + rect[1]= a; + a= 255.0*( mat->mirb*R.refcol[3] + (1.0 - mat->mirb*R.refcol[0])*(mat->b*ib +mat->ambb) +isb); + if(a>255) a=255; else if(a<0) a= 0; + rect[2]= a; + } + } + + if(mat->alpha!=1.0) { + + alpha= mat->alpha; + + /* ztra shade */ + if(mat->spectra!=0.0) { + inp= mat->spectra*inprspec; + if(inp>1.0) inp= 1.0; + + alpha= (1.0-inp)*alpha+ inp; + } + + tracol= previewback(mat->pr_back, x, y) & 255; + + tracol= (1.0-alpha)*tracol; + + rect[0]= tracol+ (rect[0]*alpha) ; + rect[1]= tracol+ (rect[1]*alpha) ; + rect[2]= tracol+ (rect[2]*alpha) ; + + } +} + + +void BIF_previewrender(SpaceButs *sbuts) +{ + Material *mat=0; + Tex *tex = NULL; + Image *ima; + Lamp *la; + LampRen *lar = NULL; + HaloRen har; + Object *ob; + World *wrld; + float lens = 0.0, vec[3]; + int x, y, starty, startx, endy, endx, radsq, xsq, ysq, last = 0; + unsigned int *rect; + + if(sbuts->cury>=PR_RECTY) return; + + if ELEM4(sbuts->mainb, BUTS_MAT, BUTS_TEX, BUTS_LAMP, BUTS_WORLD); + else return; + + har.flarec= 0; /* verderop test op postrender flare */ + + if(qtest()) { + addafterqueue(curarea->win, RENDERPREVIEW, 1); + return; + } + + MTC_Mat4One(R.viewmat); + MTC_Mat4One(R.viewinv); + + R.osatex= 0; + if(sbuts->mainb==BUTS_MAT) { + mat= sbuts->lockpoin; + if(mat==0) return; + + /* rendervars */ + init_render_world(); + init_render_material(mat); + + /* clear imats */ + for(x=0; x<8; 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); + } + if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + } + } + R.vlr= 0; + R.mat= mat; + R.matren= mat->ren; + + if(mat->mode & MA_HALO) init_previewhalo(&har, mat); + } + else if(sbuts->mainb==BUTS_TEX) { + tex= sbuts->lockpoin; + if(tex==0) return; + ima= tex->ima; + if(ima) last= ima->lastframe; + init_render_texture(tex); + free_unused_animimages(); + if(tex->ima) { + if(tex->ima!=ima) allqueue(REDRAWBUTSTEX, 0); + else if(last!=ima->lastframe) allqueue(REDRAWBUTSTEX, 0); + } + if(tex->env && tex->env->object) + MTC_Mat4Invert(tex->env->object->imat, tex->env->object->obmat); + } + else if(sbuts->mainb==BUTS_LAMP) { + ob= ((G.scene->basact)? (G.scene->basact)->object: 0); + if(ob==0 || ob->type!=OB_LAMP) return; + la= ob->data; + init_render_world(); + init_render_textures(); /* ze mogen niet twee keer!! (brightness) */ + R.totlamp= 0; + RE_add_render_lamp(ob, 0); /* 0=no shadbuf */ + lar= R.la[0]; + + /* uitzonderingen: */ + lar->spottexfac= 1.0; + lar->spotsi= cos( M_PI/3.0 ); + lar->spotbl= (1.0-lar->spotsi)*la->spotblend; + + MTC_Mat3One(lar->imat); + } + else { + wrld= sbuts->lockpoin; + if(wrld==0) return; + + lens= 35.0; + if(G.scene->camera) { + lens= ( (Camera *)G.scene->camera->data)->lens; + } + + init_render_world(); + init_render_textures(); /* dont do it twice!! (brightness) */ + } + + set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); + + if(sbuts->rect==0) { + sbuts->rect= MEM_callocN(sizeof(int)*PR_RECTX*PR_RECTY, "butsrect"); + + /* built in emboss */ + rect= sbuts->rect; + for(y=0; y<PR_RECTY; y++, rect++) *rect= 0xFFFFFFFF; + + rect= sbuts->rect + PR_RECTX-1; + for(y=0; y<PR_RECTY; y++, rect+=PR_RECTX) *rect= 0xFFFFFFFF; + } + + starty= -PR_RECTY/2; + endy= starty+PR_RECTY; + starty+= sbuts->cury; + + /* offset +1 for emboss */ + startx= -PR_RECTX/2 +1; + endx= startx+PR_RECTX -2; + + radsq= (PR_RECTX/2)*(PR_RECTY/2); + + glDrawBuffer(GL_FRONT); + + if(mat) { + if(mat->pr_type==MA_SPHERE) { + pr1_lamp[0]= 2.3; pr1_lamp[1]= -2.4; pr1_lamp[2]= -4.6; + pr2_lamp[0]= -8.8; pr2_lamp[1]= -5.6; pr2_lamp[2]= -1.5; + } + else { + pr1_lamp[0]= 1.9; pr1_lamp[1]= 3.1; pr1_lamp[2]= -8.5; + pr2_lamp[0]= 1.2; pr2_lamp[1]= -18; pr2_lamp[2]= 3.2; + } + } + + for(y=starty; y<endy; y++) { + + rect= sbuts->rect + 1 + PR_RECTX*sbuts->cury; + + if(y== -PR_RECTY/2 || y==endy-1); /* emboss */ + else if(sbuts->mainb==BUTS_MAT) { + + if(mat->mode & MA_HALO) { + for(x=startx; x<endx; x++, rect++) { + rect[0]= previewback(mat->pr_back, x, y); + } + + if(har.flarec) { + if(y==endy-2) previewflare(sbuts, &har, sbuts->rect); + } + else { + halo_preview_pixel(&har, startx, endx, y, (char *) (rect-PR_RECTX)); + } + } + else { + ysq= y*y; + for(x=startx; x<endx; x++, rect++) { + xsq= x*x; + if(mat->pr_type==MA_SPHERE) { + + if(xsq+ysq < radsq) { + R.vn[0]= x; + R.vn[1]= y; + R.vn[2]= sqrt( (float)(radsq-xsq-ysq) ); + Normalise(R.vn); + + vec[0]= R.vn[0]; + vec[1]= R.vn[2]; + vec[2]= -R.vn[1]; + + shade_preview_pixel(vec, x, y, (char *)rect, 1); + } + else { + rect[0]= previewback(mat->pr_back, x, y); + } + } + else if(mat->pr_type==MA_CUBE) { + if( ray_previewrender(x, y, vec) ) { + + shade_preview_pixel(vec, x, y, (char *)rect, 0); + } + else { + rect[0]= previewback(mat->pr_back, x, y); + } + } + else { + vec[0]= x*(2.0/PR_RECTX); + vec[1]= y*(2.0/PR_RECTX); + vec[2]= 0.0; + + R.vn[0]= R.vn[1]= 0.0; + R.vn[2]= 1.0; + + shade_preview_pixel(vec, x, y, (char *)rect, 0); + } + } + } + } + else if(sbuts->mainb==BUTS_TEX) { + for(x=startx; x<endx; x++, rect++) { + texture_preview_pixel(tex, x, y, (char *)rect); + } + } + else if(sbuts->mainb==BUTS_LAMP) { + for(x=startx; x<endx; x++, rect++) { + lamp_preview_pixel(lar, x, y, (char *)rect); + } + } + else { + for(x=startx; x<endx; x++, rect++) { + sky_preview_pixel(lens, x, y, (char *)rect); + } + } + + if(y<endy-2) { + + if(qtest()) { + addafterqueue(curarea->win, RENDERPREVIEW, 1); + break; + } + } + + display_pr_scanline(sbuts->rect, sbuts->cury); + + sbuts->cury++; + } + + if(sbuts->cury>=PR_RECTY && sbuts->mainb==BUTS_TEX) + draw_tex_crop(sbuts->lockpoin); + + glDrawBuffer(GL_BACK); + BIF_previewdraw(sbuts); + + if(sbuts->mainb==BUTS_MAT) { + end_render_material(mat); + for(x=0; x<8; x++) { + if(mat->mtex[x] && mat->mtex[x]->tex) end_render_texture(mat->mtex[x]->tex); + } + } + else if(sbuts->mainb==BUTS_TEX) { + end_render_texture(tex); + } + else if(sbuts->mainb==BUTS_WORLD) { + end_render_textures(); + } + else if(sbuts->mainb==BUTS_LAMP) { + if(R.totlamp) { + if(R.la[0]->org) MEM_freeN(R.la[0]->org); + MEM_freeN(R.la[0]); + } + R.totlamp= 0; + end_render_textures(); + } +} + |