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/src/previewrender.c')
-rw-r--r--source/blender/src/previewrender.c1074
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();
+ }
+}
+