diff options
Diffstat (limited to 'source/blender')
114 files changed, 5055 insertions, 6614 deletions
diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 8a875916a26..709e9f87cbb 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -133,12 +133,8 @@ void RE_free_envmap(struct EnvMap *env); struct EnvMap *RE_copy_envmap(struct EnvMap *env); void RE_free_envmapdata(struct EnvMap *env); int RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt); -void RE_calc_R_ref(void); extern char texstr[20][12]; /* buttons.c */ -/* memory for O is declared in the render module... */ -#include "BKE_osa_types.h" -extern Osa O; /* editsca.c */ void make_unique_prop_names(char *str); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index d0a9c1e5c6a..7b76a438e59 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -42,6 +42,9 @@ struct ListBase; struct BezTriple; struct BevList; +#define KNOTSU(nu) ( (nu)->orderu+ (nu)->pntsu+ (nu->orderu-1)*((nu)->flagu & 1) ) +#define KNOTSV(nu) ( (nu)->orderv+ (nu)->pntsv+ (nu->orderv-1)*((nu)->flagv & 1) ) + int copyintoExtendedArray(float *old, int oldx, int oldy, float *newp, int newx, int newy); void unlink_curve( struct Curve *cu); diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 34cb2c64ec6..95883501f55 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -53,6 +53,30 @@ #define DL_FRONT_CURVE 4 #define DL_BACK_CURVE 8 +/* This should, of course, become a function */ +#define DL_SURFINDEX(cyclu, cyclv, sizeu, sizev) \ +\ +if( (cyclv)==0 && a==(sizev)-1) break; \ +if(cyclu) { \ + p1= sizeu*a; \ + p2= p1+ sizeu-1; \ + p3= p1+ sizeu; \ + p4= p2+ sizeu; \ + b= 0; \ +} \ +else { \ + p2= sizeu*a; \ + p1= p2+1; \ + p4= p2+ sizeu; \ + p3= p1+ sizeu; \ + b= 1; \ +} \ +if( (cyclv) && a==sizev-1) { \ + p3-= sizeu*sizev; \ + p4-= sizeu*sizev; \ +} + + /* prototypes */ struct Object; diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 0196d8bc391..cf642932447 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -93,6 +93,8 @@ typedef struct Global { short machine, afbreek, moving, colact, zbuf; short qual, background, imagewin, animspeed; + short winpos, displaymode; /* used to be in Render */ + /** * The current version of Blender. */ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index fd278aa5329..2da0dcb5f5a 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -47,18 +47,12 @@ void free_image(struct Image *me); void free_image_buffers(struct Image *ima); struct Image *add_image(char *name); void free_unused_animimages(void); + void makepicstring(char *string, int frame); struct anim *openanim(char * name, int flags); -int calcimanr(int cfra, struct Tex *tex); -void do_laseroptics_patch(struct ImBuf *ibuf); -void de_interlace_ng(struct ImBuf *ibuf); -void de_interlace_st(struct ImBuf *ibuf); -void load_image(struct Image * ima, int flags, char *relabase, int framenum); void ima_ibuf_is_nul(struct Tex *tex); -int imagewrap(struct Tex *tex, float *texvec); -int imagewraposa(struct Tex *tex, float *texvec, float *dxt, float *dyt); +void load_image(struct Image * ima, int flags, char *relabase, int framenum); void converttopremul(struct ImBuf *ibuf); -void makemipmap(struct Image *ima); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_osa_types.h b/source/blender/blenkernel/BKE_osa_types.h deleted file mode 100644 index 28d4147c11b..00000000000 --- a/source/blender/blenkernel/BKE_osa_types.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * blenlib/BKE_osa_types.h (mar-2001 nzc) - * - * $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 ***** - */ -#ifndef BKE_OSA_TYPES_H -#define BKE_OSA_TYPES_H - -/* typedef struct Osa */ -typedef struct RE_Osa -{ - float dxco[3], dyco[3]; - float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3]; - float dxref[3], dyref[3], dxorn[3], dyorn[3]; - float dxno[3], dyno[3], dxview, dyview; - float dxlv[3], dylv[3]; - float dxwin[3], dywin[3]; - float dxsticky[3], dysticky[3]; - float dxrefract[3], dyrefract[3]; -} Osa; - -/* extern Osa O; */ -/* This one used to be done in render/extern/include/render.h, because - memory was allocated in that module. (nzc)*/ - -#endif - diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h index bb605ba55a0..270a0492f91 100644 --- a/source/blender/blenkernel/BKE_packedFile.h +++ b/source/blender/blenkernel/BKE_packedFile.h @@ -34,6 +34,9 @@ #ifndef BKE_PACKEDFILE_H #define BKE_PACKEDFILE_H +#define RET_OK 0 +#define RET_ERROR 1 + struct PackedFile; struct VFont; struct bSample; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 9d1a23952ad..538912a1f40 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -40,6 +40,21 @@ struct Base; struct AviCodecData; struct QuicktimeCodecData; +/* sequence related defines */ +#define WHILE_SEQ(base) { \ + int totseq_, seq_; Sequence **seqar; \ + build_seqar( base, &seqar, &totseq_); \ + for(seq_ = 0; seq_ < totseq_; seq_++) { \ + seq= seqar[seq_]; + + +#define END_SEQ } \ + if(seqar) MEM_freeN(seqar); \ +} + + + + void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); void free_scene(struct Scene *me); diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index c32e767ab92..b1f084fd566 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -44,6 +44,12 @@ #define TRUE 1 #endif +/* also fill in structs itself, dna cannot handle defines, duplicate in blendef.h still */ +#ifndef FILE_MAXDIR +#define FILE_MAXDIR 160 +#define FILE_MAXFILE 80 +#endif + #define ELEM(a, b, c) ( (a)==(b) || (a)==(c) ) #define ELEM3(a, b, c, d) ( ELEM(a, b, c) || (a)==(d) ) #define ELEM4(a, b, c, d, e) ( ELEM(a, b, c) || ELEM(a, d, e) ) @@ -67,18 +73,6 @@ #define MAX3(x,y,z) MAX2( MAX2((x),(y)) , (z) ) #define MAX4(x,y,z,a) MAX2( MAX2((x),(y)) , MAX2((z),(a)) ) -#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } - -#define ABS(a) ( (a)<0 ? (-(a)) : (a) ) - -#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} -#define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} - -#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} -#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} - -#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) - #define INIT_MINMAX(min, max) (min)[0]= (min)[1]= (min)[2]= 1.0e30; (max)[0]= (max)[1]= (max)[2]= -1.0e30; #define INIT_MINMAX2(min, max) (min)[0]= (min)[1]= 1.0e30; (max)[0]= (max)[1]= -1.0e30; @@ -95,17 +89,32 @@ if( (max)[0]<(vec)[0] ) (max)[0]= (vec)[0]; \ if( (max)[1]<(vec)[1] ) (max)[1]= (vec)[1]; -/* interferes elsewhere */ -/* also fill in structs itself, dna cannot handle defines */ -#define FILE_MAXDIR 160 -#define FILE_MAXFILE 80 +#define MINSIZE(val, size) ( ((val)>=0.0) ? (((val)<(size)) ? (size): (val)) : ( ((val)>(-size)) ? (-size) : (val))) + +/* some math and copy defines */ + +#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } + +#define ABS(a) ( (a)<0 ? (-(a)) : (a) ) + +#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} +#define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} +#define LONGCOPY(a, b, c) {int lcpc=c, *lcpa=(int *)a, *lcpb=(int *)b; while(lcpc-->0) *(lcpa++)= *(lcpb++);} + + +#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} +#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} + +#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) /* some misc stuff.... */ #define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c) +#define CLAMPIS(a, b, c) ((a)<(b) ? (b) : (a)>(c) ? (c) : (a)) +#define CLAMPTEST(a, b, c) if((b)<(c)) {CLAMP(a, b, c);} else {CLAMP(a, c, b);} + +#define IS_EQ(a,b) ((fabs((double)(a)-(b)) >= (double) FLT_EPSILON) ? 0 : 1) -#define KNOTSU(nu) ( (nu)->orderu+ (nu)->pntsu+ (nu->orderu-1)*((nu)->flagu & 1) ) -#define KNOTSV(nu) ( (nu)->orderv+ (nu)->pntsv+ (nu->orderv-1)*((nu)->flagv & 1) ) /* this weirdo pops up in two places ... */ #if !defined(WIN32) && !defined(__BeOS) @@ -146,28 +155,6 @@ #define ENDB MAKE_ID('E','N','D','B') -/* This should, of course, become a function */ -#define DL_SURFINDEX(cyclu, cyclv, sizeu, sizev) \ - \ - if( (cyclv)==0 && a==(sizev)-1) break; \ - if(cyclu) { \ - p1= sizeu*a; \ - p2= p1+ sizeu-1; \ - p3= p1+ sizeu; \ - p4= p2+ sizeu; \ - b= 0; \ - } \ - else { \ - p2= sizeu*a; \ - p1= p2+1; \ - p4= p2+ sizeu; \ - p3= p1+ sizeu; \ - b= 1; \ - } \ - if( (cyclv) && a==sizev-1) { \ - p3-= sizeu*sizev; \ - p4-= sizeu*sizev; \ - } /* This one rotates the bytes in an int */ #define SWITCH_INT(a) { \ @@ -176,131 +163,19 @@ s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } -/* More brain damage. Only really used by packedFile.c */ -// return values -#define RET_OK 0 -#define RET_ERROR 1 -/* and these aren't used at all */ -/* #define RET_CANCEL 2 */ -/* #define RET_YES (1 == 1) */ -/* #define RET_NO (1 == 0) */ - -/* sequence related defines */ -#define WHILE_SEQ(base) { \ - int totseq_, seq_; Sequence **seqar; \ - build_seqar( base, &seqar, &totseq_); \ - for(seq_ = 0; seq_ < totseq_; seq_++) { \ - seq= seqar[seq_]; - - -#define END_SEQ } \ - if(seqar) MEM_freeN(seqar); \ - } - - -/* not really sure about these... some kind of event codes ?*/ -/* INFO: 300 */ -/* pas op: ook in filesel.c en editobject.c */ -#define B_INFOSCR 301 -#define B_INFODELSCR 302 -#define B_INFOSCE 304 -#define B_INFODELSCE 305 -#define B_FILEMENU 306 -#define B_PACKFILE 307 - -/* From iff.h, but seemingly detached from anything else... To which - * encoding scheme do they belong? */ -#define AMI (1 << 31) -#define CDI (1 << 30) -#define Anim (1 << 29) -#define TGA (1 << 28) -#define JPG (1 << 27) -#define TIM (1 << 26) - -#define TIM_CLUT (010) -#define TIM_4 (TIM | TIM_CLUT | 0) -#define TIM_8 (TIM | TIM_CLUT | 1) -#define TIM_16 (TIM | 2) -#define TIM_24 (TIM | 3) - -#define RAWTGA (TGA | 1) - -#define JPG_STD (JPG | (0 << 8)) -#define JPG_VID (JPG | (1 << 8)) -#define JPG_JST (JPG | (2 << 8)) -#define JPG_MAX (JPG | (3 << 8)) -#define JPG_MSK (0xffffff00) - -#define AM_ham (0x0800 | AMI) -#define AM_hbrite (0x0080 | AMI) -#define AM_lace (0x0004 | AMI) -#define AM_hires (0x8000 | AMI) -#define AM_hblace (AM_hbrite | AM_lace) -#define AM_hilace (AM_hires | AM_lace) -#define AM_hamlace (AM_ham | AM_lace) - -#define RGB888 1 -#define RGB555 2 -#define DYUV 3 -#define CLUT8 4 -#define CLUT7 5 -#define CLUT4 6 -#define CLUT3 7 -#define RL7 8 -#define RL3 9 -#define MPLTE 10 - -#define DYUV1 0 -#define DYUVE 1 - -#define CD_rgb8 (RGB888 | CDI) -#define CD_rgb5 (RGB555 | CDI) -#define CD_dyuv (DYUV | CDI) -#define CD_clut8 (CLUT8 | CDI) -#define CD_clut7 (CLUT7 | CDI) -#define CD_clut4 (CLUT4 | CDI) -#define CD_clut3 (CLUT3 | CDI) -#define CD_rl7 (RL7 | CDI) -#define CD_rl3 (RL3 | CDI) -#define CD_mplte (MPLTE | CDI) - -#define C233 1 -#define YUVX 2 -#define HAMX 3 -#define TANX 4 - -#define AN_c233 (Anim | C233) -#define AN_yuvx (Anim | YUVX) -#define AN_hamx (Anim | HAMX) -#define AN_tanx (Anim | TANX) - -#define IMAGIC 0732 - -/* This used to reside in render.h. It does some texturing. */ -#define BRICON Tin= (Tin-0.5)*tex->contrast+tex->bright-0.5; \ - if(Tin<0.0) Tin= 0.0; else if(Tin>1.0) Tin= 1.0; - -#define BRICONRGB Tr= tex->rfac*((Tr-0.5)*tex->contrast+tex->bright-0.5); \ - if(Tr<0.0) Tr= 0.0; \ - Tg= tex->gfac*((Tg-0.5)*tex->contrast+tex->bright-0.5); \ - if(Tg<0.0) Tg= 0.0; \ - Tb= tex->bfac*((Tb-0.5)*tex->contrast+tex->bright-0.5); \ - if(Tb<0.0) Tb= 0.0; - -/* mystifying stuff from blendef... */ -#define SELECT 1 -#define ACTIVE 2 -#define NOT_YET 0 - -/* ???? */ + +/* Bit operations */ #define BTST(a,b) ( ( (a) & 1<<(b) )!=0 ) #define BSET(a,b) ( (a) | 1<<(b) ) +#define BCLR(a,b) ( (a) & ~(1<<(b)) ) +/* bit-row */ +#define BROW(min, max) (((max)>=31? 0xFFFFFFFF: (1<<(max+1))-1) - ((min)? ((1<<(min))-1):0) ) -/* needed for material.c*/ -#define REDRAWBUTSMAT 0x4015 -/* useless game shit */ -#define MA_FH_NOR 2 +#ifdef GS +#undef GS +#endif +#define GS(a) (*((short *)(a))) #endif diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 13218846b59..4da7d2a2f20 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -195,10 +195,9 @@ int BPY_call_importloader(char *name) #define INT 96 /* struct EnvMap; */ /* struct Tex; */ -float Ta, Tb, Tg, Tin, Tr; void do_material_tex(ShadeInput *shi){} -void externtex(struct MTex *mtex, float *vec){} +void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){} void init_render_textures(void){} void end_render_textures(void){} @@ -210,9 +209,7 @@ int RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt){ return 0; } -void RE_calc_R_ref(void){} char texstr[20][12]; /* buttons.c */ -Osa O; /* editsca.c */ void make_unique_prop_names(char *str) {} diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 69363f4d9af..db8653f0abe 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -91,6 +91,7 @@ #include "BIF_mainqueue.h" // mainqenter for onload script #include "mydevice.h" #include "nla.h" +#include "blendef.h" Global G; UserDef U; @@ -318,8 +319,8 @@ static void setup_app_data(BlendFileData *bfd, char *filename) G.scene= curscene; } else { - R.winpos= bfd->winpos; - R.displaymode= bfd->displaymode; + G.winpos= bfd->winpos; + G.displaymode= bfd->displaymode; G.fileflags= bfd->fileflags; G.curscreen= bfd->curscreen; G.scene= G.curscreen->scene; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 922b4d5cf78..228588e2c4a 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -521,18 +521,24 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co int a, back; if(ma==0) return; + shi.mat= ma; - shi.matren= ma->ren; shi.vlr= NULL; // have to do this! - ma= shi.matren; + + // copy all relevant material vars, note, keep this synced with render_types.h + memcpy(&shi.r, &shi.mat->r, 23*sizeof(float)); + // set special cases: + shi.har= shi.mat->har; + shi.osatex= 0; // also prevents reading vlr + VECCOPY(shi.vn, nor); if(ma->mode & MA_VERTEXCOLP) { if(vertcol) { - ma->r= vertcol[3]/255.0; - ma->g= vertcol[2]/255.0; - ma->b= vertcol[1]/255.0; + shi.r= vertcol[3]/255.0; + shi.g= vertcol[2]/255.0; + shi.b= vertcol[1]/255.0; } } @@ -565,24 +571,19 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co shi.ref[2]= (-1.0+inp*shi.vn[2]); } - if(ma->mode & MA_VERTEXCOLP) { - shi.mat->r= ma->r; - shi.mat->g= ma->g; - shi.mat->b= ma->b; - } do_material_tex(&shi); } if(ma->mode & MA_SHLESS) { if(vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - col1[3]= vertcol[3]*ma->r; - col1[2]= vertcol[2]*ma->g; - col1[1]= vertcol[1]*ma->b; + col1[3]= vertcol[3]*shi.r; + col1[2]= vertcol[2]*shi.g; + col1[1]= vertcol[1]*shi.b; } else { - col1[3]= (255.0*ma->r); - col1[2]= (255.0*ma->g); - col1[1]= (255.0*ma->b); + col1[3]= (255.0*shi.r); + col1[2]= (255.0*shi.g); + col1[1]= (255.0*shi.b); } if(col2) { col2[3]= col1[3]; @@ -593,14 +594,14 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co } if( vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - diff1[0]= diff2[0]= ma->r*(ma->emit+vertcol[3]/255.0); - diff1[1]= diff2[1]= ma->g*(ma->emit+vertcol[2]/255.0); - diff1[2]= diff2[2]= ma->b*(ma->emit+vertcol[1]/255.0); + diff1[0]= diff2[0]= shi.r*(shi.emit+vertcol[3]/255.0); + diff1[1]= diff2[1]= shi.g*(shi.emit+vertcol[2]/255.0); + diff1[2]= diff2[2]= shi.b*(shi.emit+vertcol[1]/255.0); } else { - diff1[0]= diff2[0]= ma->r*ma->emit; - diff1[1]= diff2[1]= ma->g*ma->emit; - diff1[2]= diff2[2]= ma->b*ma->emit; + diff1[0]= diff2[0]= shi.r*shi.emit; + diff1[1]= diff2[1]= shi.g*shi.emit; + diff1[2]= diff2[2]= shi.b*shi.emit; } shi.view[0]= 0.0; @@ -679,7 +680,7 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co back= 1; is= -is; } - inp= is*lampdist*ma->ref; + inp= is*lampdist*shi.refl; if(back==0) { add_to_diffuse(diff1, &shi, is, inp*fl->r, inp*fl->g, inp*fl->b); @@ -692,20 +693,20 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co //diff2[1]+= inp*fl->g; //diff2[2]+= inp*fl->b; } - if(ma->spec && (fl->mode & LA_NO_SPEC)==0) { + if(shi.spec!=0.0 && (fl->mode & LA_NO_SPEC)==0) { float specfac; if(ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(nor, lv, shi.view, ma->har); + specfac= Phong_Spec(nor, lv, shi.view, shi.har); else if(ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(nor, lv, shi.view, ma->har); + specfac= CookTorr_Spec(nor, lv, shi.view, shi.har); else if(ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(nor, lv, shi.view, ma->refrac, (float)ma->har); + specfac= Blinn_Spec(nor, lv, shi.view, ma->refrac, (float)shi.har); else specfac= Toon_Spec(nor, lv, shi.view, ma->param[2], ma->param[3]); if(specfac>0) { - t= specfac*ma->spec*lampdist; + t= specfac*shi.spec*lampdist; if(back==0) { if(ma->mode & MA_RAMP_SPEC) { float spec[3]; @@ -715,9 +716,9 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co isb+= t*(fl->b * spec[2]); } else { - isr+= t*(fl->r * ma->specr); - isg+= t*(fl->g * ma->specg); - isb+= t*(fl->b * ma->specb); + isr+= t*(fl->r * shi.specr); + isg+= t*(fl->g * shi.specg); + isb+= t*(fl->b * shi.specb); } } else if(col2) { @@ -729,9 +730,9 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co isb1+= t*(fl->b * spec[2]); } else { - isr1+= t*(fl->r * ma->specr); - isg1+= t*(fl->g * ma->specg); - isb1+= t*(fl->b * ma->specb); + isr1+= t*(fl->r * shi.specr); + isg1+= t*(fl->g * shi.specg); + isb1+= t*(fl->b * shi.specb); } } } @@ -742,13 +743,13 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff1, &shi); if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, &shi); - a= 256*(diff1[0] + ma->ambr +isr); + a= 256*(diff1[0] + shi.ambr +isr); if(a>255) col1[3]= 255; else col1[3]= a; - a= 256*(diff1[1] + ma->ambg +isg); + a= 256*(diff1[1] + shi.ambg +isg); if(a>255) col1[2]= 255; else col1[2]= a; - a= 256*(diff1[2] + ma->ambb +isb); + a= 256*(diff1[2] + shi.ambb +isb); if(a>255) col1[1]= 255; else col1[1]= a; @@ -756,13 +757,13 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff2, &shi); if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr1, &isg1, &isb1, &shi); - a= 256*(diff2[0] + ma->ambr +isr1); + a= 256*(diff2[0] + shi.ambr +isr1); if(a>255) col2[3]= 255; else col2[3]= a; - a= 256*(diff2[1] + ma->ambg +isg1); + a= 256*(diff2[1] + shi.ambg +isg1); if(a>255) col2[2]= 255; else col2[2]= a; - a= 256*(diff2[2] + ma->ambb +isb1); + a= 256*(diff2[2] + shi.ambb +isb1); if(a>255) col2[1]= 255; else col2[1]= a; } @@ -935,7 +936,7 @@ void shadeDispList(Object *ob) ma= give_current_material(ob, a+1); if(ma) { init_render_material(ma); - if(ma->ren->texco & TEXCO_ORCO) need_orco= 1; + if(ma->texco & TEXCO_ORCO) need_orco= 1; } } @@ -2263,7 +2264,7 @@ void imagestodisplist(void) ListBase _wireframe, *wireframe; DispList *dl; Segment *seg; - float *data, xfac, yfac, xsi, ysi, vec[3]; + float *data, xfac, yfac, xsi, ysi, vec[3], dum; int tot; _wireframe.first= 0; @@ -2285,7 +2286,7 @@ void imagestodisplist(void) tex= ma->mtex[0]->tex; /* this takes care of correct loading of new imbufs */ - externtex(ma->mtex[0], vec); + externtex(ma->mtex[0], vec, &dum, &dum, &dum, &dum, &dum); if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) { diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 988d9abfd9b..fcadd35f427 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -35,6 +35,10 @@ #include <math.h> #include <stdlib.h> +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + #include "MEM_guardedalloc.h" #include "DNA_listBase.h" #include "DNA_effect_types.h" @@ -71,6 +75,9 @@ #include "BKE_screen.h" #include "BKE_utildefines.h" +#include "render.h" // externtex, bad level call (ton) + + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -311,39 +318,38 @@ void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec) void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no) { - extern float Tin, Tr, Tg, Tb; - extern void externtex(struct MTex *mtex, float *vec); + float tin, tr, tg, tb, ta; float old; - externtex(mtex, co); + externtex(mtex, co, &tin, &tr, &tg, &tb, &ta); if(paf->texmap==PAF_TEXINT) { - Tin*= paf->texfac; - no[0]+= Tin*paf->defvec[0]; - no[1]+= Tin*paf->defvec[1]; - no[2]+= Tin*paf->defvec[2]; + tin*= paf->texfac; + no[0]+= tin*paf->defvec[0]; + no[1]+= tin*paf->defvec[1]; + no[2]+= tin*paf->defvec[2]; } else if(paf->texmap==PAF_TEXRGB) { - no[0]+= (Tr-0.5f)*paf->texfac; - no[1]+= (Tg-0.5f)*paf->texfac; - no[2]+= (Tb-0.5f)*paf->texfac; + no[0]+= (tr-0.5f)*paf->texfac; + no[1]+= (tg-0.5f)*paf->texfac; + no[2]+= (tb-0.5f)*paf->texfac; } else { /* PAF_TEXGRAD */ - old= Tin; + old= tin; co[0]+= paf->nabla; - externtex(mtex, co); - no[0]+= (old-Tin)*paf->texfac; + externtex(mtex, co, &tin, &tr, &tg, &tb, &ta); + no[0]+= (old-tin)*paf->texfac; co[0]-= paf->nabla; co[1]+= paf->nabla; - externtex(mtex, co); - no[1]+= (old-Tin)*paf->texfac; + externtex(mtex, co, &tin, &tr, &tg, &tb, &ta); + no[1]+= (old-tin)*paf->texfac; co[1]-= paf->nabla; co[2]+= paf->nabla; - externtex(mtex, co); - no[2]+= (old-Tin)*paf->texfac; + externtex(mtex, co, &tin, &tr, &tg, &tb, &ta); + no[2]+= (old-tin)*paf->texfac; } } diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 2410255c6af..3347a193d80 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -123,6 +123,8 @@ #include "BPY_extern.h" +#include "blendef.h" + static int is_dxf(char *str); static void dxf_read(char *filename); static int is_stl(char *str); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 0663fb2244e..50119cdf3a7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -31,10 +31,6 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include <stdio.h> #include <string.h> #include <fcntl.h> @@ -50,57 +46,24 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "DNA_texture_types.h" #include "DNA_image_types.h" +#include "DNA_texture_types.h" #include "DNA_packedFile_types.h" #include "BLI_blenlib.h" -#include "BKE_bad_level_calls.h" -#include "BKE_utildefines.h" - +#include "BKE_bmfont.h" +#include "BKE_packedFile.h" +#include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" - #include "BKE_image.h" -#include "BKE_bmfont.h" -#include "BKE_screen.h" +#include "BKE_scene.h" #include "BKE_texture.h" -#include "BKE_packedFile.h" -#include "BKE_library.h" - -void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2); -void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2); -float square_rctf(rctf *rf); -float clipx_rctf(rctf *rf, float x1, float x2); -float clipy_rctf(rctf *rf, float y1, float y2); -void boxsample(struct ImBuf *ibuf, - float minx, float miny, float maxx, float maxy, - float *rcol, float *gcol, float *bcol, float *acol); -void boxsampleclip(struct ImBuf *ibuf, rctf *rf, float *rcol, - float *gcol, float *bcol, float *acol); -void filtersample(struct ImBuf *ibuf, - float fx, float fy, - float *rcol, float *gcol, float *bcol, float *acol); - - - -/* If defined: check arguments on call */ -/* #define IMAGE_C_ARG_CHECK */ - -/* Communicate with texture channels. */ -extern float Tin, Tr, Tg, Tb, Ta; - -int Talpha; -int imaprepeat, imapextend; - +#include "BKE_utildefines.h" -/* - * - * Talpha==TRUE means: read alpha from image. This does not mean that Ta - * should not be used, here info can be stored about outside edge of an image! - * - */ +/* bad level; call to free_realtime_image */ +#include "BKE_bad_level_calls.h" void free_image_buffers(Image *ima) { @@ -249,6 +212,7 @@ void makepicstring(char *string, int frame) /* ******** IMAGE WRAPPING INIT ************* */ +/* used by sequencer, texture */ void converttopremul(struct ImBuf *ibuf) { int x, y, val; @@ -282,29 +246,7 @@ void converttopremul(struct ImBuf *ibuf) } } - - -void makemipmap(Image *ima) -{ - struct ImBuf *ibuf; - int minsize, curmap=0; - - ibuf= ima->ibuf; - minsize= MIN2(ibuf->x, ibuf->y); - - while(minsize>3 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) { - - ibuf= IMB_dupImBuf(ibuf); - IMB_filter(ibuf); - ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf); - IMB_freeImBuf(ibuf); - ibuf= ima->mipmap[curmap]; - - curmap++; - minsize= MIN2(ibuf->x, ibuf->y); - } -} - +/* used by sequencer, texture */ struct anim *openanim(char * name, int flags) { struct anim * anim; @@ -325,85 +267,36 @@ struct anim *openanim(char * name, int flags) return(anim); } -int calcimanr(int cfra, Tex *tex) -{ - int imanr, len, a, fra, dur; - /* here (+fie_ima/2-1) makes sure that division happens correctly */ - - if(tex->frames==0) return 1; - - cfra= cfra-tex->sfra+1; - - /* cyclic */ - if(tex->len==0) len= (tex->fie_ima*tex->frames)/2; - else len= tex->len; - - if(tex->imaflag & TEX_ANIMCYCLIC) { - cfra= ( (cfra) % len ); - if(cfra < 0) cfra+= len; - if(cfra==0) cfra= len; - } - - if(cfra<1) cfra= 1; - else if(cfra>len) cfra= len; - - /* convert current frame to current field */ - cfra= 2*(cfra); - if(R.flag & R_SEC_FIELD) cfra++; - - /* transform to images space */ - imanr= (cfra+tex->fie_ima-2)/tex->fie_ima; - if(imanr>tex->frames) imanr= tex->frames; - imanr+= tex->offset; - - if(tex->imaflag & TEX_ANIMCYCLIC) { - imanr= ( (imanr) % len ); - while(imanr < 0) imanr+= len; - if(imanr==0) imanr= len; - } +/* +load_image handles reading the image from disk or from the packedfile. +*/ - /* are there images that last longer? */ - for(a=0; a<4; a++) { - if(tex->fradur[a][0]) { - - fra= tex->fradur[a][0]; - dur= tex->fradur[a][1]-1; - - while(dur>0 && imanr>fra) { - imanr--; - dur--; - } - } - } +void load_image(Image * ima, int flags, char *relabase, int framenum) +{ + char name[FILE_MAXDIR + FILE_MAXFILE]; - return imanr; -} + if (ima->ibuf == NULL) { -void do_laseroptics_patch(ImBuf *ibuf) -{ - char *rt; - float fac; - int a, val; - - rt= (char *)ibuf->rect; - a= ibuf->x*ibuf->y; + // is there a PackedFile with this image ?; + if (ima->packedfile) { + ima->ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, flags); + } else { + strcpy(name, ima->name); + BLI_convertstringcode(name, relabase, framenum); - if(ibuf->flags & IB_fields) a+= a; + ima->ibuf = IMB_loadiffname(name , flags); + } + // check if the image is a font image... + // printf("Checking for font\n"); - while(a--) { - - fac= (rt[1]+rt[2]+rt[3])/765.0f; - val= (int)((255.0/0.8)*(fac-0.1)); - - if(val<0) val= 0; else if(val>255) val= 255; - - rt[0]= rt[1]= rt[2]= rt[3]= val; - - rt+= 4; + if (ima->ibuf) { + detectBitmapFont(ima->ibuf); + } } } + void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ { struct ImBuf * tbuf1, * tbuf2; @@ -421,7 +314,7 @@ void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ /* These rectop calls are broken!!! I added a trailing 0 arg... */ IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); - + ibuf->x /= 2; IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); IMB_rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); @@ -449,7 +342,7 @@ void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ /* These are brolenm as well... */ IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); - + ibuf->x /= 2; IMB_rectop(ibuf, tbuf2, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); IMB_rectop(ibuf, tbuf1, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); @@ -460,33 +353,6 @@ void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ ibuf->y /= 2; } -/* -load_image handles reading the image from disk or from the packedfile. -*/ - -void load_image(Image * ima, int flags, char *relabase, int framenum) -{ - char name[FILE_MAXDIR + FILE_MAXFILE]; - - if (ima->ibuf == NULL) { - - // is there a PackedFile with this image ?; - if (ima->packedfile) { - ima->ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, flags); - } else { - strcpy(name, ima->name); - BLI_convertstringcode(name, relabase, framenum); - - ima->ibuf = IMB_loadiffname(name , flags); - } - // check if the image is a font image... - // printf("Checking for font\n"); - - if (ima->ibuf) { - detectBitmapFont(ima->ibuf); - } - } -} void ima_ibuf_is_nul(Tex *tex) { @@ -494,39 +360,37 @@ void ima_ibuf_is_nul(Tex *tex) Image *ima; int a, fra, dur; char str[FILE_MAXDIR+FILE_MAXFILE], *cp; - + ima= tex->ima; if(ima==0) return; - - waitcursor(1); - + strcpy(str, ima->name); BLI_convertstringcode(str, G.sce, G.scene->r.cfra); if(tex->imaflag & TEX_STD_FIELD) de_interlacefunc= de_interlace_st; else de_interlacefunc= de_interlace_ng; - - if(tex->imaflag & TEX_ANIM5) { + if(tex->imaflag & TEX_ANIM5) { + if(ima->anim==0) ima->anim = openanim(str, IB_cmap | IB_rect); if (ima->anim) { dur = IMB_anim_get_duration(ima->anim); ima->lastquality= R.osa; fra= ima->lastframe-1; - + if(fra<0) fra = 0; if(fra>(dur-1)) fra= dur-1; ima->ibuf = IMB_anim_absolute(ima->anim, fra); - + /* patch for textbutton with name ima (B_NAMEIMA) */ if(ima->ibuf) { strcpy(ima->ibuf->name, ima->name); if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf); } } - else error("Not an anim"); - + else printf("Not an anim"); + } else { // create a packedfile for this image when autopack is on // for performance (IMB_loadiffname uses mmap) we don't do this by default @@ -535,7 +399,7 @@ void ima_ibuf_is_nul(Tex *tex) } load_image(ima, IB_rect, G.sce, G.scene->r.cfra); - + if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf); ima->lastquality= R.osa; @@ -549,15 +413,15 @@ void ima_ibuf_is_nul(Tex *tex) if(ima->ibuf->cmap) { if(tex->imaflag & TEX_ANIM5) { - + if(tex->imaflag & TEX_MORKPATCH) { - /**** PATCH TO SET COLOR 2 RIGHT (neogeo..) */ + /**** PATCH TO SET COLOR 2 RIGHT (neogeo..) */ if(ima->ibuf->maxcol > 4) { cp= (char *)(ima->ibuf->cmap+2); cp[0]= 0x80; } } - + IMB_applycmap(ima->ibuf); IMB_convert_rgba_to_abgr(ima->ibuf->x*ima->ibuf->y, ima->ibuf->rect); @@ -582,989 +446,8 @@ void ima_ibuf_is_nul(Tex *tex) if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]); ima->mipmap[a]= 0; } - - if((R.flag & R_RENDERING)==0) waitcursor(0); } -/* *********** IMAGEWRAPPING ****************** */ - - -int imagewrap(Tex *tex, float *texvec) -{ - Image *ima; - struct ImBuf *ibuf; - float fx, fy, val1, val2, val3; - int ofs, x, y; - char *rect; - - Tin= Ta= Tr= Tg= Tb= 0.0; - ima= tex->ima; - if(ima==0 || ima->ok== 0) { - return 0; - } - - if(ima->ibuf==0) ima_ibuf_is_nul(tex); - - if (ima->ok) { - ibuf = ima->ibuf; - - if(tex->imaflag & TEX_IMAROT) { - fy= texvec[0]; - fx= texvec[1]; - } - else { - fx= texvec[0]; - fy= texvec[1]; - } - - if(tex->extend == TEX_CHECKER) { - int xs, ys; - - xs= (int)floor(fx); - ys= (int)floor(fy); - fx-= xs; - fy-= ys; - - if( (tex->flag & TEX_CHECKER_ODD)==0) { - if((xs+ys) & 1);else return 0; - } - if( (tex->flag & TEX_CHECKER_EVEN)==0) { - if((xs+ys) & 1) return 0; - } - /* scale around center, (0.5, 0.5) */ - if(tex->checkerdist<1.0) { - fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5; - fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5; - } - } - - x = (int)(fx*ibuf->x); - y = (int)(fy*ibuf->y); - - if(tex->extend == TEX_CLIPCUBE) { - if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) { - return 0; - } - } - else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { - if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) { - return 0; - } - } - else { - if(tex->extend==TEX_EXTEND) { - if(x>=ibuf->x) x = ibuf->x-1; - else if(x<0) x= 0; - } - else { - x= x % ibuf->x; - if(x<0) x+= ibuf->x; - } - if(tex->extend==TEX_EXTEND) { - if(y>=ibuf->y) y = ibuf->y-1; - else if(y<0) y= 0; - } - else { - y= y % ibuf->y; - if(y<0) y+= ibuf->y; - } - } - - /* warning, no return before setting back! */ - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect+= (ibuf->x*ibuf->y); - } - - ofs = y * ibuf->x + x; - rect = (char *)( ibuf->rect+ ofs); - - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect-= (ibuf->x*ibuf->y); - } - - Talpha= 0; - if(tex->imaflag & TEX_USEALPHA) { - if(tex->imaflag & TEX_CALCALPHA); - else Talpha= 1; - } - - Tr = ((float)rect[0])/255.0f; - Tg = ((float)rect[1])/255.0f; - Tb = ((float)rect[2])/255.0f; - - if(tex->nor) { - if(tex->imaflag & TEX_NORMALMAP) { - tex->nor[0]= 0.5-Tr; - tex->nor[1]= 0.5-Tg; - tex->nor[2]= -Tb; - } - else { - /* bump: take three samples */ - val1= Tr+Tg+Tb; - - if(x<ibuf->x-1) { - rect+=4; - val2= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; - rect-=4; - } - else val2= val1; - - if(y<ibuf->y-1) { - rect+= 4*ibuf->x; - val3= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; - } - else val3= val1; - - /* do not mix up x and y here! */ - tex->nor[0]= (val1-val2); - tex->nor[1]= (val1-val3); - } - } - - BRICONRGB; - - if(Talpha) Ta= Tin= ((float)rect[3])/255.0f; - else if(tex->imaflag & TEX_CALCALPHA) { - Ta= Tin= MAX3(Tr, Tg, Tb); - } - else Ta= Tin= 1.0; - - if(tex->flag & TEX_NEGALPHA) Ta= 1.0f-Ta; - - } - - if(tex->nor) return 3; - else return 1; -} - -void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2) -/* rctf *stack; */ -/* short *count; */ -/* float x1, x2; */ -{ - rctf *rf, *newrct; - short a; - - a= *count; - rf= stack; - for(;a>0;a--) { - if(rf->xmin<x1) { - if(rf->xmax<x1) { - rf->xmin+= (x2-x1); - rf->xmax+= (x2-x1); - } - else { - if(rf->xmax>x2) rf->xmax= x2; - newrct= stack+ *count; - (*count)++; - - newrct->xmax= x2; - newrct->xmin= rf->xmin+(x2-x1); - newrct->ymin= rf->ymin; - newrct->ymax= rf->ymax; - - if(newrct->xmin==newrct->xmax) (*count)--; - - rf->xmin= x1; - } - } - else if(rf->xmax>x2) { - if(rf->xmin>x2) { - rf->xmin-= (x2-x1); - rf->xmax-= (x2-x1); - } - else { - if(rf->xmin<x1) rf->xmin= x1; - newrct= stack+ *count; - (*count)++; - - newrct->xmin= x1; - newrct->xmax= rf->xmax-(x2-x1); - newrct->ymin= rf->ymin; - newrct->ymax= rf->ymax; - - if(newrct->xmin==newrct->xmax) (*count)--; - - rf->xmax= x2; - } - } - rf++; - } - -} - -void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2) -/* rctf *stack; */ -/* short *count; */ -/* float y1, y2; */ -{ - rctf *rf, *newrct; - short a; - - a= *count; - rf= stack; - for(;a>0;a--) { - if(rf->ymin<y1) { - if(rf->ymax<y1) { - rf->ymin+= (y2-y1); - rf->ymax+= (y2-y1); - } - else { - if(rf->ymax>y2) rf->ymax= y2; - newrct= stack+ *count; - (*count)++; - - newrct->ymax= y2; - newrct->ymin= rf->ymin+(y2-y1); - newrct->xmin= rf->xmin; - newrct->xmax= rf->xmax; - - if(newrct->ymin==newrct->ymax) (*count)--; - - rf->ymin= y1; - } - } - else if(rf->ymax>y2) { - if(rf->ymin>y2) { - rf->ymin-= (y2-y1); - rf->ymax-= (y2-y1); - } - else { - if(rf->ymin<y1) rf->ymin= y1; - newrct= stack+ *count; - (*count)++; - - newrct->ymin= y1; - newrct->ymax= rf->ymax-(y2-y1); - newrct->xmin= rf->xmin; - newrct->xmax= rf->xmax; - - if(newrct->ymin==newrct->ymax) (*count)--; - - rf->ymax= y2; - } - } - rf++; - } - -} - - - -float square_rctf(rctf *rf) -/* rctf *rf; */ -{ - float x, y; - - x= rf->xmax- rf->xmin; - y= rf->ymax- rf->ymin; - return (x*y); -} - -float clipx_rctf(rctf *rf, float x1, float x2) -/* rctf *rf; */ -/* float x1, x2; */ -{ - float size; - - size= rf->xmax - rf->xmin; - - if(rf->xmin<x1) { - rf->xmin= x1; - } - if(rf->xmax>x2) { - rf->xmax= x2; - } - if(rf->xmin > rf->xmax) { - rf->xmin = rf->xmax; - return 0.0; - } - else if(size!=0.0) { - return (rf->xmax - rf->xmin)/size; - } - return 1.0; -} - -float clipy_rctf(rctf *rf, float y1, float y2) -/* rctf *rf; */ -/* float y1, y2; */ -{ - float size; - - size= rf->ymax - rf->ymin; -/* PRINT(f, size); */ - if(rf->ymin<y1) { - rf->ymin= y1; - } - if(rf->ymax>y2) { - rf->ymax= y2; - } -/* PRINT(f, size); */ - if(rf->ymin > rf->ymax) { - rf->ymin = rf->ymax; - return 0.0; - } - else if(size!=0.0) { - return (rf->ymax - rf->ymin)/size; - } - return 1.0; - -} - -void boxsampleclip(struct ImBuf *ibuf, rctf *rf, float *rcol, - float *gcol, float *bcol, float *acol) /* return color 0.0-1.0 */ -/* struct ImBuf *ibuf; */ -/* rctf *rf; */ -/* float *rcol, *gcol, *bcol, *acol; */ -{ - /* sample box, is clipped already, and minx etc. have been set at ibuf size. - Enlarge with antialiased edges of the pixels */ - - float muly,mulx,div; - int ofs; - int x, y, startx, endx, starty, endy; - char *rect; - - startx= (int)floor(rf->xmin); - endx= (int)floor(rf->xmax); - starty= (int)floor(rf->ymin); - endy= (int)floor(rf->ymax); - - if(startx < 0) startx= 0; - if(starty < 0) starty= 0; - if(endx>=ibuf->x) endx= ibuf->x-1; - if(endy>=ibuf->y) endy= ibuf->y-1; - - if(starty==endy && startx==endx) { - - ofs = starty*ibuf->x + startx; - rect = (char *)(ibuf->rect +ofs); - *rcol= ((float)rect[0])/255.0f; - *gcol= ((float)rect[1])/255.0f; - *bcol= ((float)rect[2])/255.0f; - /* alpha is global, has been set in function imagewraposa() */ - if(Talpha) { - *acol= ((float)rect[3])/255.0f; - } - } - else { - div= *rcol= *gcol= *bcol= *acol= 0.0; - for(y=starty;y<=endy;y++) { - ofs = y*ibuf->x +startx; - rect = (char *)(ibuf->rect+ofs); - - muly= 1.0; - - if(starty==endy); - else { - if(y==starty) muly= 1.0f-(rf->ymin - y); - if(y==endy) muly= (rf->ymax - y); - } - if(startx==endx) { - mulx= muly; - if(Talpha) *acol+= mulx*rect[3]; - *rcol+= mulx*rect[0]; - *gcol+= mulx*rect[1]; - *bcol+= mulx*rect[2]; - div+= mulx; - } - else { - for(x=startx;x<=endx;x++) { - mulx= muly; - if(x==startx) mulx*= 1.0f-(rf->xmin - x); - if(x==endx) mulx*= (rf->xmax - x); - - if(mulx==1.0) { - if(Talpha) *acol+= rect[3]; - *rcol+= rect[0]; - *gcol+= rect[1]; - *bcol+= rect[2]; - div+= 1.0; - } - else { - if(Talpha) *acol+= mulx*rect[3]; - *rcol+= mulx*rect[0]; - *gcol+= mulx*rect[1]; - *bcol+= mulx*rect[2]; - div+= mulx; - } - rect+=4; - } - } - } - if(div!=0.0) { - div*= 255.0; - - *bcol/= div; - *gcol/= div; - *rcol/= div; - - if(Talpha) *acol/= div; - } - else { - *rcol= *gcol= *bcol= *acol= 0.0; - } - } -} - -void boxsample(struct ImBuf *ibuf, - float minx, float miny, float maxx, float maxy, - float *rcol, float *gcol, float *bcol, float *acol) /* return color 0.0-1.0 */ -/* struct ImBuf *ibuf; */ -/* float minx, miny, maxx, maxy; */ -/* float *rcol, *gcol, *bcol, *acol; */ -{ - /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 . - * Enlarge with antialiased edges of pixels. - * If global variable 'imaprepeat' has been set, the - * clipped-away parts are sampled as well. - */ - rctf *rf, stack[8]; - float opp, tot, r, g, b, a, alphaclip= 1.0; - short count=1; - - rf= stack; - rf->xmin= minx*(ibuf->x); - rf->xmax= maxx*(ibuf->x); - rf->ymin= miny*(ibuf->y); - rf->ymax= maxy*(ibuf->y); - - if(imapextend); - else if(imaprepeat) clipx_rctf_swap(stack, &count, 0.0, (float)(ibuf->x)); - else { - alphaclip= clipx_rctf(rf, 0.0, (float)(ibuf->x)); - - if(alphaclip<=0.0) { - *rcol= *bcol= *gcol= *acol= 0.0; - return; - } - } - - if(imapextend); - else if(imaprepeat) clipy_rctf_swap(stack, &count, 0.0, (float)(ibuf->y)); - else { - alphaclip*= clipy_rctf(rf, 0.0, (float)(ibuf->y)); - - if(alphaclip<=0.0) { - *rcol= *bcol= *gcol= *acol= 0.0; - return; - } - } - - if(count>1) { - tot= *rcol= *bcol= *gcol= *acol= 0.0; - while(count--) { - boxsampleclip(ibuf, rf, &r, &g, &b, &a); - - opp= square_rctf(rf); - tot+= opp; - - *rcol+= opp*r; - *gcol+= opp*g; - *bcol+= opp*b; - if(Talpha) *acol+= opp*a; - rf++; - } - if(tot!= 0.0) { - *rcol/= tot; - *gcol/= tot; - *bcol/= tot; - if(Talpha) *acol/= tot; - } - } - else { - boxsampleclip(ibuf, rf, rcol, gcol, bcol, acol); - } - - if(Talpha==0) *acol= 1.0; - - if(alphaclip!=1.0) { - /* this is for laetr investigation, premul or not? */ - /* *rcol*= alphaclip; */ - /* *gcol*= alphaclip; */ - /* *bcol*= alphaclip; */ - *acol*= alphaclip; - } -} - -void filtersample(struct ImBuf *ibuf, - float fx, float fy, - float *rcol, float *gcol, float *bcol, float *acol) - /* return color 0.0-1.0 */ -/* struct ImBuf *ibuf; */ /* fx en fy tussen 0.0 en 1.0 */ -/* float fx, fy; */ -/* float *rcol, *gcol, *bcol, *acol; */ -{ - /* with weighted filter 3x3 - * left or right collumn is always 0 - * upper or lower row is awlays 0 - */ - - int fac, fac1, fac2, fracx, fracy, filt[4]; - int ix, iy, x4; - unsigned int r=0, g=0, b=0, a=0; - char *rowcol, *rfilt[4]; - - ix= (int)( 256.0*fx ); - fracx= (ix & 255); - ix= (ix>>8); - iy= (int)( 256.0*fy ); - fracy= (iy & 255); - iy= (iy>>8); - - if(ix>=ibuf->x) ix= ibuf->x-1; - if(iy>=ibuf->y) iy= ibuf->y-1; - - rowcol= (char *)(ibuf->rect+ iy*ibuf->x +ix); - - rfilt[0]= rfilt[1]= rfilt[2]= rfilt[3]= rowcol; - x4= 4*ibuf->x; - - if(fracx<128) { - if(ix>0) { - rfilt[0]-= 4; - rfilt[2]-=4; - } - else if(imaprepeat) { - rfilt[0]+= x4-4; - rfilt[2]+= x4-4; - } - - if(fracy<128) { - /* case left-under */ - fac1= 128+fracy; - fac2= 128-fracy; - - if(iy>0) { - rfilt[3]-= x4; - rfilt[2]-= x4; - } - else if(imaprepeat) { - fac= x4*(ibuf->y-1) ; - rfilt[3]+= fac; - rfilt[2]+= fac; - } - } - else { - /* case left-upper */ - fac2= 384-fracy; - fac1= fracy-128; - - if(iy<ibuf->y-1) { - rfilt[1]+= x4; - rfilt[0]+= x4; - } - else if(imaprepeat) { - fac= x4*(ibuf->y-1) ; - rfilt[1]-= fac; - rfilt[0]-= fac; - } - } - - filt[1]=filt[3]= 128+ fracx; - filt[0]=filt[2]= 128- fracx; - filt[0]*= fac1; - filt[1]*= fac1; - filt[2]*= fac2; - filt[3]*= fac2; - } - else { - if(fracy<128) { - /* case right-under */ - fac1= 128+fracy; - fac2= 128-fracy; - - if(iy>0) { - rfilt[3]-= x4; - rfilt[2]-= x4; - } - else if(imaprepeat) { - fac= x4*(ibuf->y-1) ; - rfilt[3]+= fac; - rfilt[2]+= fac; - } - } - else { - /* case right-upper */ - fac2= 384-fracy; - fac1= fracy-128; - - if(iy<ibuf->y-1) { - rfilt[1]+= x4; - rfilt[0]+= x4; - } - else if(imaprepeat) { - fac= x4*(ibuf->y-1) ; - rfilt[1]-= fac; - rfilt[0]-= fac; - } - } - filt[0]=filt[2]= 384-fracx; - filt[1]=filt[3]= fracx-128; - filt[0]*= fac1; - filt[1]*= fac1; - filt[2]*= fac2; - filt[3]*= fac2; - - if(ix<ibuf->x-1) { - rfilt[1]+= 4; - rfilt[3]+=4; - } - else if(imaprepeat) { - rfilt[1]-= x4-4; - rfilt[3]-= x4-4; - } - } - - for(fac=3; fac>=0; fac--) { - rowcol= rfilt[fac]; - r+= filt[fac]*rowcol[0]; - g+= filt[fac]*rowcol[1]; - b+= filt[fac]*rowcol[2]; - if(Talpha) a+= filt[fac]*rowcol[3]; /* alpha is global */ - } - *rcol= ((float)r)/16777216.0f; - *gcol= ((float)g)/16777216.0f; - *bcol= ((float)b)/16777216.0f; - if(Talpha) *acol= ((float)a)/16777216.0f; - -} - - -int imagewraposa(Tex *tex, float *texvec, float *dxt, float *dyt) -{ - struct Image *ima; - struct ImBuf *ibuf, *previbuf; - float fx, fy, minx, maxx, miny, maxy, dx, dy, fac1, fac2, fac3, fac4; - float maxd, pixsize, val1, val2, val3; - int curmap; - -#ifdef IMAGE_C_ARG_CHECK - if (!tex) { - printf("imagewraposa: null pointer to texture\n"); - } -#endif - - ima= tex->ima; -#ifdef IMAGE_C_ARG_CHECK - if (!ima) { - printf("imagewraposa: null pointer to image\n"); - } -#endif - - Tin= Ta= Tr= Tg= Tb= 0.0; - - if(ima==0 || ima->ok== 0) { - return 0; - } - - if(ima->ibuf==0) ima_ibuf_is_nul(tex); - - if (ima->ok) { - - if(tex->imaflag & TEX_MIPMAP) { - if(ima->mipmap[0]==0) makemipmap(ima); - } - - ibuf = ima->ibuf; - - Talpha= 0; - if(tex->imaflag & TEX_USEALPHA) { - if(tex->imaflag & TEX_CALCALPHA); - else Talpha= 1; - } - - if(tex->imaflag & TEX_IMAROT) { - fy= texvec[0]; - fx= texvec[1]; - } - else { - fx= texvec[0]; - fy= texvec[1]; - } - - if(ibuf->flags & IB_fields) { - if(R.r.mode & R_FIELDS) { /* field render */ - if(R.flag & R_SEC_FIELD) { /* correction for 2nd field */ - /* fac1= 0.5/( (float)ibuf->y ); */ - /* fy-= fac1; */ - } - else { /* first field */ - fac1= 0.5f/( (float)ibuf->y ); - fy+= fac1; - } - } - } - - /* pixel coordinates */ - - minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] ); - maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] ); - miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] ); - maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] ); - - /* tex_sharper has been removed */ - - minx= tex->filtersize*(maxx-minx)/2.0f; - miny= tex->filtersize*(maxy-miny)/2.0f; - - if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny); - - if(minx>0.25) minx= 0.25; - else if(minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */ - if(miny>0.25) miny= 0.25; - else if(miny<0.00001f) miny= 0.00001f; - - - /* repeat and clip */ - - /* watch it: imaprepeat is global value (see boxsample) */ - imaprepeat= (tex->extend==TEX_REPEAT); - imapextend= (tex->extend==TEX_EXTEND); - - if(tex->extend == TEX_CHECKER) { - int xs, ys, xs1, ys1, xs2, ys2, boundary; - - xs= (int)floor(fx); - ys= (int)floor(fy); - - // both checkers available, no boundary exceptions, checkerdist will eat aliasing - if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) { - fx-= xs; - fy-= ys; - } - else { - - xs1= (int)floor(fx-minx); - ys1= (int)floor(fy-miny); - xs2= (int)floor(fx+minx); - ys2= (int)floor(fy+miny); - boundary= (xs1!=xs2) || (ys1!=ys2); - - if(boundary==0) { - if( (tex->flag & TEX_CHECKER_ODD)==0) { - if((xs+ys) & 1); - else return 0; - } - if( (tex->flag & TEX_CHECKER_EVEN)==0) { - if((xs+ys) & 1) return 0; - } - fx-= xs; - fy-= ys; - } - else { - if(tex->flag & TEX_CHECKER_ODD) { - if((xs1+ys) & 1) fx-= xs2; - else fx-= xs1; - - if((ys1+xs) & 1) fy-= ys2; - else fy-= ys1; - } - if(tex->flag & TEX_CHECKER_EVEN) { - if((xs1+ys) & 1) fx-= xs1; - else fx-= xs2; - - if((ys1+xs) & 1) fy-= ys1; - else fy-= ys2; - } - } - } - - /* scale around center, (0.5, 0.5) */ - if(tex->checkerdist<1.0) { - fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5; - fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5; - minx/= (1.0-tex->checkerdist); - miny/= (1.0-tex->checkerdist); - } - } - - if(tex->extend == TEX_CLIPCUBE) { - if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0 || texvec[2]<-1.0 || texvec[2]>1.0) { - return 0; - } - } - else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { - if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) { - return 0; - } - } - else { - if(tex->extend==TEX_EXTEND) { - if(fx>1.0) fx = 1.0; - else if(fx<0.0) fx= 0.0; - } - else { - if(fx>1.0) fx -= (int)(fx); - else if(fx<0.0) fx+= 1-(int)(fx); - } - - if(tex->extend==TEX_EXTEND) { - if(fy>1.0) fy = 1.0; - else if(fy<0.0) fy= 0.0; - } - else { - if(fy>1.0) fy -= (int)(fy); - else if(fy<0.0) fy+= 1-(int)(fy); - } - } - - /* warning no return! */ - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect+= (ibuf->x*ibuf->y); - } - - /* choice: */ - if(tex->imaflag & TEX_MIPMAP) { - - dx= minx; - dy= miny; - maxd= MAX2(dx, dy); - if(maxd>0.5) maxd= 0.5; - - pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y); - - curmap= 0; - previbuf= ibuf; - while(curmap<BLI_ARRAY_NELEMS(ima->mipmap) && ima->mipmap[curmap]) { - if(maxd < pixsize) break; - previbuf= ibuf; - ibuf= ima->mipmap[curmap]; - pixsize= 1.0f / (float)MIN2(ibuf->x, ibuf->y); /* this used to be 1.0 */ - curmap++; - } - - if(previbuf!=ibuf || (tex->imaflag & TEX_INTERPOL)) { - /* sample at least 1 pixel */ - if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x; - if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y; - } - - if(tex->nor && (tex->imaflag & TEX_NORMALMAP)==0) { - /* a bit extra filter */ - minx*= 1.35f; - miny*= 1.35f; - - boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta); - val1= Tr+Tg+Tb; - boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4); - val2= fac1+fac2+fac3; - boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4); - val3= fac1+fac2+fac3; - - if(previbuf!=ibuf) { /* interpolate */ - - boxsample(previbuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &fac1, &fac2, &fac3, &fac4); - - /* calc rgb */ - dx= 2.0f*(pixsize-maxd)/pixsize; - if(dx>=1.0f) { - Ta= fac4; Tb= fac3; - Tg= fac2; Tr= fac1; - } - else { - dy= 1.0f-dx; - Tb= dy*Tb+ dx*fac3; - Tg= dy*Tg+ dx*fac2; - Tr= dy*Tr+ dx*fac1; - if(Talpha) Ta= dy*Ta+ dx*fac4; - } - - val1= dy*val1+ dx*(fac1+fac2+fac3); - boxsample(previbuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4); - val2= dy*val2+ dx*(fac1+fac2+fac3); - boxsample(previbuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4); - val3= dy*val3+ dx*(fac1+fac2+fac3); - } - - /* don't switch x or y! */ - tex->nor[0]= (val1-val2); - tex->nor[1]= (val1-val3); - } - else { - maxx= fx+minx; - minx= fx-minx; - maxy= fy+miny; - miny= fy-miny; - - boxsample(ibuf, minx, miny, maxx, maxy, &Tr, &Tg, &Tb, &Ta); - - if(previbuf!=ibuf) { /* interpolate */ - boxsample(previbuf, minx, miny, maxx, maxy, &fac1, &fac2, &fac3, &fac4); - - fx= 2.0f*(pixsize-maxd)/pixsize; - - if(fx>=1.0) { - Ta= fac4; Tb= fac3; - Tg= fac2; Tr= fac1; - } else { - fy= 1.0f-fx; - Tb= fy*Tb+ fx*fac3; - Tg= fy*Tg+ fx*fac2; - Tr= fy*Tr+ fx*fac1; - if(Talpha) Ta= fy*Ta+ fx*fac4; - } - } - } - } - else { - if((tex->imaflag & TEX_INTERPOL)) { - /* sample 1 pixel minimum */ - if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x; - if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y; - } - - if(tex->nor && (tex->imaflag & TEX_NORMALMAP)==0) { - - /* a bit extra filter */ - minx*= 1.35f; - miny*= 1.35f; - - boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta); - val1= Tr+Tg+Tb; - - boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4); - val2= fac1+fac2+fac3; - - boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+miny, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4); - val3= fac1+fac2+fac3; - - /* don't switch x or y! */ - tex->nor[0]= (val1-val2); - tex->nor[1]= (val1-val3); - } - else { - boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta); - } - } - - BRICONRGB; - - if(tex->imaflag & TEX_CALCALPHA) { - Ta= Tin= Ta*MAX3(Tr, Tg, Tb); - } - else Tin= Ta; - if(tex->flag & TEX_NEGALPHA) Ta= 1.0f-Ta; - - if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { - ibuf->rect-= (ibuf->x*ibuf->y); - } - - if(tex->nor && (tex->imaflag & TEX_NORMALMAP)) { - tex->nor[0]= 0.5-Tr; - tex->nor[1]= 0.5-Tg; - tex->nor[2]= -Tb; - } - } - else { - Tin= 0.0f; - return 0; - } - - if(tex->nor) return 3; - else return 1; -} - diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 71e19c040c5..f89b36a50cf 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -59,9 +59,7 @@ #include "BPY_extern.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif +#include "render.h" void free_material(Material *ma) { @@ -70,9 +68,6 @@ void free_material(Material *ma) BPY_free_scriptlink(&ma->scriptlink); - if(ma->ren) MEM_freeN(ma->ren); - ma->ren= NULL; - for(a=0; a<MAX_MTEX; a++) { mtex= ma->mtex[a]; if(mtex && mtex->tex) mtex->tex->id.us--; @@ -543,15 +538,9 @@ void init_render_material(Material *ma) MTex *mtex; int a, needuv=0; - if(ma->ren) return; - if(ma->flarec==0) ma->flarec= 1; - ma->ren= MEM_mallocN(sizeof(Material), "initrendermaterial"); - memcpy(ma->ren, ma, sizeof(Material)); - /* add all texcoflags from mtex */ - ma= ma->ren; ma->texco= 0; ma->mapto= 0; for(a=0; a<MAX_MTEX; a++) { @@ -584,9 +573,6 @@ void init_render_material(Material *ma) } if(needuv) ma->texco |= NEED_UV; - // optimize, render only checks for ray_mirror value */ - if((ma->mode & MA_RAYMIRROR)==0) ma->ray_mirror= 0.0; - // since the raytracer doesnt recalc O structs for each ray, we have to preset them all if(ma->mode & (MA_RAYMIRROR|MA_RAYTRANSP|MA_SHADOW_TRA)) { ma->texco |= NEED_UV|TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM; @@ -613,10 +599,7 @@ void init_render_materials() void end_render_material(Material *ma) { - - if(ma->ren) MEM_freeN(ma->ren); - ma->ren= 0; - + /* XXXX obsolete? check! */ if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { if( !(ma->mode & MA_HALO) ) { ma->r= ma->g= ma->b= 1.0; @@ -748,8 +731,6 @@ void delete_material_index() } obt= obt->id.next; } - allqueue(REDRAWBUTSMAT, 0); - /* check indices from mesh */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7a751f2d720..dbca2b6ec4f 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -169,16 +169,15 @@ Scene *add_scene(char *name) sce->r.framelen= 1.0; sce->r.frs_sec= 25; + sce->r.postgamma= 1.0; + sce->r.posthue= 1.0; + sce->r.postmul= 1.0; + sce->r.xplay= 640; sce->r.yplay= 480; sce->r.freqplay= 60; sce->r.depth= 32; - if (sce->r.avicodecdata) { -printf("this is not good\n"); - } -// sce->r.imtype= R_TARGA; - sce->r.stereomode = 1; // no stereo strcpy(sce->r.backbuf, "//backbuf"); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index e25a8a7f13c..c5f26eeb19c 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -65,7 +65,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "BKE_osa_types.h" #include "BKE_plugin_types.h" #include "BKE_bad_level_calls.h" @@ -82,8 +81,6 @@ #include "BKE_ipo.h" - - /* ------------------------------------------------------------------------- */ /* All support for plugin textures: */ @@ -241,14 +238,11 @@ ColorBand *add_colorband() int do_colorband(ColorBand *coba, float in, float out[4]) { - /* These vars form the texture channel, in render/intern/texture.c */ - extern int Talpha; CBData *cbd1, *cbd2, *cbd0, *cbd3; float fac, mfac, t[4]; int a; if(coba->tot==0) return 0; - Talpha= 1; cbd1= coba->data; if(coba->tot==1) { diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 77081f99246..abb5a2757dc 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -783,6 +783,10 @@ Vec2Addf( float *v2 ); +void tubemap(float x, float y, float z, float *u, float *v); +void spheremap(float x, float y, float z, float *u, float *v); + + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index f73005dcd9b..c4dd5de3a0e 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2492,3 +2492,38 @@ void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) *b= (float)(((col)>>16)&0xFF); *b /= 255.0f; } + + +/* *************** PROJECTIONS ******************* */ + +void tubemap(float x, float y, float z, float *u, float *v) +{ + float len; + + *v = (z + 1.0) / 2.0; + + len= sqrt(x*x+y*y); + if(len>0) { + *u = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0; + } +} + +/* ------------------------------------------------------------------------- */ + +void spheremap(float x, float y, float z, float *u, float *v) +{ + float len; + + len= sqrt(x*x+y*y+z*z); + if(len>0.0) { + + if(x==0.0 && y==0.0) *u= 0.0; /* othwise domain error */ + else *u = (1.0 - atan2(x,y)/M_PI )/2.0; + + z/=len; + *v = 1.0- saacos(z)/M_PI; + } +} + +/* ------------------------------------------------------------------------- */ + diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5e4bdd3ed7c..9efdb1f90f3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -106,32 +106,34 @@ #include "BKE_bad_level_calls.h" // for reopen_text build_seqar (from WHILE_SEQ) open_plugin_seq set_rects_butspace check_imasel_copy +#include "BKE_armature.h" // for precalc_bonelist_irestmats +#include "BKE_action.h" #include "BKE_constraint.h" -#include "BKE_utildefines.h" // SWITCH_INT WHILE_SEQ END_SEQ DATA ENDB DNA1 O_BINARY GLOB USER TEST REND -#include "BKE_main.h" // for Main +#include "BKE_curve.h" +#include "BKE_effect.h" // for give_parteff #include "BKE_global.h" // for G #include "BKE_property.h" // for get_property #include "BKE_library.h" // for wich_libbase -#include "BKE_texture.h" // for open_plugin_tex -#include "BKE_effect.h" // for give_parteff -#include "BKE_sca.h" // for init_actuator +#include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) -#include "BKE_armature.h" // for precalc_bonelist_irestmats -#include "BKE_action.h" #include "BKE_object.h" +#include "BKE_sca.h" // for init_actuator #include "BKE_scene.h" +#include "BKE_texture.h" // for open_plugin_tex +#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BIF_butspace.h" // for do_versions, patching event codes #include "BLO_readfile.h" #include "BLO_undofile.h" +#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory + #include "readfile.h" #include "genfile.h" -#include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory - #include "mydevice.h" +#include "blendef.h" /* Remark: still a weak point is the newadress() function, that doesnt solve reading from @@ -2012,7 +2014,6 @@ static void direct_link_material(FileData *fd, Material *ma) ma->ramp_col= newdataadr(fd, ma->ramp_col); ma->ramp_spec= newdataadr(fd, ma->ramp_spec); - ma->ren= NULL; /* should not be needed, nevertheless... */ } /* ************ READ MESH ***************** */ @@ -4594,11 +4595,24 @@ static void do_versions(Main *main) } if(main->versionfile <= 235) { Tex *tex= main->tex.first; + Scene *sce= main->scene.first; while(tex) { if(tex->nabla==0.0) tex->nabla= 0.025; tex= tex->id.next; } + while(sce) { + sce->r.postsat= 1.0; + sce= sce->id.next; + } + } + if(main->versionfile <= 236) { + Scene *sce= main->scene.first; + + while(sce) { + if(sce->r.postsat==0.0) sce->r.postsat= 1.0; + sce= sce->id.next; + } } /* don't forget to set version number in blender.c! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 7fc8ac914e4..3232f12f13e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -144,15 +144,17 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "BLI_linklist.h" #include "BKE_action.h" -#include "BKE_utildefines.h" // for KNOTSU KNOTSV WHILE_SEQ END_SEQ defines #include "BKE_bad_level_calls.h" // build_seqar (from WHILE_SEQ) free_oops error +#include "BKE_curve.h" #include "BKE_constraint.h" -#include "BKE_main.h" // G.main #include "BKE_global.h" // for G -#include "BKE_screen.h" // for waitcursor -#include "BKE_packedFile.h" // for packAll #include "BKE_library.h" // for set_listbasepointers +#include "BKE_main.h" // G.main +#include "BKE_packedFile.h" // for packAll +#include "BKE_screen.h" // for waitcursor +#include "BKE_scene.h" // for do_seq #include "BKE_sound.h" /* ... and for samples */ +#include "BKE_utildefines.h" // for defines #include "GEN_messaging.h" @@ -1494,8 +1496,8 @@ static void write_global(WriteData *wd) fg.curscreen= G.curscreen; fg.curscene= G.scene; - fg.displaymode= R.displaymode; - fg.winpos= R.winpos; + fg.displaymode= G.displaymode; + fg.winpos= G.winpos; fg.fileflags= (G.fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns... fg.globalf= G.f; diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h index facfecb0c6e..b82a1ab7133 100644 --- a/source/blender/include/BIF_meshtools.h +++ b/source/blender/include/BIF_meshtools.h @@ -34,7 +34,6 @@ #define BIF_MESHTOOLS_H extern void join_mesh(void); -extern void make_sticky(void); extern void fasterdraw(void); extern void slowerdraw(void); diff --git a/source/blender/include/BIF_renderwin.h b/source/blender/include/BIF_renderwin.h index efc13950bd6..6b607b110d6 100644 --- a/source/blender/include/BIF_renderwin.h +++ b/source/blender/include/BIF_renderwin.h @@ -46,6 +46,7 @@ void BIF_do_ogl_render(struct View3D *v3d, int anim); void BIF_renderwin_set_for_ogl_render(void); void BIF_renderwin_set_custom_cursor(unsigned char mask[16][2], unsigned char bitmap[16][2]); +void BIF_redraw_render_rect(void); void BIF_swap_render_rects(void); void BIF_toggle_render_display(void); diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 219b9cb1c7c..994559e6194 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -34,6 +34,7 @@ #ifndef BSE_SEQUENCE_H #define BSE_SEQUENCE_H + struct PluginSeq; struct StripElem; struct Strip; diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index 1f627234216..d4d2b2eba9b 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -31,12 +31,6 @@ #ifndef BLENDEF_H #define BLENDEF_H -#ifdef WIN32 -#else -#ifndef __BeOS -#define O_BINARY 0 -#endif -#endif /* **************** MAX ********************* */ @@ -53,46 +47,19 @@ #define MAXFLOAT ((float)3.40282347e+38) #endif -#include <float.h> - - - - -/* **************** GENERAL ********************* */ - -#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} -#define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} - -#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} -#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} +/* also fill in structs itself, dna cannot handle defines, duplicate with utildefines.h still */ +#ifndef FILE_MAXDIR +#define FILE_MAXDIR 160 +#define FILE_MAXFILE 80 +#endif -#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) -#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c) -#define CLAMPIS(a, b, c) ((a)<(b) ? (b) : (a)>(c) ? (c) : (a)) -#define CLAMPTEST(a, b, c) if((b)<(c)) {CLAMP(a, b, c);} else {CLAMP(a, c, b);} -#define IS_EQ(a,b) ((fabs((double)(a)-(b)) >= (double) FLT_EPSILON) ? 0 : 1) +#include <float.h> -#define INIT_MINMAX(min, max) (min)[0]= (min)[1]= (min)[2]= 1.0e30; (max)[0]= (max)[1]= (max)[2]= -1.0e30; -#define DO_MINMAX(vec, min, max) if( (min)[0]>(vec)[0] ) (min)[0]= (vec)[0]; \ - if( (min)[1]>(vec)[1] ) (min)[1]= (vec)[1]; \ - if( (min)[2]>(vec)[2] ) (min)[2]= (vec)[2]; \ - if( (max)[0]<(vec)[0] ) (max)[0]= (vec)[0]; \ - if( (max)[1]<(vec)[1] ) (max)[1]= (vec)[1]; \ - if( (max)[2]<(vec)[2] ) (max)[2]= (vec)[2]; \ -#define DO_MINMAX2(vec, min, max) if( (min)[0]>(vec)[0] ) (min)[0]= (vec)[0]; \ - if( (min)[1]>(vec)[1] ) (min)[1]= (vec)[1]; \ - if( (max)[0]<(vec)[0] ) (max)[0]= (vec)[0]; \ - if( (max)[1]<(vec)[1] ) (max)[1]= (vec)[1]; -#define MINSIZE(val, size) ( ((val)>=0.0) ? (((val)<(size)) ? (size): (val)) : ( ((val)>(-size)) ? (-size) : (val))) -#define BTST(a,b) ( ( (a) & 1<<(b) )!=0 ) -#define BCLR(a,b) ( (a) & ~(1<<(b)) ) -#define BSET(a,b) ( (a) | 1<<(b) ) -/* bit-row */ -#define BROW(min, max) (((max)>=31? 0xFFFFFFFF: (1<<(max+1))-1) - ((min)? ((1<<(min))-1):0) ) +/* **************** GENERAL ********************* */ // return values @@ -102,8 +69,6 @@ #define RET_YES (1 == 1) #define RET_NO (1 == 0) -#define LONGCOPY(a, b, c) {int lcpc=c, *lcpa=(int *)a, *lcpb=(int *)b; while(lcpc-->0) *(lcpa++)= *(lcpb++);} - #if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) /* big endian */ #define MAKE_ID2(c, d) ( (c)<<8 | (d) ) @@ -140,9 +105,6 @@ #define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) ) -#define KNOTSU(nu) ( (nu)->orderu+ (nu)->pntsu+ (nu->orderu-1)*((nu)->flagu & 1) ) -#define KNOTSV(nu) ( (nu)->orderv+ (nu)->pntsv+ (nu->orderv-1)*((nu)->flagv & 1) ) - /* psfont */ #define FNT_PDRAW 1 #define FNT_HAEBERLI 2 @@ -397,64 +359,9 @@ #define B_PERCENTSUBD 0x40 -/* ***************** DISPLIST ***************** */ - -#define DL_POLY 0 -#define DL_SEGM 1 -#define DL_SURF 2 -#define DL_TRIA 3 -#define DL_INDEX3 4 -#define DL_INDEX4 5 -#define DL_VERTCOL 6 -#define DL_VERTS 7 -#define DL_NORS 8 - -#define DL_SURFINDEX(cyclu, cyclv, sizeu, sizev) \ - \ - if( (cyclv)==0 && a==(sizev)-1) break; \ - if(cyclu) { \ - p1= sizeu*a; \ - p2= p1+ sizeu-1; \ - p3= p1+ sizeu; \ - p4= p2+ sizeu; \ - b= 0; \ - } \ - else { \ - p2= sizeu*a; \ - p1= p2+1; \ - p4= p2+ sizeu; \ - p3= p1+ sizeu; \ - b= 1; \ - } \ - if( (cyclv) && a==sizev-1) { \ - p3-= sizeu*sizev; \ - p4-= sizeu*sizev; \ - } - /* DISPLAYMODE */ #define R_DISPLAYVIEW 0 #define R_DISPLAYWIN 1 #define R_DISPLAYAUTO 2 - - -#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -#define RCOMP 3 -#define GCOMP 2 -#define BCOMP 1 -#define ACOMP 0 - -#else - -#define RCOMP 0 -#define GCOMP 1 -#define BCOMP 2 -#define ACOMP 3 -#endif - -#ifdef GS -#undef GS -#endif -#define GS(a) (*((short *)(a))) - #endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 06326142c64..9bbc63f729d 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -274,6 +274,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SELECTCODEC 1639 #define B_RTCHANGED 1640 #define B_SWITCHRENDER 1641 +#define B_FBUF_REDO 1642 #ifdef __NLA /* *********************** */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index fa2447a12f4..b5adabbdc15 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -93,7 +93,6 @@ typedef struct Material { struct MTex *mtex[10]; struct Ipo *ipo; - struct Material *ren; /* dynamic properties */ float friction, fh, reflect; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 36dbd75d741..04aa96c9d1f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -178,6 +178,8 @@ typedef struct RenderData { * 14: motion blur * 15: use unified renderer for this pic * 16: enable raytracing + * 17: gauss sampling for subpixels + * 18: keep float buffer after render */ int mode; @@ -208,9 +210,9 @@ typedef struct RenderData { * The gamma for the normal rendering. Used when doing * oversampling, to correctly blend subpixels to pixels. */ float gamma, gauss; - /** post-production settings. Don't really belong here */ - float postmul, postgamma, postadd, postigamma; - + /** post-production settings. */ + float postmul, postgamma, postadd, postigamma, posthue, postsat; + /* Dither noise intensity */ float dither_intensity; float pad_dither; @@ -298,6 +300,8 @@ typedef struct Scene { #define R_UNIFIED 0x8000 #define R_RAYTRACE 0x10000 #define R_GAUSS 0x20000 +#define R_FBUF 0x40000 +#define R_THREADS 0x80000 /* yafray: renderer flag (not only exclusive to yafray) */ #define R_INTERN 0 @@ -347,6 +351,7 @@ typedef struct Scene { #define R_LAMPHALO 8 #define R_RENDERING 16 #define R_ANIMRENDER 32 +#define R_REDRAW_PRV 64 /* vlakren->flag (vlak = face in dutch) char!!! */ #define R_SMOOTH 1 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 634d9e887eb..cd6a0b8bbdb 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -151,7 +151,7 @@ typedef struct Tex { short extend, len; float checkerdist, nabla; short frames, offset, sfra, fie_ima; - float norfac, *nor; + float norfac; struct Ipo *ipo; struct Image *ima; diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index f90c8f0158a..bcfb495b238 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -44,7 +44,6 @@ #include <butspace.h> #include <BKE_bad_level_calls.h> #include "sceneRender.h" -#include "render_types.h" #include "blendef.h" #include "Scene.h" #include "gen_utils.h" @@ -792,30 +791,30 @@ PyObject *M_Render_SetRenderWinPos( PyObject * self, PyObject * args ) return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expected a list" ) ); - R.winpos = 0; + G.winpos = 0; for( x = 0; x < PyList_Size( list ); x++ ) { if( !PyArg_Parse( PyList_GetItem( list, x ), "s", &loc ) ) { return EXPP_ReturnPyObjError( PyExc_TypeError, "python list not parseable\n" ); } if( strcmp( loc, "SW" ) == 0 || strcmp( loc, "sw" ) == 0 ) - R.winpos |= 1; + G.winpos |= 1; else if( strcmp( loc, "S" ) == 0 || strcmp( loc, "s" ) == 0 ) - R.winpos |= 2; + G.winpos |= 2; else if( strcmp( loc, "SE" ) == 0 || strcmp( loc, "se" ) == 0 ) - R.winpos |= 4; + G.winpos |= 4; else if( strcmp( loc, "W" ) == 0 || strcmp( loc, "w" ) == 0 ) - R.winpos |= 8; + G.winpos |= 8; else if( strcmp( loc, "C" ) == 0 || strcmp( loc, "c" ) == 0 ) - R.winpos |= 16; + G.winpos |= 16; else if( strcmp( loc, "E" ) == 0 || strcmp( loc, "e" ) == 0 ) - R.winpos |= 32; + G.winpos |= 32; else if( strcmp( loc, "NW" ) == 0 || strcmp( loc, "nw" ) == 0 ) - R.winpos |= 64; + G.winpos |= 64; else if( strcmp( loc, "N" ) == 0 || strcmp( loc, "n" ) == 0 ) - R.winpos |= 128; + G.winpos |= 128; else if( strcmp( loc, "NE" ) == 0 || strcmp( loc, "ne" ) == 0 ) - R.winpos |= 256; + G.winpos |= 256; else return EXPP_ReturnPyObjError( PyExc_AttributeError, "list contains unknown string\n" ); @@ -828,7 +827,7 @@ PyObject *M_Render_SetRenderWinPos( PyObject * self, PyObject * args ) //------------------------------------Render.EnableDispView() ----------- PyObject *M_Render_EnableDispView( PyObject * self ) { - R.displaymode = R_DISPLAYVIEW; + G.displaymode = R_DISPLAYVIEW; allqueue( REDRAWBUTSSCENE, 0 ); return EXPP_incr_ret( Py_None ); @@ -837,7 +836,7 @@ PyObject *M_Render_EnableDispView( PyObject * self ) //------------------------------------Render.EnableDispWin() ------------ PyObject *M_Render_EnableDispWin( PyObject * self ) { - R.displaymode = R_DISPLAYWIN; + G.displaymode = R_DISPLAYWIN; allqueue( REDRAWBUTSSCENE, 0 ); return EXPP_incr_ret( Py_None ); @@ -919,14 +918,14 @@ PyObject *RenderData_Play( BPy_RenderData * self ) } } if( BLI_exist( file ) ) { - calc_renderwin_rectangle( R.winpos, pos, size ); + calc_renderwin_rectangle( G.winpos, pos, size ); sprintf( str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file ); system( str ); } else { makepicstring( file, self->renderContext->sfra ); if( BLI_exist( file ) ) { - calc_renderwin_rectangle( R.winpos, pos, size ); + calc_renderwin_rectangle( G.winpos, pos, size ); sprintf( str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file ); system( str ); diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index e4c4f7edf13..b7761cd97d4 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -1,6 +1,7 @@ #!/usr/bin/python Import ('user_options_dict') Import ('library_env') +Import ('sdl_env') render_env = library_env.Copy () @@ -9,6 +10,7 @@ source_files = ['intern/source/RE_callbacks.c', 'intern/source/envmap.c', 'intern/source/errorHandler.c', 'intern/source/gammaCorrectionTables.c', + 'intern/source/imagetexture.c', 'intern/source/initrender.c', 'intern/source/jitter.c', 'intern/source/pixelblending.c', @@ -36,6 +38,7 @@ render_env.Append (CPPPATH = ['intern/include', '../quicktime', '../include', '../../kernel/gen_messaging', - '../yafray']) + '../yafray'] + + sdl_env['CPPPATH']) render_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/blender_render', source=source_files) diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h index d3953204678..209cf52b250 100644 --- a/source/blender/render/extern/include/render.h +++ b/source/blender/render/extern/include/render.h @@ -40,9 +40,6 @@ /* fixes. I think it is risky to always include it... */ /* ------------------------------------------------------------------------- */ -/* fix for OSA and defmaterial extern */ -#include "BKE_osa_types.h" -#include "DNA_material_types.h" #ifdef __cplusplus extern "C" { @@ -69,8 +66,6 @@ extern "C" { /* ------------------------------------------------------------------------- */ extern RE_Render R; /* rendercore.c */ -extern Osa O; /* rendercore.c */ -extern Material defmaterial; /* initrender.c */ extern unsigned short *igamtab1; /* initrender.c */ extern unsigned short *gamtab; /* initrender.c */ @@ -80,7 +75,7 @@ struct View3D; /* Function definitions */ /* */ /* All functions that need to be externally visible must be declared here. */ -/* Currently, this interface contains 29 functions and 11 callbacks. */ +/* Currently, this interface contains 38 functions and 11 callbacks. */ /* ------------------------------------------------------------------------- */ @@ -88,11 +83,12 @@ struct View3D; /* shadbuf.c (1) */ /* ------------------------------------------------------------------------- */ +/* only for renderconvertor */ void RE_initshadowbuf(struct LampRen *lar, float mat[][4]); /* ------------------------------------------------------------------------- */ -/* initrender (14) */ +/* initrender (9) */ /* ------------------------------------------------------------------------- */ struct View3D; @@ -107,7 +103,7 @@ struct View3D; void RE_initrender(struct View3D *ogl_render_view3d); /** - * + * only for renderconvertor */ void RE_setwindowclip(int mode, int jmode); @@ -117,12 +113,12 @@ void RE_setwindowclip(int mode, int jmode); */ void RE_animrender(struct View3D *ogl_render_view3d); void RE_free_render_data(void); -void RE_free_filt_mask(void); -void RE_init_filt_mask(void); void RE_init_render_data(void); + /* jitterate is used by blenkernel effect */ void RE_jitterate1(float *jit1, float *jit2, int num, float rad1); void RE_jitterate2(float *jit1, float *jit2, int num, float rad2); void RE_make_existing_file(char *name); +void RE_floatbuffer_to_output(void); /* ------------------------------------------------------------------------- */ /* zbuf (2) */ @@ -151,7 +147,7 @@ void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_t /* ------------------------------------------------------------------------- */ -/* texture */ +/* texture (9) */ /* ------------------------------------------------------------------------- */ struct MTex; struct Tex; @@ -161,17 +157,11 @@ void end_render_textures(void); void init_render_texture(struct Tex *tex); void end_render_texture(struct Tex *tex); -void tubemap(float x, float y, float z, float *adr1, float *adr2); -void spheremap(float x, float y, float z, float *adr1, float *adr2); - void do_material_tex(ShadeInput *shi); -void externtex(struct MTex *mtex, float *vec); -void externtexcol(struct MTex *mtex, float *orco, char *col); -void do_lamp_tex(struct LampRen *la, float *lavec, ShadeInput *shi); -void do_sky_tex(float *); - -int multitex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex); +void do_lamp_tex(struct LampRen *la, float *lavec, ShadeInput *shi, float *fcol); +int multitex_ext(struct Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta); +void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta); /* ------------------------------------------------------------------------- */ /* envmap (4) */ @@ -186,7 +176,7 @@ struct EnvMap *RE_add_envmap(void); struct EnvMap *RE_copy_envmap(struct EnvMap *env); /* --------------------------------------------------------------------- */ -/* rendercore (2) */ +/* rendercore (10) */ /* --------------------------------------------------------------------- */ float Phong_Spec(float *n, float *l, float *v, int hard); float CookTorr_Spec(float *n, float *l, float *v, int hard); @@ -206,9 +196,8 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) struct VlakRen *RE_findOrAddVlak(int nr); struct VertRen *RE_findOrAddVert(int nr); struct HaloRen *RE_findOrAddHalo(int nr); -HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, float *orco, float hasize, - float vectsize); - +HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize, + float vectsize, int seed); /** * callbacks (11): @@ -255,13 +244,13 @@ int RE_testclip(float *v); /* patch for the external if, to support the split for the ui */ void RE_addalphaAddfac(char *doel, char *bron, char addfac); void RE_sky_char(float *view, char *col); -void RE_sky(float *view, float *col); void RE_renderflare(struct HaloRen *har); /** * Shade the pixel at xn, yn for halo har, and write the result to col. * Also called in: previewrender.c * @param har The halo to be rendered on this location - * @param col [unsigned int 3] The destination colour vector + * @param col [char 4] The destination colour vector + * @param colf [float 4] destination colour vector (need both) * @param zz Some kind of distance * @param dist Square of the distance of this coordinate to the halo's center * @param x [f] Pixel x relative to center @@ -269,7 +258,7 @@ void RE_renderflare(struct HaloRen *har); * @param flarec Flare counter? Always har->flarec... */ void RE_shadehalo(struct HaloRen *har, - char *col, + char *col, float *colf, unsigned int zz, float dist, float x, diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 9f1fb9efef2..f8826228535 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -51,14 +51,48 @@ /* ------------------------------------------------------------------------- */ +/* localized texture result data */ +typedef struct TexResult { + float tin, tr, tg, tb, ta; + int talpha; + float *nor; +} TexResult; + /* localized renderloop data */ typedef struct ShadeInput { - struct Material *mat, *matren; + struct Material *mat; struct VlakRen *vlr; float co[3]; + + /* copy from material, keep synced so we can do memcopy */ + /* current size: 23*4 */ + float r, g, b; + float specr, specg, specb; + float mirr, mirg, mirb; + float ambr, ambb, ambg; + + float amb, emit, ang, spectra, ray_mirror; + float alpha, refl, spec, zoffs, add; + float translucency; + /* end direct copy from material */ + + /* individual copies: */ + int har; + + /* texture coordinates */ float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; float vn[3], view[3], refcol[4], displace[3]; + /* dx/dy OSA coordinates */ + float dxco[3], dyco[3]; + float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3]; + float dxref[3], dyref[3], dxorn[3], dyorn[3]; + float dxno[3], dyno[3], dxview, dyview; + float dxlv[3], dylv[3]; + float dxwin[3], dywin[3]; + float dxsticky[3], dysticky[3]; + float dxrefract[3], dyrefract[3]; + float xs, ys; /* pixel to be rendered */ short osatex; int mask; @@ -69,7 +103,7 @@ typedef struct ShadeInput /* here only stuff to initalize the render itself */ typedef struct RE_Render { - float grvec[3], inprz, inprh; + float grvec[3]; float imat[3][3]; float viewmat[4][4], viewinv[4][4]; @@ -113,6 +147,7 @@ typedef struct RE_Render unsigned int *rectspare; /* */ /* for 8 byte systems! */ long *rectdaps; + float *rectftot; /* original full color buffer */ short win, winpos, winx, winy, winxof, winyof; short winpop, displaymode, sparex, sparey; @@ -125,17 +160,6 @@ typedef struct RE_Render /* ------------------------------------------------------------------------- */ -/** - * Part as in part-rendering. An image rendered in parts is rendered - * to a list of parts, with x,y size, and a pointer to the render - * output stored per part. Internal! - */ -typedef struct Part -{ - struct Part *next, *prev; - unsigned int *rect; - short x, y; -} Part; typedef struct ShadBuf { short samp, shadhalostep; @@ -186,14 +210,14 @@ typedef struct RadFace { typedef struct VlakRen { struct VertRen *v1, *v2, *v3, *v4; + unsigned int lay; + unsigned int raycount; float n[3]; struct Material *mat; struct TFace *tface; unsigned int *vcol; char snproj, puno; char flag, ec; - unsigned int lay; - unsigned int raycount; RadFace *radface; Object *ob; } VlakRen; @@ -202,12 +226,12 @@ typedef struct VlakRen typedef struct HaloRen { + short miny, maxy; float alfa, xs, ys, rad, radsq, sin, cos, co[3], no[3]; + float hard, b, g, r; unsigned int zs, zd; - unsigned int zBufDist;/* depth in the z-buffer coordinate system */ - short miny, maxy; - short hard, b, g, r; - char starpoints, add, type, tex; + unsigned int zBufDist; /* depth in the z-buffer coordinate system */ + char starpoints, type, add, tex; char linec, ringc, seed; short flarec; /* used to be a char. why ?*/ float hasize; @@ -274,9 +298,9 @@ typedef struct LampRen /* ray optim */ VlakRen *vlr_last; - struct LampRen *org; struct MTex *mtex[MAX_MTEX]; } LampRen; + #endif /* RENDER_TYPES_H */ diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index c77bb01f6ac..7a44a139b20 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -40,8 +40,11 @@ * environment map as texture. * (initrender.c) */ + +struct TexResult; + void make_envmaps(void); -int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex); +int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); #endif /* ENVMAP_EXT_H */ diff --git a/source/blender/render/intern/include/gammaCorrectionTables.h b/source/blender/render/intern/include/gammaCorrectionTables.h index 8df743e468d..6197f769f6f 100644 --- a/source/blender/render/intern/include/gammaCorrectionTables.h +++ b/source/blender/render/intern/include/gammaCorrectionTables.h @@ -67,12 +67,7 @@ float invGammaCorrect(float col); /** * Tell whether or not to do gamma. */ -int doGamma(void); - -/** - * Set/unset performing gamma corrections. - */ -void setDoGamma(int); +extern int do_gamma; #endif diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h index 06c5f032c7d..15ec3eb69a3 100644 --- a/source/blender/render/intern/include/initrender.h +++ b/source/blender/render/intern/include/initrender.h @@ -42,16 +42,7 @@ /* Functions */ -void init_def_material(void); -void init_render_jit(int nr); -float calc_weight(float *weight, int i, int j); -void defaultlamp(void); void schrijfplaatje(char *name); -void initparts(void); -short setpart(short nr); /* return 0 als geen goede part */ -void addparttorect(short nr, Part *part); -void add_to_blurbuf(int blur); -void oldRenderLoop(void); /* Calls the old renderer. Contains the PART and FIELD loops. */ void render(void); /* Switch between the old and the unified renderer. */ /* void write_screendump(char *name); not here !*/ diff --git a/source/blender/render/intern/include/jitter.h b/source/blender/render/intern/include/jitter.h index f270207cc22..696ded297b1 100644 --- a/source/blender/render/intern/include/jitter.h +++ b/source/blender/render/intern/include/jitter.h @@ -41,7 +41,8 @@ extern "C" { extern float jit[64][2]; -void initjit(float *jitarr, int num); +extern void initjit(float *jitarr, int num); +extern void init_render_jit(int nr); #ifdef __cplusplus } diff --git a/source/blender/render/intern/include/old_zbuffer_types.h b/source/blender/render/intern/include/old_zbuffer_types.h deleted file mode 100644 index 4adf5f047ba..00000000000 --- a/source/blender/render/intern/include/old_zbuffer_types.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * $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 ***** - * Datatypes for old zbuffering algorithms. - */ - -#ifndef OLD_ZBUFFER_TYPES_H -#define OLD_ZBUFFER_TYPES_H "$Id$" - -typedef struct PixStr -{ - struct PixStr *next; - int vlak0, vlak; - unsigned int z; - unsigned int mask; - short aantal, ronde; -} PixStr; - -/* ------------------------------------------------------------------------- */ - -typedef struct PixStrMain -{ - struct PixStr *ps; - struct PixStrMain *next; -} PixStrMain; - -/* ------------------------------------------------------------------------- */ - -#endif - diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h index b413bc8b8a1..f5e96d075da 100644 --- a/source/blender/render/intern/include/pixelblending.h +++ b/source/blender/render/intern/include/pixelblending.h @@ -39,19 +39,6 @@ /* local includes */ #include "vanillaRenderPipe_types.h" -/* own include */ -#include "pixelblending_types.h" - -/** - * Samples pixel, depending on R.osa setting - */ -int addtosampcol(unsigned short *sampcol, unsigned short *shortcol, int mask); - -/** - * Samples pixel, bring your own R.osa setting - */ -int addToSampCol(unsigned short *sampcol, unsigned short *shortcol, int mask, int osaNr); - /** * Halo-add pixel, bring your own R.osa setting, and add factor */ diff --git a/source/blender/render/intern/include/pixelblending_types.h b/source/blender/render/intern/include/pixelblending_types.h deleted file mode 100644 index dac9924494f..00000000000 --- a/source/blender/render/intern/include/pixelblending_types.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * pixelblending_types.h - * types pixelblending - * - * $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 ***** - */ - -#ifndef PIXELBLENDING_TYPES_H -#define PIXELBLENDING_TYPES_H - -/* Threshold for a 'full' pixel: pixels with alpha above this level are */ -/* considered opaque This is the decimal value for 0xFFF0 / 0xFFFF */ -#define RE_FULL_COLOUR_FLOAT 0.9998 -/* Threshold for an 'empty' pixel: pixels with alpha above this level are */ -/* considered completely transparent. This is the decimal value */ -/* for 0x000F / 0xFFFF */ -#define RE_EMPTY_COLOUR_FLOAT 0.0002 -/* A 100% pixel. Sometimes, seems to be too little.... Hm....... */ -#define RE_UNITY_COLOUR_FLOAT 1.0 -/* A 0% pixel. I wonder how 0 the 0.0 is... */ -#define RE_ZERO_COLOUR_FLOAT 0.0 - -/* threshold for alpha */ -#define RE_FULL_ALPHA_FLOAT 0.9998 - -/* Same set of defines for shorts */ -#define RE_FULL_COLOUR_SHORT 0xFFF0 -#define RE_EMPTY_COLOUR_SHORT 0x0000 - -#endif /* PIXELBLENDING_EXT_H */ - diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h index dd429f9ff61..2f888cf05cf 100644 --- a/source/blender/render/intern/include/pixelshading.h +++ b/source/blender/render/intern/include/pixelshading.h @@ -51,12 +51,13 @@ * mask is pixel coverage in bits * @return pointer to the object */ -void *renderPixel(float x, float y, int *t, int mask); +void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *t, int mask); -void *renderHaloPixel(float x, float y, int haloNr) ; +void *renderHaloPixel(RE_COLBUFTYPE *collector, float x, float y, int haloNr) ; void setSkyBlendingMode(enum RE_SkyAlphaBlendingType mode); + void shadeHaloFloat(HaloRen *har, float *col, unsigned int zz, float dist, float xn, @@ -69,13 +70,14 @@ enum RE_SkyAlphaBlendingType getSkyBlendingMode(void); /** * Render the sky at pixel (x, y). */ -void renderSkyPixelFloat(float x, float y); +void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y); /* used by shadeSkyPixel: */ -void shadeSkyPixelFloat(float y, float *view); +void shadeSkyPixelFloat(float *colf, float *view, float *dxyview); void renderSpotHaloPixel(float x, float y, float *target); -void shadeSkyPixel(float fx, float fy); -void fillBackgroundImage(float x, float y); +void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy); +void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y); +void fillBackgroundImageChar(char *col, float x, float y); /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/include/render_intern.h b/source/blender/render/intern/include/render_intern.h deleted file mode 100644 index 25302ad97bd..00000000000 --- a/source/blender/render/intern/include/render_intern.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * render_int.h - * misc internal defines for renderer - * - * $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 ***** - */ - - /* XXX, should die, no good reason to write - * regular (non-file related) endian dependant - * code. - */ -#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -#define RCOMP 3 -#define GCOMP 2 -#define BCOMP 1 -#define ACOMP 0 -#else -#define RCOMP 0 -#define GCOMP 1 -#define BCOMP 2 -#define ACOMP 3 -#endif - -#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);} -#define QUATCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2); *(v1+3)= *(v2+3);} - -#define CLAMPIS(a, b, c) ((a)<(b) ? (b) : (a)>(c) ? (c) : (a)) - -typedef struct { - int a, b, c, d; -} byte16; - -#define COPY_16(a,b) (*((byte16 *)(a))= *((byte16 *)(b))) - diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 964300ad27b..e66e405d383 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -54,20 +54,36 @@ typedef struct ShadeResult } ShadeResult; -float mistfactor(float *co); /* dist en hoogte, return alpha */ +typedef struct PixStr +{ + struct PixStr *next; + int vlak0, vlak; + unsigned int z; + unsigned int mask; + short aantal, ronde; +} PixStr; + +/* ------------------------------------------------------------------------- */ + +typedef struct PixStrMain +{ + struct PixStr *ps; + struct PixStrMain *next; +} PixStrMain; + + +float mistfactor(float *co); /* dist and height, return alpha */ -void render_lighting_halo(struct HaloRen *har, float *colf); -unsigned int calchalo_z(struct HaloRen *har, unsigned int zz); -void add_halo_flare(void); +void add_halo_flare(void); -void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, int i3); +void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, int i3); -void shade_color(struct ShadeInput *shi, ShadeResult *shr); -void shade_lamp_loop(struct ShadeInput *shi, ShadeResult *shr); +void shade_color(struct ShadeInput *shi, ShadeResult *shr); +void shade_lamp_loop(struct ShadeInput *shi, ShadeResult *shr); -float fresnel_fac(float *view, float *vn, float fresnel, float fac); -void calc_R_ref(struct ShadeInput *shi); -float spec(float inp, int hard); +float fresnel_fac(float *view, float *vn, float fresnel, float fac); +void calc_R_ref(struct ShadeInput *shi); +float spec(float inp, int hard); /* -------- ray.c ------- */ @@ -76,36 +92,12 @@ extern void ray_trace(ShadeInput *, ShadeResult *); extern void ray_ao(ShadeInput *, World *, float *); /** - * Apply the background (sky). Depending on the active alphamode and - * worldmode, different filling strategies are applied. - * Active alphamode = R.r.alphamode - * Active worldmode = R.wrld.mode - * <LI> - * <IT> R_ALPHAPREMUL - do not fill sky, but apply alpha to colours - * <IT> R_ALPHAKEY - do not fill sky, do not apply alpha to colours - * <IT> R_ADDSKY - fill skycolour in the background, blend - * transparent colours with the background - * (there's also a world dependency here? - * <LI> - * <IT> R.wrld.mode == WO_MIST - * <IT> R.r.bufflag == 1, R.flag == R_SEC_FIELD - * <IT> R.wrld.skytype == ( WO_SKYBLEND ^ WO_SKYTEX) - * <IT> R.wrld.skytype == WO_SKYPAPER - * <IT> R.r.mode == R_PANORAMA ) - * </LI> - * </LI> - * @param rect - * @param y - */ -void scanlinesky(char *rect, int y); - -/** - * Do z buffer stuff. + * Do z buffer and shade */ void zbufshade(void); /** - * Insert transparent faces into the z buffer? + * zbuffer and shade, anti aliased */ void zbufshadeDA(void); /* Delta Accum Pixel Struct */ @@ -113,20 +105,6 @@ void zbufshadeDA(void); /* Delta Accum Pixel Struct */ * Also called in: zbuf.c */ void *shadepixel(float x, float y, int vlaknr, int mask, float *col); -void shadepixel_short(float x, float y, int vlaknr, int mask, unsigned short *shortcol); - -/** - * Shade the pixel at xn, yn for halo har, and write the result to col. - * Also called in: previewrender.c - * @param har The halo to be rendered on this location - * @param col [unsigned int 3] The destination colour vector - * @param zz Some kind of distance - * @param dist Square of the distance of this coordinate to the halo's center - * @param x [f] Pixel x relative to center - * @param y [f] Pixel y relative to center - * @param flarec Flare counter? Always har->flarec... - */ -/* void shadehalo(struct HaloRen *har, char *col, unsigned int zz, float dist, float x, float y, short flarec); */ /** * A cryptic but very efficient way of counting the number of bits that diff --git a/source/blender/render/intern/include/rendercore_int.h b/source/blender/render/intern/include/rendercore_int.h deleted file mode 100644 index 6b6ae899a8d..00000000000 --- a/source/blender/render/intern/include/rendercore_int.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * render_int.h - * - * $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 ***** - */ - -#ifndef RENDER_INT_H -#define RENDER_INT_H - -#include "zbuf_types.h" -#include "render_types.h" - -void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens); -void add_filt_mask(unsigned int mask, unsigned short *col, unsigned int *rb1, unsigned int *rb2, unsigned int *rb3); -void addps(long *rd, int vlak, unsigned int z, short ronde); -PixStr *addpsmain(void); -float count_maskf(unsigned short mask); -void freeps(void); -void halovert(void); -void renderhalo(HaloRen *har); /* postprocess versie */ -void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, short ys); - -#endif /* RENDER_INT_H */ - diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h index f0bdcd224b6..279d5319b21 100644 --- a/source/blender/render/intern/include/shadbuf.h +++ b/source/blender/render/intern/include/shadbuf.h @@ -52,7 +52,7 @@ void makeshadowbuf(LampRen *lar); * @param inp The inproduct between viewvector and ? * */ -float testshadowbuf(struct ShadBuf *shb, float *rco, float inp); +float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp); /** * Determines the shadow factor for lamp <lar>, between <p1> diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 9932f5a60ea..866f631dac6 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -35,12 +35,32 @@ #ifndef TEXTURE_EXT_H #define TEXTURE_EXT_H +#define BRICONT texres->tin= (texres->tin-0.5)*tex->contrast+tex->bright-0.5; \ +if(texres->tin<0.0) texres->tin= 0.0; else if(texres->tin>1.0) texres->tin= 1.0; + +#define BRICONTRGB texres->tr= tex->rfac*((texres->tr-0.5)*tex->contrast+tex->bright-0.5); \ +if(texres->tr<0.0) texres->tr= 0.0; \ +texres->tg= tex->gfac*((texres->tg-0.5)*tex->contrast+tex->bright-0.5); \ +if(texres->tg<0.0) texres->tg= 0.0; \ +texres->tb= tex->bfac*((texres->tb-0.5)*tex->contrast+tex->bright-0.5); \ +if(texres->tb<0.0) texres->tb= 0.0; + + struct HaloRen; struct ShadeInput; +struct TexResult; +struct Tex; + +/* texture.h */ void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf); +void do_sky_tex(float *lo, float *dxyview, float *hor, float *zen, float *blend); void render_realtime_texture(struct ShadeInput *shi); +/* imagetexture.h */ + +int imagewraposa(struct Tex *tex, float *texvec, float *dxt, float *dyt, struct TexResult *texres); +int imagewrap(struct Tex *tex, float *texvec, struct TexResult *texres); #endif /* TEXTURE_EXT_H */ diff --git a/source/blender/render/intern/include/vanillaRenderPipe.h b/source/blender/render/intern/include/vanillaRenderPipe.h index 1ace0c23610..f242b8522fc 100644 --- a/source/blender/render/intern/include/vanillaRenderPipe.h +++ b/source/blender/render/intern/include/vanillaRenderPipe.h @@ -45,5 +45,15 @@ */ void zBufShadeAdvanced(void); +/** + * Copy the colour buffer output to R.rectot, to line y. + */ +void transferColourBufferToOutput(float *buf, int y); +/** + * using default transforms for brightness, gamma, hue, saturation etc. + */ +void std_floatcol_to_charcol(float *buf, char *target); + + #endif /* VANILLARENDERPIPE_EXT_H */ diff --git a/source/blender/render/intern/include/vanillaRenderPipe_int.h b/source/blender/render/intern/include/vanillaRenderPipe_int.h deleted file mode 100644 index 980befae66f..00000000000 --- a/source/blender/render/intern/include/vanillaRenderPipe_int.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * vanillaRenderPipe_int.h - * - * $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 ***** - */ - -#ifndef VANILLARENDERPIPE_INT_H -#define VANILLARENDERPIPE_INT_H - -#include "vanillaRenderPipe_types.h" -#include "zbufferdatastruct_types.h" - -/** - * Z buffer initializer, for new pipeline. - * <LI> - * <IT> AColourBuffer : colour buffer for one line - * <IT> APixbufExt : pixel data buffer for one line, depth RE_ZBUFLEN - * </LI> - */ -void initRenderBuffers(int width); -/* void initRenderBuffers(void); */ - -/** - * Z buffer destructor, frees stuff from initZBuffers(). - */ -void freeRenderBuffers(void); - -/** - * Fill the accumulation buffer APixbufExt with face and halo indices. - * Note: Uses globals. - * @param y the line number to set - */ -void calcZBufLine(int y); - -/** - * Shade and render the pixels in this line, into AColourBuffer - * Note: Uses globals. - * @param y the line number to set - */ -void renderZBufLine(int y); - -/** - * Count and sort the list behind ap into buf. Sorts on min. distance. - * Low index <=> high z - */ -int countAndSortPixelFaces(int buf[RE_MAX_FACES_PER_PIXEL][5], - RE_APixstrExt *ap); - -/** - * Compose the conflict and colour stacks - * Note: Uses globals. - */ -int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], - struct RE_faceField* stack, int ptr, - int totvlak, float x, float y, int osaNr); -/** - * Integrate conflicting layers. - * Note: Uses globals. - */ -int resolveConflict(struct RE_faceField* stack, int ptr, float x, float y); - -/** - * Integrate the colour stack, defer conflicts. - * Note: Uses globals. - */ -void integrateStack(struct RE_faceField* stack, int ptr, - float x, float y, int osaNr); - -/** - * Calculate the view depth to this object on this location, with - * the current view parameters in R. - */ -int calcDepth(float x, float y, void *data, int type); - - - -/** - * Fills in distances of all faces in a z buffer, for given jitter settings. - */ -int fillZBufDistances(void); - -/** - * Fills in distances of faces in the z buffer. - * - * Halo z buffering ---------------------------------------------- - * - * A halo is treated here as a billboard: no z-extension, always - * oriented perpendicular to the viewer. The rest of the z-buffer - * stores face-numbers first, then calculates colours as the - * final image is rendered. We'll use the same approach here, - * which differs from the original method (which was add halos per - * scan line). This means that the z-buffer now also needs to - * store info about what sort of 'thing' the index refers to. - * - * Halo extension: - * h.maxy --------- - * | h.xs + h.rad - * | h.xs - * | h.xs - h.rad - * h.miny --------- - * - * These coordinates must be clipped to picture size. - * I'm not quite certain about halo numbering. - * - * Halos and jittering ------------------------------------------- - * - * Halos were not jittered previously. Now they are. I wonder - * whether this may have some adverse effects here. - - * @return 1 for succes, 0 if the operation was interrupted. - */ -int zBufferAllFaces(void); - -/** - * Fills in distances of halos in the z buffer. - * @return 1 for succes, 0 if the operation was interrupted. - */ -int zBufferAllHalos(void); - -/** - * New fill function for z buffer, for edge-only rendering. - */ -void zBufferFillEdge(float *vec1, float *vec2); - -/** - * New fill function for z buffer. - */ -void zBufferFillFace(float *v1, float *v2, float *v3); - -/** - * One more filler: fill in halo data in z buffer. - * Empty so far, but may receive content of halo loop. - */ -void zBufferFillHalo(void); - -/** - * Copy the colour buffer output to R.rectot, to line y. - */ -void transferColourBufferToOutput(int y); - -/** - * Set the colour buffer fields to zero. - */ -void eraseColBuf(RE_COLBUFTYPE *buf); - -/** - * Blend source over dest, and leave result in dest. 1 pixel. - */ -void blendOverFloat(int type, float* dest, float* source, void* data); - -/** - * Blend source over dest, and leave result in dest. 1 pixel into - * multiple bins. - */ -void blendOverFloatRow(int type, float* dest, float* source, - void* data, int mask, int osaNr) ; - -/** - * Do a post-process step on a finalized render image. - */ -void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target); - -#endif /* VANILLARENDERPIPE_INT_H */ - diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index fdfa5b19abe..fe72db4ee41 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -112,7 +112,7 @@ void zbuffershad(struct LampRen *lar); * Also called in: render.c * @param y the line number to set */ -void abufsetrow(int y); +void abufsetrow(float *acolrow, int y); /** @@ -165,12 +165,12 @@ int vergzvlak(const void *x1, const void *x2); * @param c2 * @param c3 */ -void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3); +void zbufclip(unsigned int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3); /** * same, for edges */ -void zbufclipwire(struct VlakRen *vlr); +void zbufclipwire(unsigned int zvlnr, struct VlakRen *vlr); #ifdef __cplusplus } diff --git a/source/blender/render/intern/include/zbuf_int.h b/source/blender/render/intern/include/zbuf_int.h deleted file mode 100644 index 59a394d2908..00000000000 --- a/source/blender/render/intern/include/zbuf_int.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * zbuf_int.h - * internal interface for zbuf.h (ie. functions that are not used - * anywhere else) - * - * $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 ***** - */ - -#ifndef ZBUF_INT_H -#define ZBUF_INT_H - -#include "render_types.h" -#include "zbuf_types.h" - -/** - * Convert a homogenous coordinate to a z buffer coordinate. The - * function makes use of Zmulx, Zmuly, the x and y scale factors for - * the screen, and Zjitx, Zjity, the pixel offset. (These are declared - * in render.c) The normalised z coordinate must fall on [0, 1]. - * @param zco [3, 4 floats] pointer to the resulting z buffer coordinate - * @param hoco [4 floats] pointer to the homogenous coordinate of the - * vertex in world space. - */ -void hoco_to_zco(float *zco, float *hoco); - -/** - * Fill the z buffer for alpha? - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ -void zbufinvulAc(float *v1, float *v2, float *v3); - -/** - * Fill the z buffer, but invert z order, and add the face index to - * the corresponing face buffer. - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ -void zbufinvulGLinv(float *v1, float *v2, float *v3); - -/** - * Fill the z buffer, and add the face index to - * the corresponing face buffer. Writes into R.rectz and R.rectot. It - * assumes that Zvlnr is set to the face index of the face under - * consideration. Zvlnr is written into R.rectot. R.rectz - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ -void zbufinvulGL(float *v1, float *v2, float *v3); - -/** - * Fill the z buffer. The face buffer is not operated on! - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ -void zbufinvulGL_onlyZ(float *v1, float *v2, float *v3); - -/** - * Prints 3 unlabelled floating point values to stdout. Used for diagnostics. - * @param v1 any float - * @param v2 any float - * @param v3 any float - */ -void print3floats(float *v1, float *v2, float *v3); - -/** - * Checks labda and uses this to make decision about clipping the line - * segment from v1 to v2. labda is the factor by which the vector is - * cut. ( calculate s + l * ( t - s )). The result is appended to the - * vertex list of this face. - * Note: uses globals. - * (arguments: one int, one pointer to int... why?) - * @param v1 start coordinate s - * @param v2 target coordinate t - * @param b1 - * @param b2 - * @param clve vertex vector. - */ -static void maakvertpira(float *v1, float *v2, int *b1, int b2, int *clve); - -/** - * Sets labda: flag, and parametrize the clipping of vertices in - * viewspace coordinates. labda = -1 means no clipping, labda in [0, - * 1] means a clipping. - * Note: uses globals. - * @param v1 start coordinate s - * @param v2 target coordinate t - * @param b1 - * @param b2 - * @param b3 - * @param a index for coordinate (x, y, or z) - */ -static void clipp(float *v1, float *v2, int b1, int *b2, int *b3, int a); - -/** - * Tests whether this coordinate is 'inside' or 'outside' of the view - * volume? By definition, this is in [0, 1]. - * @param p vertex z difference plus coordinate difference? - * @param q origin z plus r minus some coordinate? - * @param u1 [in/out] clip fraction for ? - * @param u2 [in/out] - * @return 0 if point is outside, or 1 if the point lies on the clip - * boundary - */ -static short cliptestf(float p, float q, float *u1, float *u2); - - -/* not documented yet */ -/* not sure if these should stay static... */ - -static int clipline(float *v1, float *v2); - -/** - * Provide book-keeping for the z buffer data lists. - */ -APixstr *addpsmainA(void); -void freepsA(void); -APixstr *addpsA(void); - -/** - * Fill function for the z buffer (fills lines) - */ -void zbuflineAc(float *vec1, float *vec2); -void zbufline(float *vec1, float *vec2); - - -/** - * Copy results from the solid face z buffering to the transparent - * buffer. - */ -void copyto_abufz(int sample); - -/** - * Do accumulation z buffering. - */ -void zbuffer_abuf(void); - -/** - * Shade this face at this location in SCS. - */ -void shadetrapixel(float x, float y, int vlak, int mask, unsigned short *shortcol); - -/** - * Determine the distance to the camera of this halo, in ZCS. - */ -unsigned int calcHaloDist(HaloRen *har); - -#endif /* ZBUF_INT_H */ - diff --git a/source/blender/render/intern/source/Makefile b/source/blender/render/intern/source/Makefile index 400e6045c03..b55084b708b 100644 --- a/source/blender/render/intern/source/Makefile +++ b/source/blender/render/intern/source/Makefile @@ -58,6 +58,7 @@ CPPFLAGS += -I../../../../kernel/gen_messaging CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # not very neat: the rest of blender.. CPPFLAGS += -I../../../include +CPPFLAGS += $(NAN_SDLCFLAGS) ifeq ($(WITH_QUICKTIME), true) CPPFLAGS += -DWITH_QUICKTIME diff --git a/source/blender/render/intern/source/RE_callbacks.c b/source/blender/render/intern/source/RE_callbacks.c index c6b74867c73..acc115b2b87 100644 --- a/source/blender/render/intern/source/RE_callbacks.c +++ b/source/blender/render/intern/source/RE_callbacks.c @@ -34,7 +34,6 @@ #include <stdlib.h> /* for NULL??? */ #include <stdio.h> #include "render.h" -#include "render_intern.h" #include "RE_callbacks.h" #ifdef HAVE_CONFIG_H diff --git a/source/blender/render/intern/source/edgeRender.c b/source/blender/render/intern/source/edgeRender.c index 51d24236cd3..2181224871b 100644 --- a/source/blender/render/intern/source/edgeRender.c +++ b/source/blender/render/intern/source/edgeRender.c @@ -60,11 +60,11 @@ #include "MEM_guardedalloc.h" #include "MTC_vectorops.h" +#include "BKE_utildefines.h" #include "RE_callbacks.h" #include "edgeRender.h" #include "render.h" -#include "render_intern.h" #include "zbuf.h" /* for zbufclipwire and zbufclip */ #include "jitter.h" @@ -79,18 +79,12 @@ char edgeRender_c[] = "$Id$"; #endif /* ------------------------------------------------------------------------- */ -/* the lazy way: */ -#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) - -/* ------------------------------------------------------------------------- */ /* These function pointers are used for z buffer filling. */ -extern void (*zbuffunc)(float *, float *, float *); -extern void (*zbuflinefunc)(float *, float *); +extern void (*zbuffunc)(unsigned int, float *, float *, float *); +extern void (*zbuflinefunc)(unsigned int, float *, float *); extern float Zmulx, Zmuly; /* Some kind of scale? */ extern float Zjitx,Zjity; /* The x,y values for jitter offset */ -extern unsigned int Zvlnr; /* Face rendering pointer and counter: these */ -extern VlakRen *Zvlr; /* are used for 'caching' render results. */ /* ------------------------------------------------------------------------- */ @@ -148,12 +142,12 @@ void renderEdges(char * colourRect); /** * Buffer an edge between these two vertices in the e.r. distance buffer. */ -void fillEdgeRenderEdge(float *vec1, float *vec2); +static void fillEdgeRenderEdge(unsigned int, float *vec1, float *vec2); /** * Buffer a face between these two vertices in the e.r. distance buffer. */ -void fillEdgeRenderFace(float *v1, float *v2, float *v3); +static void fillEdgeRenderFace(unsigned int, float *v1, float *v2, float *v3); /** * Compose the edge render colour buffer. @@ -598,6 +592,8 @@ void calcEdgeRenderColBuf(char* colTargetBuffer) /* rendering, this should be ok. */ int zBufferEdgeRenderObjects(void) { + VlakRen *vlr= NULL; + unsigned int zvlnr; int keepLooping; int faceCounter; /* counter for face number */ Material *ma; @@ -607,30 +603,30 @@ int zBufferEdgeRenderObjects(void) faceCounter = 0; while ( (faceCounter < R.totvlak) && keepLooping) { - if((faceCounter & 255)==0) { Zvlr= R.blovl[faceCounter>>8]; } - else Zvlr++; + if((faceCounter & 255)==0) { vlr= R.blovl[faceCounter>>8]; } + else vlr++; - ma= Zvlr->mat; + ma= vlr->mat; /*exp*/ mat_cache = ma; /* face number is used in the fill functions */ - Zvlnr = faceCounter + 1; + zvlnr = faceCounter + 1; - if(Zvlr->flag & R_VISIBLE) { + if(vlr->flag & R_VISIBLE) { /* here we cull all transparent faces if mode == 0 */ if (selectmode || !(ma->mode & MA_ZTRA)) { /* here we can add all kinds of extra selection criteria */ - if(ma->mode & (MA_WIRE)) zbufclipwire(Zvlr); + if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); else { - zbufclip(Zvlr->v1->ho, Zvlr->v2->ho, Zvlr->v3->ho, - Zvlr->v1->clip, Zvlr->v2->clip, Zvlr->v3->clip); - if(Zvlr->v4) { - Zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ - zbufclip(Zvlr->v1->ho, Zvlr->v3->ho, Zvlr->v4->ho, - Zvlr->v1->clip, Zvlr->v3->clip, Zvlr->v4->clip); + zbufclip(zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, + vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + if(vlr->v4) { + zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ + zbufclip(zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, + vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } @@ -643,7 +639,7 @@ int zBufferEdgeRenderObjects(void) /* ------------------------------------------------------------------------- */ -void fillEdgeRenderFace(float *v1, float *v2, float *v3) +static void fillEdgeRenderFace(unsigned int zvlnr, float *v1, float *v2, float *v3) { /* Coordinates of the vertices are specified in ZCS */ double z0; /* used as temp var*/ @@ -851,7 +847,7 @@ void fillEdgeRenderFace(float *v1, float *v2, float *v3) /* ------------------------------------------------------------------------- */ -void fillEdgeRenderEdge(float *vec1, float *vec2) +static void fillEdgeRenderEdge(unsigned int zvlnr, float *vec1, float *vec2) { int start, end, x, y, oldx, oldy, ofs; int dz, vergz/* , mask */; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index f5a87ba7ae7..99ff21bd44e 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -49,6 +49,8 @@ #include "MEM_guardedalloc.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BKE_utildefines.h" + #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" /* for rectcpy */ @@ -58,38 +60,24 @@ #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "BIF_space.h" -#include "BIF_toolbox.h" - #include "BKE_library.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_world.h" // init_render_world #include "BKE_image.h" // BKE_write_ibuf +#include "MTC_matrixops.h" /* this module */ #include "RE_callbacks.h" #include "render.h" -#include "render_intern.h" #include "envmap.h" #include "mydevice.h" -#include "rendercore.h" /* calls zbufShade(DA).... I want to replace this with my own :)*/ +#include "rendercore.h" #include "renderHelp.h" -#include "MTC_matrixops.h" +#include "texture.h" #include "zbuf.h" -/* ------------------------------------------------------------------------- */ - -void envmap_split_ima(EnvMap *env); -void envmap_renderdata(EnvMap *env); -void envmap_transmatrix(float mat[][4], int part); -void env_rotate_scene(float mat[][4], int mode); -void env_layerflags(unsigned int notlay); -void env_set_imats(void); -void render_envmap(EnvMap *env); -int envcube_isect(float *vec, float *answ); -static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face); /* ------------------------------------------------------------------------- */ @@ -156,7 +144,7 @@ void RE_free_envmap(EnvMap *env) /* ------------------------------------------------------------------------- */ -void envmap_split_ima(EnvMap *env) +static void envmap_split_ima(EnvMap *env) { ImBuf *ibuf; Image *ima; @@ -168,7 +156,7 @@ void envmap_split_ima(EnvMap *env) dx= env->ima->ibuf->y; dx/= 2; if(3*dx != env->ima->ibuf->x) { - error("Incorrect envmap size"); + printf("Incorrect envmap size\n"); env->ok= 0; env->ima->ok= 0; } @@ -199,7 +187,7 @@ void envmap_split_ima(EnvMap *env) /* ------------------------------------------------------------------------- */ /* ****************** RENDER ********************** */ -void envmap_renderdata(EnvMap *env) +static void envmap_renderdata(EnvMap *env) { static RE_Render envR; static Object *camera; @@ -245,7 +233,7 @@ void envmap_renderdata(EnvMap *env) /* ------------------------------------------------------------------------- */ -void envmap_transmatrix(float mat[][4], int part) +static void envmap_transmatrix(float mat[][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; @@ -277,7 +265,7 @@ void envmap_transmatrix(float mat[][4], int part) /* ------------------------------------------------------------------------- */ -void env_rotate_scene(float mat[][4], int mode) +static void env_rotate_scene(float mat[][4], int mode) { VlakRen *vlr = NULL; VertRen *ver = NULL; @@ -366,7 +354,7 @@ void env_rotate_scene(float mat[][4], int mode) /* ------------------------------------------------------------------------- */ -void env_layerflags(unsigned int notlay) +static void env_layerflags(unsigned int notlay) { VlakRen *vlr = NULL; int a; @@ -392,7 +380,7 @@ void env_hideobject(Object *ob) /* ------------------------------------------------------------------------- */ -void env_set_imats() +static void env_set_imats() { Base *base; float mat[4][4]; @@ -409,7 +397,7 @@ void env_set_imats() /* ------------------------------------------------------------------------- */ -void render_envmap(EnvMap *env) +static void render_envmap(EnvMap *env) { /* only the cubemap is implemented */ ImBuf *ibuf; @@ -420,6 +408,11 @@ void render_envmap(EnvMap *env) /* need a recalc: ortho-render has no correct viewinv */ MTC_Mat4Invert(oldviewinv, R.viewmat); + /* do first, envmap_renderdata copies entire R struct */ + if(R.rectz) MEM_freeN(R.rectz); R.rectz= NULL; + if(R.rectot) MEM_freeN(R.rectot); R.rectot= NULL; + if(R.rectftot) MEM_freeN(R.rectftot); R.rectftot= NULL; + /* setup necessary globals */ envmap_renderdata(env); @@ -480,8 +473,9 @@ void render_envmap(EnvMap *env) } - if(R.rectz) MEM_freeN(R.rectz); R.rectz= 0; - if(R.rectot) MEM_freeN(R.rectot); R.rectot= 0; + if(R.rectz) MEM_freeN(R.rectz); R.rectz= NULL; + if(R.rectot) MEM_freeN(R.rectot); R.rectot= NULL; + if(R.rectftot) MEM_freeN(R.rectftot); R.rectftot= NULL; if(RE_local_test_break()) RE_free_envmapdata(env); else { @@ -557,7 +551,7 @@ void make_envmaps() if(do_init) { RE_local_init_render_display(); RE_local_clear_render_display(R.win); - allqueue(REDRAWBUTSSHADING, 0); // bad! + R.flag |= R_REDRAW_PRV; } // restore R.r.mode |= trace; @@ -566,7 +560,7 @@ void make_envmaps() /* ------------------------------------------------------------------------- */ -int envcube_isect(float *vec, float *answ) +static int envcube_isect(float *vec, float *answ) { float labda; int face; @@ -639,17 +633,16 @@ static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int fac /* ------------------------------------------------------------------------- */ -extern float Tin, Ta, Tr, Tg, Tb; /* texture.c */ -int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) +int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { /* texvec should be the already reflected normal */ EnvMap *env; - float fac, vec[3], sco[3], col[20], dxts[3], dyts[3]; + float fac, vec[3], sco[3], dxts[3], dyts[3]; int face, face1; env= tex->env; if(env==0 || env->object==0) { - Tin= 0.0; + texres->tin= 0.0; return 0; } if(env->stype==ENV_LOAD) { @@ -662,7 +655,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) if(env->ok==0) { - Tin= 0.0; + texres->tin= 0.0; return 0; } @@ -674,16 +667,17 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) tex->ima= env->cube[face]; if(osatex) { + MTC_Mat4Mul3Vecfl(env->object->imat, dxt); MTC_Mat4Mul3Vecfl(env->object->imat, dyt); set_dxtdyt(dxts, dyts, dxt, dyt, face); - imagewraposa(tex, sco, dxts, dyts); + imagewraposa(tex, sco, dxts, dyts, texres); /* edges? */ - if(Ta<1.0) { - col[0]= Ta; col[1]= Tr; col[2]= Tg; col[3]= Tb; + if(texres->ta<1.0) { + TexResult texr1, texr2; VecAddf(vec, vec, dxt); face1= envcube_isect(vec, sco); @@ -692,12 +686,11 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) if(face!=face1) { tex->ima= env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, sco, dxts, dyts); - col[4]= Ta; col[5]= Tr; col[6]= Tg; col[7]= Tb; + imagewraposa(tex, sco, dxts, dyts, &texr1); } - else col[4]= col[5]= col[6]= col[7]= 0.0; + else texr1.tr= texr1.tg= texr1.tb= texr1.ta= 0.0; - /* here was the nasty bug! col[5,6,7] were not zero-ed. FPE! */ + /* here was the nasty bug! results were not zero-ed. FPE! */ VecAddf(vec, vec, dyt); face1= envcube_isect(vec, sco); @@ -706,23 +699,23 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) if(face!=face1) { tex->ima= env->cube[face1]; set_dxtdyt(dxts, dyts, dxt, dyt, face1); - imagewraposa(tex, sco, dxts, dyts); - col[8]= Ta; col[9]= Tr; col[10]= Tg; col[11]= Tb; + imagewraposa(tex, sco, dxts, dyts, &texr2); } - else col[8]= col[9]= col[10]= col[11]= 0.0; - - fac= (col[0]+col[4]+col[8]); - fac= 1.0/fac; + else texr2.tr= texr2.tg= texr2.tb= texr2.ta= 0.0; - Tr= fac*(col[0]*col[1] + col[4]*col[5] + col[8]*col[9] ); - Tg= fac*(col[0]*col[2] + col[4]*col[6] + col[8]*col[10] ); - Tb= fac*(col[0]*col[3] + col[4]*col[7] + col[8]*col[11] ); - Ta= 1.0; - + fac= (texres->ta+texr1.ta+texr2.ta); + if(fac!=0.0) { + fac= 1.0/fac; + + texres->tr= fac*(texres->ta*texres->tr + texr1.ta*texr1.tr + texr2.ta*texr2.tr ); + texres->tg= fac*(texres->ta*texres->tg + texr1.ta*texr1.tg + texr2.ta*texr2.tg ); + texres->tb= fac*(texres->ta*texres->tb + texr1.ta*texr1.tb + texr2.ta*texr2.tb ); + } + texres->ta= 1.0; } } else { - imagewrap(tex, sco); + imagewrap(tex, sco, texres); } tex->ima= env->ima; diff --git a/source/blender/render/intern/source/errorHandler.c b/source/blender/render/intern/source/errorHandler.c index ed72a68a968..0ab927a9cd9 100644 --- a/source/blender/render/intern/source/errorHandler.c +++ b/source/blender/render/intern/source/errorHandler.c @@ -33,8 +33,8 @@ #include "GEN_messaging.h" #include "stdio.h" + #include "errorHandler.h" -#include "render_intern.h" #ifdef HAVE_CONFIG_H #include <config.h> diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c index 8af6edf76da..0e27aacd9e3 100644 --- a/source/blender/render/intern/source/gammaCorrectionTables.c +++ b/source/blender/render/intern/source/gammaCorrectionTables.c @@ -35,7 +35,6 @@ #include "gammaCorrectionTables.h" #include <stdlib.h> #include <math.h> -#include "render_intern.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -65,7 +64,7 @@ static float inv_colour_step; static float valid_gamma; static float valid_inv_gamma; static int gamma_table_initialised = 0; -static int do_gamma; +int do_gamma=0; /* ------------------------------------------------------------------------- */ float gammaCorrect(float c) @@ -153,19 +152,5 @@ int gammaTableIsInitialised(void) } /* ------------------------------------------------------------------------- */ -int doGamma() -{ - return do_gamma; -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set/unset performing gamma corrections. - */ -void setDoGamma(int i) -{ - do_gamma = i; -} /* eof */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c new file mode 100644 index 00000000000..e961729df16 --- /dev/null +++ b/source/blender/render/intern/source/imagetexture.c @@ -0,0 +1,911 @@ +/** + * + * $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 ***** + */ + + + +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <math.h> +#ifndef WIN32 +#include <unistd.h> +#else +#include <io.h> +#endif + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "DNA_image_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" + +#include "BLI_blenlib.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_image.h" +#include "BKE_texture.h" +#include "BKE_library.h" + +#include "SDL_thread.h" + +#include "render.h" +#include "texture.h" + + +int imaprepeat, imapextend; + + +/* *********** IMAGEWRAPPING ****************** */ + + +int imagewrap(Tex *tex, float *texvec, TexResult *texres) +{ + Image *ima; + struct ImBuf *ibuf; + float fx, fy, val1, val2, val3; + int ofs, x, y; + char *rect; + + texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0; + ima= tex->ima; + if(ima==NULL || ima->ok== 0) { + return 0; + } + + if(ima->ibuf==NULL) { + extern SDL_mutex *load_ibuf_lock; // initrender.c + if(load_ibuf_lock) SDL_mutexP(load_ibuf_lock); + if(ima->ibuf==NULL) ima_ibuf_is_nul(tex); + if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock); + } + + if (ima->ok) { + ibuf = ima->ibuf; + + if(tex->imaflag & TEX_IMAROT) { + fy= texvec[0]; + fx= texvec[1]; + } + else { + fx= texvec[0]; + fy= texvec[1]; + } + + if(tex->extend == TEX_CHECKER) { + int xs, ys; + + xs= (int)floor(fx); + ys= (int)floor(fy); + fx-= xs; + fy-= ys; + + if( (tex->flag & TEX_CHECKER_ODD)==0) { + if((xs+ys) & 1);else return 0; + } + if( (tex->flag & TEX_CHECKER_EVEN)==0) { + if((xs+ys) & 1) return 0; + } + /* scale around center, (0.5, 0.5) */ + if(tex->checkerdist<1.0) { + fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5; + fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5; + } + } + + x = (int)(fx*ibuf->x); + y = (int)(fy*ibuf->y); + + if(tex->extend == TEX_CLIPCUBE) { + if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) { + return 0; + } + } + else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { + if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) { + return 0; + } + } + else { + if(tex->extend==TEX_EXTEND) { + if(x>=ibuf->x) x = ibuf->x-1; + else if(x<0) x= 0; + } + else { + x= x % ibuf->x; + if(x<0) x+= ibuf->x; + } + if(tex->extend==TEX_EXTEND) { + if(y>=ibuf->y) y = ibuf->y-1; + else if(y<0) y= 0; + } + else { + y= y % ibuf->y; + if(y<0) y+= ibuf->y; + } + } + + /* warning, no return before setting back! */ + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { + ibuf->rect+= (ibuf->x*ibuf->y); + } + + ofs = y * ibuf->x + x; + rect = (char *)( ibuf->rect+ ofs); + + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { + ibuf->rect-= (ibuf->x*ibuf->y); + } + + if(tex->imaflag & TEX_USEALPHA) { + if(tex->imaflag & TEX_CALCALPHA); + else texres->talpha= 1; + } + + texres->tr = ((float)rect[0])/255.0f; + texres->tg = ((float)rect[1])/255.0f; + texres->tb = ((float)rect[2])/255.0f; + + if(texres->nor) { + if(tex->imaflag & TEX_NORMALMAP) { + texres->nor[0]= 0.5-texres->tr; + texres->nor[1]= 0.5-texres->tg; + texres->nor[2]= -texres->tb; + } + else { + /* bump: take three samples */ + val1= texres->tr+texres->tg+texres->tb; + + if(x<ibuf->x-1) { + rect+=4; + val2= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; + rect-=4; + } + else val2= val1; + + if(y<ibuf->y-1) { + rect+= 4*ibuf->x; + val3= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; + } + else val3= val1; + + /* do not mix up x and y here! */ + texres->nor[0]= (val1-val2); + texres->nor[1]= (val1-val3); + } + } + + //BRICONTRGB; + + if(texres->talpha) texres->ta= texres->tin= ((float)rect[3])/255.0f; + else if(tex->imaflag & TEX_CALCALPHA) { + texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb); + } + else texres->ta= texres->tin= 1.0; + + if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta; + + } + + if(texres->nor) return 3; + else return 1; +} + +static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2) +{ + rctf *rf, *newrct; + short a; + + a= *count; + rf= stack; + for(;a>0;a--) { + if(rf->xmin<x1) { + if(rf->xmax<x1) { + rf->xmin+= (x2-x1); + rf->xmax+= (x2-x1); + } + else { + if(rf->xmax>x2) rf->xmax= x2; + newrct= stack+ *count; + (*count)++; + + newrct->xmax= x2; + newrct->xmin= rf->xmin+(x2-x1); + newrct->ymin= rf->ymin; + newrct->ymax= rf->ymax; + + if(newrct->xmin==newrct->xmax) (*count)--; + + rf->xmin= x1; + } + } + else if(rf->xmax>x2) { + if(rf->xmin>x2) { + rf->xmin-= (x2-x1); + rf->xmax-= (x2-x1); + } + else { + if(rf->xmin<x1) rf->xmin= x1; + newrct= stack+ *count; + (*count)++; + + newrct->xmin= x1; + newrct->xmax= rf->xmax-(x2-x1); + newrct->ymin= rf->ymin; + newrct->ymax= rf->ymax; + + if(newrct->xmin==newrct->xmax) (*count)--; + + rf->xmax= x2; + } + } + rf++; + } + +} + +static void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2) +{ + rctf *rf, *newrct; + short a; + + a= *count; + rf= stack; + for(;a>0;a--) { + if(rf->ymin<y1) { + if(rf->ymax<y1) { + rf->ymin+= (y2-y1); + rf->ymax+= (y2-y1); + } + else { + if(rf->ymax>y2) rf->ymax= y2; + newrct= stack+ *count; + (*count)++; + + newrct->ymax= y2; + newrct->ymin= rf->ymin+(y2-y1); + newrct->xmin= rf->xmin; + newrct->xmax= rf->xmax; + + if(newrct->ymin==newrct->ymax) (*count)--; + + rf->ymin= y1; + } + } + else if(rf->ymax>y2) { + if(rf->ymin>y2) { + rf->ymin-= (y2-y1); + rf->ymax-= (y2-y1); + } + else { + if(rf->ymin<y1) rf->ymin= y1; + newrct= stack+ *count; + (*count)++; + + newrct->ymin= y1; + newrct->ymax= rf->ymax-(y2-y1); + newrct->xmin= rf->xmin; + newrct->xmax= rf->xmax; + + if(newrct->ymin==newrct->ymax) (*count)--; + + rf->ymax= y2; + } + } + rf++; + } +} + +static float square_rctf(rctf *rf) +{ + float x, y; + + x= rf->xmax- rf->xmin; + y= rf->ymax- rf->ymin; + return (x*y); +} + +static float clipx_rctf(rctf *rf, float x1, float x2) +{ + float size; + + size= rf->xmax - rf->xmin; + + if(rf->xmin<x1) { + rf->xmin= x1; + } + if(rf->xmax>x2) { + rf->xmax= x2; + } + if(rf->xmin > rf->xmax) { + rf->xmin = rf->xmax; + return 0.0; + } + else if(size!=0.0) { + return (rf->xmax - rf->xmin)/size; + } + return 1.0; +} + +static float clipy_rctf(rctf *rf, float y1, float y2) +{ + float size; + + size= rf->ymax - rf->ymin; + + if(rf->ymin<y1) { + rf->ymin= y1; + } + if(rf->ymax>y2) { + rf->ymax= y2; + } + + if(rf->ymin > rf->ymax) { + rf->ymin = rf->ymax; + return 0.0; + } + else if(size!=0.0) { + return (rf->ymax - rf->ymin)/size; + } + return 1.0; + +} + +static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) +{ + /* sample box, is clipped already, and minx etc. have been set at ibuf size. + Enlarge with antialiased edges of the pixels */ + + float muly,mulx,div; + int ofs; + int x, y, startx, endx, starty, endy; + char *rect; + + startx= (int)floor(rf->xmin); + endx= (int)floor(rf->xmax); + starty= (int)floor(rf->ymin); + endy= (int)floor(rf->ymax); + + if(startx < 0) startx= 0; + if(starty < 0) starty= 0; + if(endx>=ibuf->x) endx= ibuf->x-1; + if(endy>=ibuf->y) endy= ibuf->y-1; + + if(starty==endy && startx==endx) { + + ofs = starty*ibuf->x + startx; + rect = (char *)(ibuf->rect +ofs); + texres->tr= ((float)rect[0])/255.0f; + texres->tg= ((float)rect[1])/255.0f; + texres->tb= ((float)rect[2])/255.0f; + /* alpha has been set in function imagewraposa() */ + if(texres->talpha) { + texres->ta= ((float)rect[3])/255.0f; + } + } + else { + div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0; + for(y=starty;y<=endy;y++) { + ofs = y*ibuf->x +startx; + rect = (char *)(ibuf->rect+ofs); + + muly= 1.0; + + if(starty==endy); + else { + if(y==starty) muly= 1.0f-(rf->ymin - y); + if(y==endy) muly= (rf->ymax - y); + } + if(startx==endx) { + mulx= muly; + if(texres->talpha) texres->ta+= mulx*rect[3]; + texres->tr+= mulx*rect[0]; + texres->tg+= mulx*rect[1]; + texres->tb+= mulx*rect[2]; + div+= mulx; + } + else { + for(x=startx;x<=endx;x++) { + mulx= muly; + if(x==startx) mulx*= 1.0f-(rf->xmin - x); + if(x==endx) mulx*= (rf->xmax - x); + + if(mulx==1.0) { + if(texres->talpha) texres->ta+= rect[3]; + texres->tr+= rect[0]; + texres->tg+= rect[1]; + texres->tb+= rect[2]; + div+= 1.0; + } + else { + if(texres->talpha) texres->ta+= mulx*rect[3]; + texres->tr+= mulx*rect[0]; + texres->tg+= mulx*rect[1]; + texres->tb+= mulx*rect[2]; + div+= mulx; + } + rect+=4; + } + } + } + if(div!=0.0) { + div*= 255.0; + + texres->tb/= div; + texres->tg/= div; + texres->tr/= div; + + if(texres->talpha) texres->ta/= div; + } + else { + texres->tr= texres->tg= texres->tb= texres->ta= 0.0; + } + } +} + +static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres) +{ + /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 . + * Enlarge with antialiased edges of pixels. + * If global variable 'imaprepeat' has been set, the + * clipped-away parts are sampled as well. + */ + TexResult texr; + rctf *rf, stack[8]; + float opp, tot, alphaclip= 1.0; + short count=1; + + rf= stack; + rf->xmin= minx*(ibuf->x); + rf->xmax= maxx*(ibuf->x); + rf->ymin= miny*(ibuf->y); + rf->ymax= maxy*(ibuf->y); + + if(imapextend); + else if(imaprepeat) clipx_rctf_swap(stack, &count, 0.0, (float)(ibuf->x)); + else { + alphaclip= clipx_rctf(rf, 0.0, (float)(ibuf->x)); + + if(alphaclip<=0.0) { + texres->tr= texres->tb= texres->tg= texres->ta= 0.0; + return; + } + } + + if(imapextend); + else if(imaprepeat) clipy_rctf_swap(stack, &count, 0.0, (float)(ibuf->y)); + else { + alphaclip*= clipy_rctf(rf, 0.0, (float)(ibuf->y)); + + if(alphaclip<=0.0) { + texres->tr= texres->tb= texres->tg= texres->ta= 0.0; + return; + } + } + + if(count>1) { + tot= texres->tr= texres->tb= texres->tg= texres->ta= 0.0; + while(count--) { + boxsampleclip(ibuf, rf, &texr); + + opp= square_rctf(rf); + tot+= opp; + + texres->tr+= opp*texr.tr; + texres->tg+= opp*texr.tg; + texres->tb+= opp*texr.tb; + if(texres->talpha) texres->ta+= opp*texr.ta; + rf++; + } + if(tot!= 0.0) { + texres->tr/= tot; + texres->tg/= tot; + texres->tb/= tot; + if(texres->talpha) texres->ta/= tot; + } + } + else { + boxsampleclip(ibuf, rf, texres); + } + + if(texres->talpha==0) texres->ta= 1.0; + + if(alphaclip!=1.0) { + /* this is for laetr investigation, premul or not? */ + /* texres->tr*= alphaclip; */ + /* texres->tg*= alphaclip; */ + /* texres->tb*= alphaclip; */ + texres->ta*= alphaclip; + } +} + +static void makemipmap(Image *ima) +{ + struct ImBuf *ibuf; + int minsize, curmap=0; + + ibuf= ima->ibuf; + minsize= MIN2(ibuf->x, ibuf->y); + + while(minsize>3 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) { + + ibuf= IMB_dupImBuf(ibuf); + IMB_filter(ibuf); + ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf); + IMB_freeImBuf(ibuf); + ibuf= ima->mipmap[curmap]; + + curmap++; + minsize= MIN2(ibuf->x, ibuf->y); + } +} + + +int imagewraposa(Tex *tex, float *texvec, float *dxt, float *dyt, TexResult *texres) +{ + extern SDL_mutex *load_ibuf_lock; // initrender.c + TexResult texr; + Image *ima; + ImBuf *ibuf, *previbuf; + float fx, fy, minx, maxx, miny, maxy, dx, dy; + float maxd, pixsize, val1, val2, val3; + int curmap; + + + ima= tex->ima; + + texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0; + + if(ima==NULL || ima->ok== 0) { + return 0; + } + + if(ima->ibuf==NULL) { + if(load_ibuf_lock) SDL_mutexP(load_ibuf_lock); + if(ima->ibuf==NULL) ima_ibuf_is_nul(tex); + if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock); + } + + if (ima->ok) { + + if(tex->imaflag & TEX_MIPMAP) { + if(ima->mipmap[0]==NULL) { + if(load_ibuf_lock) SDL_mutexP(load_ibuf_lock); + if(ima->mipmap[0]==NULL) makemipmap(ima); + if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock); + } + } + + ibuf = ima->ibuf; + + if(tex->imaflag & TEX_USEALPHA) { + if(tex->imaflag & TEX_CALCALPHA); + else texres->talpha= 1; + } + + texr.talpha= texres->talpha; + + if(tex->imaflag & TEX_IMAROT) { + fy= texvec[0]; + fx= texvec[1]; + } + else { + fx= texvec[0]; + fy= texvec[1]; + } + + if(ibuf->flags & IB_fields) { + if(R.r.mode & R_FIELDS) { /* field render */ + if(R.flag & R_SEC_FIELD) { /* correction for 2nd field */ + /* fac1= 0.5/( (float)ibuf->y ); */ + /* fy-= fac1; */ + } + else { /* first field */ + fy+= 0.5f/( (float)ibuf->y ); + } + } + } + + /* pixel coordinates */ + + minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] ); + maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] ); + miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] ); + maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] ); + + /* tex_sharper has been removed */ + + minx= tex->filtersize*(maxx-minx)/2.0f; + miny= tex->filtersize*(maxy-miny)/2.0f; + + if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny); + + if(minx>0.25) minx= 0.25; + else if(minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */ + if(miny>0.25) miny= 0.25; + else if(miny<0.00001f) miny= 0.00001f; + + + /* repeat and clip */ + + /* watch it: imaprepeat is global value (see boxsample) */ + imaprepeat= (tex->extend==TEX_REPEAT); + imapextend= (tex->extend==TEX_EXTEND); + + if(tex->extend == TEX_CHECKER) { + int xs, ys, xs1, ys1, xs2, ys2, boundary; + + xs= (int)floor(fx); + ys= (int)floor(fy); + + // both checkers available, no boundary exceptions, checkerdist will eat aliasing + if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) { + fx-= xs; + fy-= ys; + } + else { + + xs1= (int)floor(fx-minx); + ys1= (int)floor(fy-miny); + xs2= (int)floor(fx+minx); + ys2= (int)floor(fy+miny); + boundary= (xs1!=xs2) || (ys1!=ys2); + + if(boundary==0) { + if( (tex->flag & TEX_CHECKER_ODD)==0) { + if((xs+ys) & 1); + else return 0; + } + if( (tex->flag & TEX_CHECKER_EVEN)==0) { + if((xs+ys) & 1) return 0; + } + fx-= xs; + fy-= ys; + } + else { + if(tex->flag & TEX_CHECKER_ODD) { + if((xs1+ys) & 1) fx-= xs2; + else fx-= xs1; + + if((ys1+xs) & 1) fy-= ys2; + else fy-= ys1; + } + if(tex->flag & TEX_CHECKER_EVEN) { + if((xs1+ys) & 1) fx-= xs1; + else fx-= xs2; + + if((ys1+xs) & 1) fy-= ys1; + else fy-= ys2; + } + } + } + + /* scale around center, (0.5, 0.5) */ + if(tex->checkerdist<1.0) { + fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5; + fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5; + minx/= (1.0-tex->checkerdist); + miny/= (1.0-tex->checkerdist); + } + } + + if(tex->extend == TEX_CLIPCUBE) { + if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0 || texvec[2]<-1.0 || texvec[2]>1.0) { + return 0; + } + } + else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) { + if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) { + return 0; + } + } + else { + if(tex->extend==TEX_EXTEND) { + if(fx>1.0) fx = 1.0; + else if(fx<0.0) fx= 0.0; + } + else { + if(fx>1.0) fx -= (int)(fx); + else if(fx<0.0) fx+= 1-(int)(fx); + } + + if(tex->extend==TEX_EXTEND) { + if(fy>1.0) fy = 1.0; + else if(fy<0.0) fy= 0.0; + } + else { + if(fy>1.0) fy -= (int)(fy); + else if(fy<0.0) fy+= 1-(int)(fy); + } + } + + /* warning no return! */ + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { + ibuf->rect+= (ibuf->x*ibuf->y); + } + + /* choice: */ + if(tex->imaflag & TEX_MIPMAP) { + + dx= minx; + dy= miny; + maxd= MAX2(dx, dy); + if(maxd>0.5) maxd= 0.5; + + pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y); + + curmap= 0; + previbuf= ibuf; + while(curmap<BLI_ARRAY_NELEMS(ima->mipmap) && ima->mipmap[curmap]) { + if(maxd < pixsize) break; + previbuf= ibuf; + ibuf= ima->mipmap[curmap]; + pixsize= 1.0f / (float)MIN2(ibuf->x, ibuf->y); /* this used to be 1.0 */ + curmap++; + } + + if(previbuf!=ibuf || (tex->imaflag & TEX_INTERPOL)) { + /* sample at least 1 pixel */ + if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x; + if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y; + } + + if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) { + /* a bit extra filter */ + minx*= 1.35f; + miny*= 1.35f; + + boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, texres); + val1= texres->tr+texres->tg+texres->tb; + boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &texr); + val2= texr.tr + texr.tg + texr.tb; + boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &texr); + val3= texr.tr + texr.tg + texr.tb; + + if(previbuf!=ibuf) { /* interpolate */ + + boxsample(previbuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &texr); + + /* calc rgb */ + dx= 2.0f*(pixsize-maxd)/pixsize; + if(dx>=1.0f) { + texres->ta= texr.ta; texres->tb= texr.tb; + texres->tg= texr.tg; texres->tr= texr.tr; + } + else { + dy= 1.0f-dx; + texres->tb= dy*texres->tb+ dx*texr.tb; + texres->tg= dy*texres->tg+ dx*texr.tg; + texres->tr= dy*texres->tr+ dx*texr.tr; + texres->ta= dy*texres->ta+ dx*texr.ta; + } + + val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb); + boxsample(previbuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &texr); + val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb); + boxsample(previbuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &texr); + val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb); + } + + /* don't switch x or y! */ + texres->nor[0]= (val1-val2); + texres->nor[1]= (val1-val3); + } + else { + maxx= fx+minx; + minx= fx-minx; + maxy= fy+miny; + miny= fy-miny; + + boxsample(ibuf, minx, miny, maxx, maxy, texres); + + if(previbuf!=ibuf) { /* interpolate */ + boxsample(previbuf, minx, miny, maxx, maxy, &texr); + + fx= 2.0f*(pixsize-maxd)/pixsize; + + if(fx>=1.0) { + texres->ta= texr.ta; texres->tb= texr.tb; + texres->tg= texr.tg; texres->tr= texr.tr; + } else { + fy= 1.0f-fx; + texres->tb= fy*texres->tb+ fx*texr.tb; + texres->tg= fy*texres->tg+ fx*texr.tg; + texres->tr= fy*texres->tr+ fx*texr.tr; + texres->ta= fy*texres->ta+ fx*texr.ta; + } + } + } + } + else { + if((tex->imaflag & TEX_INTERPOL)) { + /* sample 1 pixel minimum */ + if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x; + if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y; + } + + if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) { + + /* a bit extra filter */ + minx*= 1.35f; + miny*= 1.35f; + + boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, texres); + val1= texres->tr+texres->tg+texres->tb; + + boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &texr); + val2= texr.tr + texr.tg + texr.tb; + + boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+miny, fy+2.0f*miny, &texr); + val3= texr.tr + texr.tg + texr.tb; + + /* don't switch x or y! */ + texres->nor[0]= (val1-val2); + texres->nor[1]= (val1-val3); + } + else { + boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres); + } + } + + BRICONTRGB; + + if(tex->imaflag & TEX_CALCALPHA) { + texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb); + } + else texres->tin= texres->ta; + + if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta; + + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { + ibuf->rect-= (ibuf->x*ibuf->y); + } + + if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) { + texres->nor[0]= 0.5-texres->tr; + texres->nor[1]= 0.5-texres->tg; + texres->nor[2]= -texres->tb; + } + } + else { + texres->tin= 0.0f; + return 0; + } + + if(texres->nor) return 3; + else return 1; +} diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index be1f659d7e6..b4edee17bb6 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -86,17 +86,20 @@ #include "quicktime_export.h" #endif +#include "SDL_thread.h" + /* this module */ #include "render.h" -#include "render_intern.h" #include "RE_callbacks.h" #include "zbuf.h" #include "rendercore.h" /* part handler for the old renderer, shading functions */ +#include "pixelshading.h" #include "renderPreAndPost.h" #include "vanillaRenderPipe.h" #include "renderHelp.h" #include "jitter.h" +#include "gammaCorrectionTables.h" /* Own includes */ #include "initrender.h" @@ -104,72 +107,16 @@ /* yafray: include for yafray export/render */ #include "YafRay_Api.h" -/* Some crud :/ */ -#define ELEM3(a, b, c, d) ( ELEM(a, b, c) || (a)==(d) ) - -/* from render.c */ -extern float fmask[256], centLut[16], *fmask1[9], *fmask2[9]; -extern unsigned short *mask1[9], *mask2[9], *igamtab2; -extern char cmask[256], *centmask; +float centLut[16], *fmask1[9], *fmask2[9]; +unsigned short *gamtab, *igamtab2, *igamtab1; +char cmask[256], *centmask; Material defmaterial; -short pa; /* pa is global part, for print */ -short allparts[65][4]; -int qscount; - -/* ********************* *********************** */ - - -void init_def_material(void) -{ - Material *ma; - - ma= &defmaterial; - - init_material(&defmaterial); - - init_render_material(ma); -} - -void RE_init_render_data(void) -{ - memset(&R, 0, sizeof(RE_Render)); - memset(&O, 0, sizeof(Osa)); - O.dxwin[0]= 1.0; - O.dywin[1]= 1.0; - - R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove"); - R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl"); - R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha"); - R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray"); - - init_def_material(); -} - -void RE_free_render_data() -{ - MEM_freeN(R.blove); - R.blove= 0; - MEM_freeN(R.blovl); - R.blovl= 0; - MEM_freeN(R.bloha); - R.bloha= 0; - MEM_freeN(R.la); - R.la= 0; - if(R.rectot) MEM_freeN(R.rectot); - if(R.rectz) MEM_freeN(R.rectz); - if(R.rectspare) MEM_freeN(R.rectspare); - R.rectot= 0; - R.rectz= 0; - R.rectspare= 0; - - end_render_material(&defmaterial); -} /* ****************** GAMMA, MASKS and LUTS **************** */ -float calc_weight(float *weight, int i, int j) +static float calc_weight(float *weight, int i, int j) { float x, y, dist, totw= 0.0, fac; int a; @@ -201,23 +148,20 @@ float calc_weight(float *weight, int i, int j) return totw; } -void RE_init_filt_mask(void) +static void init_filt_mask(void) { static int firsttime=1; static int lastosa=0; static int lastgauss=0; static float lastgamma= 0.0; - float gamma, igamma, flweight[32]; + float gamma, igamma, flweight[32], fmask[256]; float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4; int i, j, a; - unsigned short *m1, *m2, shweight[32]; if(firsttime) { firsttime= 0; for(a=0; a<9;a++) { - mask1[a]= MEM_mallocN(256*sizeof(short), "initfilt"); - mask2[a]= MEM_mallocN(256*sizeof(short), "initfilt"); fmask1[a]= MEM_mallocN(256*sizeof(float), "initfilt"); fmask2[a]= MEM_mallocN(256*sizeof(float), "initfilt"); } @@ -294,10 +238,8 @@ void RE_init_filt_mask(void) } for(a=0; a<9;a++) { - memset(mask1[a], 0, 256*2); - memset(mask2[a], 0, 256*2); - memset(fmask1[a], 0, 256*4); - memset(fmask2[a], 0, 256*4); + memset(fmask1[a], 0, 256*sizeof(float)); + memset(fmask2[a], 0, 256*sizeof(float)); } /* calculate totw */ @@ -315,60 +257,41 @@ void RE_init_filt_mask(void) memset(weight, 0, sizeof(weight)); calc_weight(weight, i, j); - for(a=0; a<16; a++) shweight[a]= weight[a]*(65535.0/totw); for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw); - m1= mask1[ 3*(j+1)+i+1 ]; - m2= mask2[ 3*(j+1)+i+1 ]; m3= fmask1[ 3*(j+1)+i+1 ]; m4= fmask2[ 3*(j+1)+i+1 ]; for(a=0; a<256; a++) { if(a & 1) { - m1[a]+= shweight[0]; - m2[a]+= shweight[8]; m3[a]+= flweight[0]; m4[a]+= flweight[8]; } if(a & 2) { - m1[a]+= shweight[1]; - m2[a]+= shweight[9]; m3[a]+= flweight[1]; m4[a]+= flweight[9]; } if(a & 4) { - m1[a]+= shweight[2]; - m2[a]+= shweight[10]; m3[a]+= flweight[2]; m4[a]+= flweight[10]; } if(a & 8) { - m1[a]+= shweight[3]; - m2[a]+= shweight[11]; m3[a]+= flweight[3]; m4[a]+= flweight[11]; } if(a & 16) { - m1[a]+= shweight[4]; - m2[a]+= shweight[12]; m3[a]+= flweight[4]; m4[a]+= flweight[12]; } if(a & 32) { - m1[a]+= shweight[5]; - m2[a]+= shweight[13]; m3[a]+= flweight[5]; m4[a]+= flweight[13]; } if(a & 64) { - m1[a]+= shweight[6]; - m2[a]+= shweight[14]; m3[a]+= flweight[6]; m4[a]+= flweight[14]; } if(a & 128) { - m1[a]+= shweight[7]; - m2[a]+= shweight[15]; m3[a]+= flweight[7]; m4[a]+= flweight[15]; } @@ -452,13 +375,11 @@ void RE_init_filt_mask(void) } } -void RE_free_filt_mask() +static void free_filt_mask() { int a; for(a=0; a<9; a++) { - MEM_freeN(mask1[a]); - MEM_freeN(mask2[a]); MEM_freeN(fmask1[a]); MEM_freeN(fmask2[a]); } @@ -469,9 +390,9 @@ void RE_free_filt_mask() MEM_freeN(centmask); } -/* add stuff */ - +/* unused */ +#if 0 void defaultlamp() { LampRen *lar; @@ -489,8 +410,60 @@ void defaultlamp() lar->b= 1.0; lar->lay= 65535; } +#endif + + + +/* ********************* init calls *********************** */ +static void init_def_material(void) +{ + Material *ma; + + ma= &defmaterial; + + init_material(&defmaterial); + + init_render_material(ma); +} + +void RE_init_render_data(void) +{ + memset(&R, 0, sizeof(RE_Render)); + + R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove"); + R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl"); + R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha"); + R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray"); + + init_def_material(); + init_filt_mask(); +} + +void RE_free_render_data() +{ + MEM_freeN(R.blove); + R.blove= NULL; + MEM_freeN(R.blovl); + R.blovl= NULL; + MEM_freeN(R.bloha); + R.bloha= NULL; + MEM_freeN(R.la); + R.la= NULL; + if(R.rectot) MEM_freeN(R.rectot); + if(R.rectftot) MEM_freeN(R.rectftot); + if(R.rectz) MEM_freeN(R.rectz); + if(R.rectspare) MEM_freeN(R.rectspare); + R.rectot= NULL; + R.rectftot= NULL; + R.rectz= NULL; + R.rectspare= NULL; + + end_render_material(&defmaterial); + free_filt_mask(); +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void RE_make_existing_file(char *name) @@ -601,13 +574,41 @@ void RE_setwindowclip(int mode, int jmode) /* ~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~~~~ */ -#define PART_EMPTY -2 +/** +* Part as in part-rendering. An image rendered in parts is rendered +* to a list of parts, with x,y size, and a pointer to the render +* output stored per part. Internal! +*/ +typedef struct Part +{ + struct Part *next, *prev; + unsigned int *rect; // color 4x8 bits + float *rectf; // color 4x32 bits + unsigned int *rectz; // zbuffer + + short minx, miny, maxx, maxy, x, y; +} Part; + +static void freeparts(void) +{ + Part *part= R.parts.first; + while(part) { + if(part->rect) MEM_freeN(part->rect); + if(part->rectz) MEM_freeN(part->rectz); + if(part->rectf) MEM_freeN(part->rectf); + part= part->next; + } + BLI_freelistN(&R.parts); +} -void initparts() +static void initparts(void) { + Part *pa; short nr, xd, yd, xpart, ypart, xparts, yparts; short a, xminb, xmaxb, yminb, ymaxb; + freeparts(); + if(R.r.mode & R_BORDER) { xminb= R.r.border.xmin*R.rectx; xmaxb= R.r.border.xmax*R.rectx; @@ -629,9 +630,6 @@ void initparts() xparts= R.r.xparts; /* for border */ yparts= R.r.yparts; - for(nr=0;nr<xparts*yparts;nr++) - allparts[nr][0]= PART_EMPTY; /* clear array */ - xpart= R.rectx/xparts; ypart= R.recty/yparts; @@ -645,82 +643,108 @@ void initparts() xpart= (xmaxb-xminb)/xparts; ypart= (ymaxb-yminb)/yparts; } - + for(nr=0; nr<xparts*yparts; nr++) { - + pa= MEM_callocN(sizeof(Part), "new part"); + if(R.r.mode & R_PANORAMA) { - allparts[nr][0]= 0; - allparts[nr][1]= 0; - allparts[nr][2]= R.rectx; - allparts[nr][3]= R.recty; + pa->minx= pa->miny= 0; + pa->maxx= pa->x= R.rectx; + pa->maxy= pa->y= R.recty; } else { xd= (nr % xparts); yd= (nr-xd)/xparts; - allparts[nr][0]= xminb+ xd*xpart; - allparts[nr][1]= yminb+ yd*ypart; - if(xd<R.r.xparts-1) allparts[nr][2]= allparts[nr][0]+xpart; - else allparts[nr][2]= xmaxb; - if(yd<R.r.yparts-1) allparts[nr][3]= allparts[nr][1]+ypart; - else allparts[nr][3]= ymaxb; + pa->minx= xminb+ xd*xpart; + pa->miny= yminb+ yd*ypart; + if(xd<R.r.xparts-1) pa->maxx= pa->minx+xpart; + else pa->maxx= xmaxb; + if(yd<R.r.yparts-1) pa->maxy= pa->miny+ypart; + else pa->maxy= ymaxb; - if(allparts[nr][2]-allparts[nr][0]<=0) allparts[nr][0]= PART_EMPTY; - if(allparts[nr][3]-allparts[nr][1]<=0) allparts[nr][0]= PART_EMPTY; - - /* gauss needs 1 pixel extra to work */ + pa->x= pa->maxx-pa->minx; + pa->y= pa->maxy-pa->miny; + } + + if(pa->x>0 && pa->y>0) { + /* Gauss needs 1 pixel extra to work */ if(xparts*yparts>1 && (R.r.mode & R_GAUSS)) { - allparts[nr][0]-= 1; - allparts[nr][1]-= 1; - allparts[nr][2]+= 1; - allparts[nr][3]+= 1; + pa->minx-= 1; + pa->miny-= 1; + pa->maxx+= 1; + pa->maxy+= 1; + pa->x+= 2; + pa->y+= 2; } + BLI_addtail(&R.parts, pa); } + else MEM_freeN(pa); } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -short setpart(short nr) /* return 0 if incorrect part */ +static void setpart(Part *pa) { - if(allparts[nr][0]== PART_EMPTY) return 0; - - R.xstart= allparts[nr][0]-R.afmx; - R.ystart= allparts[nr][1]-R.afmy; - R.xend= allparts[nr][2]-R.afmx; - R.yend= allparts[nr][3]-R.afmy; - R.rectx= R.xend-R.xstart; - R.recty= R.yend-R.ystart; - - return 1; + R.xstart= pa->minx-R.afmx; + R.ystart= pa->miny-R.afmy; + R.xend= pa->maxx-R.afmx; + R.yend= pa->maxy-R.afmy; + R.rectx= pa->x; + R.recty= pa->y; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void addparttorect(short nr, Part *part) +static void addparttorect(Part *pa) { - unsigned int *rt, *rp; + float *rf, *rfp; + unsigned int *rt, *rtp, *rz, *rzp; int y, heigth, len, copylen; - /* the right offset in rectot */ + /* calc the right offset in rects, zbuffer cannot exist... */ - rp= part->rect; - copylen=len= (allparts[nr][2]-allparts[nr][0]); - heigth= (allparts[nr][3]-allparts[nr][1]); + rtp= pa->rect; + rzp= pa->rectz; + rfp= pa->rectf; + + copylen=len= pa->x; + heigth= pa->y; if(R.r.mode & R_GAUSS) { - rp+= 1+len; + + rtp+= 1+len; + if(rzp) rzp+= 1+len; + if(rfp) rfp+= 4*(1+len); + copylen= len-2; heigth -= 2; - rt= R.rectot+ (allparts[nr][1] + 1)*R.rectx+ (allparts[nr][0]+1); + rt= R.rectot+ (pa->miny + 1)*R.rectx+ (pa->minx+1); + rz= R.rectz+ (pa->miny + 1)*R.rectx+ (pa->minx+1); + rf= R.rectftot+ 4*( (pa->miny + 1)*R.rectx + (pa->minx+1) ); + } + else { + rt= R.rectot+ pa->miny*R.rectx+ pa->minx; + rz= R.rectz+ pa->miny*R.rectx+ pa->minx; + rf= R.rectftot+ 4*(pa->miny*R.rectx+ pa->minx); } - else rt= R.rectot+ allparts[nr][1]*R.rectx+ allparts[nr][0]; - for(y=0; y<heigth; y++) { - memcpy(rt, rp, 4*copylen); + memcpy(rt, rtp, 4*copylen); rt+= R.rectx; - rp+= len; + rtp+= len; + + if(rzp) { + memcpy(rz, rzp, 4*copylen); + rz+= R.rectx; + rzp+= len; + } + if(rfp) { + memcpy(rf, rfp, 16*copylen); + rf+= 4*R.rectx; + rfp+= 4*len; + } } } @@ -728,7 +752,7 @@ void addparttorect(short nr, Part *part) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void add_to_blurbuf(int blur) +static void add_to_blurbuf(int blur) { static unsigned int *blurrect= 0; int tot, gamval; @@ -797,7 +821,7 @@ void yafrayRender() R.flag |= R_RENDERING; /* !!! */ if (R.rectz) MEM_freeN(R.rectz); - R.rectz = 0; + R.rectz = NULL; // switch must be done before prepareScene() if (!R.r.YFexportxml) @@ -815,39 +839,70 @@ void yafrayRender() /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void render() { - /* yafray: render, see above */ - if (R.r.renderer==R_YAFRAY) - yafrayRender(); - else - oldRenderLoop(); -} + +// exported to other files, belongs in include... later +SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL; -void oldRenderLoop(void) /* here the PART and FIELD loops */ +static void renderloop_setblending(void) { - Part *part; - unsigned int *rt, *rt1, *rt2; - int len, y; - short blur, a,fields,fi,parts; /* pa is a global because of print */ + + /* this value should only be set here. do_gamma is for gammablended adding of subpixels */ + do_gamma= 0; + if(R.r.mode & R_GAMMA) { + if((R.r.mode & R_OSA)) do_gamma= 1; + } + + /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */ + init_filt_mask(); + + switch (R.r.alphamode) { + case R_ALPHAKEY: + setSkyBlendingMode(RE_ALPHA_KEY); + break; + case R_ALPHAPREMUL: + setSkyBlendingMode(RE_ALPHA_PREMUL); + break; + default: + setSkyBlendingMode(RE_ALPHA_SKY); + } + + /* SHould use slider when the gamma button is pressed. */ + if (do_gamma) { + makeGammaTables(2.0); + } else { + makeGammaTables(1.0); + } + +} - if (R.rectz) MEM_freeN(R.rectz); - R.rectz = 0; +static void mainRenderLoop(void) /* here the PART and FIELD loops */ +{ + Part *pa; + int blur, fields, fi, totparts, nr; + + /* create mutexes for threaded render */ + render_abuf_lock = SDL_CreateMutex(); + load_ibuf_lock = SDL_CreateMutex(); + if(R.rectz) MEM_freeN(R.rectz); + R.rectz = NULL; + if(R.rectftot) MEM_freeN(R.rectftot); + R.rectftot = NULL; + /* FIELD LOOP */ + totparts= R.r.xparts*R.r.yparts; fields= 1; - parts= R.r.xparts*R.r.yparts; if(R.r.mode & R_FIELDS) { fields= 2; - R.rectf1= R.rectf2= 0; /* field rects */ + R.rectf1= R.rectf2= NULL; /* field rects */ R.r.ysch/= 2; R.afmy/= 2; R.r.yasp*= 2; R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); } - for(fi=0; fi<fields; fi++) { @@ -874,7 +929,7 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur); initparts(); /* always do, because of border */ - setpart(0); + setpart(R.parts.first); RE_local_init_render_display(); RE_local_clear_render_display(R.win); @@ -882,20 +937,18 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ prepareScene(); - /* PARTS */ - R.parts.first= R.parts.last= 0; - for(pa=0; pa<parts; pa++) { + /* PARTS LOOP */ + nr= 0; + for(pa= R.parts.first; pa; pa= pa->next, nr++) { if(RE_local_test_break()) break; - if(pa) { /* because case pa==0 has been done */ - if(setpart(pa)==0) break; - } + setpart(pa); if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur); else RE_setwindowclip(0,-1); - if(R.r.mode & R_PANORAMA) setPanoRot(pa); + if(R.r.mode & R_PANORAMA) setPanoRot(nr); /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */ /* There may be some interference with z-coordinate */ @@ -903,10 +956,13 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ doClipping(RE_projectverto); if(RE_local_test_break()) break; - - + /* rectot is for result and integer face indices */ - R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + if(R.rectot) MEM_freeN(R.rectot); + R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + + if(R.rectftot) MEM_freeN(R.rectftot); + if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot"); if(R.r.mode & R_MBLUR) { RE_local_printrenderinfo(0.0, R.osa - blur); @@ -928,17 +984,14 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)); else { /* HANDLE PART OR BORDER */ - if(parts>1 || (R.r.mode & R_BORDER)) { + if(totparts>1 || (R.r.mode & R_BORDER)) { - part= MEM_callocN(sizeof(Part), "part"); - BLI_addtail(&R.parts, part); - part->rect= R.rectot; + pa->rect= R.rectot; R.rectot= NULL; - - if (R.rectz) { - MEM_freeN(R.rectz); - R.rectz= NULL; - } + pa->rectf= R.rectftot; + R.rectftot= NULL; + pa->rectz= R.rectz; + R.rectz= NULL; } } @@ -955,36 +1008,31 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; - if(parts>1 || (R.r.mode & R_BORDER)) { + if(totparts>1 || (R.r.mode & R_BORDER)) { + int a; + if(R.rectot) MEM_freeN(R.rectot); + if(R.rectftot) MEM_freeN(R.rectftot); + if(R.rectz) MEM_freeN(R.rectz); - R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + R.rectz= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectz"); + if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot"); + else R.rectftot= NULL; - part= R.parts.first; - for(pa=0; pa<parts; pa++) { - if(allparts[pa][0]== PART_EMPTY) break; - if(part==0) break; + for(a=0, pa= R.parts.first; pa; pa= pa->next, a++) { - if(R.r.mode & R_PANORAMA) { - if(pa) { - allparts[pa][0] += pa*R.r.xsch; - allparts[pa][2] += pa*R.r.xsch; - } + if(R.r.mode & R_PANORAMA) { // pano is fake parts... + pa->minx += a*R.r.xsch; + pa->maxx += a*R.r.xsch; } - addparttorect(pa, part); - - part= part->next; - } - - part= R.parts.first; - while(part) { - MEM_freeN(part->rect); - part= part->next; + addparttorect(pa); } - BLI_freelistN(&R.parts); } } - + + freeparts(); + if( (R.flag & R_HALO)) { if(RE_local_test_break()==0) add_halo_flare(); } @@ -1006,7 +1054,7 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if(R.r.mode & R_FIELDS) { if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot; else R.rectf1= R.rectot; - R.rectot= 0; + R.rectot= NULL; } if(RE_local_test_break()) break; @@ -1021,8 +1069,11 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if(R.rectot) MEM_freeN(R.rectot); /* happens when a render has been stopped */ R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - + if(RE_local_test_break()==0) { + unsigned int *rt, *rt1, *rt2; + int len, a; + rt= R.rectot; if(R.r.mode & R_ODDFIELD) { @@ -1045,48 +1096,58 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ rt2+= R.rectx; } } + + if(R.rectf1) MEM_freeN(R.rectf1); + R.rectf1= NULL; + if(R.rectf2) MEM_freeN(R.rectf2); + R.rectf2= NULL; + /* fbuf and zbuf free, image size differs now */ + if(R.rectftot) MEM_freeN(R.rectftot); + R.rectftot= NULL; + if(R.rectz) MEM_freeN(R.rectz); + R.rectz= NULL; + } - /* R.rectx= R.r.xsch; */ - /* if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; */ - /* R.recty= R.r.ysch; */ - /* if border: still do skybuf */ if(R.r.mode & R_BORDER) { if( (R.r.mode & R_MOVIECROP)==0) { if(R.r.bufflag & 1) { + unsigned int *rt; + int x, y; + R.xstart= -R.afmx; R.ystart= -R.afmy; rt= R.rectot; - for(y=0; y<R.recty; y++, rt+= R.rectx) scanlinesky((char *)rt, y); + for(y=0; y<R.recty; y++) { + for(x=0; x<R.rectx; x++, rt++) { + if(*rt==0) fillBackgroundImageChar((char *)rt, x, y); + } + } } } } set_mblur_offs(0); - /* FREE */ - - /* zbuf test */ - - /* don't free R.rectz, only when its size is not the same as R.rectot */ - - if (R.rectz && parts == 1 && (R.r.mode & R_FIELDS) == 0); - else { - if(R.rectz) MEM_freeN(R.rectz); - R.rectz= 0; - } - - if(R.rectf1) MEM_freeN(R.rectf1); - R.rectf1= 0; - if(R.rectf2) MEM_freeN(R.rectf2); - R.rectf2= 0; + /* mutexes free */ + SDL_DestroyMutex(load_ibuf_lock); + SDL_DestroyMutex(render_abuf_lock); + load_ibuf_lock= NULL; + render_abuf_lock= NULL; } +void render() { + /* yafray: render, see above */ + if (R.r.renderer==R_YAFRAY) + yafrayRender(); + else + mainRenderLoop(); +} /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -extern unsigned short usegamtab; + void RE_initrender(struct View3D *ogl_render_view3d) { double start_time; @@ -1163,23 +1224,16 @@ void RE_initrender(struct View3D *ogl_render_view3d) } } - usegamtab= 0; /* see also further */ - if(R.r.mode & (R_OSA|R_MBLUR)) { R.osa= R.r.osa; if(R.osa>16) R.osa= 16; init_render_jit(R.osa); - /* this value sometimes is reset temporally, for example in transp zbuf */ - if(R.r.mode & R_GAMMA) { - if((R.r.mode & R_OSA)) usegamtab= 1; - } } else R.osa= 0; - /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */ - RE_init_filt_mask(); + renderloop_setblending(); // alpha, sky, gamma /* when rendered without camera object */ /* it has to done here because of envmaps */ @@ -1205,14 +1259,15 @@ void RE_initrender(struct View3D *ogl_render_view3d) if(R.rectot) MEM_freeN(R.rectot); R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + if(R.rectftot) MEM_freeN(R.rectftot); + R.rectftot= NULL; + RE_local_timecursor((G.scene->r.cfra)); if(RE_local_test_break()==0) do_render_seq(); /* display */ - if(R.rectot) RE_local_render_display(0, R.recty-1, - R.rectx, R.recty, - R.rectot); + if(R.rectot) RE_local_render_display(0, R.recty-1, R.rectx, R.recty,R.rectot); } else if(R.r.scemode & R_OGL) { R.rectx= R.r.xsch; @@ -1221,6 +1276,9 @@ void RE_initrender(struct View3D *ogl_render_view3d) if(R.rectot) MEM_freeN(R.rectot); R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); + if(R.rectftot) MEM_freeN(R.rectftot); + R.rectftot= NULL; + RE_local_init_render_display(); drawview3d_render(ogl_render_view3d); } @@ -1232,8 +1290,11 @@ void RE_initrender(struct View3D *ogl_render_view3d) if(G.scene->camera==0) { error("No camera"); /* needed because R.rectx and R.recty can be unmatching R.rectot */ + if(R.rectot) MEM_freeN(R.rectot); R.rectot= NULL; + if(R.rectftot) MEM_freeN(R.rectftot); + R.rectftot= NULL; G.afbreek=1; return; @@ -1252,22 +1313,16 @@ void RE_initrender(struct View3D *ogl_render_view3d) /* display again: fields/seq/parts/pano etc */ if(R.rectot) { RE_local_init_render_display(); - RE_local_render_display(0, R.recty-1, - R.rectx, R.recty, - R.rectot); + RE_local_render_display(0, R.recty-1, R.rectx, R.recty, R.rectot); } else RE_local_clear_render_display(R.win); if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */ RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1); - /* restore variables */ - //R.osatex= 0; - //R.vlr= 0; - ///* at cubemap */ /* these flags remain on, until reset in caller to render (renderwin.c) */ - R.flag &= (R_RENDERING|R_ANIMRENDER); + R.flag &= (R_RENDERING|R_ANIMRENDER|R_REDRAW_PRV); } void RE_animrender(struct View3D *ogl_render_view3d) @@ -1285,8 +1340,7 @@ void RE_animrender(struct View3D *ogl_render_view3d) if(G.scene->r.scemode & R_OGL) R.r.mode &= ~R_PANORAMA; - // these calculations apply for - // all movie formats + // these calculations apply for all movie formats R.rectx= (R.r.size*R.r.xsch)/100; R.recty= (R.r.size*R.r.ysch)/100; if(R.r.mode & R_PANORAMA) { @@ -1295,7 +1349,7 @@ void RE_animrender(struct View3D *ogl_render_view3d) } if(R.r.mode & R_MOVIECROP) { initparts(); - setpart(0); // this will adjust r.rectx + setpart(R.parts.first); // this will adjust r.rectx } if (0) { @@ -1358,7 +1412,7 @@ void RE_animrender(struct View3D *ogl_render_view3d) } - (G.scene->r.cfra)= cfrao; + G.scene->r.cfra= cfrao; /* restore time */ if(R.r.mode & (R_FIELDS|R_MBLUR)) { diff --git a/source/blender/render/intern/source/jitter.c b/source/blender/render/intern/source/jitter.c index 50f465f4932..98bb1543068 100644 --- a/source/blender/render/intern/source/jitter.c +++ b/source/blender/render/intern/source/jitter.c @@ -40,12 +40,8 @@ #include "BLI_arithb.h" #include "BLI_rand.h" #include "render.h" -#include "render_intern.h" #include "jitter.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif float jit[64][2]; diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index 357be706ff9..05a5671b48f 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -39,13 +39,11 @@ /* global includes */ #include "render.h" -#include "render_intern.h" /* local includes */ #include "vanillaRenderPipe_types.h" /* own includes */ -#include "pixelblending_types.h" #include "pixelblending.h" #include "gammaCorrectionTables.h" @@ -63,6 +61,17 @@ /* blending difficulties otherwise. Be careful here. */ #define RE_ALPHA_CLIPPING + + +/* Threshold for a 'full' pixel: pixels with alpha above this level are */ +/* considered opaque This is the decimal value for 0xFFF0 / 0xFFFF */ +#define RE_FULL_COLOUR_FLOAT 0.9998 +/* Threshold for an 'empty' pixel: pixels with alpha above this level are */ +/* considered completely transparent. This is the decimal value */ +/* for 0x000F / 0xFFFF */ +#define RE_EMPTY_COLOUR_FLOAT 0.0002 + + /* functions --------------------------------------------------------------- */ /* @@ -103,7 +112,7 @@ void applyKeyAlphaCharCol(char* target) { } } -} /* end of void applyKeyAlphaCharCol(char* target) */ +} /* ------------------------------------------------------------------------- */ @@ -116,7 +125,7 @@ void addAddSampColF(float *sampvec, float *source, int mask, int osaNr, if(mask & (1<<a)) addalphaAddfacFloat(sampvec, source, addfac); sampvec+= 4; } -} /* end of void addAddSampColF(float, float, int, int) */ +} /* ------------------------------------------------------------------------- */ @@ -128,7 +137,7 @@ void addOverSampColF(float *sampvec, float *source, int mask, int osaNr) if(mask & (1<<a)) addAlphaOverFloat(sampvec, source); sampvec+= 4; } -} /* end of void addOverSampColF(float, float, int, int) */ +} /* ------------------------------------------------------------------------- */ @@ -142,35 +151,7 @@ int addUnderSampColF(float *sampvec, float *source, int mask, int osaNr) sampvec+= 4; } return retval; -} /* end of int addToSampColF(float, float, int, int) */ - -/* ------------------------------------------------------------------------- */ - -int addToSampCol(unsigned short *sampcol, unsigned short *shortcol, int mask, int osaNr) -{ - int a, retval = osaNr; - - for(a=0; a < osaNr; a++) { - if(mask & (1<<a)) addAlphaUnderShort(sampcol, shortcol); - if(sampcol[3]>0xFFF0) retval--; - sampcol+= 4; - } - return retval; -} /* end of int addToSampCol(unsigned short, uhost, int, int) */ - -/* ------------------------------------------------------------------------- */ - -int addtosampcol(unsigned short *sampcol, unsigned short *shortcol, int mask) -{ - int a, retval = R.osa; - - for(a=0; a < R.osa; a++) { - if(mask & (1<<a)) addAlphaUnderShort(sampcol, shortcol); - if(sampcol[3]>0xFFF0) retval--; - sampcol+= 4; - } - return retval; -} /* end of int addtosampcol(unsigned short *sampcol, unsigned short *shortcol, int mask) */ +} /* ------------------------------------------------------------------------- */ @@ -180,12 +161,6 @@ void addAlphaOverShort(unsigned short *doel, unsigned short *bron) unsigned int c; unsigned int mul; - if( doel[3]==0 || bron[3]>=0xFFF0) { /* has been tested */ - *((unsigned int *)doel)= *((unsigned int *)bron); - *((unsigned int *)(doel+2))= *((unsigned int *)(bron+2)); - return; - } - mul= 0xFFFF-bron[3]; c= ((mul*doel[0])>>16)+bron[0]; @@ -201,7 +176,7 @@ void addAlphaOverShort(unsigned short *doel, unsigned short *bron) if(c>=0xFFF0) doel[3]=0xFFF0; else doel[3]= c; -} /* end of void addAlphaOverShort(unsigned short *doel, unsigned short *bron) */ +} /* ------------------------------------------------------------------------- */ @@ -233,8 +208,8 @@ void addAlphaUnderShort(unsigned short *doel, unsigned short *bron) if(c>=0xFFF0) doel[3]=0xFFF0; else doel[3]= c; -} /* end of void addAlphaUnderShort(unsigned short *doel, unsigned short *bron) */ - +} + /* ------------------------------------------------------------------------- */ void addAlphaOverFloat(float *dest, float *source) @@ -257,8 +232,7 @@ void addAlphaOverFloat(float *dest, float *source) c= (mul*dest[3]) + source[3]; dest[3]= c; -} /* end of void addAlphaOverFloat(float *doel, float *bron) */ - +} /* ------------------------------------------------------------------------- */ @@ -291,7 +265,7 @@ void addAlphaUnderFloat(float *dest, float *source) c= (mul*source[3]) + dest[3]; dest[3]= c; -} /* end of void addAlphaUnderFloat(float *doel, float *bron) */ +} /* ------------------------------------------------------------------------- */ @@ -301,7 +275,7 @@ void cpShortColV2CharColV(unsigned short *source, char *dest) dest[1] = source[1]>>8; dest[2] = source[2]>>8; dest[3] = source[3]>>8; -} /* end of void cpShortColV2CharColV(unsigned short *source, char *dest) */ +} /* ------------------------------------------------------------------------- */ void cpCharColV2ShortColV(char *source, unsigned short *dest) @@ -310,7 +284,7 @@ void cpCharColV2ShortColV(char *source, unsigned short *dest) dest[1] = source[1]<<8; dest[2] = source[2]<<8; dest[3] = source[3]<<8; -} /* end of void cpShortColV2CharColV(char *source, unsigned short *dest) */ +} /* ------------------------------------------------------------------------- */ @@ -320,7 +294,7 @@ void cpIntColV2CharColV(unsigned int *source, char *dest) dest[1] = source[1]>>24; dest[2] = source[2]>>24; dest[3] = source[3]>>24; -} /* end of void cpIntColV2CharColV(unsigned int *source, char *dest) */ +} /* ------------------------------------------------------------------------- */ @@ -330,7 +304,8 @@ void cpCharColV2FloatColV(char *source, float *dest) dest[1] = source[1]/255.0; dest[2] = source[2]/255.0; dest[3] = source[3]/255.0; -} /* end of void cpCharColV2FloatColV(char *source, float *dest) */ +} + /* ------------------------------------------------------------------------- */ void cpShortColV2FloatColV(unsigned short *source, float *dest) @@ -339,7 +314,7 @@ void cpShortColV2FloatColV(unsigned short *source, float *dest) dest[1] = source[1]/65535.0; dest[2] = source[2]/65535.0; dest[3] = source[3]/65535.0; -} /* end of void cpShortColV2FloatColV(char *source, float *dest) */ +} /* ------------------------------------------------------------------------- */ @@ -362,7 +337,7 @@ void cpFloatColV2CharColV(float* source, char *dest) else if (source[3] > 1.0) dest[3] = 255; else dest[3] = (char) (source[3] * 255.0); -} /* end of void cpFloatColV2CharColV(float* source, char *dest) */ +} /* ------------------------------------------------------------------------- */ @@ -372,7 +347,7 @@ void cpShortColV(unsigned short *source, unsigned short *dest) dest[1] = source[1]; dest[2] = source[2]; dest[3] = source[3]; -} /* end of void cpShortColV(unsigned short *source, unsigned short *dest) */ +} /* ------------------------------------------------------------------------- */ void cpFloatColV(float *source, float *dest) @@ -381,7 +356,7 @@ void cpFloatColV(float *source, float *dest) dest[1] = source[1]; dest[2] = source[2]; dest[3] = source[3]; -} /* end of void cpFloatColV(float *source, float *dest) */ +} /* ------------------------------------------------------------------------- */ @@ -391,7 +366,7 @@ void cpCharColV(char *source, char *dest) dest[1] = source[1]; dest[2] = source[2]; dest[3] = source[3]; -} /* end of void cpCharColV(char *source, char *dest) */ +} /* ------------------------------------------------------------------------- */ void addalphaAddfacFloat(float *dest, float *source, char addfac) @@ -432,7 +407,7 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac) #endif dest[3]= c; -} /* end of void addalphaAddfacFloat(unsigned short *doel, unsigned short *bron, char addfac_help) */ +} /* ------------------------------------------------------------------------- */ @@ -468,7 +443,7 @@ void addalphaAddfacShort(unsigned short *doel, unsigned short *bron, char addfac if(c > 65535.0) doel[3] = 65535; else doel[3]= floor(c); -} /* end of void addalphaAddfacShort(unsigned short *doel, unsigned short *bron, char addfac_help) */ +} /* ------------------------------------------------------------------------- */ @@ -520,7 +495,7 @@ void addHaloToHaloShort(unsigned short *d, unsigned short *s) if( c[3] > 65535.0 ) d[3] = 65535; else d[3]= floor(c[3]); -} /* end of void addHaloToHaloShort(unsigned short *dest, unsigned short *source, char addfac) */ +} /* ------------------------------------------------------------------------- */ @@ -542,17 +517,15 @@ void sampleShortColV2ShortColV(unsigned short *sample, unsigned short *dest, int dest[2]= intcol[2]/osaNr; dest[3]= intcol[3]/osaNr; -} /* end of void sampleShortColVToShortColV(unsigned short *sample, unsigned short *dest) */ - +} /* ------------------------------------------------------------------------- */ -float *fmask1[9], *fmask2[9]; - /* filtered adding to scanlines */ void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float *rb3) { /* calc the value of mask */ + extern float *fmask1[], *fmask2[]; float val, r, g, b, al; unsigned int a, maskand, maskshift; int j; @@ -615,7 +588,7 @@ void sampleFloatColV2FloatColVFilter(float *sample, float *dest1, float *dest2, dest2[7]= sample[3]; } else { - if (doGamma()) { + if (do_gamma) { /* use a LUT and interpolation to do the gamma correction */ for(a=0; a < osaNr; a++, scol+=4) { intcol[0] = gammaCorrect( (scol[0]<1.0) ? scol[0]:1.0 ); diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index e1b468153f3..84416601986 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -45,6 +45,7 @@ #include "MTC_vectorops.h" #include "DNA_camera_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_image_types.h" #include "DNA_texture_types.h" @@ -56,11 +57,11 @@ #include "render.h" #include "texture.h" -#include "render_intern.h" #include "vanillaRenderPipe_types.h" #include "pixelblending.h" #include "rendercore.h" /* for some shading functions... */ +#include "shadbuf.h" #include "zbufferdatastruct.h" #include "renderHelp.h" @@ -69,13 +70,6 @@ #include "errorHandler.h" #include "pixelshading.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -/* The collector is the communication channel with the render pipe. */ -extern RE_COLBUFTYPE collector[4]; /* used throughout as pixel colour accu */ /* ton: - unified render now uses face render routines from rendercore.c @@ -83,16 +77,15 @@ extern RE_COLBUFTYPE collector[4]; /* used throughout as pixel colour accu */ /* ------------------------------------------------------------------------- */ -void *renderPixel(float x, float y, int *obdata, int mask) +void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int mask) { void* data = NULL; if (obdata[3] & RE_POLY) { - /* face pixels aren't rendered in floats yet, so we wrap it here */ data = shadepixel(x, y, obdata[1], mask, collector); } else if (obdata[3] & RE_HALO) { - data = renderHaloPixel(x, y, obdata[1]); + data = renderHaloPixel(collector, x, y, obdata[1]); } else if( obdata[1] == 0 ) { /* for lamphalo, but doesn't seem to be called? Actually it is, and */ @@ -126,7 +119,7 @@ static unsigned int calcHaloZ(HaloRen *har, unsigned int zz) return zz; } -void *renderHaloPixel(float x, float y, int haloNr) +void *renderHaloPixel(RE_COLBUFTYPE *collector, float x, float y, int haloNr) { HaloRen *har = NULL; float dist = 0.0; @@ -144,8 +137,8 @@ void *renderHaloPixel(float x, float y, int haloNr) dist = ((x - har->xs) * (x - har->xs)) + ((y - har->ys) * (y - har->ys) * R.ycor * R.ycor) ; - collector[0] = RE_ZERO_COLOUR_FLOAT; collector[1] = RE_ZERO_COLOUR_FLOAT; - collector[2] = RE_ZERO_COLOUR_FLOAT; collector[3] = RE_ZERO_COLOUR_FLOAT; + collector[0] = 0.0f; collector[1] = 0.0f; + collector[2] = 0.0f; collector[3] = 0.0f; if (dist < har->radsq) { shadeHaloFloat(har, collector, zz, dist, @@ -159,14 +152,184 @@ void *renderHaloPixel(float x, float y, int haloNr) /* ------------------------------------------------------------------------- */ extern float hashvectf[]; -void shadeHaloFloat(HaloRen *har, - float *col, unsigned int zz, - float dist, float xn, - float yn, short flarec) + +static void render_lighting_halo(HaloRen *har, float *colf) +{ + LampRen *lar; + float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn; + float ir, ig, ib, shadfac, soft, lacol[3]; + int a; + + ir= ig= ib= 0.0; + + VECCOPY(rco, har->co); + dco[0]=dco[1]=dco[2]= 1.0/har->rad; + + vn= har->no; + + for(a=0; a<R.totlamp; a++) { + lar= R.la[a]; + + /* test for lamplayer */ + if(lar->mode & LA_LAYER) if((lar->lay & har->lay)==0) continue; + + /* lampdist cacluation */ + if(lar->type==LA_SUN || lar->type==LA_HEMI) { + VECCOPY(lv, lar->vec); + lampdist= 1.0; + } + else { + lv[0]= rco[0]-lar->co[0]; + lv[1]= rco[1]-lar->co[1]; + lv[2]= rco[2]-lar->co[2]; + ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]); + lv[0]/= ld; + lv[1]/= ld; + lv[2]/= ld; + + /* ld is re-used further on (texco's) */ + + if(lar->mode & LA_QUAD) { + t= 1.0; + if(lar->ld1>0.0) + t= lar->dist/(lar->dist+lar->ld1*ld); + if(lar->ld2>0.0) + t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld); + + lampdist= t; + } + else { + lampdist= (lar->dist/(lar->dist+ld)); + } + + if(lar->mode & LA_SPHERE) { + t= lar->dist - ld; + if(t<0.0) continue; + + t/= lar->dist; + lampdist*= (t); + } + + } + + lacol[0]= lar->r; + lacol[1]= lar->g; + lacol[2]= lar->b; + + if(lar->mode & LA_TEXTURE) { + ShadeInput shi; + VECCOPY(shi.co, rco); + shi.osatex= 0; + do_lamp_tex(lar, lv, &shi, lacol); + } + + if(lar->type==LA_SPOT) { + + if(lar->mode & LA_SQUARE) { + if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) { + float x, lvrot[3]; + + /* rotate view to lampspace */ + VECCOPY(lvrot, lv); + MTC_Mat3MulVecfl(lar->imat, lvrot); + + x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); + /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ + + inpr= 1.0/(sqrt(1.0+x*x)); + } + else inpr= 0.0; + } + else { + inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]; + } + + t= lar->spotsi; + if(inpr<t) continue; + else { + t= inpr-t; + i= 1.0; + soft= 1.0; + if(t<lar->spotbl && lar->spotbl!=0.0) { + /* soft area */ + i= t/lar->spotbl; + t= i*i; + soft= (3.0*t-2.0*t*i); + inpr*= soft; + } + if(lar->mode & LA_ONLYSHADOW) { + /* if(ma->mode & MA_SHADOW) { */ + /* dot product positive: front side face! */ + inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; + if(inp>0.0) { + /* testshadowbuf==0.0 : 100% shadow */ + shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp); + if( shadfac>0.0 ) { + shadfac*= inp*soft*lar->energy; + ir -= shadfac; + ig -= shadfac; + ib -= shadfac; + + continue; + } + } + /* } */ + } + lampdist*=inpr; + } + if(lar->mode & LA_ONLYSHADOW) continue; + + } + + /* dot product and reflectivity*/ + + inp= 1.0-fabs(vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]); + + /* inp= cos(0.5*M_PI-acos(inp)); */ + + i= inp; + + if(lar->type==LA_HEMI) { + i= 0.5*i+0.5; + } + if(i>0.0) { + i*= lampdist; + } + + /* shadow */ + if(i> -0.41) { /* heuristic valua! */ + shadfac= 1.0; + if(lar->shb) { + shadfac = testshadowbuf(lar->shb, rco, dco, dco, inp); + if(shadfac==0.0) continue; + i*= shadfac; + } + } + + if(i>0.0) { + ir+= i*lacol[0]; + ig+= i*lacol[1]; + ib+= i*lacol[2]; + } + } + + if(ir<0.0) ir= 0.0; + if(ig<0.0) ig= 0.0; + if(ib<0.0) ib= 0.0; + + colf[0]*= ir; + colf[1]*= ig; + colf[2]*= ib; + +} + + + +void shadeHaloFloat(HaloRen *har, float *col, unsigned int zz, + float dist, float xn, float yn, short flarec) { /* fill in col */ - /* migrate: fill collector */ - float t, zn, radist, ringf=0.0, linef=0.0, alpha, si, co, colf[4]; + float t, zn, radist, ringf=0.0, linef=0.0, alpha, si, co; int a; if(R.wrld.mode & WO_MIST) { @@ -306,59 +469,53 @@ void shadeHaloFloat(HaloRen *har, /* The colour is either the rgb spec-ed by the user, or extracted from */ /* the texture */ if(har->tex) { - colf[0]= har->r; colf[1]= har->g; colf[2]= har->b; - colf[3]= dist; - do_halo_tex(har, xn, yn, colf); - colf[0]*= colf[3]; - colf[1]*= colf[3]; - colf[2]*= colf[3]; + col[0]= har->r; + col[1]= har->g; + col[2]= har->b; + col[3]= dist; + + do_halo_tex(har, xn, yn, col); + + col[0]*= col[3]; + col[1]*= col[3]; + col[2]*= col[3]; } else { - colf[0]= dist*har->r; - colf[1]= dist*har->g; - colf[2]= dist*har->b; - if(har->type & HA_XALPHA) colf[3]= dist*dist; - else colf[3]= dist; + col[0]= dist*har->r; + col[1]= dist*har->g; + col[2]= dist*har->b; + if(har->type & HA_XALPHA) col[3]= dist*dist; + else col[3]= dist; } if(har->mat && har->mat->mode & MA_HALO_SHADE) { /* we test for lights because of preview... */ - if(R.totlamp) render_lighting_halo(har, colf); + if(R.totlamp) render_lighting_halo(har, col); } - /* Next, we do the line and ring factor modifications. It seems we do */ - /* uchar calculations, but it's basically doing float arith with a 255 */ - /* scale factor. */ + /* Next, we do the line and ring factor modifications. */ if(linef!=0.0) { Material *ma= har->mat; - colf[0]+= 255.0*linef * ma->specr; - colf[1]+= 255.0*linef * ma->specg; - colf[2]+= 255.0*linef * ma->specb; + col[0]+= linef * ma->specr; + col[1]+= linef * ma->specg; + col[2]+= linef * ma->specb; - if(har->type & HA_XALPHA) colf[3]+= linef*linef; - else colf[3]+= linef; + if(har->type & HA_XALPHA) col[3]+= linef*linef; + else col[3]+= linef; } if(ringf!=0.0) { Material *ma= har->mat; - colf[0]+= 255.0*ringf * ma->mirr; - colf[1]+= 255.0*ringf * ma->mirg; - colf[2]+= 255.0*ringf * ma->mirb; + col[0]+= ringf * ma->mirr; + col[1]+= ringf * ma->mirg; + col[2]+= ringf * ma->mirb; - if(har->type & HA_XALPHA) colf[3]+= ringf*ringf; - else colf[3]+= ringf; + if(har->type & HA_XALPHA) col[3]+= ringf*ringf; + else col[3]+= ringf; } - - /* convert to [0.0; 1.0] range */ - col[0] = colf[0] / 255.0; - col[1] = colf[1] / 255.0; - col[2] = colf[2] / 255.0; - col[3] = colf[3]; - -} /* end of shadeHaloFloat() */ - +} /* ------------------------------------------------------------------------- */ /* @@ -390,7 +547,7 @@ enum RE_SkyAlphaBlendingType getSkyBlendingMode() { } /* This one renders into collector, as always. */ -void renderSkyPixelFloat(float x, float y) +void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y) { switch (keyingType) { @@ -418,7 +575,7 @@ void renderSkyPixelFloat(float x, float y) break; case RE_ALPHA_SKY: /* Fill in the sky as if it were a normal face. */ - shadeSkyPixel(x, y); + shadeSkyPixel(collector, x, y); collector[3]= 0.0; break; default: @@ -431,9 +588,9 @@ void renderSkyPixelFloat(float x, float y) /* Stuff the sky colour into the collector. */ -void shadeSkyPixel(float fx, float fy) +void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy) { - float view[3]; + float view[3], dxyview[2]; /* The rules for sky: @@ -445,7 +602,7 @@ void shadeSkyPixel(float fx, float fy) /* 1. Do a backbuffer image: */ if(R.r.bufflag & 1) { - if(R.backbuf) fillBackgroundImage(fx, fy); + if(R.backbuf) fillBackgroundImage(collector, fx, fy); return; } else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { /* @@ -458,7 +615,7 @@ void shadeSkyPixel(float fx, float fy) collector[0] = R.wrld.horr; collector[1] = R.wrld.horg; collector[2] = R.wrld.horb; - collector[3] = RE_UNITY_COLOUR_FLOAT; + collector[3] = 1.0f; } else { /* 3. Which type(s) is(are) this (these)? This has to be done when no simple @@ -486,8 +643,8 @@ void shadeSkyPixel(float fx, float fy) fac= Normalise(view); if(R.wrld.skytype & WO_SKYTEX) { - O.dxview= 1.0/fac; - O.dyview= R.ycor/fac; + dxyview[0]= 1.0/fac; + dxyview[1]= R.ycor/fac; } } @@ -504,16 +661,15 @@ void shadeSkyPixel(float fx, float fy) } /* get sky colour in the collector */ - shadeSkyPixelFloat(fy, view); + shadeSkyPixelFloat(collector, view, dxyview); + collector[3] = 1.0f; } - - } -/* Only line number is important here. Result goes to collector[4] */ -void shadeSkyPixelFloat(float y, float *view) +/* Only view vector is important here. Result goes to colf[3] */ +void shadeSkyPixelFloat(float *colf, float *view, float *dxyview) { - float lo[3]; + float lo[3], zen[3], hor[3], blend, blendm; /* Why is this setting forced? Seems silly to me. It is tested in the texture unit. */ R.wrld.skytype |= WO_ZENUP; @@ -521,19 +677,22 @@ void shadeSkyPixelFloat(float y, float *view) /* Some view vector stuff. */ if(R.wrld.skytype & WO_SKYREAL) { - R.inprz= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]; + blend= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]; - if(R.inprz<0.0) R.wrld.skytype-= WO_ZENUP; - R.inprz= fabs(R.inprz); + if(blend<0.0) R.wrld.skytype-= WO_ZENUP; + blend= fabs(blend); } else if(R.wrld.skytype & WO_SKYPAPER) { - R.inprz= 0.5+ 0.5*view[1]; + blend= 0.5+ 0.5*view[1]; } else { /* the fraction of how far we are above the bottom of the screen */ - R.inprz= fabs(0.5+ view[1]); + blend= fabs(0.5+ view[1]); } + hor[0]= R.wrld.horr; hor[1]= R.wrld.horr; hor[2]= R.wrld.horb; + zen[0]= R.wrld.zenr; zen[1]= R.wrld.zenr; zen[2]= R.wrld.zenb; + /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */ /* SKYBLEND is active, the texture and colour blend are added. */ if(R.wrld.skytype & WO_SKYTEX) { @@ -545,33 +704,23 @@ void shadeSkyPixelFloat(float y, float *view) SWAP(float, lo[1], lo[2]); } - - /* sky texture? I wonder how this manages to work... */ - /* Does this communicate with R.wrld.hor{rgb}? Yes. */ - do_sky_tex(lo); - /* internally, T{rgb} are used for communicating colours in the */ - /* texture pipe, externally, this particular routine uses the */ - /* R.wrld.hor{rgb} thingies. */ - + do_sky_tex(lo, dxyview, hor, zen, &blend); } - /* Why are this R. members? because textures need it (ton) */ - if(R.inprz>1.0) R.inprz= 1.0; - R.inprh= 1.0-R.inprz; + if(blend>1.0) blend= 1.0; + blendm= 1.0-blend; /* No clipping, no conversion! */ if(R.wrld.skytype & WO_SKYBLEND) { - collector[0] = (R.inprh*R.wrld.horr + R.inprz*R.wrld.zenr); - collector[1] = (R.inprh*R.wrld.horg + R.inprz*R.wrld.zeng); - collector[2] = (R.inprh*R.wrld.horb + R.inprz*R.wrld.zenb); + colf[0] = (blendm*hor[0] + blend*zen[0]); + colf[1] = (blendm*hor[1] + blend*zen[1]); + colf[2] = (blendm*hor[2] + blend*zen[2]); } else { /* Done when a texture was grabbed. */ - collector[0]= R.wrld.horr; - collector[1]= R.wrld.horg; - collector[2]= R.wrld.horb; + colf[0]= hor[0]; + colf[1]= hor[1]; + colf[2]= hor[2]; } - - collector[3]= RE_UNITY_COLOUR_FLOAT; } @@ -583,30 +732,25 @@ void shadeSkyPixelFloat(float y, float *view) should be really easy. I hope I understand the way ImBuf works correctly. (nzc) */ -void fillBackgroundImage(float x, float y) +void fillBackgroundImageChar(char *col, float x, float y) { int iy, ix; unsigned int* imBufPtr; - char *colSource; /* This double check is bad... */ if (!(R.backbuf->ok)) { /* Something went sour here... bail... */ - collector[0] = 0.0; - collector[1] = 0.0; - collector[2] = 0.0; - collector[3] = 1.0; + col[0] = 0; + col[1] = 0; + col[2] = 0; + col[3] = 255; return; } /* load image if not already done?*/ if(R.backbuf->ibuf==0) { - R.backbuf->ibuf= IMB_loadiffname(R.backbuf->name, IB_rect); - if(R.backbuf->ibuf==0) { - /* load failed .... keep skipping */ - R.backbuf->ok= 0; - return; - } + R.backbuf->ok= 0; + return; } /* Now for the real extraction: */ @@ -629,10 +773,17 @@ void fillBackgroundImage(float x, float y) + (iy * R.backbuf->ibuf->x) + ix; - colSource = (char*) imBufPtr; - - cpCharColV2FloatColV(colSource, collector); + *( (int *)col) = *imBufPtr; + +} +void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y) +{ + char col[4]; + + fillBackgroundImageChar(col, x, y); + cpCharColV2FloatColV(col, collector); + } /* eof */ diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index 1638bf87435..6dcf15ba606 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -45,9 +45,9 @@ #include <BLI_rand.h> #include "render.h" -#include "render_intern.h" #include "rendercore.h" #include "pixelblending.h" +#include "pixelshading.h" #include "jitter.h" #include "texture.h" @@ -74,8 +74,6 @@ typedef struct Octree { float ocfacx,ocfacy,ocfacz; float min[3], max[3]; int ocres; - /* for optimize, last intersected face */ - VlakRen *vlr_last; } Octree; @@ -87,6 +85,9 @@ typedef struct Isect { float ddalabda; float col[4]; /* RGBA for shadow_tra */ int lay; /* -1 default, set for layer lamps */ + short vlrisect; /* flag whether vlrcontr was done or not */ + /* for optimize, last intersected face */ + VlakRen *vlr_last; } Isect; typedef struct Branch @@ -148,47 +149,36 @@ static void calc_ocval_face(float *v1, float *v2, float *v3, float *v4, short x, } -static void calc_ocval_ray(OcVal *ov, float x1, float y1, float z1, - float x2, float y2, float z2) +static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, float *vec2) { - static float ox1, ox2, oy1, oy2, oz1, oz2; + int ocmin, ocmax; - if(ov==NULL) { - ox1= x1; ox2= x2; - oy1= y1; oy2= y2; - oz1= z1; oz2= z2; + if(vec1[0]<vec2[0]) { + ocmin= OCVALRES*(vec1[0] - xo); + ocmax= OCVALRES*(vec2[0] - xo); + } else { + ocmin= OCVALRES*(vec2[0] - xo); + ocmax= OCVALRES*(vec1[0] - xo); } - else { - int ocmin, ocmax; - - if(ox1<ox2) { - ocmin= OCVALRES*(ox1 - ((int)x1)); - ocmax= OCVALRES*(ox2 - ((int)x1)); - } else { - ocmin= OCVALRES*(ox2 - ((int)x1)); - ocmax= OCVALRES*(ox1 - ((int)x1)); - } - ov->ocx= BROW(ocmin, ocmax); + ov->ocx= BROW(ocmin, ocmax); - if(oy1<oy2) { - ocmin= OCVALRES*(oy1 - ((int)y1)); - ocmax= OCVALRES*(oy2 - ((int)y1)); - } else { - ocmin= OCVALRES*(oy2 - ((int)y1)); - ocmax= OCVALRES*(oy1 - ((int)y1)); - } - ov->ocy= BROW(ocmin, ocmax); + if(vec1[1]<vec2[1]) { + ocmin= OCVALRES*(vec1[1] - yo); + ocmax= OCVALRES*(vec2[1] - yo); + } else { + ocmin= OCVALRES*(vec2[1] - yo); + ocmax= OCVALRES*(vec1[1] - yo); + } + ov->ocy= BROW(ocmin, ocmax); - if(oz1<oz2) { - ocmin= OCVALRES*(oz1 - ((int)z1)); - ocmax= OCVALRES*(oz2 - ((int)z1)); - } else { - ocmin= OCVALRES*(oz2 - ((int)z1)); - ocmax= OCVALRES*(oz1 - ((int)z1)); - } - ov->ocz= BROW(ocmin, ocmax); - + if(vec1[2]<vec2[2]) { + ocmin= OCVALRES*(vec1[2] - zo); + ocmax= OCVALRES*(vec2[2] - zo); + } else { + ocmin= OCVALRES*(vec2[2] - zo); + ocmax= OCVALRES*(vec1[2] - zo); } + ov->ocz= BROW(ocmin, ocmax); } /* ************* octree ************** */ @@ -451,7 +441,7 @@ void freeoctree(void) printf("branches %d nodes %d\n", branchcount, nodecount); printf("raycount %d \n", raycount); printf("ray coherent %d \n", coherent_ray); - // printf("accepted %d rejected %d\n", accepted, rejected); + printf("accepted %d rejected %d\n", accepted, rejected); } branchcount= 0; nodecount= 0; @@ -483,7 +473,6 @@ void makeoctree() /* fill main octree struct */ g_oc.ocres= R.r.ocres; ocres2= g_oc.ocres*g_oc.ocres; - g_oc.vlr_last= NULL; INIT_MINMAX(g_oc.min, g_oc.max); /* first min max octree space */ @@ -710,11 +699,8 @@ static short intersection(Isect *is) VertRen *v1,*v2,*v3,*v4=NULL; float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22,r0,r1,r2; float m0, m1, m2, divdet, det1; - static short vlrisect=0; short ok=0; - - is->vlr->raycount= raycount; - + v1= is->vlr->v1; v2= is->vlr->v2; if(is->vlr->v4) { @@ -811,7 +797,6 @@ static short intersection(Isect *is) /* for mirror: large faces can be filled in too often, this prevents a face being detected too soon... */ if(is->labda > is->ddalabda) { - is->vlr->raycount= 0; return 0; } } @@ -819,7 +804,7 @@ static short intersection(Isect *is) /* when a shadow ray leaves a face, it can be little outside the edges of it, causing intersection to be detected in its neighbour face */ - if(is->vlrcontr && vlrisect); // optimizing, the tests below are not needed + if(is->vlrcontr && is->vlrisect); // optimizing, the tests below are not needed else if(is->labda< .1) { VlakRen *vlr= is->vlrorig; short de= 0; @@ -838,10 +823,10 @@ static short intersection(Isect *is) if(is->vlrcontr==NULL) { is->vlrcontr= vlr; - vlrisect= intersection2(vlr, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]); + is->vlrisect= intersection2(vlr, -r0, -r1, -r2, is->start[0], is->start[1], is->start[2]); } - if(vlrisect) return 1; + if(is->vlrisect) return 1; return 0; } } @@ -853,23 +838,20 @@ static short intersection(Isect *is) } /* check all faces in this node */ -static int testnode(Isect *is, Node *no, int x, int y, int z) +static int testnode(Isect *is, Node *no, OcVal ocval) { VlakRen *vlr; - short nr=0, ocvaldone=0; - OcVal ocval, *ov; + short nr=0; + OcVal *ov; if(is->mode==DDA_SHADOW) { vlr= no->v[0]; while(vlr) { - if(raycount != vlr->raycount) { + if(is->vlrorig != vlr) { + if(is->lay & vlr->lay) { - if(ocvaldone==0) { - calc_ocval_ray(&ocval, (float)x, (float)y, (float)z, 0.0, 0.0, 0.0); - ocvaldone= 1; - } ov= no->ov+nr; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { @@ -877,7 +859,7 @@ static int testnode(Isect *is, Node *no, int x, int y, int z) is->vlr= vlr; if(intersection(is)) { - g_oc.vlr_last= vlr; + is->vlr_last= vlr; return 1; } } @@ -904,12 +886,7 @@ static int testnode(Isect *is, Node *no, int x, int y, int z) vlr= no->v[0]; while(vlr) { - if(raycount != vlr->raycount) { - - if(ocvaldone==0) { - calc_ocval_ray(&ocval, (float)x, (float)y, (float)z, 0.0, 0.0, 0.0); - ocvaldone= 1; - } + if(is->vlrorig != vlr) { ov= no->ov+nr; if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { @@ -942,81 +919,59 @@ static int testnode(Isect *is, Node *no, int x, int y, int z) /* find the Node for the octree coord x y z */ static Node *ocread(int x, int y, int z) { - static int mdiff=0, xo, yo, zo; Branch *br; - int oc1, diff; - - /* outside of octree check, reset */ - if( x >= g_oc.ocres) { - xo= g_oc.ocres; yo= g_oc.ocres; zo= g_oc.ocres; - return NULL; - } + int oc1; - diff= (xo ^ x) | (yo ^ y) | (zo ^ z); - - if(diff>mdiff) { - - xo=x; yo=y; zo=z; - x<<=2; - y<<=1; - - br= g_oc.adrbranch[0]; - - if(g_oc.ocres==512) { - oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= br->b[oc1]; - if(br==NULL) { - mdiff= 255; - return NULL; - } + x<<=2; + y<<=1; + + br= g_oc.adrbranch[0]; + + if(g_oc.ocres==512) { + oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; + br= br->b[oc1]; + if(br==NULL) { + return NULL; } - if(g_oc.ocres>=256) { - oc1= ((x & 512)+(y & 256)+(z & 128))>>7; - br= br->b[oc1]; - if(br==NULL) { - mdiff= 127; - return NULL; - } + } + if(g_oc.ocres>=256) { + oc1= ((x & 512)+(y & 256)+(z & 128))>>7; + br= br->b[oc1]; + if(br==NULL) { + return NULL; } - if(g_oc.ocres>=128) { - oc1= ((x & 256)+(y & 128)+(z & 64))>>6; - br= br->b[oc1]; - if(br==NULL) { - mdiff= 63; - return NULL; - } + } + if(g_oc.ocres>=128) { + oc1= ((x & 256)+(y & 128)+(z & 64))>>6; + br= br->b[oc1]; + if(br==NULL) { + return NULL; } - - oc1= ((x & 128)+(y & 64)+(z & 32))>>5; + } + + oc1= ((x & 128)+(y & 64)+(z & 32))>>5; + br= br->b[oc1]; + if(br) { + oc1= ((x & 64)+(y & 32)+(z & 16))>>4; br= br->b[oc1]; if(br) { - - oc1= ((x & 64)+(y & 32)+(z & 16))>>4; + oc1= ((x & 32)+(y & 16)+(z & 8))>>3; br= br->b[oc1]; if(br) { - oc1= ((x & 32)+(y & 16)+(z & 8))>>3; + oc1= ((x & 16)+(y & 8)+(z & 4))>>2; br= br->b[oc1]; if(br) { - oc1= ((x & 16)+(y & 8)+(z & 4))>>2; + oc1= ((x & 8)+(y & 4)+(z & 2))>>1; br= br->b[oc1]; if(br) { - oc1= ((x & 8)+(y & 4)+(z & 2))>>1; - br= br->b[oc1]; - if(br) { - mdiff=0; - oc1= ((x & 4)+(y & 2)+(z & 1)); - return (Node *)br->b[oc1]; - } - else mdiff=1; + oc1= ((x & 4)+(y & 2)+(z & 1)); + return (Node *)br->b[oc1]; } - else mdiff=3; } - else mdiff=7; } - else mdiff=15; } - else mdiff=31; } + return NULL; } @@ -1081,9 +1036,10 @@ static int do_coherence_test(int ocx1, int ocx2, int ocy1, int ocy2, int ocz1, i static int d3dda(Isect *is) { Node *no; + OcVal ocval; + float vec1[3], vec2[3]; float u1,u2,ox1,ox2,oy1,oy2,oz1,oz2; float labdao,labdax,ldx,labday,ldy,labdaz,ldz, ddalabda; - float vec1[3], vec2[3]; int dx,dy,dz; int xo,yo,zo,c1=0; int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2; @@ -1092,17 +1048,15 @@ static int d3dda(Isect *is) if(branchcount==0) return 0; /* do this before intersect calls */ - raycount++; - is->vlrorig->raycount= raycount; is->vlrcontr= NULL; /* to check shared edge */ /* only for shadow! */ if(is->mode==DDA_SHADOW) { /* check with last intersected shadow face */ - if(g_oc.vlr_last!=NULL && g_oc.vlr_last!=is->vlrorig) { - if(is->lay & g_oc.vlr_last->lay) { - is->vlr= g_oc.vlr_last; + if(is->vlr_last!=NULL && is->vlr_last!=is->vlrorig) { + if(is->lay & is->vlr_last->lay) { + is->vlr= is->vlr_last; VECSUB(is->vec, is->end, is->start); if(intersection(is)) return 1; } @@ -1143,7 +1097,7 @@ static int d3dda(Isect *is) if(c1==0) return 0; /* reset static variables in ocread */ - ocread(g_oc.ocres, 0, 0); + //ocread(g_oc.ocres, 0, 0); /* setup 3dda to traverse octree */ ox1= (is->start[0]-g_oc.min[0])*g_oc.ocfacx; @@ -1166,10 +1120,12 @@ static int d3dda(Isect *is) if(ocx1==ocx2 && ocy1==ocy2 && ocz1==ocz2) { no= ocread(ocx1, ocy1, ocz1); if(no) { - /* no calc, this is store */ - calc_ocval_ray(NULL, ox1, oy1, oz1, ox2, oy2, oz2); + /* exact intersection with node */ + vec1[0]= ox1; vec1[1]= oy1; vec1[2]= oz1; + vec2[0]= ox2; vec2[1]= oy2; vec2[2]= oz2; + calc_ocval_ray(&ocval, (float)ocx1, (float)ocy1, (float)ocz1, vec1, vec2); is->ddalabda= 1.0; - if( testnode(is, no, ocx1, ocy1, ocz1) ) return 1; + if( testnode(is, no, ocval) ) return 1; } } else { @@ -1225,7 +1181,7 @@ static int d3dda(Isect *is) } xo=ocx1; yo=ocy1; zo=ocz1; - ddalabda= MIN3(labdax,labday,labdaz); + labdao= ddalabda= MIN3(labdax,labday,labdaz); vec2[0]= ox1; vec2[1]= oy1; @@ -1241,15 +1197,14 @@ static int d3dda(Isect *is) /* calculate ray intersection with octree node */ VECCOPY(vec1, vec2); - // dox,y,z is negative + // dox,y,z is negative vec2[0]= ox1-ddalabda*dox; vec2[1]= oy1-ddalabda*doy; vec2[2]= oz1-ddalabda*doz; - /* no calc, this is store */ - calc_ocval_ray(NULL, vec1[0], vec1[1], vec1[2], vec2[0], vec2[1], vec2[2]); - + calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); + is->ddalabda= ddalabda; - if( testnode(is, no, xo,yo,zo) ) return 1; + if( testnode(is, no, ocval) ) return 1; } labdao= ddalabda; @@ -1319,7 +1274,7 @@ static int d3dda(Isect *is) } /* reached end, no intersections found */ - g_oc.vlr_last= NULL; + is->vlr_last= NULL; return 0; } @@ -1342,7 +1297,8 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shi->vlr= vlr; shi->mat= vlr->mat; - shi->matren= shi->mat->ren; + memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h + shi->har= shi->mat->har; /* face normal, check for flip */ l= vlr->n[0]*shi->view[0]+vlr->n[1]*shi->view[1]+vlr->n[2]*shi->view[2]; @@ -1358,10 +1314,13 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) // Osa structs we leave unchanged now SWAP(int, osatex, shi->osatex); + shi->dxco[0]= shi->dxco[1]= shi->dxco[2]= 0.0; + shi->dyco[0]= shi->dyco[1]= shi->dyco[2]= 0.0; + // but, set O structs zero where it can confuse texture code - if(shi->matren->texco & (TEXCO_NORM|TEXCO_REFL) ) { - O.dxno[0]= O.dxno[1]= O.dxno[2]= 0.0; - O.dyno[0]= O.dyno[1]= O.dyno[2]= 0.0; + if(shi->mat->texco & (TEXCO_NORM|TEXCO_REFL) ) { + shi->dxno[0]= shi->dxno[1]= shi->dxno[2]= 0.0; + shi->dyno[0]= shi->dyno[1]= shi->dyno[2]= 0.0; } if(vlr->v4) { @@ -1374,26 +1333,28 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr) shade_input_set_coords(shi, is->u, is->v, 0, 1, 2); } - SWAP(int, osatex, shi->osatex); + // SWAP(int, osatex, shi->osatex); XXXXX!!!! if(is->mode==DDA_SHADOW_TRA) shade_color(shi, shr); else { shade_lamp_loop(shi, shr); - if(shi->matren->translucency!=0.0) { + if(shi->translucency!=0.0) { ShadeResult shr_t; VecMulf(shi->vn, -1.0); VecMulf(vlr->n, -1.0); shade_lamp_loop(shi, &shr_t); - shr->diff[0]+= shi->matren->translucency*shr_t.diff[0]; - shr->diff[1]+= shi->matren->translucency*shr_t.diff[1]; - shr->diff[2]+= shi->matren->translucency*shr_t.diff[2]; + shr->diff[0]+= shi->translucency*shr_t.diff[0]; + shr->diff[1]+= shi->translucency*shr_t.diff[1]; + shr->diff[2]+= shi->translucency*shr_t.diff[2]; VecMulf(shi->vn, -1.0); VecMulf(vlr->n, -1.0); } } + SWAP(int, osatex, shi->osatex); // XXXXX!!!! + if(flip) { vlr->n[0]= -vlr->n[0]; vlr->n[1]= -vlr->n[1]; @@ -1499,20 +1460,20 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen if(depth>0) { - if(shi.matren->mode & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha!=1.0) { + if(shi.mat->mode & (MA_RAYTRANSP|MA_ZTRA) && shr.alpha!=1.0) { float f, f1, refract[3], tracol[3]; - if(shi.matren->mode & MA_RAYTRANSP) { + if(shi.mat->mode & MA_RAYTRANSP) { /* odd depths: use normal facing viewer, otherwise flip */ if(traflag & RAY_TRAFLIP) { float norm[3]; norm[0]= - shi.vn[0]; norm[1]= - shi.vn[1]; norm[2]= - shi.vn[2]; - refraction(refract, norm, shi.view, shi.matren->ang); + refraction(refract, norm, shi.view, shi.ang); } else { - refraction(refract, shi.vn, shi.view, shi.matren->ang); + refraction(refract, shi.vn, shi.view, shi.ang); } traflag |= RAY_TRA; traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP); @@ -1532,9 +1493,9 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen shr.alpha= 1.0; } - if(shi.matren->mode & MA_RAYMIRROR) { - f= shi.matren->ray_mirror; - if(f!=0.0) f*= fresnel_fac(shi.view, shi.vn, shi.matren->fresnel_mir_i, shi.matren->fresnel_mir); + if(shi.mat->mode & MA_RAYMIRROR) { + f= shi.ray_mirror; + if(f!=0.0) f*= fresnel_fac(shi.view, shi.vn, shi.mat->fresnel_mir_i, shi.mat->fresnel_mir); } else f= 0.0; @@ -1551,9 +1512,9 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen //col[1]+= shr.spec[1]; //col[2]+= shr.spec[2]; - fr= shi.matren->mirr; - fg= shi.matren->mirg; - fb= shi.matren->mirb; + fr= shi.mirr; + fg= shi.mirg; + fb= shi.mirb; col[0]= f*fr*(1.0-shr.spec[0])*col[0] + f1*shr.diff[0] + shr.spec[0]; col[1]= f*fg*(1.0-shr.spec[1])*col[1] + f1*shr.diff[1] + shr.spec[1]; @@ -1576,8 +1537,8 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen VECCOPY(shi.view, vec); Normalise(shi.view); - - RE_sky(shi.view, col); + + shadeSkyPixelFloat(col, shi.view, NULL); } } @@ -1666,7 +1627,7 @@ static float *jitter_plane(LampRen *lar, int xs, int ys) tot= lar->ray_totsamp; if(lar->jitter==NULL) { - + lar->jitter= (float *)4; // mislead thread quickly (tsk!) fp=lar->jitter= MEM_mallocN(4*tot*2*sizeof(float), "lamp jitter tab"); /* fill table with random locations, area_size large */ @@ -1688,13 +1649,25 @@ static float *jitter_plane(LampRen *lar, int xs, int ys) } if(lar->ray_samp_type & LA_SAMP_JITTER) { - static int xold=0, yold=0; - /* new OSA allows to enter this function many times for 1 pixel */ - if(xold!=xs || yold!=ys) { - jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand()); - xold= xs; yold= ys; + /* made it threadsafe */ + if(ys & 1) { + static int xold=0, yold=0; + + if(xold!=xs || yold!=ys) { + jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand()); + xold= xs; yold= ys; + } + return lar->jitter+2*tot; + } + else { + static int xold=0, yold=0; + + if(xold!=xs || yold!=ys) { + jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand()); + xold= xs; yold= ys; + } + return lar->jitter+4*tot; } - return lar->jitter+2*tot; } if(lar->ray_samp_type & LA_SAMP_DITHER) { return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1)); @@ -1714,19 +1687,19 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) float i, f, f1, fr, fg, fb, vec[3], mircol[3], tracol[3]; int do_tra, do_mir; - do_tra= ((shi->matren->mode & (MA_RAYTRANSP|MA_ZTRA)) && shr->alpha!=1.0); - do_mir= ((shi->matren->mode & MA_RAYMIRROR) && shi->matren->ray_mirror!=0.0); + do_tra= ((shi->mat->mode & (MA_RAYTRANSP|MA_ZTRA)) && shr->alpha!=1.0); + do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0); vlr= shi->vlr; if(do_tra) { float refract[3]; - if(shi->matren->mode & MA_RAYTRANSP) { - refraction(refract, shi->vn, shi->view, shi->matren->ang); - traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP); + if(shi->mat->mode & MA_RAYTRANSP) { + refraction(refract, shi->vn, shi->view, shi->ang); + traceray(shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP); } else - traceray(shi->matren->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0); + traceray(shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0); f= shr->alpha; f1= 1.0-f; shr->diff[0]= f*shr->diff[0] + f1*tracol[0]; @@ -1737,18 +1710,18 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) if(do_mir) { - i= shi->matren->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->matren->fresnel_mir_i, shi->matren->fresnel_mir); + i= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->mat->fresnel_mir_i, shi->mat->fresnel_mir); if(i!=0.0) { - fr= shi->matren->mirr; - fg= shi->matren->mirg; - fb= shi->matren->mirb; + fr= shi->mirr; + fg= shi->mirg; + fb= shi->mirb; if(vlr->flag & R_SMOOTH) reflection(vec, shi->vn, shi->view, vlr->n); else reflection(vec, shi->vn, shi->view, NULL); - traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0); + traceray(shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0); f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i; shr->diff[0]= f*mircol[0] + f1*shr->diff[0]; @@ -1928,9 +1901,31 @@ static void DistributedSpherical(float *sphere, int tot, int iter) } } + +static float *threadsafe_table_sphere(int test, int xs, int ys) +{ + static float sphere1[2*3*256]; + static float sphere2[2*3*256]; + static int xs1=-1, xs2=-1, ys1=-1, ys2=-1; + + if(ys & 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; + } +} + static float *sphere_sampler(int type, int resol, int xs, int ys) { - static float sphere[2*3*256], sphere1[2*3*256]; + static float sphere[2*3*256]; + float *sphere1; int tot; float *vec; @@ -1948,16 +1943,19 @@ static float *sphere_sampler(int type, int resol, int xs, int ys) } } else { - static int last_distr= 0, xold=0xffff, yold=0; + static int last_distr= 0; float cosf, sinf, cost, sint; float ang, *vec1; int a; - if(last_distr!=resol) DistributedSpherical(sphere, tot, 16); - last_distr= resol; + if(last_distr!=resol) { + last_distr= resol; + DistributedSpherical(sphere, tot, 16); + } - if(xold!=xs || yold!=ys) { - xold=xs; yold=ys; + sphere1= threadsafe_table_sphere(1, xs, ys); + if(sphere1==NULL) { + sphere1= threadsafe_table_sphere(0, xs, ys); // random rotation ang= BLI_frand(); @@ -1988,21 +1986,12 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) int j=0, tot, actual=0, skyadded=0; isec.vlrorig= shi->vlr; + isec.vlr_last= NULL; isec.mode= DDA_SHADOW; isec.lay= -1; shadfac[0]= shadfac[1]= shadfac[2]= 0.0; - /* if sky texture used, these values have to be reset back to original */ - if(wrld->aocolor==WO_AOSKYCOL && G.scene->world) { - R.wrld.horr= G.scene->world->horr; - R.wrld.horg= G.scene->world->horg; - R.wrld.horb= G.scene->world->horb; - R.wrld.zenr= G.scene->world->zenr; - R.wrld.zeng= G.scene->world->zeng; - R.wrld.zenb= G.scene->world->zenb; - } - // bias prevents smoothed faces to appear flat if(shi->vlr->flag & R_SMOOTH) { bias= G.scene->world->aobias; @@ -2060,7 +2049,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) shadfac[2]+= (1.0-fac)*R.wrld.horb + fac*R.wrld.zenb; } else { - RE_sky(view, skycol); + shadeSkyPixelFloat(skycol, view, NULL); shadfac[0]+= skycol[0]; shadfac[1]+= skycol[1]; shadfac[2]+= skycol[2]; @@ -2089,16 +2078,18 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) { Isect isec; - Material stored; float lampco[3]; - if(shi->matren->mode & MA_SHADOW_TRA) { - isec.mode= DDA_SHADOW_TRA; - /* needed to prevent shade_ray changing matren (textures) */ - stored= *(shi->matren); - } + /* setup isec */ + if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= DDA_SHADOW_TRA; else isec.mode= DDA_SHADOW; + if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; + + /* only when not mir tracing, first hit optimm */ + if(shi->depth==0) isec.vlr_last= lar->vlr_last; + else isec.vlr_last= NULL; + isec.vlrorig= shi->vlr; shadfac[3]= 1.0; // 1=full light @@ -2111,15 +2102,12 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) VECCOPY(lampco, lar->co); } - /* only when not tracing, first hit optimm */ - if(shi->depth==0) g_oc.vlr_last= lar->vlr_last; - /* transp-shadow and soft not implemented yet */ if(lar->ray_totsamp<2 || isec.mode == DDA_SHADOW_TRA) { - /* set up isec */ + + /* set up isec vec */ VECCOPY(isec.start, shi->co); VECCOPY(isec.end, lampco); - isec.vlrorig= shi->vlr; if(isec.mode==DDA_SHADOW_TRA) { isec.col[0]= isec.col[1]= isec.col[2]= 1.0; @@ -2142,8 +2130,6 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) float fac=0.0, div=0.0, vec[3]; int a, j= -1, mask; - isec.vlrorig= shi->vlr; - fac= 0.0; jitlamp= jitter_plane(lar, floor(shi->xs+0.5), floor(shi->ys+0.5)); @@ -2188,13 +2174,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) shadfac[3]= 1.0-fac/div; } - if(shi->matren->mode & MA_SHADOW_TRA) { - /* needed to prevent shade_ray changing matren (textures) */ - *(shi->matren)= stored; - } - /* for first hit optim, set last interesected shadow face */ - if(shi->depth==0) lar->vlr_last= g_oc.vlr_last; + if(shi->depth==0) lar->vlr_last= isec.vlr_last; } diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c index 6b29e644722..ef885eccbc3 100644 --- a/source/blender/render/intern/source/renderHelp.c +++ b/source/blender/render/intern/source/renderHelp.c @@ -38,17 +38,13 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_utildefines.h" #include "BLI_arithb.h" #include "render.h" -#include "render_intern.h" #include "renderHelp.h" #include "zbuf.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - static float panovco, panovsi; static float panophi=0.0; static float tempPanoPhi; diff --git a/source/blender/render/intern/source/renderPreAndPost.c b/source/blender/render/intern/source/renderPreAndPost.c index 8c43f0cc90e..0f7a98843ce 100644 --- a/source/blender/render/intern/source/renderPreAndPost.c +++ b/source/blender/render/intern/source/renderPreAndPost.c @@ -35,7 +35,6 @@ #include "MEM_guardedalloc.h" #include "render.h" -#include "render_intern.h" #include "renderPreAndPost.h" #include "RE_callbacks.h" @@ -56,11 +55,6 @@ void prepareScene() int a; extern void makeoctree(void); - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= 0; - if(R.rectz) MEM_freeN(R.rectz); - R.rectz= 0; - RE_local_get_renderdata(); /* SHADOW BUFFER */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 098444b18b2..a561e39fb6f 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -37,6 +37,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "MTC_matrixops.h" + #include "BKE_utildefines.h" #include "DNA_mesh_types.h" @@ -54,11 +55,12 @@ /* local include */ #include "RE_callbacks.h" -#include "old_zbuffer_types.h" #include "render.h" -#include "render_intern.h" #include "zbuf.h" /* stuff like bgnaccumbuf, fillrect, ...*/ #include "pixelblending.h" +#include "pixelshading.h" +#include "vanillaRenderPipe.h" /* transfercolour... */ +#include "gammaCorrectionTables.h" #include "shadbuf.h" #include "renderHelp.h" @@ -73,62 +75,16 @@ /* own include */ #include "rendercore.h" -#include "rendercore_int.h" #ifdef HAVE_CONFIG_H #include <config.h> #endif -/* globals for this file */ -/* moved to renderData.c? Not yet... */ -RE_Render R; -Osa O; - -PixStrMain psmfirst; -int psmteller; +#include "SDL_thread.h" -float fmask[256], centLut[16]; -unsigned short usegamtab=0, *mask1[9], *mask2[9], *igamtab1, *igamtab2, *gamtab; -char cmask[256], *centmask; -/* functions */ -/* comes from texture.c (only used here !) */ -/* extern void do_halo_tex(HaloRen *har, float xn, float yn, float *colf); */ - -void gamtabdit(unsigned short *in, char *out); -/* int count_mask(unsigned short ); */ -void scanlinehalo(unsigned int *rectz, unsigned int *rectt, short ys); -/* void add_halo_flare(void); */ -void edge_enhance(void); - -/* Dither with gamma table? */ -void gamtabdit(unsigned short *in, char *out) -/* unsigned short *in; */ -/* char *out; */ -{ - static short rerr=0, gerr=0, berr=0; - unsigned int col; - char *cp; - - cp= (char *)&col; - out[0]= in[0]>>8; - - col= gamtab[in[2]]+berr; - if(col>65535) col= 65535; - out[1]= cp[2]; - berr= cp[3]; - - col= gamtab[in[4]]+gerr; - if(col>65535) col= 65535; - out[2]= cp[2]; - gerr= cp[3]; - - col= gamtab[in[6]]+rerr; - if(col>65535) col= 65535; - out[3]= cp[2]; - rerr= cp[3]; - -} +/* global for this file. struct render will be more dynamic later, to allow multiple renderers */ +RE_Render R; float mistfactor(float *co) /* dist en height, return alpha */ { @@ -167,55 +123,7 @@ float mistfactor(float *co) /* dist en height, return alpha */ return (1.0-fac)* (1-R.wrld.misi); } -void RE_sky(float *view, float *col) -{ - float lo[3]; - - R.wrld.skytype |= WO_ZENUP; - - if(R.wrld.skytype & WO_SKYREAL) { - - R.inprz= view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]; - - if(R.inprz<0.0) R.wrld.skytype-= WO_ZENUP; - R.inprz= fabs(R.inprz); - } - else if(R.wrld.skytype & WO_SKYPAPER) { - R.inprz= 0.5+ 0.5*view[1]; - } - else { - R.inprz= fabs(0.5+ view[1]); - } - - if(R.wrld.skytype & WO_SKYTEX) { - VECCOPY(lo, view); - if(R.wrld.skytype & WO_SKYREAL) { - - MTC_Mat3MulVecfl(R.imat, lo); - - SWAP(float, lo[1], lo[2]); - - } - - do_sky_tex(lo); - - } - - if(R.inprz>1.0) R.inprz= 1.0; - R.inprh= 1.0-R.inprz; - - if(R.wrld.skytype & WO_SKYBLEND) { - col[0]= (R.inprh*R.wrld.horr + R.inprz*R.wrld.zenr); - col[1]= (R.inprh*R.wrld.horg + R.inprz*R.wrld.zeng); - col[2]= (R.inprh*R.wrld.horb + R.inprz*R.wrld.zenb); - } - else { - col[0]= R.wrld.horr; - col[1]= R.wrld.horg; - col[2]= R.wrld.horb; - } -} - +/* external for preview only */ void RE_sky_char(float *view, char *col) { float f, colf[3]; @@ -223,7 +131,8 @@ void RE_sky_char(float *view, char *col) dither_value = ( (BLI_frand()-0.5)*R.r.dither_intensity)/256.0; - RE_sky(view, colf); + shadeSkyPixelFloat(colf, view, NULL); + f= 255.0*(colf[0]+dither_value); if(f<=0.0) col[0]= 0; else if(f>255.0) col[0]= 255; else col[0]= (char)f; @@ -236,176 +145,11 @@ void RE_sky_char(float *view, char *col) col[3]= 1; /* to prevent wrong optimalisation alphaover of flares */ } -/* ------------------------------------------------------------------------- */ - -void scanlinesky(char *rect, int y) -{ - /* have to type this! set to : addalphaUnder: char*, char* - * addalphaUnderGamma: ditto called with char *, uint* !!! - * unmangle this shit... */ - void (*alphafunc)(); - float fac, u, v, view[3]; - int dx, x, dy, ofs; - unsigned int col=0, *rt; - char *cp, *cp1; - - if(R.r.alphamode & R_ALPHAPREMUL) return; - - if(R.r.alphamode & R_ALPHAKEY) { - - cp= (char *)&col; - cp[3]= 0; - /* raytrace can change the R.wrld.horr, so we make sure we have the good one */ - if(G.scene->world) { - cp[0]= 255.0*G.scene->world->horr; - cp[1]= 255.0*G.scene->world->horg; - cp[2]= 255.0*G.scene->world->horb; - } - else { - cp[0]= 255.0*R.wrld.horr; - cp[1]= 255.0*R.wrld.horg; - cp[2]= 255.0*R.wrld.horb; - } - for(x=0; x<R.rectx; x++, rect+= 4) { - if(rect[3]==0) { - *( ( unsigned int *)rect)= col; - } - else { - /* prevent 'col' to be in the image */ - cp1= (char *)rect; - if( cp[0]==cp1[0] && cp[1]==cp1[1] && cp[2]==cp1[2] ) { - - if(cp1[3]==255) cp1[3]= 254; - else cp1[3]++; - } - - if(rect[3]!=255) { - keyalpha(rect); - } - } - } - return; - } - - if(R.wrld.mode & WO_MIST) alphafunc= addalphaUnder; - else alphafunc= addalphaUnderGamma; - - - if(R.r.bufflag & 1) { - if(R.backbuf && R.backbuf->ok) { - if(R.backbuf->ibuf==0) { - R.backbuf->ibuf= IMB_loadiffname(R.backbuf->name, IB_rect); - if(R.backbuf->ibuf==0) { - R.backbuf->ok= 0; - return; - } - } - /* which scanline/ */ - dy= ((y+R.afmy+R.ystart)*R.backbuf->ibuf->y)/(2*R.afmy); // this division enables border/part render too - - if(R.flag & R_SEC_FIELD) { - if((R.r.mode & R_ODDFIELD)==0) { - if( dy<R.backbuf->ibuf->y) dy++; - } - else { - if( dy>0) dy--; - } - } - - if(dy<0) dy= 0; - else if(dy>=R.backbuf->ibuf->y) dy= R.backbuf->ibuf->y-1; - - rt= (R.backbuf->ibuf->rect + dy*R.backbuf->ibuf->x); - - /* at which location */ - fac= ((float)R.backbuf->ibuf->x)/(float)(2*R.afmx); - ofs= (R.afmx+R.xstart)*fac; - rt+= ofs; - - dx= (int) (65536.0*fac); - - ofs= 0; - x= R.rectx; - while( x-- ) { - if( rect[3] != 255) { - if(rect[3]==0) *((unsigned int *)rect)= *rt; - else { - alphafunc(rect, rt); - } - } - rect+= 4; - - ofs+= dx; - while( ofs > 65535 ) { - ofs-= 65536; - rt++; - } - } - - } - return; - } - - if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { - for(x=0; x<R.rectx; x++, rect+= 4) { - if(rect[3] != 255) { - if(rect[3]==0) *((unsigned int *)rect)= R.wrld.fastcol; - else { - alphafunc(rect, &R.wrld.fastcol); - } - } - } - } - else { - - for(x=0; x<R.rectx; x++, rect+= 4) { - if(rect[3] < 254) { - if(R.wrld.skytype & WO_SKYPAPER) { - view[0]= (x+(R.xstart))/(float)R.afmx; - view[1]= (y+(R.ystart))/(float)R.afmy; - view[2]= 0.0; - } - else { - view[0]= (x+(R.xstart)+0.5); - - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; - else view[1]= (y+R.ystart+1.0)*R.ycor; - } - else view[1]= (y+R.ystart+0.5)*R.ycor; - - view[2]= -R.viewfac; - - fac= Normalise(view); - if(R.wrld.skytype & WO_SKYTEX) { - O.dxview= 1.0/fac; - O.dyview= R.ycor/fac; - } - } - - if(R.r.mode & R_PANORAMA) { - float panoco, panosi; - panoco = getPanovCo(); - panosi = getPanovSi(); - u= view[0]; v= view[2]; - - view[0]= panoco*u + panosi*v; - view[2]= -panosi*u + panoco*v; - } - - RE_sky_char(view, (char *)&col); - - if(rect[3]==0) *((unsigned int *)rect)= col; - else alphafunc(rect, &col); - } - } - } -} /* ************************************** */ -void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) +static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) { double a, b, c, disc, nray[3], npos[3]; float t0, t1 = 0.0, t2= 0.0, t3, haint; @@ -591,12 +335,6 @@ static void renderspothalo(ShadeInput *shi, float *col) lar= R.la[a]; if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) { - if(lar->org) { - lar->r= lar->org->r; - lar->g= lar->org->g; - lar->b= lar->org->b; - } - spothalo(lar, shi, &i); if(i>0.0) { col[3]+= i; @@ -610,386 +348,8 @@ static void renderspothalo(ShadeInput *shi, float *col) if(col[3]>1.0) col[3]= 1.0; } -void render_lighting_halo(HaloRen *har, float *colf) -{ - LampRen *lar; - float i, inp, inpr, rco[3], lv[3], lampdist, ld, t, *vn; - float ir, ig, ib, shadfac, soft; - int a; - - ir= ig= ib= 0.0; - VECCOPY(rco, har->co); - vn= har->no; - - O.dxco[0]= har->hasize; - O.dxco[1]= 0.0; - O.dxco[2]= 0.0; - - O.dyco[0]= 0.0; - O.dyco[1]= har->hasize; - O.dyco[2]= 0.0; - - for(a=0; a<R.totlamp; a++) { - lar= R.la[a]; - - /* test for lamplayer */ - if(lar->mode & LA_LAYER) if((lar->lay & har->lay)==0) continue; - - /* lampdist cacluation */ - if(lar->type==LA_SUN || lar->type==LA_HEMI) { - VECCOPY(lv, lar->vec); - lampdist= 1.0; - } - else { - lv[0]= rco[0]-lar->co[0]; - lv[1]= rco[1]-lar->co[1]; - lv[2]= rco[2]-lar->co[2]; - ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]); - lv[0]/= ld; - lv[1]/= ld; - lv[2]/= ld; - - /* ld is re-used further on (texco's) */ - - if(lar->mode & LA_QUAD) { - t= 1.0; - if(lar->ld1>0.0) - t= lar->dist/(lar->dist+lar->ld1*ld); - if(lar->ld2>0.0) - t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld); - - lampdist= t; - } - else { - lampdist= (lar->dist/(lar->dist+ld)); - } - - if(lar->mode & LA_SPHERE) { - t= lar->dist - ld; - if(t<0.0) continue; - - t/= lar->dist; - lampdist*= (t); - } - - } - - if(lar->mode & LA_TEXTURE) { - ShadeInput shi; - VECCOPY(shi.co, rco); - shi.osatex= 0; - do_lamp_tex(lar, lv, &shi); - } - - if(lar->type==LA_SPOT) { - - if(lar->mode & LA_SQUARE) { - if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0) { - float x, lvrot[3]; - - /* rotate view to lampspace */ - VECCOPY(lvrot, lv); - MTC_Mat3MulVecfl(lar->imat, lvrot); - - x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); - /* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */ - - inpr= 1.0/(sqrt(1.0+x*x)); - } - else inpr= 0.0; - } - else { - inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]; - } - - t= lar->spotsi; - if(inpr<t) continue; - else { - t= inpr-t; - i= 1.0; - soft= 1.0; - if(t<lar->spotbl && lar->spotbl!=0.0) { - /* soft area */ - i= t/lar->spotbl; - t= i*i; - soft= (3.0*t-2.0*t*i); - inpr*= soft; - } - if(lar->mode & LA_ONLYSHADOW) { - /* if(ma->mode & MA_SHADOW) { */ - /* dot product positive: front side face! */ - inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; - if(inp>0.0) { - /* testshadowbuf==0.0 : 100% shadow */ - shadfac = testshadowbuf(lar->shb, rco, inp); - if( shadfac>0.0 ) { - shadfac*= inp*soft*lar->energy; - ir -= shadfac; - ig -= shadfac; - ib -= shadfac; - - continue; - } - } - /* } */ - } - lampdist*=inpr; - } - if(lar->mode & LA_ONLYSHADOW) continue; - - } - - /* dot product and reflectivity*/ - - inp= 1.0-fabs(vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]); - - /* inp= cos(0.5*M_PI-acos(inp)); */ - - i= inp; - - if(lar->type==LA_HEMI) { - i= 0.5*i+0.5; - } - if(i>0.0) { - i*= lampdist; - /* i*= lampdist*ma->ref; */ - } - - /* shadow */ - if(i> -0.41) { /* heuristic valua! */ - shadfac= 1.0; - if(lar->shb) { - /* if(ma->mode & MA_SHADOW) { */ - shadfac = testshadowbuf(lar->shb, rco, inp); - if(shadfac==0.0) continue; - i*= shadfac; - /* } */ - } - } - - if(i>0.0) { - ir+= i*lar->r; - ig+= i*lar->g; - ib+= i*lar->b; - } - } - - if(ir<0.0) ir= 0.0; - if(ig<0.0) ig= 0.0; - if(ib<0.0) ib= 0.0; - - colf[0]*= ir; - colf[1]*= ig; - colf[2]*= ib; - -} - - -void RE_shadehalo(HaloRen *har, char *col, unsigned int zz, float dist, float xn, float yn, short flarec) -{ - /* fill in in col */ - extern float hashvectf[]; - float t, zn, radist, ringf=0.0, linef=0.0, alpha, si, co, colf[4]; - int colt, a; - - if(R.wrld.mode & WO_MIST) { - if(har->type & HA_ONLYSKY) { - /* stars have no mist */ - alpha= har->alfa; - } - else { - /* patchy... */ - R.zcor= -har->co[2]; - alpha= mistfactor(har->co)*har->alfa; - } - } - else alpha= har->alfa; - - if(alpha==0.0) { - col[0] = 0; - col[1] = 0; - col[2] = 0; - col[3] = 0; - -/* *( (int *)col )=0; */ - - return; - } - - radist= sqrt(dist); - - /* watch it: abused value: flarec was set to zero in pixstruct */ - if(flarec) har->pixels+= (int)(har->rad-radist); - - if(har->ringc) { - float *rc, fac; - int ofs; - - /* per ring an antialised circle */ - ofs= har->seed; - - for(a= har->ringc; a>0; a--, ofs+=2) { - - rc= hashvectf + (ofs % 768); - - fac= fabs( rc[1]*(har->rad*fabs(rc[0]) - radist) ); - - if(fac< 1.0) { - ringf+= (1.0-fac); - } - } - } - - if(har->type & HA_VECT) { - dist= fabs( har->cos*(yn) - har->sin*(xn) )/har->rad; - if(dist>1.0) dist= 1.0; - if(har->tex) { - zn= har->sin*xn - har->cos*yn; - yn= har->cos*xn + har->sin*yn; - xn= zn; - } - } - else dist= dist/har->radsq; - - if(har->type & HA_FLARECIRC) { - - dist= 0.5+fabs(dist-0.5); - - } - - if(har->hard>=30) { - dist= sqrt(dist); - if(har->hard>=40) { - dist= sin(dist*M_PI_2); - if(har->hard>=50) { - dist= sqrt(dist); - } - } - } - else if(har->hard<20) dist*=dist; - - dist=(1.0-dist); - - if(har->linec) { - float *rc, fac; - int ofs; - - /* per starpoint an antialaised line */ - ofs= har->seed; - - for(a= har->linec; a>0; a--, ofs+=3) { - - rc= hashvectf + (ofs % 768); - - fac= fabs( (xn)*rc[0]+(yn)*rc[1]); - - if(fac< 1.0 ) { - linef+= (1.0-fac); - } - } - - linef*= dist; - - } - - if(har->starpoints) { - float ster, hoek; - /* rotation */ - hoek= atan2(yn, xn); - hoek*= (1.0+0.25*har->starpoints); - - co= cos(hoek); - si= sin(hoek); - - hoek= (co*xn+si*yn)*(co*yn-si*xn); - - ster= fabs(hoek); - if(ster>1.0) { - ster= (har->rad)/(ster); - - if(ster<1.0) dist*= sqrt(ster); - } - } - - /* halo intersected? */ - if(har->zs> zz-har->zd) { - t= ((float)(zz-har->zs))/(float)har->zd; - alpha*= sqrt(sqrt(t)); - } - - dist*= alpha; - ringf*= dist; - linef*= alpha; - - if(dist<0.003) { - *( (int *)col )=0; - return; - } - - /* texture? */ - if(har->tex) { - colf[0]= har->r; colf[1]= har->g; colf[2]= har->b; - colf[3]= dist; - do_halo_tex(har, xn, yn, colf); // can return without setting colf - - /* dist== colf[3]; */ - - colf[0]*= colf[3]; - colf[1]*= colf[3]; - colf[2]*= colf[3]; - - } - else { - colf[0]= dist*har->r; - colf[1]= dist*har->g; - colf[2]= dist*har->b; - - if(har->type & HA_XALPHA) colf[3]= dist*dist; - else colf[3]= dist; - } - - if(har->mat && har->mat->mode & MA_HALO_SHADE) { - /* we test for lights because of preview... */ - if(R.totlamp) render_lighting_halo(har, colf); - } - - if(linef!=0.0) { - Material *ma= har->mat; - - colf[0]+= 255.0*linef*ma->specr; - colf[1]+= 255.0*linef*ma->specg; - colf[2]+= 255.0*linef*ma->specb; - - if(har->type & HA_XALPHA) colf[3]+= linef*linef; - else colf[3]+= linef; - } - if(ringf!=0.0) { - Material *ma= har->mat; - - colf[0]+= 255.0*ringf*ma->mirr; - colf[1]+= 255.0*ringf*ma->mirg; - colf[2]+= 255.0*ringf*ma->mirb; - - if(har->type & HA_XALPHA) colf[3]+= ringf*ringf; - else colf[3]+= ringf; - } - - colt= 255.0*colf[3]; - if(colt>254) col[3]= 255; else col[3]= colt; - - colt= colf[2]; - if(colt>254) col[2]= 255; else col[2]= colt; - - colt= colf[1]; - if(colt>254) col[1]= 255; else col[1]= colt; - - colt= colf[0]; - if(colt>254) col[0]= 255; else col[0]= colt; - -} - -unsigned int calchalo_z(HaloRen *har, unsigned int zz) +static unsigned int calchalo_z(HaloRen *har, unsigned int zz) { if(har->type & HA_ONLYSKY) { @@ -1003,23 +363,24 @@ unsigned int calchalo_z(HaloRen *har, unsigned int zz) return zz; } -void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, short ys) +static void scanlinehaloPS(unsigned int *rectz, long *rectdelta, float *rowbuf, short ys) { HaloRen *har = NULL; PixStr *ps; - float dist,xsq,ysq,xn,yn; - unsigned int a, *rz, *rt, zz; + float dist, xsq, ysq, xn, yn; + float *rb; + float col[4], accol[4]; + unsigned int a, *rz, zz; long *rd; - int accol[4]; - short minx,maxx,x,aantal, aantalm, flarec; - char col[4]; + short minx, maxx, x, aantal, aantalm, flarec; - for(a=0;a<R.tothalo;a++) { - if((a & 255)==0) har= R.bloha[a>>8]; + for(a=0; a<R.tothalo; a++) { + if((a & 255)==0) { + har= R.bloha[a>>8]; + if( RE_local_test_break() ) break; + } else har++; - if( RE_local_test_break() ) break; - if(ys>har->maxy); else if(ys<har->miny); else { @@ -1032,9 +393,9 @@ void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, s if(minx<0) minx= 0; if(maxx>=R.rectx) maxx= R.rectx-1; - rt= rectt+minx; - rd= rectdelta+minx; - rz= rectz+minx; + rb= rowbuf + 4*minx; + rd= rectdelta + minx; + rz= rectz + minx; yn= (ys-har->ys)*R.ycor; ysq= yn*yn; @@ -1047,21 +408,25 @@ void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, s xsq= xn*xn; dist= xsq+ysq; if(dist<har->radsq) { + ps= (PixStr *) POINTER_FROM_CODE(*rd); aantal= 0; - accol[0]=accol[1]=accol[2]=accol[3]= 0; + accol[0]=accol[1]=accol[2]=accol[3]= 0.0; + while(ps) { aantalm= count_mask(ps->mask); aantal+= aantalm; zz= calchalo_z(har, ps->z); if(zz> har->zs) { - *( (int *)col )= 0; - RE_shadehalo(har, col, zz, dist, xn, yn, flarec); - accol[0]+= aantalm*col[0]; - accol[1]+= aantalm*col[1]; - accol[2]+= aantalm*col[2]; - accol[3]+= aantalm*col[3]; + float fac; + + shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); + fac= ((float)aantalm)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; flarec= 0; } @@ -1072,22 +437,28 @@ void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, s zz= calchalo_z(har, *rz); if(zz> har->zs) { - *( (int *)col )= 0; - RE_shadehalo(har, col, zz, dist, xn, yn, flarec); - accol[0]+= aantal*col[0]; - accol[1]+= aantal*col[1]; - accol[2]+= aantal*col[2]; - accol[3]+= aantal*col[3]; + float fac; + + shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); + fac= ((float)aantal)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; } - - col[0]= accol[0]/R.osa; - col[1]= accol[1]/R.osa; - col[2]= accol[2]/R.osa; - col[3]= accol[3]/R.osa; + col[0]= accol[0]; + col[1]= accol[1]; + col[2]= accol[2]; + col[3]= accol[3]; /* if(behind > (R.osa>>1)) addalphaUnder(rt,col); */ - RE_addalphaAddfac((char *)rt, (char *)col, har->add); + if(do_gamma) { + col[0]= gammaCorrect(col[0]); + col[1]= gammaCorrect(col[1]); + col[2]= gammaCorrect(col[2]); + } + addalphaAddfacFloat(rb, col, har->add); } } else { @@ -1097,29 +468,32 @@ void scanlinehaloPS(unsigned int *rectz, long *rectdelta, unsigned int *rectt, s xsq= xn*xn; dist= xsq+ysq; if(dist<har->radsq) { - RE_shadehalo(har, col, zz, dist, xn, yn, flarec); - RE_addalphaAddfac((char *)rt, (char *)col, har->add); + shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); + if(do_gamma) { + col[0]= gammaCorrect(col[0]); + col[1]= gammaCorrect(col[1]); + col[2]= gammaCorrect(col[2]); + } + addalphaAddfacFloat(rb, col, har->add); } } } - rt++; + rb+=4; rz++; rd++; } - } } } - } -void scanlinehalo(unsigned int *rectz, unsigned int *rectt, short ys) +static void scanlinehalo(unsigned int *rectz, float *rowbuf, short ys) { HaloRen *har = NULL; - float dist,xsq,ysq,xn,yn; - unsigned int a, *rz, *rt, zz; - short minx,maxx, x; - char col[4]; + float dist, xsq, ysq, xn, yn, *rb; + float col[4]; + unsigned int a, *rz, zz; + short minx, maxx, x; for(a=0; a<R.tothalo; a++) { if((a & 255)==0) har= R.bloha[a>>8]; @@ -1139,8 +513,8 @@ void scanlinehalo(unsigned int *rectz, unsigned int *rectt, short ys) if(minx<0) minx= 0; if(maxx>=R.rectx) maxx= R.rectx-1; - rt= rectt+minx; - rz= rectz+minx; + rb= rowbuf + 4*minx; + rz= rectz + minx; yn= (ys-har->ys)*R.ycor; ysq= yn*yn; @@ -1152,93 +526,17 @@ void scanlinehalo(unsigned int *rectz, unsigned int *rectt, short ys) xsq= xn*xn; dist= xsq+ysq; if(dist<har->radsq) { - RE_shadehalo(har, col, zz, dist, xn, yn, har->flarec); - RE_addalphaAddfac((char *)rt, (char *)col, har->add); + shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec); + addalphaAddfacFloat(rb, col, har->add); } } - rt++; + rb+=4; rz++; } } } } - -} - -void halovert() -{ - HaloRen *har = NULL; - float dist, xsq, ysq, xn, yn; - unsigned int a, *rectz, *rz, *rectt, *rt, zz; - int minx, maxx, miny, maxy, x, y; - char col[4]; - - - for(a=0;a<R.tothalo;a++) { - if((a & 255)==0) har= R.bloha[a>>8]; - else har++; - - if(RE_local_test_break() ) break; - - if(har->maxy<0); - else if(R.recty<har->miny); - else { - minx= floor(har->xs-har->rad); - maxx= ceil(har->xs+har->rad); - - if(maxx<0); - else if(R.rectx<minx); - else { - - miny= floor(har->ys-har->rad); - maxy= ceil(har->ys+har->rad); - - if(minx<0) minx= 0; - if(maxx>=R.rectx) maxx= R.rectx-1; - if(miny<0) miny= 0; - if(maxy>R.recty) maxy= R.recty; - - rectt= R.rectot+ R.rectx*miny; - rectz= R.rectz+ R.rectx*miny; - - for(y=miny;y<maxy;y++) { - - rz= rectz+minx; - - rt= (rectt+minx); - - yn= (y - har->ys)*R.ycor; - ysq= yn*yn; - for(x=minx;x<=maxx;x++) { - - zz= calchalo_z(har, *rz); - - if(zz> har->zs) { - - xn= x - har->xs; - xsq= xn*xn; - dist= xsq+ysq; - if(dist<har->radsq) { - RE_shadehalo(har, col, zz, dist, xn, yn, har->flarec); - - RE_addalphaAddfac((char *)rt, (char *)col, har->add); - - } - } - rt++; - rz++; - } - - rectt+= R.rectx; - rectz+= R.rectx; - - if(RE_local_test_break() ) break; - } - - } - } - } } /* ---------------- shaders ----------------------- */ @@ -1564,7 +862,7 @@ float OrenNayar_Diff(float *n, float *l, float *v, float rough ) /* --------------------------------------------- */ - +/* also called from texture.c */ void calc_R_ref(ShadeInput *shi) { float i; @@ -1577,36 +875,36 @@ void calc_R_ref(ShadeInput *shi) shi->ref[2]= (shi->view[2]+i*shi->vn[2]); if(shi->osatex) { if(shi->vlr->flag & R_SMOOTH) { - i= -2*( (shi->vn[0]+O.dxno[0])*(shi->view[0]+O.dxview) + - (shi->vn[1]+O.dxno[1])*shi->view[1]+ (shi->vn[2]+O.dxno[2])*shi->view[2] ); + i= -2*( (shi->vn[0]+shi->dxno[0])*(shi->view[0]+shi->dxview) + + (shi->vn[1]+shi->dxno[1])*shi->view[1]+ (shi->vn[2]+shi->dxno[2])*shi->view[2] ); - O.dxref[0]= shi->ref[0]- ( shi->view[0]+O.dxview+i*(shi->vn[0]+O.dxno[0])); - O.dxref[1]= shi->ref[1]- (shi->view[1]+ i*(shi->vn[1]+O.dxno[1])); - O.dxref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+O.dxno[2])); + shi->dxref[0]= shi->ref[0]- ( shi->view[0]+shi->dxview+i*(shi->vn[0]+shi->dxno[0])); + shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*(shi->vn[1]+shi->dxno[1])); + shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dxno[2])); - i= -2*( (shi->vn[0]+O.dyno[0])*shi->view[0]+ - (shi->vn[1]+O.dyno[1])*(shi->view[1]+O.dyview)+ (shi->vn[2]+O.dyno[2])*shi->view[2] ); + i= -2*( (shi->vn[0]+shi->dyno[0])*shi->view[0]+ + (shi->vn[1]+shi->dyno[1])*(shi->view[1]+shi->dyview)+ (shi->vn[2]+shi->dyno[2])*shi->view[2] ); - O.dyref[0]= shi->ref[0]- (shi->view[0]+ i*(shi->vn[0]+O.dyno[0])); - O.dyref[1]= shi->ref[1]- (shi->view[1]+O.dyview+i*(shi->vn[1]+O.dyno[1])); - O.dyref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+O.dyno[2])); + shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*(shi->vn[0]+shi->dyno[0])); + shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*(shi->vn[1]+shi->dyno[1])); + shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*(shi->vn[2]+shi->dyno[2])); } else { - i= -2*( shi->vn[0]*(shi->view[0]+O.dxview) + + i= -2*( shi->vn[0]*(shi->view[0]+shi->dxview) + shi->vn[1]*shi->view[1]+ shi->vn[2]*shi->view[2] ); - O.dxref[0]= shi->ref[0]- (shi->view[0]+O.dxview+i*shi->vn[0]); - O.dxref[1]= shi->ref[1]- (shi->view[1]+ i*shi->vn[1]); - O.dxref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); + shi->dxref[0]= shi->ref[0]- (shi->view[0]+shi->dxview+i*shi->vn[0]); + shi->dxref[1]= shi->ref[1]- (shi->view[1]+ i*shi->vn[1]); + shi->dxref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); i= -2*( shi->vn[0]*shi->view[0]+ - shi->vn[1]*(shi->view[1]+O.dyview)+ shi->vn[2]*shi->view[2] ); + shi->vn[1]*(shi->view[1]+shi->dyview)+ shi->vn[2]*shi->view[2] ); - O.dyref[0]= shi->ref[0]- (shi->view[0]+ i*shi->vn[0]); - O.dyref[1]= shi->ref[1]- (shi->view[1]+O.dyview+i*shi->vn[1]); - O.dyref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); + shi->dyref[0]= shi->ref[0]- (shi->view[0]+ i*shi->vn[0]); + shi->dyref[1]= shi->ref[1]- (shi->view[1]+shi->dyview+i*shi->vn[1]); + shi->dyref[2]= shi->ref[2]- (shi->view[2]+ i*shi->vn[2]); } } @@ -1632,34 +930,32 @@ float fresnel_fac(float *view, float *vn, float grad, float fac) void shade_color(ShadeInput *shi, ShadeResult *shr) { - Material *ma= shi->matren; + Material *ma= shi->mat; if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - ma->r= shi->vcol[0]; - ma->g= shi->vcol[1]; - ma->b= shi->vcol[2]; + shi->r= shi->vcol[0]; + shi->g= shi->vcol[1]; + shi->b= shi->vcol[2]; } - ma->alpha= shi->mat->alpha; // copy to render material, for fresnel and spectra - if(ma->texco) { if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - shi->mat->r= shi->vcol[0]; - shi->mat->g= shi->vcol[1]; - shi->mat->b= shi->vcol[2]; + shi->r= shi->vcol[0]; + shi->g= shi->vcol[1]; + shi->b= shi->vcol[2]; } do_material_tex(shi); } if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) { if(ma->fresnel_tra!=0.0) - ma->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); + shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); } - shr->diff[0]= ma->r; - shr->diff[1]= ma->g; - shr->diff[2]= ma->b; - shr->alpha= ma->alpha; + shr->diff[0]= shi->r; + shr->diff[1]= shi->g; + shr->diff[2]= shi->b; + shr->alpha= shi->alpha; } /* r g b = 1 value, col = vector */ @@ -1729,7 +1025,7 @@ static void ramp_blend(int type, float *r, float *g, float *b, float fac, float /* ramp for at end of shade */ void ramp_diffuse_result(float *diff, ShadeInput *shi) { - Material *ma= shi->matren; + Material *ma= shi->mat; float col[4], fac=0; if(ma->ramp_col) { @@ -1749,7 +1045,7 @@ void ramp_diffuse_result(float *diff, ShadeInput *shi) /* r,g,b denote energy, ramp is used with different values to make new material color */ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b) { - Material *ma= shi->matren; + Material *ma= shi->mat; float col[4], colt[3], fac=0; if(ma->ramp_col && (ma->mode & MA_RAMP_COL)) { @@ -1757,9 +1053,9 @@ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, fl /* MA_RAMP_IN_RESULT is exceptional */ if(ma->rampin_col==MA_RAMP_IN_RESULT) { // normal add - diff[0] += r * ma->r; - diff[1] += g * ma->g; - diff[2] += b * ma->b; + diff[0] += r * shi->r; + diff[1] += g * shi->g; + diff[2] += b * shi->b; } else { /* input */ @@ -1779,7 +1075,7 @@ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, fl /* blending method */ fac= col[3]*ma->rampfac_col; - colt[0]= ma->r; colt[1]= ma->g; colt[2]= ma->b; + colt[0]= shi->r; colt[1]= shi->g; colt[2]= shi->b; ramp_blend(ma->rampblend_col, colt, colt+1, colt+2, fac, col); @@ -1790,15 +1086,15 @@ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, fl } } else { - diff[0] += r * ma->r; - diff[1] += g * ma->g; - diff[2] += b * ma->b; + diff[0] += r * shi->r; + diff[1] += g * shi->g; + diff[2] += b * shi->b; } } void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) { - Material *ma= shi->matren; + Material *ma= shi->mat; float col[4]; float fac; @@ -1817,13 +1113,13 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) /* is = dot product shade, t = spec energy */ void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) { - Material *ma= shi->matren; + Material *ma= shi->mat; float col[4]; float fac=0.0; - spec[0]= ma->specr; - spec[1]= ma->specg; - spec[2]= ma->specb; + spec[0]= shi->specr; + spec[1]= shi->specg; + spec[2]= shi->specb; /* MA_RAMP_IN_RESULT is exception */ if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) { @@ -1856,18 +1152,15 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) { float f, shadfac[4]; - if((wrld->mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->matren->amb!=0.0) { + if((wrld->mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) { ray_ao(shi, wrld, shadfac); if(wrld->aocolor==WO_AOPLAIN) { if (wrld->aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0; else if (wrld->aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0; - f= wrld->aoenergy*shadfac[3]*shi->matren->amb; + f= wrld->aoenergy*shadfac[3]*shi->amb; add_to_diffuse(shr->diff, shi, f, f, f, f); - //shr->diff[0] += f; - //shr->diff[1] += f; - //shr->diff[2] += f; } else { if (wrld->aomix==WO_AOADDSUB) { @@ -1880,11 +1173,8 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) shadfac[1] = shadfac[1]-1.0; shadfac[2] = shadfac[2]-1.0; } - f= wrld->aoenergy*shi->matren->amb; + f= wrld->aoenergy*shi->amb; add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]); - //shr->diff[0] += f*shadfac[0]; - //shr->diff[1] += f*shadfac[1]; - //shr->diff[2] += f*shadfac[2]; } } } @@ -1892,9 +1182,9 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) { LampRen *lar; - Material *ma= shi->matren; + Material *ma= shi->mat; VlakRen *vlr= shi->vlr; - float i, inp, inpr, is, t, lv[3], lampdist, ld = 0; + float i, inp, inpr, is, t, lv[3], lacol[3], lampdist, ld = 0; float lvrot[3], *vn, *view, shadfac[4], soft, phongcorr; // shadfac = rgba int a; @@ -1931,7 +1221,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) inp= vn[0]*lv[0] + vn[1]*lv[1] + vn[2]*lv[2]; - if(lar->shb) i = testshadowbuf(lar->shb, shi->co, inp); + if(lar->shb) i = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp); else { float shad[4]; ray_shadow(shi, lar, shad); @@ -1968,17 +1258,17 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } if(ir>0.0) { shadfac[3]/= ir; - shr->alpha= (shi->mat->alpha)*(1.0-shadfac[3]); + shr->alpha= (shi->alpha)*(1.0-shadfac[3]); } } - if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->matren->amb!=0.0) { + if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) { float f; ray_ao(shi, &R.wrld, shadfac); // shadfac==0: full light shadfac[3]= 1.0-shadfac[3]; - f= R.wrld.aoenergy*shadfac[3]*shi->matren->amb; + f= R.wrld.aoenergy*shadfac[3]*shi->amb; if(R.wrld.aomix==WO_AOADD) { shr->alpha += f; @@ -1997,44 +1287,42 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - ma->r= shi->vcol[0]; - ma->g= shi->vcol[1]; - ma->b= shi->vcol[2]; + shi->r= shi->vcol[0]; + shi->g= shi->vcol[1]; + shi->b= shi->vcol[2]; } - ma->alpha= shi->mat->alpha; // copy to render material, for fresnel and spectra - /* envmap hack, always reset */ shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0; if(ma->texco) { if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - shi->mat->r= shi->vcol[0]; - shi->mat->g= shi->vcol[1]; - shi->mat->b= shi->vcol[2]; + shi->r= shi->vcol[0]; + shi->g= shi->vcol[1]; + shi->b= shi->vcol[2]; } do_material_tex(shi); } if(ma->mode & MA_SHLESS) { - shr->diff[0]= ma->r; - shr->diff[1]= ma->g; - shr->diff[2]= ma->b; - shr->alpha= ma->alpha; + shr->diff[0]= shi->r; + shr->diff[1]= shi->g; + shr->diff[2]= shi->b; + shr->alpha= shi->alpha; return; } if( (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { // add_to_diffuse(shr->diff, shi, 1.0, ma->emit+shi->vcol[0], ma->emit+shi->vcol[1], ma->emit+shi->vcol[2]); - shr->diff[0]= ma->r*(ma->emit+shi->vcol[0]); - shr->diff[1]= ma->g*(ma->emit+shi->vcol[1]); - shr->diff[2]= ma->b*(ma->emit+shi->vcol[2]); + shr->diff[0]= shi->r*(shi->emit+shi->vcol[0]); + shr->diff[1]= shi->g*(shi->emit+shi->vcol[1]); + shr->diff[2]= shi->b*(shi->emit+shi->vcol[2]); } else { // add_to_diffuse(shr->diff, shi, 1.0, ma->emit, ma->emit, ma->emit); - shr->diff[0]= ma->r*ma->emit; - shr->diff[1]= ma->g*ma->emit; - shr->diff[2]= ma->b*ma->emit; + shr->diff[0]= shi->r*shi->emit; + shr->diff[1]= shi->g*shi->emit; + shr->diff[2]= shi->b*shi->emit; } ambient_occlusion(&R.wrld, shi, shr); @@ -2089,8 +1377,10 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } } - if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi); - + lacol[0]= lar->r; + lacol[1]= lar->g; + lacol[2]= lar->b; + /* init transp shadow */ shadfac[3]= 1.0; if(ma->mode & MA_SHADOW_TRA) shadfac[0]= shadfac[1]= shadfac[2]= 1.0; @@ -2135,17 +1425,19 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(lar->mode & LA_OSATEX) { shi->osatex= 1; /* signal for multitex() */ - O.dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+O.dxco[0])/ld; - O.dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+O.dxco[1])/ld; - O.dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+O.dxco[2])/ld; + shi->dxlv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dxco[0])/ld; + shi->dxlv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dxco[1])/ld; + shi->dxlv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dxco[2])/ld; - O.dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+O.dyco[0])/ld; - O.dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+O.dyco[1])/ld; - O.dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+O.dyco[2])/ld; + shi->dylv[0]= lv[0] - (shi->co[0]-lar->co[0]+shi->dyco[0])/ld; + shi->dylv[1]= lv[1] - (shi->co[1]-lar->co[1]+shi->dyco[1])/ld; + shi->dylv[2]= lv[2] - (shi->co[2]-lar->co[2]+shi->dyco[2])/ld; } } + if(lar->mode & LA_TEXTURE) do_lamp_tex(lar, lv, shi, lacol); + /* dot product and reflectivity */ /* inp = dotproduct, is = shader result, i = lamp energy (with shadow) */ @@ -2186,7 +1478,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) i= is*phongcorr; if(i>0.0) { - i*= lampdist*ma->ref; + i*= lampdist*shi->refl; } /* shadow and spec, (lampdist==0 outside spot) */ @@ -2197,7 +1489,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(lar->type==LA_HEMI); // no shadow else { if(lar->shb) { - shadfac[3] = testshadowbuf(lar->shb, shi->co, inp); + shadfac[3] = testshadowbuf(lar->shb, shi->co, shi->dxco, shi->dyco, inp); } else if(lar->mode & LA_SHAD_RAY) { ray_shadow(shi, lar, shadfac); @@ -2207,9 +1499,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(lar->mode & LA_ONLYSHADOW) { shadfac[3]= i*lar->energy*(1.0-shadfac[3]); - shr->diff[0] -= shadfac[3]*ma->r; - shr->diff[1] -= shadfac[3]*ma->g; - shr->diff[2] -= shadfac[3]*ma->b; + shr->diff[0] -= shadfac[3]*shi->r; + shr->diff[1] -= shadfac[3]*shi->g; + shr->diff[2] -= shadfac[3]*shi->b; continue; } @@ -2222,7 +1514,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } /* specularity */ - if(shadfac[3]>0.0 && ma->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) { + if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) { if(lar->type==LA_HEMI) { /* hemi uses no spec shaders (yet) */ @@ -2239,40 +1531,40 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) t= 0.5*t+0.5; } - t= shadfac[3]*ma->spec*spec(t, ma->har); - shr->spec[0]+= t*(lar->r * ma->specr); - shr->spec[1]+= t*(lar->g * ma->specg); - shr->spec[2]+= t*(lar->b * ma->specb); + t= shadfac[3]*shi->spec*spec(t, shi->har); + shr->spec[0]+= t*(lacol[0] * shi->specr); + shr->spec[1]+= t*(lacol[1] * shi->specg); + shr->spec[2]+= t*(lacol[2] * shi->specb); } else { /* specular shaders */ float specfac; if(ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(vn, lv, view, ma->har); + specfac= Phong_Spec(vn, lv, view, shi->har); else if(ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(vn, lv, view, ma->har); + specfac= CookTorr_Spec(vn, lv, view, shi->har); else if(ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)ma->har); + specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har); else specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3]); /* area lamp correction */ if(lar->type==LA_AREA) specfac*= inp; - t= shadfac[3]*ma->spec*lampdist*specfac; + t= shadfac[3]*shi->spec*lampdist*specfac; if(ma->mode & MA_RAMP_SPEC) { float spec[3]; do_specular_ramp(shi, specfac, t, spec); - shr->spec[0]+= t*(lar->r * spec[0]); - shr->spec[1]+= t*(lar->g * spec[1]); - shr->spec[2]+= t*(lar->b * spec[2]); + shr->spec[0]+= t*(lacol[0] * spec[0]); + shr->spec[1]+= t*(lacol[1] * spec[1]); + shr->spec[2]+= t*(lacol[2] * spec[2]); } else { - shr->spec[0]+= t*(lar->r * ma->specr); - shr->spec[1]+= t*(lar->g * ma->specg); - shr->spec[2]+= t*(lar->b * ma->specb); + shr->spec[0]+= t*(lacol[0] * shi->specr); + shr->spec[1]+= t*(lacol[1] * shi->specg); + shr->spec[2]+= t*(lacol[2] * shi->specb); } } } @@ -2281,43 +1573,43 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* in case 'no diffuse' we still do most calculus, spec can be in shadow */ if(i>0.0 && !(lar->mode & LA_NO_DIFF)) { if(ma->mode & MA_SHADOW_TRA) { - add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lar->r, i*shadfac[1]*lar->g, i*shadfac[2]*lar->b); + add_to_diffuse(shr->diff, shi, is, i*shadfac[0]*lacol[0], i*shadfac[1]*lacol[1], i*shadfac[2]*lacol[2]); } else { - add_to_diffuse(shr->diff, shi, is, i*lar->r, i*lar->g, i*lar->b); + add_to_diffuse(shr->diff, shi, is, i*lacol[0], i*lacol[1], i*lacol[2]); } } } if(ma->mode & (MA_ZTRA|MA_RAYTRANSP)) { if(ma->fresnel_tra!=0.0) - ma->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); + shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); - if(ma->spectra!=0.0) { + if(shi->spectra!=0.0) { t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]); - t *= ma->spectra; + t *= shi->spectra; if(t>1.0) t= 1.0; - ma->alpha= (1.0-t)*ma->alpha+t; + shi->alpha= (1.0-t)*shi->alpha+t; } } - shr->alpha= ma->alpha; + shr->alpha= shi->alpha; if(shr->spec[0]<0.0) shr->spec[0]= 0.0; if(shr->spec[1]<0.0) shr->spec[1]= 0.0; if(shr->spec[2]<0.0) shr->spec[2]= 0.0; - shr->diff[0]+= ma->r*ma->amb*shi->rad[0]; - shr->diff[0]+= ma->ambr; + shr->diff[0]+= shi->r*shi->amb*shi->rad[0]; + shr->diff[0]+= shi->ambr; if(shr->diff[0]<0.0) shr->diff[0]= 0.0; - shr->diff[1]+= ma->g*ma->amb*shi->rad[1]; - shr->diff[1]+= ma->ambg; + shr->diff[1]+= shi->g*shi->amb*shi->rad[1]; + shr->diff[1]+= shi->ambg; if(shr->diff[1]<0.0) shr->diff[1]= 0.0; - shr->diff[2]+= ma->b*ma->amb*shi->rad[2]; - shr->diff[2]+= ma->ambb; + shr->diff[2]+= shi->b*shi->amb*shi->rad[2]; + shr->diff[2]+= shi->ambb; if(shr->diff[2]<0.0) shr->diff[2]= 0.0; if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi); @@ -2325,9 +1617,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* refcol is for envmap only */ if(shi->refcol[0]!=0.0) { - shr->diff[0]= ma->mirr*shi->refcol[1] + (1.0 - ma->mirr*shi->refcol[0])*shr->diff[0]; - shr->diff[1]= ma->mirg*shi->refcol[2] + (1.0 - ma->mirg*shi->refcol[0])*shr->diff[1]; - shr->diff[2]= ma->mirb*shi->refcol[3] + (1.0 - ma->mirb*shi->refcol[0])*shr->diff[2]; + shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*shr->diff[0]; + shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*shr->diff[1]; + shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*shr->diff[2]; } } @@ -2337,8 +1629,8 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i VertRen *v1, *v2, *v3; VlakRen *vlr= shi->vlr; float l, dl; - short texco= shi->matren->texco; - int mode= shi->matren->mode; + short texco= shi->mat->texco; + int mode= shi->mat->mode; char p1, p2, p3; /* for rendering of quads, the following values are used to denote vertices: @@ -2400,30 +1692,30 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i u= (shi->co[0]-v3->co[0])*t11-(shi->co[1]-v3->co[1])*t10; v= (shi->co[1]-v3->co[1])*t00-(shi->co[0]-v3->co[0])*t01; if(shi->osatex) { - O.dxuv[0]= O.dxco[0]*t11- O.dxco[1]*t10; - O.dxuv[1]= O.dxco[1]*t00- O.dxco[0]*t01; - O.dyuv[0]= O.dyco[0]*t11- O.dyco[1]*t10; - O.dyuv[1]= O.dyco[1]*t00- O.dyco[0]*t01; + shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[1]*t10; + shi->dxuv[1]= shi->dxco[1]*t00- shi->dxco[0]*t01; + shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[1]*t10; + shi->dyuv[1]= shi->dyco[1]*t00- shi->dyco[0]*t01; } } else if(vlr->snproj==1) { u= (shi->co[0]-v3->co[0])*t11-(shi->co[2]-v3->co[2])*t10; v= (shi->co[2]-v3->co[2])*t00-(shi->co[0]-v3->co[0])*t01; if(shi->osatex) { - O.dxuv[0]= O.dxco[0]*t11- O.dxco[2]*t10; - O.dxuv[1]= O.dxco[2]*t00- O.dxco[0]*t01; - O.dyuv[0]= O.dyco[0]*t11- O.dyco[2]*t10; - O.dyuv[1]= O.dyco[2]*t00- O.dyco[0]*t01; + shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[2]*t10; + shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[0]*t01; + shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[2]*t10; + shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[0]*t01; } } else { u= (shi->co[1]-v3->co[1])*t11-(shi->co[2]-v3->co[2])*t10; v= (shi->co[2]-v3->co[2])*t00-(shi->co[1]-v3->co[1])*t01; if(shi->osatex) { - O.dxuv[0]= O.dxco[1]*t11- O.dxco[2]*t10; - O.dxuv[1]= O.dxco[2]*t00- O.dxco[1]*t01; - O.dyuv[0]= O.dyco[1]*t11- O.dyco[2]*t10; - O.dyuv[1]= O.dyco[2]*t00- O.dyco[1]*t01; + shi->dxuv[0]= shi->dxco[1]*t11- shi->dxco[2]*t10; + shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[1]*t01; + shi->dyuv[0]= shi->dyco[1]*t11- shi->dyco[2]*t10; + shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[1]*t01; } } } @@ -2459,14 +1751,14 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i Normalise(shi->vn); if(shi->osatex && (texco & (TEXCO_NORM|TEXCO_REFL)) ) { - dl= O.dxuv[0]+O.dxuv[1]; - O.dxno[0]= dl*n3[0]-O.dxuv[0]*n1[0]-O.dxuv[1]*n2[0]; - O.dxno[1]= dl*n3[1]-O.dxuv[0]*n1[1]-O.dxuv[1]*n2[1]; - O.dxno[2]= dl*n3[2]-O.dxuv[0]*n1[2]-O.dxuv[1]*n2[2]; - dl= O.dyuv[0]+O.dyuv[1]; - O.dyno[0]= dl*n3[0]-O.dyuv[0]*n1[0]-O.dyuv[1]*n2[0]; - O.dyno[1]= dl*n3[1]-O.dyuv[0]*n1[1]-O.dyuv[1]*n2[1]; - O.dyno[2]= dl*n3[2]-O.dyuv[0]*n1[2]-O.dyuv[1]*n2[2]; + dl= shi->dxuv[0]+shi->dxuv[1]; + shi->dxno[0]= dl*n3[0]-shi->dxuv[0]*n1[0]-shi->dxuv[1]*n2[0]; + shi->dxno[1]= dl*n3[1]-shi->dxuv[0]*n1[1]-shi->dxuv[1]*n2[1]; + shi->dxno[2]= dl*n3[2]-shi->dxuv[0]*n1[2]-shi->dxuv[1]*n2[2]; + dl= shi->dyuv[0]+shi->dyuv[1]; + shi->dyno[0]= dl*n3[0]-shi->dyuv[0]*n1[0]-shi->dyuv[1]*n2[0]; + shi->dyno[1]= dl*n3[1]-shi->dyuv[0]*n1[1]-shi->dyuv[1]*n2[1]; + shi->dyno[2]= dl*n3[2]-shi->dyuv[0]*n1[2]-shi->dyuv[1]*n2[2]; } } @@ -2474,7 +1766,7 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i VECCOPY(shi->vn, vlr->n); } - /* texture coordinates. O.dxuv O.dyuv have been set */ + /* texture coordinates. shi->dxuv shi->dyuv have been set */ if(texco & NEED_UV) { if(texco & TEXCO_ORCO) { if(v1->orco) { @@ -2489,14 +1781,14 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->lo[2]= l*o3[2]-u*o1[2]-v*o2[2]; if(shi->osatex) { - dl= O.dxuv[0]+O.dxuv[1]; - O.dxlo[0]= dl*o3[0]-O.dxuv[0]*o1[0]-O.dxuv[1]*o2[0]; - O.dxlo[1]= dl*o3[1]-O.dxuv[0]*o1[1]-O.dxuv[1]*o2[1]; - O.dxlo[2]= dl*o3[2]-O.dxuv[0]*o1[2]-O.dxuv[1]*o2[2]; - dl= O.dyuv[0]+O.dyuv[1]; - O.dylo[0]= dl*o3[0]-O.dyuv[0]*o1[0]-O.dyuv[1]*o2[0]; - O.dylo[1]= dl*o3[1]-O.dyuv[0]*o1[1]-O.dyuv[1]*o2[1]; - O.dylo[2]= dl*o3[2]-O.dyuv[0]*o1[2]-O.dyuv[1]*o2[2]; + dl= shi->dxuv[0]+shi->dxuv[1]; + shi->dxlo[0]= dl*o3[0]-shi->dxuv[0]*o1[0]-shi->dxuv[1]*o2[0]; + shi->dxlo[1]= dl*o3[1]-shi->dxuv[0]*o1[1]-shi->dxuv[1]*o2[1]; + shi->dxlo[2]= dl*o3[2]-shi->dxuv[0]*o1[2]-shi->dxuv[1]*o2[2]; + dl= shi->dyuv[0]+shi->dyuv[1]; + shi->dylo[0]= dl*o3[0]-shi->dyuv[0]*o1[0]-shi->dyuv[1]*o2[0]; + shi->dylo[1]= dl*o3[1]-shi->dyuv[0]*o1[1]-shi->dyuv[1]*o2[1]; + shi->dylo[2]= dl*o3[2]-shi->dyuv[0]*o1[2]-shi->dyuv[1]*o2[2]; } } } @@ -2505,10 +1797,10 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i VECCOPY(shi->gl, shi->co); MTC_Mat4MulVecfl(R.viewinv, shi->gl); if(shi->osatex) { - VECCOPY(O.dxgl, O.dxco); - MTC_Mat3MulVecfl(R.imat, O.dxco); - VECCOPY(O.dygl, O.dyco); - MTC_Mat3MulVecfl(R.imat, O.dyco); + VECCOPY(shi->dxgl, shi->dxco); + MTC_Mat3MulVecfl(R.imat, shi->dxco); + VECCOPY(shi->dygl, shi->dyco); + MTC_Mat3MulVecfl(R.imat, shi->dyco); } } if((texco & TEXCO_UV) || (mode & (MA_VERTEXCOL|MA_FACETEXTURE))) { @@ -2567,19 +1859,19 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i if(shi->osatex) { float duv[2]; - dl= O.dxuv[0]+O.dxuv[1]; - duv[0]= O.dxuv[0]; - duv[1]= O.dxuv[1]; + dl= shi->dxuv[0]+shi->dxuv[1]; + duv[0]= shi->dxuv[0]; + duv[1]= shi->dxuv[1]; - O.dxuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); - O.dxuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); + shi->dxuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); + shi->dxuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); - dl= O.dyuv[0]+O.dyuv[1]; - duv[0]= O.dyuv[0]; - duv[1]= O.dyuv[1]; + dl= shi->dyuv[0]+shi->dyuv[1]; + duv[0]= shi->dyuv[0]; + duv[1]= shi->dyuv[1]; - O.dyuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); - O.dyuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); + shi->dyuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); + shi->dyuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); } if(mode & MA_FACETEXTURE) { @@ -2660,10 +1952,15 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) vlr= RE_findOrAddVlak( (vlaknr-1) & 0x7FFFFF); - shi.mat= vlr->mat; - shi.matren= shi.mat->ren; shi.vlr= vlr; - shi.osatex= (shi.matren->texco & TEXCO_OSA); + shi.mat= vlr->mat; + + // copy all relevant material vars, note, keep this synced with render_types.h + memcpy(&shi.r, &shi.mat->r, 23*sizeof(float)); + // set special cases: + shi.har= shi.mat->har; + if((shi.mat->mode & MA_RAYMIRROR)==0) shi.ray_mirror= 0.0; + shi.osatex= (shi.mat->texco & TEXCO_OSA); v1= vlr->v1; dvlak= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; @@ -2702,13 +1999,13 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) float u= dvlak/(deler-vlr->n[0]); float v= dvlak/(deler- R.ycor*vlr->n[1]); - O.dxco[0]= shi.co[0]- (shi.view[0]-1.0)*u; - O.dxco[1]= shi.co[1]- (shi.view[1])*u; - O.dxco[2]= shi.co[2]- (shi.view[2])*u; + shi.dxco[0]= shi.co[0]- (shi.view[0]-1.0)*u; + shi.dxco[1]= shi.co[1]- (shi.view[1])*u; + shi.dxco[2]= shi.co[2]- (shi.view[2])*u; - O.dyco[0]= shi.co[0]- (shi.view[0])*v; - O.dyco[1]= shi.co[1]- (shi.view[1]-1.0*R.ycor)*v; - O.dyco[2]= shi.co[2]- (shi.view[2])*v; + shi.dyco[0]= shi.co[0]- (shi.view[0])*v; + shi.dyco[1]= shi.co[1]- (shi.view[1]-1.0*R.ycor)*v; + shi.dyco[2]= shi.co[2]- (shi.view[2])*v; } @@ -2716,9 +2013,9 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) R.zcor*= fac; /* for mist */ if(shi.osatex) { - if( (shi.matren->texco & TEXCO_REFL) ) { - O.dxview= -1.0/fac; - O.dyview= -R.ycor/fac; + if( (shi.mat->texco & TEXCO_REFL) ) { + shi.dxview= -1.0/fac; + shi.dyview= -R.ycor/fac; } } @@ -2729,13 +2026,19 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) shade_input_set_coords(&shi, 1.0, 1.0, 0, 1, 2); /* this only avalailable for scanline */ - if(shi.matren->texco & TEXCO_WINDOW) { + if(shi.mat->texco & TEXCO_WINDOW) { shi.winco[0]= (x+(R.xstart))/(float)R.afmx; shi.winco[1]= (y+(R.ystart))/(float)R.afmy; shi.winco[2]= 0.0; + if(shi.osatex) { + shi.dxwin[0]= 0.5/(float)R.r.xsch; + shi.dywin[1]= 0.5/(float)R.r.ysch; + shi.dxwin[1]= shi.dxwin[2]= 0.0; + shi.dywin[0]= shi.dywin[2]= 0.0; + } } - /* after this the u and v AND O.dxuv and O.dyuv are incorrect */ - if(shi.matren->texco & TEXCO_STICKY) { + /* after this the u and v AND shi.dxuv and shi.dyuv are incorrect */ + if(shi.mat->texco & TEXCO_STICKY) { if(v1->sticky) { extern float Zmulx, Zmuly; float *o1, *o2, *o3, hox, hoy, l, dl, u, v; @@ -2772,17 +2075,17 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) shi.sticky[2]= 0.0; if(shi.osatex) { - O.dxuv[0]= s11/Zmulx; - O.dxuv[1]= - s01/Zmulx; - O.dyuv[0]= - s10/Zmuly; - O.dyuv[1]= s00/Zmuly; + shi.dxuv[0]= s11/Zmulx; + shi.dxuv[1]= - s01/Zmulx; + shi.dyuv[0]= - s10/Zmuly; + shi.dyuv[1]= s00/Zmuly; - dl= O.dxuv[0]+O.dxuv[1]; - O.dxsticky[0]= dl*o3[0]-O.dxuv[0]*o1[0]-O.dxuv[1]*o2[0]; - O.dxsticky[1]= dl*o3[1]-O.dxuv[0]*o1[1]-O.dxuv[1]*o2[1]; - dl= O.dyuv[0]+O.dyuv[1]; - O.dysticky[0]= dl*o3[0]-O.dyuv[0]*o1[0]-O.dyuv[1]*o2[0]; - O.dysticky[1]= dl*o3[1]-O.dyuv[0]*o1[1]-O.dyuv[1]*o2[1]; + dl= shi.dxuv[0]+shi.dxuv[1]; + shi.dxsticky[0]= dl*o3[0]-shi.dxuv[0]*o1[0]-shi.dxuv[1]*o2[0]; + shi.dxsticky[1]= dl*o3[1]-shi.dxuv[0]*o1[1]-shi.dxuv[1]*o2[1]; + dl= shi.dyuv[0]+shi.dyuv[1]; + shi.dysticky[0]= dl*o3[0]-shi.dyuv[0]*o1[0]-shi.dyuv[1]*o2[0]; + shi.dysticky[1]= dl*o3[1]-shi.dyuv[0]*o1[1]-shi.dyuv[1]*o2[1]; } } } @@ -2790,21 +2093,21 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) /* ------ main shading loop */ shade_lamp_loop(&shi, &shr); - if(shi.matren->translucency!=0.0) { + if(shi.translucency!=0.0) { ShadeResult shr_t; VecMulf(shi.vn, -1.0); VecMulf(shi.vlr->n, -1.0); shade_lamp_loop(&shi, &shr_t); - shr.diff[0]+= shi.matren->translucency*shr_t.diff[0]; - shr.diff[1]+= shi.matren->translucency*shr_t.diff[1]; - shr.diff[2]+= shi.matren->translucency*shr_t.diff[2]; + shr.diff[0]+= shi.translucency*shr_t.diff[0]; + shr.diff[1]+= shi.translucency*shr_t.diff[1]; + shr.diff[2]+= shi.translucency*shr_t.diff[2]; VecMulf(shi.vn, -1.0); VecMulf(shi.vlr->n, -1.0); } if(R.r.mode & R_RAYTRACE) { - if(shi.matren->ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { + if(shi.ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { ray_trace(&shi, &shr); } } @@ -2817,7 +2120,7 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) /* exposure correction */ if(R.wrld.exp!=0.0 || R.wrld.range!=1.0) { - if((shi.matren->mode & MA_SHLESS)==0) { + if((shi.mat->mode & MA_SHLESS)==0) { col[0]= R.wrld.linfac*(1.0-exp( col[0]*R.wrld.logfac) ); col[1]= R.wrld.linfac*(1.0-exp( col[1]*R.wrld.logfac) ); col[2]= R.wrld.linfac*(1.0-exp( col[2]*R.wrld.logfac) ); @@ -2825,7 +2128,7 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) } /* MIST */ - if( (R.wrld.mode & WO_MIST) && (shi.matren->mode & MA_NOMIST)==0 ){ + if( (R.wrld.mode & WO_MIST) && (shi.mat->mode & MA_NOMIST)==0 ){ alpha= mistfactor(shi.co); } else alpha= 1.0; @@ -2873,39 +2176,24 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) return vlr; } -void shadepixel_short(float x, float y, int vlaknr, int mask, unsigned short *shortcol) +static void shadepixel_sky(float x, float y, int vlaknr, int mask, float *colf) { - float colf[4]; + float collector[4]; shadepixel(x, y, vlaknr, mask, colf); - - if(colf[0]<=0.0) shortcol[0]= 0; else if(colf[0]>=1.0) shortcol[0]= 65535; - else shortcol[0]= 65535.0*colf[0]; - if(colf[1]<=0.0) shortcol[1]= 0; else if(colf[1]>=1.0) shortcol[1]= 65535; - else shortcol[1]= 65535.0*colf[1]; - if(colf[2]<=0.0) shortcol[2]= 0; else if(colf[2]>=1.0) shortcol[2]= 65535; - else shortcol[2]= 65535.0*colf[2]; - if(colf[3]<=0.0) shortcol[3]= 0; else if(colf[3]>=1.0) shortcol[3]= 65535; - else shortcol[3]= 65535.0*colf[3]; - - if(usegamtab) { - shortcol[0]= igamtab2[ shortcol[0] ]; - shortcol[1]= igamtab2[ shortcol[1] ]; - shortcol[2]= igamtab2[ shortcol[2] ]; - shortcol[3]= igamtab2[ shortcol[3] ]; - } - - if(R.r.dither_intensity!=0.0) { - short dither_value = (short)((BLI_frand() -.5)*R.r.dither_intensity*256.0); - /* no dither for color 0 or 255, is OK. intensity is <= 2.0 */ - if(shortcol[0]>255 && shortcol[0] < 65280) shortcol[0]+= dither_value; - if(shortcol[1]>255 && shortcol[1] < 65280) shortcol[1]+= dither_value; - if(shortcol[2]>255 && shortcol[2] < 65280) shortcol[2]+= dither_value; - } - + if(colf[3] != 1.0) { + renderSkyPixelFloat(collector, x, y); + addAlphaOverFloat(collector, colf); + QUATCOPY(colf, collector); + } } -PixStr *addpsmain() +/* ************* pixel struct ******** */ + +PixStrMain psmfirst; +int psmteller; + +static PixStr *addpsmain(void) { PixStrMain *psm; @@ -2925,7 +2213,7 @@ PixStr *addpsmain() return psm->ps; } -void freeps() +static void freeps(void) { PixStrMain *psm,*next; @@ -2945,7 +2233,7 @@ void freeps() psmfirst.ps= 0; } -void addps(long *rd, int vlak, unsigned int z, short ronde) +static void addps(long *rd, int vlak, unsigned int z, short ronde) { static PixStr *prev; PixStr *ps, *last = NULL; @@ -2995,67 +2283,11 @@ void addps(long *rd, int vlak, unsigned int z, short ronde) int count_mask(unsigned short mask) { + extern char cmask[256]; return (cmask[mask & 255]+cmask[mask>>8]); } -float count_maskf(unsigned short mask) -{ - return (fmask[mask & 255]+fmask[mask>>8]); -} - - -void add_filt_mask(unsigned int mask, unsigned short *col, unsigned int *rb1, unsigned int *rb2, unsigned int *rb3) -{ - /* calc the value of mask */ - unsigned int a, maskand, maskshift; - int j; - unsigned short val, r, g, b, al; - - al= col[3]; - r= col[0]; - g= col[1]; - b= col[2]; - - maskand= (mask & 255); - maskshift= (mask >>8); - - for(j=2; j>=0; j--) { - - a= j; - - val= *(mask1[a] +maskand) + *(mask2[a] +maskshift); - if(val) { - rb1[3]+= val*al; - rb1[0]+= val*r; - rb1[1]+= val*g; - rb1[2]+= val*b; - } - a+=3; - - val= *(mask1[a] +maskand) + *(mask2[a] +maskshift); - if(val) { - rb2[3]+= val*al; - rb2[0]+= val*r; - rb2[1]+= val*g; - rb2[2]+= val*b; - } - a+=3; - - val= *(mask1[a] +maskand) + *(mask2[a] +maskshift); - if(val) { - rb3[3]+= val*al; - rb3[0]+= val*r; - rb3[1]+= val*g; - rb3[2]+= val*b; - } - - rb1+= 4; - rb2+= 4; - rb3+= 4; - } -} - -void edge_enhance(void) +static void edge_enhance(void) { /* use zbuffer to define edges, add it to the image */ int val, y, x, col, *rz, *rz1, *rz2, *rz3; @@ -3074,7 +2306,6 @@ void edge_enhance(void) rz1= (int *)R.rectz; rz2= rz1+R.rectx; rz3= rz2+R.rectx; - rz= (int *)R.rectot+R.rectx; if(R.r.mode & R_OSA) { cp= (char *)(R.rectaccu+R.rectx); @@ -3082,12 +2313,10 @@ void edge_enhance(void) else { cp= (char *)(R.rectot+R.rectx); } - - /* rz itself does not seem to be used. */ + cp+= 4; for(y=0; y<R.recty-2; y++) { - rz++; for(x=0; x<R.rectx-2; x++, rz++, rz1++, rz2++, rz3++, cp+=4) { col= abs(12*rz2[1]-rz1[0]-2*rz1[1]-rz1[2]-2*rz2[0]-2*rz2[2]-rz3[0]-2*rz3[1]-rz3[2])/3; @@ -3129,25 +2358,135 @@ void edge_enhance(void) } /* ********************* MAINLOOPS ******************** */ +struct renderlineDA { + long *rd; + unsigned int *rz; + float *rb1, *rb2, *rb3; + float *acol; + int y; +}; + +static int do_renderlineDA(void *poin) +{ + struct renderlineDA *rl= poin; + PixStr *ps; + float xs, ys; + float fcol[4], *acol=NULL; + long *rd= rl->rd; + int samp, curmask, face, mask, fullmask; + int b, x, full_osa, face0; + + fullmask= (1<<R.osa)-1; + + if(R.flag & R_ZTRA) { /* zbuf tra */ + abufsetrow(rl->acol, rl->y); + acol= rl->acol; + } + + for(x=0; x<R.rectx; x++, rd++) { + + if( IS_A_POINTER_CODE(*rd)) + ps= (PixStr *) POINTER_FROM_CODE(*rd); + else ps= NULL; + + if(ps) face0= ps->vlak0; + else face0= (int)*rd; + mask= 0; + + /* complex loop, because first pixelstruct has a vlak0, without mask */ + while(TRUE) { + + if(ps==NULL) { + face= face0; + curmask= (~mask) & fullmask; + } + else { + face= ps->vlak; + curmask= ps->mask; + } + + /* check osa level */ + if(face==0) full_osa= 0; + else { + VlakRen *vlr= RE_findOrAddVlak( (face-1) & 0x7FFFFF); + full_osa= (vlr->flag & R_FULL_OSA); + } + + if(full_osa) { + for(samp=0; samp<R.osa; samp++) { + if(curmask & (1<<samp)) { + xs= (float)x + jit[samp][0]; + ys= (float)rl->y + jit[samp][1]; + shadepixel_sky(xs, ys, face, (1<<samp), fcol); + + if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol); + if(do_gamma) { + fcol[0]= gammaCorrect(fcol[0]); + fcol[1]= gammaCorrect(fcol[1]); + fcol[2]= gammaCorrect(fcol[2]); + } + add_filt_fmask(1<<samp, fcol, rl->rb1, rl->rb2, rl->rb3); + } + } + } + else { + extern char *centmask; // initrender.c + extern float centLut[16]; + + b= centmask[curmask]; + xs= (float)x+centLut[b & 15]; + ys= (float)rl->y+centLut[b>>4]; + shadepixel_sky(xs, ys, face, curmask, fcol); + + if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol); + + if(do_gamma) { + fcol[0]= gammaCorrect(fcol[0]); + fcol[1]= gammaCorrect(fcol[1]); + fcol[2]= gammaCorrect(fcol[2]); + } + add_filt_fmask(curmask, fcol, rl->rb1, rl->rb2, rl->rb3); + } + + mask |= curmask; + + if(ps==NULL) break; + else ps= ps->next; + } + + rl->rb1+=4; + rl->rb2+=4; + rl->rb3+=4; + if(acol) acol+=4; + } + + if(R.flag & R_HALO) { + /* from these pixels the pixstr is 1 scanline old */ + scanlinehaloPS(rl->rz, rl->rd, rl->rb2-4*R.rectx + 4, rl->y); + } + + return 1; +} -extern unsigned short *Acolrow; -/* short zbuffermetdehand(); */ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ { extern float Zjitx,Zjity; - PixStr *ps; - float xd, yd, xs, ys; - unsigned int *rz, *rp, *rt, mask, fullmask; - unsigned int *rowbuf1, *rowbuf2, *rowbuf3, *rb1, *rb2, *rb3; - int a, b; + struct renderlineDA rl1, rl2; + float xd, yd, *rf; long *rd; - unsigned short *colrb, *acol, shortcol[4]; + unsigned int *rz, *rp, *rt; + float *rowbuf1, *rowbuf2, *rowbuf3, *rowbuf0, *rowbuf1a, *rowbuf2a, *rb3; + int a; short v, x, y; - char *colrt, tempcol[4]; R.rectdaps= MEM_callocN(sizeof(long)*R.rectx*R.recty+4,"zbufDArectd"); - if(R.flag & R_ZTRA) bgnaccumbuf(); - + + if(R.flag & R_ZTRA) { + bgnaccumbuf(); + rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); + rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); + } + psmteller= 0; if(R.r.mode & R_EDGE) { @@ -3195,6 +2534,7 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ if(RE_local_test_break()) break; } + if(R.flag & (R_ZTRA+R_HALO) ) { /* to get back correct values of zbuffer Z for transp and halos */ xd= jit[0][0]; yd= jit[0][1]; @@ -3207,169 +2547,186 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ rd= R.rectdaps; rz= R.rectz; - colrt= (char *)R.rectot; - + rt= R.rectot; + rf= R.rectftot; - fullmask= (1<<R.osa)-1; /* the rowbuf is 4 pixels larger than an image! */ - rowbuf1= MEM_callocN(3*(R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf2= MEM_callocN(3*(R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf3= MEM_callocN(3*(R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - - for(y=0;y<=R.recty;y++) { + rowbuf0= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); + rowbuf1= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); + rowbuf2= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); + rowbuf1a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); + rowbuf2a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); + rowbuf3= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rb1= rowbuf1; - rb2= rowbuf2; - rb3= rowbuf3; + for(y=0; y<=R.recty; y++, rd+=R.rectx, rt+=R.rectx, rz+= R.rectx) { if(y<R.recty) { - for(x=0; x<R.rectx; x++, rd++) { - int samp, curmask, face; - int full_osa, face0; - - if( IS_A_POINTER_CODE(*rd)) - ps= (PixStr *) POINTER_FROM_CODE(*rd); - else ps= NULL; - - if(ps) face0= ps->vlak0; - else face0= (int)*rd; - mask= 0; - - /* complex loop, because first pixelstruct has a vlak0, without mask */ - while(TRUE) { - - if(ps==NULL) { - face= face0; - curmask= (~mask) & fullmask; - } - else { - face= ps->vlak; - curmask= ps->mask; + rl1.rd= rd; + rl1.rz= rz; + rl1.y= y; + rl1.rb1= rowbuf1; + rl1.rb2= rowbuf2; + rl1.rb3= rowbuf3; + + if(R.r.mode & R_THREADS) { + if((y & 1)==0) { + SDL_Thread *thread; + + thread = SDL_CreateThread(do_renderlineDA, &rl1); + if ( thread == NULL ) { + fprintf(stderr, "Unable to create thread"); + G.afbreek= 1; + break; } - /* check osa level */ - if(face==0) full_osa= 0; - else { - VlakRen *vlr= RE_findOrAddVlak( (face-1) & 0x7FFFFF); - full_osa= (vlr->flag & R_FULL_OSA); - } + rl2.rd= rd+R.rectx; + rl2.rz= rz+R.rectx; + rl2.y= y+1; + rl2.rb1= rowbuf0; + rl2.rb2= rowbuf1a; + rl2.rb3= rowbuf2a; - if(full_osa) { - for(samp=0; samp<R.osa; samp++) { - if(curmask & (1<<samp)) { - xs= (float)x + jit[samp][0]; - ys= (float)y + jit[samp][1]; - shadepixel_short(xs, ys, face, (1<<samp), shortcol); - - if(shortcol[3]) add_filt_mask(1<<samp, shortcol, rb1, rb2, rb3); - } + do_renderlineDA(&rl2); + SDL_WaitThread(thread, NULL); + + if(R.r.mode & R_GAUSS) { + float *rb1= rowbuf1, *rb2= rowbuf2, *rb1a= rowbuf1a, *rb2a= rowbuf2a; + a= 4*(R.rectx + 4); + while(a--) { + *rb1 += *rb1a; + *rb2 += *rb2a; + *(rb1a++)= 0; rb1++; + *(rb2a++)= 0; rb2++; } } else { - b= centmask[curmask]; - xs= (float)x+centLut[b & 15]; - ys= (float)y+centLut[b>>4]; - shadepixel_short(xs, ys, face, curmask, shortcol); - - if(shortcol[3]) add_filt_mask(curmask, shortcol, rb1, rb2, rb3); + SWAP(float *, rowbuf1a, rowbuf1); } - - mask |= curmask; - - if(ps==NULL) break; - else ps= ps->next; } - rb1+=4; - rb2+=4; - rb3+=4; } + else do_renderlineDA(&rl1); + } + /* convert 4x32 bits buffer to 4x8, add halos. this can't be threaded due to gauss */ if(y>0) { - - colrb= (unsigned short *)(rowbuf3+4); - - /* WATCH IT: ENDIAN */ - - for(x=0; x<R.rectx; x++,colrt+=4) { - colrt[0]= ( (char *) (gamtab+colrb[0+MOST_SIG_BYTE]) )[MOST_SIG_BYTE]; - colrt[1]= ( (char *) (gamtab+colrb[2+MOST_SIG_BYTE]) )[MOST_SIG_BYTE]; - colrt[2]= ( (char *) (gamtab+colrb[4+MOST_SIG_BYTE]) )[MOST_SIG_BYTE]; - colrt[3]= ( (char *) (gamtab+colrb[6+MOST_SIG_BYTE]) )[MOST_SIG_BYTE]; - colrb+= 8; - } - if(R.flag & R_ZTRA) { - abufsetrow(y-1); - acol= Acolrow; - colrt-= 4*R.rectx; - - for(x=0; x<R.rectx; x++, colrt+=4, acol+=4) { - if(acol[3]) { - tempcol[0]= (acol[0]>>8); - tempcol[1]= (acol[1]>>8); - tempcol[2]= (acol[2]>>8); - tempcol[3]= (acol[3]>>8); - addalphaOver(colrt, tempcol); - } - } + transferColourBufferToOutput(rowbuf3+4, y-1); + if(R.rectftot) { + memcpy(rf, rowbuf3+4, 4*sizeof(float)*R.rectx); + rf+= 4*R.rectx; } - if(R.flag & R_HALO) { - /* from these pixels the pixstr is 1 scanline old */ - scanlinehaloPS(rz-R.rectx, rd-2*R.rectx, ((unsigned int *)colrt)-R.rectx, y-1); - - } - scanlinesky(colrt-4*R.rectx, y-1); - } if(y<R.recty) { - memset(rowbuf3, 0, (R.rectx+4)*4*4); + memset(rowbuf3, 0, (R.rectx+4)*4*sizeof(int)); rb3= rowbuf3; rowbuf3= rowbuf2; rowbuf2= rowbuf1; - rowbuf1= rb3; + rowbuf1= rowbuf0; + rowbuf0= rb3; if( y>0) { if((y & 1)==0) { RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot); } } - rz+= R.rectx; } if(RE_local_test_break()) break; } if( (R.r.mode & R_EDGE) && RE_local_test_break()==0) { - rt= R.rectot; - rp= R.rectaccu; - for(a= R.rectx*R.recty; a>0; a--, rt++, rp++) { - addalphaOver((char *)rt, (char *)rp); + if(R.rectftot) { + float *rtf= R.rectftot, colf[4]; + rp= R.rectaccu; + for(a= R.rectx*R.recty; a>0; a--, rtf+=4, rp++) { + cpCharColV2FloatColV((char *)rp, colf); + addAlphaOverFloat(rtf, colf); + } + RE_floatbuffer_to_output(); + } + else { + rt= R.rectot; + rp= R.rectaccu; + for(a= R.rectx*R.recty; a>0; a--, rt++, rp++) { + addalphaOver((char *)rt, (char *)rp); + } } } MEM_freeN(R.rectdaps); freeps(); + MEM_freeN(rowbuf0); MEM_freeN(rowbuf1); MEM_freeN(rowbuf2); + MEM_freeN(rowbuf1a); + MEM_freeN(rowbuf2a); MEM_freeN(rowbuf3); - R.rectdaps= 0; + R.rectdaps= NULL; if(R.r.mode & R_EDGE) if(R.rectaccu) MEM_freeN(R.rectaccu); - R.rectaccu= 0; - if(R.flag & R_ZTRA) endaccumbuf(); + R.rectaccu= NULL; + if(R.flag & R_ZTRA) { + endaccumbuf(); + MEM_freeN(rl1.acol); + MEM_freeN(rl2.acol); + } } /* end of void zbufshadeDA() */ /* ------------------------------------------------------------------------ */ +struct renderline { + float *rowbuf, *acol; + unsigned int *rp, *rz; + short ys; + float y; +}; + +static int do_renderline(void *poin) +{ + struct renderline *rl= poin; + float *fcol= rl->rowbuf; + float *acol=NULL; + int x; + + if(R.flag & R_ZTRA) { /* zbuf tra */ + abufsetrow(rl->acol, rl->ys); + acol= rl->acol; + } + + for(x=0; x<R.rectx; x++, (rl->rp)++, fcol+=4) { + + shadepixel_sky((float)x, rl->y, *(rl->rp), 0, fcol); + if(acol) { + if(acol[3]!=0.0) addAlphaOverFloat(fcol, acol); + acol+= 4; + } + } + + if(R.flag & R_HALO) { + scanlinehalo(rl->rz, rl->rowbuf, rl->ys); + } + + transferColourBufferToOutput(rl->rowbuf, rl->y); + + if(R.rectftot) { + memcpy(R.rectftot + 4*rl->ys*R.rectx, rl->rowbuf, 4*sizeof(float)*R.rectx); + } + + return 1; +} + + void zbufshade(void) { + struct renderline rl1, rl2; extern float Zjitx,Zjity; unsigned int *rz,*rp; float fy; - int x,y; - unsigned short *acol, shortcol[4]; - char *charcol, *rt; + int y; + rl1.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade"); + rl2.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade"); + Zjitx=Zjity= -0.5; zbufferall(); @@ -3377,84 +2734,93 @@ void zbufshade(void) /* SHADE */ rp= R.rectot; rz= R.rectz; - charcol= (char *)shortcol; - - #ifdef BBIG_ENDIAN - #else - charcol++; /* short is read different then */ - #endif - if(R.flag & R_ZTRA) bgnaccumbuf(); + if(R.flag & R_ZTRA) { + rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); + rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); + bgnaccumbuf(); + } for(y=0; y<R.recty; y++) { fy= y; - if(R.flag & R_ZTRA) { /* zbuf tra */ - abufsetrow(y); - acol= Acolrow; + rl1.rp= rp; + rl1.rz= rz; + rl1.y= fy; + rl1.ys= y; + + if(R.r.mode & R_THREADS) { + SDL_Thread *thread; - for(x=0; x<R.rectx; x++, rp++, acol+= 4) { - - shadepixel_short((float)x, fy, *rp, 0, shortcol); - - if(acol[3]) addAlphaOverShort(shortcol, acol); - - if(shortcol[3]) { - rt= (char *)rp; - rt[0]= charcol[0]; - rt[1]= charcol[2]; - rt[2]= charcol[4]; - rt[3]= charcol[6]; - } - else *rp= 0; + thread = SDL_CreateThread(do_renderline, &rl1); + if ( thread == NULL ) { + fprintf(stderr, "Unable to create thread"); + G.afbreek= 1; + break; } + rp+= R.rectx; + rz+= R.rectx; + + if(y < R.recty-1) { + rl2.rp= rp; + rl2.rz= rz; + rl2.y= fy+1.0; + rl2.ys= y+1; + do_renderline(&rl2); + rp+= R.rectx; + rz+= R.rectx; + y++; + } + SDL_WaitThread(thread, NULL); } else { - for(x=0; x<R.rectx; x++, rp++) { - shadepixel_short((float)x, fy, *rp, 0, shortcol); - if(shortcol[3]) { - rt= (char *)rp; - rt[0]= charcol[0]; - rt[1]= charcol[2]; - rt[2]= charcol[4]; - rt[3]= charcol[6]; - } - else *rp= 0; - } + do_renderline(&rl1); + rp+= R.rectx; + rz+= R.rectx; } - if(R.flag & R_HALO) { - scanlinehalo(rz, (rp-R.rectx), y); - rz+= R.rectx; - } - scanlinesky( (char *)(rp-R.rectx), y); - if(y & 1) { RE_local_render_display(y-1, y, R.rectx, R.recty, R.rectot); } if(RE_local_test_break()) break; } - - if(R.flag & R_ZTRA) endaccumbuf(); + + MEM_freeN(rl1.rowbuf); + MEM_freeN(rl2.rowbuf); + + if(R.flag & R_ZTRA) { + endaccumbuf(); + MEM_freeN(rl1.acol); + MEM_freeN(rl2.acol); + } if(R.r.mode & R_EDGE) edge_enhance(); - /* if((R.flag & R_HALO) && blender_test_break()==0) halovert(); */ - } /* end of void zbufshade() */ /* ------------------------------------------------------------------------ */ -void renderhalo(HaloRen *har) /* postprocess version */ +void RE_shadehalo(HaloRen *har, char *col, float *colf, unsigned int zz, float dist, float xn, float yn, short flarec) { + + shadeHaloFloat(har, colf, zz, dist, xn, yn, flarec); - float dist, xsq, ysq, xn, yn; + if(colf[0]<=0.0) col[0]= 0; else if(colf[0]>=1.0) col[0]= 255; else col[0]= 255.0*colf[0]; + if(colf[1]<=0.0) col[1]= 0; else if(colf[1]>=1.0) col[1]= 255; else col[1]= 255.0*colf[1]; + if(colf[2]<=0.0) col[2]= 0; else if(colf[2]>=1.0) col[2]= 255; else col[2]= 255.0*colf[2]; + if(colf[3]<=0.0) col[3]= 0; else if(colf[3]>=1.0) col[3]= 255; else col[3]= 255.0*colf[3]; + +} + +static void renderhalo(HaloRen *har) /* postprocess version */ +{ + + float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf; unsigned int *rectt, *rt; int minx, maxx, miny, maxy, x, y; char col[4]; - har->miny= miny= har->ys - har->rad/R.ycor; har->maxy= maxy= har->ys + har->rad/R.ycor; @@ -3474,11 +2840,13 @@ void renderhalo(HaloRen *har) /* postprocess version */ if(maxy>R.recty) maxy= R.recty; rectt= R.rectot+ R.rectx*miny; + rectft= R.rectftot+ 4*R.rectx*miny; + + for(y=miny; y<maxy; y++) { - for(y=miny;y<maxy;y++) { - - rt= (rectt+minx); - + rt= rectt+minx; + rtf= rectft+4*minx; + yn= (y - har->ys)*R.ycor; ysq= yn*yn; @@ -3487,22 +2855,26 @@ void renderhalo(HaloRen *har) /* postprocess version */ xsq= xn*xn; dist= xsq+ysq; if(dist<har->radsq) { - RE_shadehalo(har, col, 0, dist, xn, yn, har->flarec); - - RE_addalphaAddfac((char *)rt, col, har->add); + + shadeHaloFloat(har, colf, 0, dist, xn, yn, har->flarec); + if(R.rectftot) addalphaAddfacFloat(rtf, colf, har->add); + else { + std_floatcol_to_charcol(colf, col); + RE_addalphaAddfac((char *)rt, col, har->add); + } } rt++; + rtf+=4; } rectt+= R.rectx; + rectft+= 4*R.rectx; if(RE_local_test_break()) break; } - } } -} /* end of void renderhalo(HaloRen *har), postprocess version */ - +} /* ------------------------------------------------------------------------ */ void RE_renderflare(HaloRen *har) @@ -3541,9 +2913,9 @@ void RE_renderflare(HaloRen *har) for(b=1; b<har->flarec; b++) { - fla.r= fabs(255.0*rc[0]); - fla.g= fabs(255.0*rc[1]); - fla.b= fabs(255.0*rc[2]); + fla.r= fabs(rc[0]); + fla.g= fabs(rc[1]); + fla.b= fabs(rc[2]); fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]); fla.hard= 20.0 + fabs(70*rc[7]); fla.tex= 0; @@ -3609,7 +2981,9 @@ void add_halo_flare(void) } R.r.mode= mode; -} /* end of void add_halo_flare() */ + + if(R.rectftot) RE_floatbuffer_to_output(); +} /* end of render.c */ diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index b717029c4ba..00fff240fb9 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -59,18 +59,17 @@ #include <math.h> #include <string.h> + #include "MEM_guardedalloc.h" +#include "BKE_utildefines.h" #include "BLI_arithb.h" +#include "DNA_material_types.h" #include "DNA_texture_types.h" + #include "BKE_texture.h" #include "render.h" -#include "render_intern.h" - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif /* ------------------------------------------------------------------------- */ @@ -176,16 +175,12 @@ VlakRen *RE_findOrAddVlak(int nr) /* ------------------------------------------------------------------------- */ -extern float Tin, Tr, Tg, Tb; -HaloRen *RE_inithalo(Material *ma, - float *vec, - float *vec1, - float *orco, - float hasize, - float vectsize) +HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, + float *orco, float hasize, float vectsize, int seed) { HaloRen *har; MTex *mtex; + float tin, tr, tg, tb, ta; float xn, yn, zn, texvec[3], hoco[4], hoco1[4]; if(hasize==0) return 0; @@ -213,7 +208,7 @@ HaloRen *RE_inithalo(Material *ma, har->ys= 0.5*R.recty*(hoco[1]/zn); har->zs= 0x7FFFFF*(1.0+hoco[2]/zn); - har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); + har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); xn= har->xs - 0.5*R.rectx*(hoco1[0]/hoco1[3]); yn= har->ys - 0.5*R.recty*(hoco1[1]/hoco1[3]); @@ -233,13 +228,13 @@ HaloRen *RE_inithalo(Material *ma, if(ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; har->alfa= ma->alpha; - har->r= 255.0*ma->r; - har->g= 255.0*ma->g; - har->b= 255.0*ma->b; - har->add= 255.0*ma->add; - har->mat= ma->ren; + har->r= ma->r; + har->g= ma->g; + har->b= ma->b; + har->add= (255.0*ma->add); + har->mat= ma; har->hard= ma->har; - har->seed= ma->ren->seed1 % 256; + har->seed= seed % 256; if(ma->mode & MA_STAR) har->starpoints= ma->starc; if(ma->mode & MA_HALO_LINES) har->linec= ma->linec; @@ -270,19 +265,19 @@ HaloRen *RE_inithalo(Material *ma, } } - externtex(mtex, texvec); + externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta); - yn= Tin*mtex->colfac; - zn= Tin*mtex->varfac; + yn= tin*mtex->colfac; + zn= tin*mtex->varfac; if(mtex->mapto & MAP_COL) { zn= 1.0-yn; - har->r= 255.0*(yn*Tr+ zn*ma->r); - har->g= 255.0*(yn*Tg+ zn*ma->g); - har->b= 255.0*(yn*Tb+ zn*ma->b); + har->r= (yn*tr+ zn*ma->r); + har->g= (yn*tg+ zn*ma->g); + har->b= (yn*tb+ zn*ma->b); } if(mtex->texco & 16) { - har->alfa= 255.0*Tin; + har->alfa= tin; } } } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index b1f8a246a85..b87635a51c2 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -42,38 +42,32 @@ #include "MTC_matrixops.h" #include "MEM_guardedalloc.h" -#include "BLI_arithb.h" #include "DNA_lamp_types.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" #include "render.h" -#include "render_intern.h" #include "shadbuf.h" #include "renderHelp.h" #include "jitter.h" #include "zbuf.h" -#ifdef HAVE_CONFIG_H -#include <config.h> +/* XXX, could be better implemented... +*/ +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define RCOMP 3 +#define GCOMP 2 +#define BCOMP 1 +#define ACOMP 0 +#else +#define RCOMP 0 +#define GCOMP 1 +#define BCOMP 2 +#define ACOMP 3 #endif -/* if defined: objects don't cast shadows anymore */ -/* #define RE_NO_SHADOWS */ - -/* unused? */ -static int bias= 0x00500000; -/* crud */ -#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) - -/* ------------------------------------------------------------------------- */ - -void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1); -int sizeoflampbuf(struct ShadBuf *shb); -int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr); -float readshadowbuf(struct ShadBuf *shb, int xs, int ys, int zs); -float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs); -float *give_jitter_tab(int samp); /* ------------------------------------------------------------------------- */ @@ -138,7 +132,7 @@ void RE_initshadowbuf(LampRen *lar, float mat[][4]) /* ------------------------------------------------------------------------- */ -void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* reads part from rectz in r1 */ +static void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* reads part from rectz in r1 */ { unsigned int len4, *rz; @@ -154,8 +148,8 @@ void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* reads part from } } - -int sizeoflampbuf(struct ShadBuf *shb) +#if 0 +static int sizeoflampbuf(struct ShadBuf *shb) { int num,count=0; char *cp; @@ -167,8 +161,9 @@ int sizeoflampbuf(struct ShadBuf *shb) return 256*count; } +#endif -float *give_jitter_tab(int samp) +static float *give_jitter_tab(int samp) { /* these are all possible jitter tables, takes up some * 12k, not really bad! @@ -345,7 +340,7 @@ void makeshadowbuf(LampRen *lar) /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */ } -int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr) +static int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr) { /* return a 1 if fully compressed shadbuf-tile && z==const */ static int *rz; @@ -372,7 +367,7 @@ int firstreadshadbuf(struct ShadBuf *shb, int xs, int ys, int nr) return 0; } -float readshadowbuf(struct ShadBuf *shb, int xs, int ys, int zs) /* return 1.0 : fully in light */ +static float readshadowbuf(struct ShadBuf *shb, int bias, int xs, int ys, int zs) /* return 1.0 : fully in light */ { float temp; int *rz, ofs; @@ -435,12 +430,13 @@ float readshadowbuf(struct ShadBuf *shb, int xs, int ys, int zs) /* return 1.0 : } } - -float testshadowbuf(struct ShadBuf *shb, float *rco, float inp) /* return 1.0: no shadow at all */ +/* the externally called shadow testing (reading) function */ +/* return 1.0: no shadow at all */ +float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp) { float fac, co[4], dx[3], dy[3], aantal=0; float xs1,ys1, siz, *j, xres, yres; - int xs,ys, zs; + int xs,ys, zs, bias; short a,num; /* if(inp <= 0.0) return 1.0; */ @@ -477,20 +473,20 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float inp) /* return 1.0: bias= (1.5-inp*inp)*shb->bias; if(num==1) { - return readshadowbuf(shb,(int)xs1, (int)ys1, zs); + return readshadowbuf(shb, bias, (int)xs1, (int)ys1, zs); } - co[0]= rco[0]+O.dxco[0]; - co[1]= rco[1]+O.dxco[1]; - co[2]= rco[2]+O.dxco[2]; + co[0]= rco[0]+dxco[0]; + co[1]= rco[1]+dxco[1]; + co[2]= rco[2]+dxco[2]; co[3]= 1.0; MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dx[0]= xs1- siz*(1.0+co[0]/co[3]); dx[1]= ys1- siz*(1.0+co[1]/co[3]); - co[0]= rco[0]+O.dyco[0]; - co[1]= rco[1]+O.dyco[1]; - co[2]= rco[2]+O.dyco[2]; + co[0]= rco[0]+dyco[0]; + co[1]= rco[1]+dyco[1]; + co[2]= rco[2]+dyco[2]; co[3]= 1.0; MTC_Mat4MulVec4fl(shb->persmat,co); /* rational hom co */ dy[0]= xs1- siz*(1.0+co[0]/co[3]); @@ -512,7 +508,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float inp) /* return 1.0: if(firstreadshadbuf(shb, (int)(xs1+xres), (int)ys1, 1)) { if(firstreadshadbuf(shb, (int)xs1, (int)(ys1+yres), 1)) { if(firstreadshadbuf(shb, (int)(xs1+xres), (int)(ys1+yres), 1)) { - return readshadowbuf(shb,(int)xs1, (int)ys1, zs); + return readshadowbuf(shb, bias,(int)xs1, (int)ys1, zs); } } } @@ -526,7 +522,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float inp) /* return 1.0: ys= ys1 + yres*(j[1] + 0.5); j+=2; - aantal+= readshadowbuf(shb, xs, ys, zs); + aantal+= readshadowbuf(shb, bias, xs, ys, zs); } /* Renormalizes for the sample number: */ @@ -535,13 +531,16 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float inp) /* return 1.0: /* different function... sampling behind clipend can be LIGHT, bias is negative! */ /* return: light */ -float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs) +static float readshadowbuf_halo(struct ShadBuf *shb, int xs, int ys, int zs) { float temp; int *rz, ofs; - int zbias, zsamp; + int bias, zbias, zsamp; char *ct, *cz; + /* negative! The other side is more important */ + bias= -shb->bias; + /* simpleclip */ if(xs<0 || ys<0) return 0.0; if(xs>=shb->size || ys>=shb->size) return 0.0; @@ -616,8 +615,6 @@ float shadow_halo(LampRen *lar, float *p1, float *p2) int dx = 0, dy = 0; siz= 0.5*(float)shb->size; - /* negative! The other side is more important */ - bias= -shb->bias; co[0]= p1[0]; co[1]= p1[1]; diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index b360def02a6..c30a62c9789 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -62,7 +62,6 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "BKE_osa_types.h" #include "BKE_plugin_types.h" #include "BKE_utildefines.h" @@ -78,14 +77,66 @@ #include "render.h" #include "rendercore.h" #include "envmap.h" - -/* These vars form the texture channel */ -float Tin, Tr, Tg, Tb, Ta, Txtra; -extern int Talpha; +#include "texture.h" /* ------------------------------------------------------------------------- */ +int calcimanr(int cfra, Tex *tex) +{ + int imanr, len, a, fra, dur; + + /* here (+fie_ima/2-1) makes sure that division happens correctly */ + + if(tex->frames==0) return 1; + + cfra= cfra-tex->sfra+1; + + /* cyclic */ + if(tex->len==0) len= (tex->fie_ima*tex->frames)/2; + else len= tex->len; + + if(tex->imaflag & TEX_ANIMCYCLIC) { + cfra= ( (cfra) % len ); + if(cfra < 0) cfra+= len; + if(cfra==0) cfra= len; + } + + if(cfra<1) cfra= 1; + else if(cfra>len) cfra= len; + + /* convert current frame to current field */ + cfra= 2*(cfra); + if(R.flag & R_SEC_FIELD) cfra++; + + /* transform to images space */ + imanr= (cfra+tex->fie_ima-2)/tex->fie_ima; + if(imanr>tex->frames) imanr= tex->frames; + imanr+= tex->offset; + + if(tex->imaflag & TEX_ANIMCYCLIC) { + imanr= ( (imanr) % len ); + while(imanr < 0) imanr+= len; + if(imanr==0) imanr= len; + } + + /* are there images that last longer? */ + for(a=0; a<4; a++) { + if(tex->fradur[a][0]) { + + fra= tex->fradur[a][0]; + dur= tex->fradur[a][1]-1; + + while(dur>0 && imanr>fra) { + imanr--; + dur--; + } + } + } + + return imanr; +} + void init_render_texture(Tex *tex) { Image *ima; @@ -93,9 +144,6 @@ void init_render_texture(Tex *tex) unsigned short numlen; char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE]; - /* is also used as signal */ - tex->nor= NULL; - /* imap test */ if(tex->frames && tex->ima && tex->ima->name) { /* frames */ strcpy(name, tex->ima->name); @@ -195,36 +243,36 @@ void end_render_textures() /* ------------------------------------------------------------------------- */ /* this allows colorbanded textures to control normals as well */ -static void tex_normal_derivate(float fac, Tex *tex) +static void tex_normal_derivate(Tex *tex, TexResult *texres) { if (tex->flag & TEX_COLORBAND) { float col[4]; - if (do_colorband(tex->coba, fac, col)) { + if (do_colorband(tex->coba, texres->tin, col)) { float fac0, fac1, fac2, fac3; fac0= (col[0]+col[1]+col[2]); - do_colorband(tex->coba, tex->nor[0], col); + do_colorband(tex->coba, texres->nor[0], col); fac1= (col[0]+col[1]+col[2]); - do_colorband(tex->coba, tex->nor[1], col); + do_colorband(tex->coba, texres->nor[1], col); fac2= (col[0]+col[1]+col[2]); - do_colorband(tex->coba, tex->nor[2], col); + do_colorband(tex->coba, texres->nor[2], col); fac3= (col[0]+col[1]+col[2]); - tex->nor[0]= 0.3333*(fac0 - fac1); - tex->nor[1]= 0.3333*(fac0 - fac2); - tex->nor[2]= 0.3333*(fac0 - fac3); + texres->nor[0]= 0.3333*(fac0 - fac1); + texres->nor[1]= 0.3333*(fac0 - fac2); + texres->nor[2]= 0.3333*(fac0 - fac3); return; } } - tex->nor[0]= fac - tex->nor[0]; - tex->nor[1]= fac - tex->nor[1]; - tex->nor[2]= fac - tex->nor[2]; + texres->nor[0]= texres->tin - texres->nor[0]; + texres->nor[1]= texres->tin - texres->nor[1]; + texres->nor[2]= texres->tin - texres->nor[2]; } -static int blend(Tex *tex, float *texvec) +static int blend(Tex *tex, float *texvec, TexResult *texres) { float x, y, t; @@ -238,32 +286,32 @@ static int blend(Tex *tex, float *texvec) } if(tex->stype==0) { /* lin */ - Tin= (1.0+x)/2.0; + texres->tin= (1.0+x)/2.0; } else if(tex->stype==1) { /* quad */ - Tin= (1.0+x)/2.0; - if(Tin<0.0) Tin= 0.0; - else Tin*= Tin; + texres->tin= (1.0+x)/2.0; + if(texres->tin<0.0) texres->tin= 0.0; + else texres->tin*= texres->tin; } else if(tex->stype==2) { /* ease */ - Tin= (1.0+x)/2.0; - if(Tin<=.0) Tin= 0.0; - else if(Tin>=1.0) Tin= 1.0; + texres->tin= (1.0+x)/2.0; + if(texres->tin<=.0) texres->tin= 0.0; + else if(texres->tin>=1.0) texres->tin= 1.0; else { - t= Tin*Tin; - Tin= (3.0*t-2.0*t*Tin); + t= texres->tin*texres->tin; + texres->tin= (3.0*t-2.0*t*texres->tin); } } else if(tex->stype==3) { /* diag */ - Tin= (2.0+x+y)/4.0; + texres->tin= (2.0+x+y)/4.0; } else { /* sphere */ - Tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]); - if(Tin<0.0) Tin= 0.0; - if(tex->stype==5) Tin*= Tin; /* halo */ + texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]); + if(texres->tin<0.0) texres->tin= 0.0; + if(tex->stype==5) texres->tin*= texres->tin; /* halo */ } - BRICON; + BRICONT; return 0; } @@ -273,33 +321,34 @@ static int blend(Tex *tex, float *texvec) /* newnoise: all noisebased types now have different noisebases to choose from */ -static int clouds(Tex *tex, float *texvec) +static int clouds(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + + texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { // calculate bumpnormal - tex->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } if (tex->stype==1) { // in this case, int. value should really be computed from color, // and bumpnormal from that, would be too slow, looks ok as is - Tr = Tin; - Tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - Tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - BRICONRGB; - Ta = 1.0; + texres->tr = texres->tin; + texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + BRICONTRGB; + texres->ta = 1.0; return (rv+1); } - BRICON; + BRICONT; return rv; @@ -326,22 +375,22 @@ static float wood_int(Tex *tex, float x, float y, float z) return wi; } -static int wood(Tex *tex, float *texvec) +static int wood(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Tin = wood_int(tex, texvec[0], texvec[1], texvec[2]); - if (tex->nor!=NULL) { + texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]); + if (texres->nor!=NULL) { /* calculate bumpnormal */ - tex->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); - tex->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); - tex->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); + texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); + texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); + texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; } @@ -362,31 +411,31 @@ static float marble_int(Tex *tex, float x, float y, float z) return mi; } -static int marble(Tex *tex, float *texvec) +static int marble(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Tin = marble_int(tex, texvec[0], texvec[1], texvec[2]); + texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { /* calculate bumpnormal */ - tex->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); - tex->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); - tex->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); + texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); + texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); + texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; } /* ------------------------------------------------------------------------- */ -static int magic(Tex *tex, float *texvec) +static int magic(Tex *tex, float *texvec, TexResult *texres) { float x, y, z, turb=1.0; int n; @@ -447,14 +496,14 @@ static int magic(Tex *tex, float *texvec) y/= turb; z/= turb; } - Tr= 0.5-x; - Tg= 0.5-y; - Tb= 0.5-z; + texres->tr= 0.5-x; + texres->tg= 0.5-y; + texres->tb= 0.5-z; - Tin= 0.3333*(Tr+Tg+Tb); + texres->tin= 0.3333*(texres->tr+texres->tg+texres->tb); - BRICONRGB; - Ta= 1.0; + BRICONTRGB; + texres->ta= 1.0; return 1; } @@ -462,26 +511,26 @@ static int magic(Tex *tex, float *texvec) /* ------------------------------------------------------------------------- */ /* newnoise: stucci also modified to use different noisebasis */ -static int stucci(Tex *tex, float *texvec) +static int stucci(Tex *tex, float *texvec, TexResult *texres) { float b2, ofs; - if(tex->nor == NULL) return 0; + if(texres->nor == NULL) return 0; ofs= tex->turbul/200.0; - Tin=b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->tin=b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); if(tex->stype) ofs*=(b2*b2); - tex->nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex->nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex->nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); + texres->nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); - tex_normal_derivate(b2, tex); + tex_normal_derivate(tex, texres); if(tex->stype==2) { - tex->nor[0]= -tex->nor[0]; - tex->nor[1]= -tex->nor[1]; - tex->nor[2]= -tex->nor[2]; + texres->nor[0]= -texres->nor[0]; + texres->nor[1]= -texres->nor[1]; + texres->nor[2]= -texres->nor[2]; } return 2; @@ -490,7 +539,7 @@ static int stucci(Tex *tex, float *texvec) /* ------------------------------------------------------------------------- */ /* newnoise: musgrave terrain noise types */ -static float mg_mFractalOrfBmTex(Tex *tex, float *texvec) +static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ float (*mgravefunc)(float, float, float, float, float, float, int); @@ -500,27 +549,27 @@ static float mg_mFractalOrfBmTex(Tex *tex, float *texvec) else mgravefunc = mg_fBm; - Tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); + texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { float offs= tex->nabla/tex->noisesize; // also scaling of texvec /* calculate bumpnormal */ - tex->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); - tex->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); - tex->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); + texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); + texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); + texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; } -static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec) +static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ float (*mgravefunc)(float, float, float, float, float, float, float, float, int); @@ -530,71 +579,71 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec) else mgravefunc = mg_HybridMultiFractal; - Tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); + texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { float offs= tex->nabla/tex->noisesize; // also scaling of texvec /* calculate bumpnormal */ - tex->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); - tex->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); - tex->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); + texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); + texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); + texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; } -static float mg_HTerrainTex(Tex *tex, float *texvec) +static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Tin = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); + texres->tin = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { float offs= tex->nabla/tex->noisesize; // also scaling of texvec /* calculate bumpnormal */ - tex->nor[0] = tex->ns_outscale*mg_HeteroTerrain(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); - tex->nor[1] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); - tex->nor[2] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); + texres->nor[0] = tex->ns_outscale*mg_HeteroTerrain(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); + texres->nor[1] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); + texres->nor[2] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; } -static float mg_distNoiseTex(Tex *tex, float *texvec) +static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); + texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { float offs= tex->nabla/tex->noisesize; // also scaling of texvec /* calculate bumpnormal */ - tex->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); - tex->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); - tex->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2); + texres->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); + texres->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); + texres->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } - BRICON; + BRICONT; return rv; @@ -605,7 +654,7 @@ static float mg_distNoiseTex(Tex *tex, float *texvec) /* ------------------------------------------------------------------------- */ /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */ -static float voronoiTex(Tex *tex, float *texvec) +static float voronoiTex(Tex *tex, float *texvec, TexResult *texres) { int rv=0; /* return value, int:0, col:1, nor:2, everything:3 */ float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbours */ @@ -617,63 +666,63 @@ static float voronoiTex(Tex *tex, float *texvec) if (sc!=0.f) sc = tex->ns_outscale/sc; voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - Tin = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); + texres->tin = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); if (tex->vn_coltype) { float ca[3]; /* cell color */ cellNoiseV(pa[0], pa[1], pa[2], ca); - Tr = aw1*ca[0]; - Tg = aw1*ca[1]; - Tb = aw1*ca[2]; + texres->tr = aw1*ca[0]; + texres->tg = aw1*ca[1]; + texres->tb = aw1*ca[2]; cellNoiseV(pa[3], pa[4], pa[5], ca); - Tr += aw2*ca[0]; - Tg += aw2*ca[1]; - Tb += aw2*ca[2]; + texres->tr += aw2*ca[0]; + texres->tg += aw2*ca[1]; + texres->tb += aw2*ca[2]; cellNoiseV(pa[6], pa[7], pa[8], ca); - Tr += aw3*ca[0]; - Tg += aw3*ca[1]; - Tb += aw3*ca[2]; + texres->tr += aw3*ca[0]; + texres->tg += aw3*ca[1]; + texres->tb += aw3*ca[2]; cellNoiseV(pa[9], pa[10], pa[11], ca); - Tr += aw4*ca[0]; - Tg += aw4*ca[1]; - Tb += aw4*ca[2]; + texres->tr += aw4*ca[0]; + texres->tg += aw4*ca[1]; + texres->tb += aw4*ca[2]; if (tex->vn_coltype>=2) { float t1 = (da[1]-da[0])*10; if (t1>1) t1=1; - if (tex->vn_coltype==3) t1*=Tin; else t1*=sc; - Tr *= t1; - Tg *= t1; - Tb *= t1; + if (tex->vn_coltype==3) t1*=texres->tin; else t1*=sc; + texres->tr *= t1; + texres->tg *= t1; + texres->tb *= t1; } else { - Tr *= sc; - Tg *= sc; - Tb *= sc; + texres->tr *= sc; + texres->tg *= sc; + texres->tb *= sc; } } - if (tex->nor!=NULL) { + if (texres->nor!=NULL) { float offs= tex->nabla/tex->noisesize; // also scaling of texvec /* calculate bumpnormal */ voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - tex->nor[0] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); + texres->nor[0] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); - tex->nor[1] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); + texres->nor[1] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm); - tex->nor[2] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); + texres->nor[2] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); - tex_normal_derivate(Tin, tex); + tex_normal_derivate(tex, texres); rv += 2; } if (tex->vn_coltype) { - BRICONRGB; - Ta = 1.0; + BRICONTRGB; + texres->ta = 1.0; return (rv+1); } - BRICON; + BRICONT; return rv; @@ -682,7 +731,7 @@ static float voronoiTex(Tex *tex, float *texvec) /* ------------------------------------------------------------------------- */ -static int texnoise(Tex *tex) +static int texnoise(Tex *tex, TexResult *texres) { float div=3.0; int val, ran, loop; @@ -697,84 +746,52 @@ static int texnoise(Tex *tex) div*= 3.0; } - Tin= ((float)val)/div;; + texres->tin= ((float)val)/div;; - BRICON; + BRICONT; return 0; } /* ------------------------------------------------------------------------- */ -static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) +static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { PluginTex *pit; int rgbnor=0; - Tin= 0.0; + texres->tin= 0.0; pit= tex->plugin; if(pit && pit->doit) { - if(tex->nor) { - VECCOPY(pit->result+5, tex->nor); + if(texres->nor) { + VECCOPY(pit->result+5, texres->nor); } if(osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, dxt, dyt); else rgbnor= ((TexDoit)pit->doit)(tex->stype, pit->data, texvec, 0, 0); - Tin= pit->result[0]; + texres->tin= pit->result[0]; if(rgbnor & TEX_NOR) { - if(tex->nor) { - VECCOPY(tex->nor, pit->result+5); + if(texres->nor) { + VECCOPY(texres->nor, pit->result+5); } } if(rgbnor & TEX_RGB) { - Tr= pit->result[1]; - Tg= pit->result[2]; - Tb= pit->result[3]; - Ta= pit->result[4]; + texres->tr= pit->result[1]; + texres->tg= pit->result[2]; + texres->tb= pit->result[3]; + texres->ta= pit->result[4]; - BRICONRGB; + BRICONTRGB; } - BRICON; + BRICONT; } return rgbnor; } -/* *************** PROJECTIONS ******************* */ - -void tubemap(float x, float y, float z, float *adr1, float *adr2) -{ - float len; - - *adr2 = (z + 1.0) / 2.0; - - len= sqrt(x*x+y*y); - if(len>0) { - *adr1 = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0; - } -} - -/* ------------------------------------------------------------------------- */ - -void spheremap(float x, float y, float z, float *adr1, float *adr2) -{ - float len; - - len= sqrt(x*x+y*y+z*z); - if(len>0.0) { - - if(x==0.0 && y==0.0) *adr1= 0.0; /* othwise domain error */ - else *adr1 = (1.0 - atan2(x,y)/M_PI )/2.0; - - z/=len; - *adr2 = 1.0- saacos(z)/M_PI; - } -} - -/* ------------------------------------------------------------------------- */ static int cubemap_glob(MTex *mtex, VlakRen *vlr, float x, float y, float z, float *adr1, float *adr2) { @@ -1065,98 +1082,123 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float /* ************************************** */ -int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex) +static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ - Talpha= 0; /* is set when image texture returns alpha (considered premul) */ + texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ switch(tex->type) { case 0: - Tin= 0.0; + texres->tin= 0.0; return 0; case TEX_CLOUDS: - retval= clouds(tex, texvec); + retval= clouds(tex, texvec, texres); break; case TEX_WOOD: - retval= wood(tex, texvec); + retval= wood(tex, texvec, texres); break; case TEX_MARBLE: - retval= marble(tex, texvec); + retval= marble(tex, texvec, texres); break; case TEX_MAGIC: - retval= magic(tex, texvec); + retval= magic(tex, texvec, texres); break; case TEX_BLEND: - retval= blend(tex, texvec); + retval= blend(tex, texvec, texres); break; case TEX_STUCCI: - retval= stucci(tex, texvec); + retval= stucci(tex, texvec, texres); if (tex->flag & TEX_COLORBAND); - else Tin= 0.0; // stucci doesnt return Tin, for backwards compat... + else texres->tin= 0.0; // stucci doesnt return Tin, for backwards compat... break; case TEX_NOISE: - retval= texnoise(tex); + retval= texnoise(tex, texres); break; case TEX_IMAGE: - if(osatex) retval= imagewraposa(tex, texvec, dxt, dyt); - else retval= imagewrap(tex, texvec); + if(osatex) retval= imagewraposa(tex, texvec, dxt, dyt, texres); + else retval= imagewrap(tex, texvec, texres); break; case TEX_PLUGIN: - retval= plugintex(tex, texvec, dxt, dyt, osatex); + retval= plugintex(tex, texvec, dxt, dyt, osatex, texres); break; case TEX_ENVMAP: - retval= envmaptex(tex, texvec, dxt, dyt, osatex); + retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres); break; case TEX_MUSGRAVE: /* newnoise: musgrave types */ - /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */ + /* ton: added this, for Blender convention reason. scaling texvec here is so-so ... */ VecMulf(texvec, 1.0/tex->noisesize); switch(tex->stype) { case TEX_MFRACTAL: case TEX_FBM: - retval= mg_mFractalOrfBmTex(tex, texvec); + retval= mg_mFractalOrfBmTex(tex, texvec, texres); break; case TEX_RIDGEDMF: case TEX_HYBRIDMF: - retval= mg_ridgedOrHybridMFTex(tex, texvec); + retval= mg_ridgedOrHybridMFTex(tex, texvec, texres); break; case TEX_HTERRAIN: - retval= mg_HTerrainTex(tex, texvec); + retval= mg_HTerrainTex(tex, texvec, texres); break; } break; /* newnoise: voronoi type */ case TEX_VORONOI: - /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */ + /* ton: added this, for Blender convention reason. scaling texvec here is so-so ... */ VecMulf(texvec, 1.0/tex->noisesize); - retval= voronoiTex(tex, texvec); + retval= voronoiTex(tex, texvec, texres); break; case TEX_DISTNOISE: - /* ton: added this, for Blender convention reason. scaling texvec here is so-so... */ + /* ton: added this, for Blender convention reason. scaling texvec here is so-so ... */ VecMulf(texvec, 1.0/tex->noisesize); - retval= mg_distNoiseTex(tex, texvec); + retval= mg_distNoiseTex(tex, texvec, texres); break; } if (tex->flag & TEX_COLORBAND) { float col[4]; - if (do_colorband(tex->coba, Tin, col)) { + if (do_colorband(tex->coba, texres->tin, col)) { + texres->talpha= 1; + texres->tr= col[0]; + texres->tg= col[1]; + texres->tb= col[2]; + texres->ta= col[3]; retval |= 1; - Tr= col[0]; - Tg= col[1]; - Tb= col[2]; - Ta= col[3]; } } return retval; } +int multitex_ext(Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta) +{ + TexResult texr; + float dummy[3]; + int retval; + + /* does not return Tin, hackish... */ + if(tex->type==TEX_STUCCI) { + texr.nor= dummy; + dummy[0]= 1.0; + dummy[1]= dummy[2]= 0.0; + } + else texr.nor= NULL; + + retval= multitex(tex, texvec, NULL, NULL, 0, &texr); + if(tex->type==TEX_STUCCI) *tin= texr.nor[0]; + else *tin= texr.tin; + *tr= texr.tr; + *tg= texr.tg; + *tb= texr.tb; + *ta= texr.ta; + return retval; +} + /* ------------------------------------------------------------------------- */ /* in = destination, tex = texture, out = previous color */ @@ -1304,10 +1346,9 @@ static float texture_value_blend(float tex, float out, float fact, float facg, i void do_material_tex(ShadeInput *shi) { - Material *mat_col, *mat_colspec, *mat_colmir, *mat_ref, *mat_amb; - Material *mat_spec, *mat_har, *mat_emit, *mat_alpha, *mat_ray_mirr, *mat_translu; MTex *mtex; Tex *tex; + TexResult texres; float *co = NULL, *dx = NULL, *dy = NULL; float fact, facm, factt, facmm, stencilTin=1.0; float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3], Tnor=1.0; @@ -1315,8 +1356,6 @@ void do_material_tex(ShadeInput *shi) /* here: test flag if there's a tex (todo) */ - mat_col=mat_colspec=mat_colmir=mat_ref=mat_spec=mat_har=mat_emit=mat_alpha=mat_ray_mirr=mat_translu=mat_amb= shi->mat; - for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { /* separate tex switching */ @@ -1330,10 +1369,10 @@ void do_material_tex(ShadeInput *shi) /* which coords */ if(mtex->texco==TEXCO_ORCO) { - co= shi->lo; dx= O.dxlo; dy= O.dylo; + co= shi->lo; dx= shi->dxlo; dy= shi->dylo; } else if(mtex->texco==TEXCO_STICKY) { - co= shi->sticky; dx= O.dxsticky; dy= O.dysticky; + co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky; } else if(mtex->texco==TEXCO_OBJECT) { Object *ob= mtex->object; @@ -1344,8 +1383,8 @@ void do_material_tex(ShadeInput *shi) VECCOPY(tempvec, shi->co); MTC_Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { - VECCOPY(dxt, O.dxco); - VECCOPY(dyt, O.dyco); + VECCOPY(dxt, shi->dxco); + VECCOPY(dyt, shi->dyco); MTC_Mat4Mul3Vecfl(ob->imat, dxt); MTC_Mat4Mul3Vecfl(ob->imat, dyt); } @@ -1353,32 +1392,32 @@ void do_material_tex(ShadeInput *shi) else { /* if object doesn't exist, do not use orcos (not initialized) */ co= shi->co; - dx= O.dxco; dy= O.dyco; + dx= shi->dxco; dy= shi->dyco; } } else if(mtex->texco==TEXCO_REFL) { - co= shi->ref; dx= O.dxref; dy= O.dyref; + co= shi->ref; dx= shi->dxref; dy= shi->dyref; } else if(mtex->texco==TEXCO_NORM) { - co= shi->orn; dx= O.dxno; dy= O.dyno; + co= shi->orn; dx= shi->dxno; dy= shi->dyno; } else if(mtex->texco==TEXCO_GLOB) { - co= shi->gl; dx= O.dxco; dy= O.dyco; + co= shi->gl; dx= shi->dxco; dy= shi->dyco; } else if(mtex->texco==TEXCO_UV) { - co= shi->uv; dx= O.dxuv; dy= O.dyuv; + co= shi->uv; dx= shi->dxuv; dy= shi->dyuv; } else if(mtex->texco==TEXCO_WINDOW) { - co= shi->winco; dx= O.dxwin; dy= O.dywin; + co= shi->winco; dx= shi->dxwin; dy= shi->dywin; } else continue; // can happen when texco defines disappear and it renders old files /* de pointer defines if bumping happens */ if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) { - tex->nor= norvec; + texres.nor= norvec; norvec[0]= norvec[1]= norvec[2]= 0.0; } - else tex->nor= NULL; + else texres.nor= NULL; if(warpdone) { VECADD(tempvec, co, warpvec); @@ -1459,81 +1498,81 @@ void do_material_tex(ShadeInput *shi) } } - rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex); + rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres); /* texture output */ if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { - Tin= (0.35*Tr+0.45*Tg+0.2*Tb); - rgbnor-= 1; + texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); + rgbnor-= TEX_RGB; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgbnor & TEX_RGB) { - Tr= 1.0-Tr; - Tg= 1.0-Tg; - Tb= 1.0-Tb; + texres.tr= 1.0-texres.tr; + texres.tg= 1.0-texres.tg; + texres.tb= 1.0-texres.tb; } - Tin= 1.0-Tin; + texres.tin= 1.0-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgbnor & TEX_RGB) { - fact= Ta; - Ta*= stencilTin; + fact= texres.ta; + texres.ta*= stencilTin; stencilTin*= fact; } else { - fact= Tin; - Tin*= stencilTin; + fact= texres.tin; + texres.tin*= stencilTin; stencilTin*= fact; } } else { - Ta*= stencilTin; + texres.ta*= stencilTin; Tnor*= stencilTin; - Tin*= stencilTin; + texres.tin*= stencilTin; } - if(tex->nor) { + if(texres.nor) { if((rgbnor & TEX_NOR)==0) { /* make our own normal */ if(rgbnor & TEX_RGB) { - tex->nor[0]= Tr; - tex->nor[1]= Tg; - tex->nor[2]= Tb; + texres.nor[0]= texres.tr; + texres.nor[1]= texres.tg; + texres.nor[2]= texres.tb; } else { - float co= 0.5*cos(Tin-0.5); - float si= 0.5*sin(Tin-0.5); + float co= 0.5*cos(texres.tin-0.5); + float si= 0.5*sin(texres.tin-0.5); float f1, f2; f1= shi->vn[0]; f2= shi->vn[1]; - tex->nor[0]= f1*co+f2*si; - tex->nor[1]= f2*co-f1*si; + texres.nor[0]= f1*co+f2*si; + texres.nor[1]= f2*co-f1*si; f1= shi->vn[1]; f2= shi->vn[2]; - tex->nor[1]= f1*co+f2*si; - tex->nor[2]= f2*co-f1*si; + texres.nor[1]= f1*co+f2*si; + texres.nor[2]= f2*co-f1*si; } } // warping, local space if(mtex->mapto & MAP_WARP) { - warpvec[0]= mtex->warpfac*tex->nor[0]; - warpvec[1]= mtex->warpfac*tex->nor[1]; - warpvec[2]= mtex->warpfac*tex->nor[2]; + warpvec[0]= mtex->warpfac*texres.nor[0]; + warpvec[1]= mtex->warpfac*texres.nor[1]; + warpvec[2]= mtex->warpfac*texres.nor[2]; warpdone= 1; } // rotate to global coords if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) { if(shi->vlr && shi->vlr->ob) { - float len= Normalise(tex->nor); + float len= Normalise(texres.nor); // can be optimized... (ton) - Mat4Mul3Vecfl(shi->vlr->ob->obmat, tex->nor); - Mat4Mul3Vecfl(R.viewmat, tex->nor); - Normalise(tex->nor); - VecMulf(tex->nor, len); + Mat4Mul3Vecfl(shi->vlr->ob->obmat, texres.nor); + Mat4Mul3Vecfl(R.viewmat, texres.nor); + Normalise(texres.nor); + VecMulf(texres.nor, len); } } } @@ -1543,7 +1582,7 @@ void do_material_tex(ShadeInput *shi) if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { float tcol[3]; - tcol[0]=Tr; tcol[1]=Tg; tcol[2]=Tb; + tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb; if((rgbnor & TEX_RGB)==0) { tcol[0]= mtex->r; @@ -1551,22 +1590,20 @@ void do_material_tex(ShadeInput *shi) tcol[2]= mtex->b; } else if(mtex->mapto & MAP_ALPHA) { - Tin= stencilTin; + texres.tin= stencilTin; } - else Tin= Ta; + else texres.tin= texres.ta; if(mtex->mapto & MAP_COL) { - texture_rgb_blend(&shi->matren->r, tcol, &mat_col->r, Tin, mtex->colfac, mtex->blendtype); - mat_col= shi->matren; + texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, mtex->colfac, mtex->blendtype); } if(mtex->mapto & MAP_COLSPEC) { - texture_rgb_blend(&shi->matren->specr, tcol, &mat_colspec->specr, Tin, mtex->colfac, mtex->blendtype); - mat_colspec= shi->matren; + texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, mtex->colfac, mtex->blendtype); } if(mtex->mapto & MAP_COLMIR) { // exception for envmap only if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) { - fact= Tin*mtex->colfac; + fact= texres.tin*mtex->colfac; facm= 1.0- fact; shi->refcol[0]= fact + facm*shi->refcol[0]; shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1]; @@ -1574,13 +1611,12 @@ void do_material_tex(ShadeInput *shi) shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3]; } else { - texture_rgb_blend(&shi->matren->mirr, tcol, &mat_colmir->mirr, Tin, mtex->colfac, mtex->blendtype); + texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mtex->colfac, mtex->blendtype); } - mat_colmir= shi->matren; } } if( (mtex->mapto & MAP_NORM) ) { - if(tex->nor) { + if(texres.nor) { if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; else tex->norfac= mtex->norfac; @@ -1591,14 +1627,14 @@ void do_material_tex(ShadeInput *shi) fact= Tnor*tex->norfac; if(fact>1.0) fact= 1.0; facm= 1.0- fact; - shi->vn[0]= facm*shi->vn[0] + fact*tex->nor[0]; - shi->vn[1]= facm*shi->vn[1] + fact*tex->nor[1]; - shi->vn[2]= facm*shi->vn[2] + fact*tex->nor[2]; + shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0]; + shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1]; + shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2]; } else { - shi->vn[0]+= Tnor*tex->norfac*tex->nor[0]; - shi->vn[1]+= Tnor*tex->norfac*tex->nor[1]; - shi->vn[2]+= Tnor*tex->norfac*tex->nor[2]; + shi->vn[0]+= Tnor*tex->norfac*texres.nor[0]; + shi->vn[1]+= Tnor*tex->norfac*texres.nor[1]; + shi->vn[2]+= Tnor*tex->norfac*texres.nor[2]; } Normalise(shi->vn); @@ -1615,25 +1651,25 @@ void do_material_tex(ShadeInput *shi) if( mtex->mapto & MAP_DISPLACE ) { /* Now that most textures offer both Nor and Intensity, allow */ /* both to work, and let user select with slider. */ - if(tex->nor) { + if(texres.nor) { if(mtex->maptoneg & MAP_DISPLACE) tex->norfac= -mtex->norfac; else tex->norfac= mtex->norfac; - shi->displace[0]+= 0.2f*Tnor*tex->norfac*tex->nor[0]; - shi->displace[1]+= 0.2f*Tnor*tex->norfac*tex->nor[1]; - shi->displace[2]+= 0.2f*Tnor*tex->norfac*tex->nor[2]; + shi->displace[0]+= 0.2f*Tnor*tex->norfac*texres.nor[0]; + shi->displace[1]+= 0.2f*Tnor*tex->norfac*texres.nor[1]; + shi->displace[2]+= 0.2f*Tnor*tex->norfac*texres.nor[2]; } if(rgbnor & TEX_RGB) { - if(Talpha) Tin= Ta; - else Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + if(texres.talpha) texres.tin= texres.ta; + else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); } if(mtex->maptoneg & MAP_DISPLACE) { - factt= (0.5-Tin)*mtex->dispfac; facmm= 1.0-factt; + factt= (0.5-texres.tin)*mtex->dispfac; facmm= 1.0-factt; } else { - factt= (Tin-0.5)*mtex->dispfac; facmm= 1.0-factt; + factt= (texres.tin-0.5)*mtex->dispfac; facmm= 1.0-factt; } if(mtex->blendtype==MTEX_BLEND) { @@ -1657,81 +1693,66 @@ void do_material_tex(ShadeInput *shi) if(mtex->mapto & MAP_VARS) { if(rgbnor & TEX_RGB) { - if(Talpha) Tin= Ta; - else Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + if(texres.talpha) texres.tin= texres.ta; + else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); } if(mtex->mapto & MAP_REF) { int flip= mtex->maptoneg & MAP_REF; - shi->matren->ref= texture_value_blend(mtex->def_var, mat_ref->ref, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->ref<0.0) shi->matren->ref= 0.0; - mat_ref= shi->matren; + shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->refl<0.0) shi->refl= 0.0; } if(mtex->mapto & MAP_SPEC) { int flip= mtex->maptoneg & MAP_SPEC; - shi->matren->spec= texture_value_blend(mtex->def_var, mat_spec->spec, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->spec<0.0) shi->matren->spec= 0.0; - mat_spec= shi->matren; + shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->spec<0.0) shi->spec= 0.0; } if(mtex->mapto & MAP_EMIT) { int flip= mtex->maptoneg & MAP_EMIT; - shi->matren->emit= texture_value_blend(mtex->def_var, mat_emit->emit, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->emit<0.0) shi->matren->emit= 0.0; - mat_emit= shi->matren; + shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->emit<0.0) shi->emit= 0.0; } if(mtex->mapto & MAP_ALPHA) { int flip= mtex->maptoneg & MAP_ALPHA; - shi->matren->alpha= texture_value_blend(mtex->def_var, mat_alpha->alpha, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->alpha<0.0) shi->matren->alpha= 0.0; - else if(shi->matren->alpha>1.0) shi->matren->alpha= 1.0; - mat_alpha= shi->matren; + shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->alpha<0.0) shi->alpha= 0.0; + else if(shi->alpha>1.0) shi->alpha= 1.0; } if(mtex->mapto & MAP_HAR) { int flip= mtex->maptoneg & MAP_HAR; float har; // have to map to 0-1 - har= ((float)mat_har->har)/128.0; - har= 128.0*texture_value_blend(mtex->def_var, har, Tin, mtex->varfac, mtex->blendtype, flip); + har= ((float)shi->har)/128.0; + har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, mtex->varfac, mtex->blendtype, flip); - if(har<1.0) shi->matren->har= 1; - else if(har>511.0) shi->matren->har= 511; - else shi->matren->har= (int)har; - mat_har= shi->matren; + if(har<1.0) shi->har= 1; + else if(har>511.0) shi->har= 511; + else shi->har= (int)har; } if(mtex->mapto & MAP_RAYMIRR) { int flip= mtex->maptoneg & MAP_RAYMIRR; - shi->matren->ray_mirror= texture_value_blend(mtex->def_var, mat_ray_mirr->ray_mirror, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->ray_mirror<0.0) shi->matren->ray_mirror= 0.0; - else if(shi->matren->ray_mirror>1.0) shi->matren->ray_mirror= 1.0; - mat_ray_mirr= shi->matren; + shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0; + else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0; } if(mtex->mapto & MAP_TRANSLU) { int flip= mtex->maptoneg & MAP_TRANSLU; - shi->matren->translucency= texture_value_blend(mtex->def_var, mat_translu->translucency, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->translucency<0.0) shi->matren->translucency= 0.0; - else if(shi->matren->translucency>1.0) shi->matren->translucency= 1.0; - mat_translu= shi->matren; + shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->translucency<0.0) shi->translucency= 0.0; + else if(shi->translucency>1.0) shi->translucency= 1.0; } if(mtex->mapto & MAP_AMB) { int flip= mtex->maptoneg & MAP_AMB; - shi->matren->amb= texture_value_blend(mtex->def_var, mat_amb->amb, Tin, mtex->varfac, mtex->blendtype, flip); - - if(shi->matren->amb<0.0) shi->matren->amb= 0.0; - else if(shi->matren->amb>1.0) shi->matren->amb= 1.0; - mat_amb= shi->matren; + shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, mtex->varfac, mtex->blendtype, flip); + if(shi->amb<0.0) shi->amb= 0.0; + else if(shi->amb>1.0) shi->amb= 1.0; } } } @@ -1743,13 +1764,15 @@ void do_material_tex(ShadeInput *shi) void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) { MTex *mtex; + TexResult texres; float texvec[3], dxt[3], dyt[3], fact, facm, dx; int rgb, osatex; mtex= har->mat->mtex[0]; - if(mtex->tex==0) return; + if(mtex->tex==NULL) return; + /* no normal mapping */ - mtex->tex->nor= NULL; + texres.nor= NULL; texvec[0]= xn/har->rad; texvec[1]= yn/har->rad; @@ -1793,60 +1816,58 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt); - rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex); + rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres); /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - Tr= 1.0-Tr; - Tg= 1.0-Tg; - Tb= 1.0-Tb; + texres.tr= 1.0-texres.tr; + texres.tg= 1.0-texres.tg; + texres.tb= 1.0-texres.tb; } - else Tin= 1.0-Tin; + else texres.tin= 1.0-texres.tin; } /* mapping */ if(mtex->mapto & MAP_COL) { if(rgb==0) { - Tr= mtex->r; - Tg= mtex->g; - Tb= mtex->b; + texres.tr= mtex->r; + texres.tg= mtex->g; + texres.tb= mtex->b; } else if(mtex->mapto & MAP_ALPHA) { - Tin= 1.0; + texres.tin= 1.0; } - else Tin= Ta; + else texres.tin= texres.ta; - fact= Tin*mtex->colfac; + fact= texres.tin*mtex->colfac; facm= 1.0-fact; if(mtex->blendtype==MTEX_MUL) { facm= 1.0-mtex->colfac; } - else fact*= 256; - /* note: halo colors are still 0-255, should map that for new mixing functions... */ if(mtex->blendtype==MTEX_SUB) fact= -fact; if(mtex->blendtype==MTEX_BLEND) { - colf[0]= (fact*Tr + facm*har->r); - colf[1]= (fact*Tg + facm*har->g); - colf[2]= (fact*Tb + facm*har->b); + colf[0]= (fact*texres.tr + facm*har->r); + colf[1]= (fact*texres.tg + facm*har->g); + colf[2]= (fact*texres.tb + facm*har->b); } else if(mtex->blendtype==MTEX_MUL) { - colf[0]= (facm+fact*Tr)*har->r; - colf[1]= (facm+fact*Tg)*har->g; - colf[2]= (facm+fact*Tb)*har->b; + colf[0]= (facm+fact*texres.tr)*har->r; + colf[1]= (facm+fact*texres.tg)*har->g; + colf[2]= (facm+fact*texres.tb)*har->b; } else { - colf[0]= (fact*Tr + har->r); - colf[1]= (fact*Tg + har->g); - colf[2]= (fact*Tb + har->b); + colf[0]= (fact*texres.tr + har->r); + colf[1]= (fact*texres.tg + har->g); + colf[2]= (fact*texres.tb + har->b); CLAMP(colf[0], 0.0, 1.0); CLAMP(colf[1], 0.0, 1.0); @@ -1855,29 +1876,28 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) } if(mtex->mapto & MAP_ALPHA) { if(rgb) { - if(Talpha) Tin= Ta; - else Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + if(texres.talpha) texres.tin= texres.ta; + else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); } - colf[3]*= Tin; + colf[3]*= texres.tin; } } /* ------------------------------------------------------------------------- */ -void do_sky_tex(float *lo) +/* hor and zen are RGB vectors, blend is 1 float, should all be initialized */ +void do_sky_tex(float *lo, float *dxyview, float *hor, float *zen, float *blend) { - World *wrld_hor, *wrld_zen; MTex *mtex; + TexResult texres; float *co, fact, stencilTin=1.0; float tempvec[3], texvec[3], dxt[3], dyt[3]; int tex_nr, rgb= 0, ok; - /* todo: add flag to test if there's a tex */ + texres.nor= NULL; - wrld_hor= wrld_zen= G.scene->world; - for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { if(R.wrld.mtex[tex_nr]) { mtex= R.wrld.mtex[tex_nr]; @@ -1889,8 +1909,14 @@ void do_sky_tex(float *lo) co= lo; /* dxt dyt just from 1 value */ - dxt[0]= dxt[1]= dxt[2]= O.dxview; - dyt[0]= dyt[1]= dyt[2]= O.dyview; + if(dxyview) { + dxt[0]= dxt[1]= dxt[2]= dxyview[0]; + dyt[0]= dyt[1]= dyt[2]= dxyview[1]; + } + else { + dxt[0]= dxt[1]= dxt[2]= 0.0; + dyt[0]= dyt[1]= dyt[2]= 0.0; + } /* Grab the mapping settings for this texture */ switch(mtex->texco) { @@ -1920,12 +1946,6 @@ void do_sky_tex(float *lo) } else { /* potentially dangerous... check with multitex! */ - R.wrld.horr= (wrld_hor->horr); - R.wrld.horg= (wrld_hor->horg); - R.wrld.horb= (wrld_hor->horb); - R.wrld.zenr= (wrld_hor->zenr); - R.wrld.zeng= (wrld_hor->zeng); - R.wrld.zenb= (wrld_hor->zenb); continue; } break; @@ -1950,36 +1970,36 @@ void do_sky_tex(float *lo) /* texture */ if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, dxt, dyt); - rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa); + rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres); /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - Tr= 1.0-Tr; - Tg= 1.0-Tg; - Tb= 1.0-Tb; + texres.tr= 1.0-texres.tr; + texres.tg= 1.0-texres.tg; + texres.tb= 1.0-texres.tb; } - else Tin= 1.0-Tin; + else texres.tin= 1.0-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgb) { - fact= Ta; - Ta*= stencilTin; + fact= texres.ta; + texres.ta*= stencilTin; stencilTin*= fact; } else { - fact= Tin; - Tin*= stencilTin; + fact= texres.tin; + texres.tin*= stencilTin; stencilTin*= fact; } } else { - if(rgb) Ta *= stencilTin; - else Tin*= stencilTin; + if(rgb) texres.ta *= stencilTin; + else texres.tin*= stencilTin; } /* colour mapping */ @@ -1987,17 +2007,16 @@ void do_sky_tex(float *lo) float tcol[3]; if(rgb==0) { - Tr= mtex->r; - Tg= mtex->g; - Tb= mtex->b; + texres.tr= mtex->r; + texres.tg= mtex->g; + texres.tb= mtex->b; } - else Tin= Ta; + else texres.tin= texres.ta; - tcol[0]= Tr; tcol[1]= Tg; tcol[2]= Tb; + tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb; if(mtex->mapto & WOMAP_HORIZ) { - texture_rgb_blend(&R.wrld.horr, tcol, &wrld_hor->horr, Tin, mtex->colfac, mtex->blendtype); - wrld_hor= &R.wrld; + texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype); } if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) { ok= 0; @@ -2010,41 +2029,32 @@ void do_sky_tex(float *lo) else ok= 1; if(ok) { - texture_rgb_blend(&R.wrld.zenr, tcol, &wrld_hor->zenr, Tin, mtex->colfac, mtex->blendtype); - wrld_zen= &R.wrld; - } - else { - /* otherwise zenRGB undefined */ - R.wrld.zenr= wrld_zen->zenr; - R.wrld.zeng= wrld_zen->zeng; - R.wrld.zenb= wrld_zen->zenb; + texture_rgb_blend(zen, tcol, zen, texres.tin, mtex->colfac, mtex->blendtype); } } } if(mtex->mapto & WOMAP_BLEND) { - if(rgb) Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); - R.inprz= texture_value_blend(mtex->def_var, R.inprz, Tin, mtex->varfac, mtex->blendtype, 0); + *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->varfac, mtex->blendtype, 0); } } } } /* ------------------------------------------------------------------------- */ -/* explicit lampren stuff should be factored out! or rather, the - texturing stuff might need to go...*/ -void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) +/* colf supposed to be initialized with la->r,g,b */ + +void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf) { Object *ob; - LampRen *la_col; MTex *mtex; Tex *tex; + TexResult texres; float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0; float texvec[3], dxt[3], dyt[3], tempvec[3]; int tex_nr, rgb= 0; - la_col= la->org; - tex_nr= 0; for(; tex_nr<MAX_MTEX; tex_nr++) { @@ -2053,8 +2063,8 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) mtex= la->mtex[tex_nr]; tex= mtex->tex; - if(tex==0) continue; - tex->nor= NULL; + if(tex==NULL) continue; + texres.nor= NULL; /* which coords */ if(mtex->texco==TEXCO_OBJECT) { @@ -2066,19 +2076,19 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) VECCOPY(tempvec, shi->co); MTC_Mat4MulVecfl(ob->imat, tempvec); if(shi->osatex) { - VECCOPY(dxt, O.dxco); - VECCOPY(dyt, O.dyco); + VECCOPY(dxt, shi->dxco); + VECCOPY(dyt, shi->dyco); MTC_Mat4Mul3Vecfl(ob->imat, dxt); MTC_Mat4Mul3Vecfl(ob->imat, dyt); } } else { co= shi->co; - dx= O.dxco; dy= O.dyco; + dx= shi->dxco; dy= shi->dyco; } } else if(mtex->texco==TEXCO_GLOB) { - co= shi->gl; dx= O.dxco; dy= O.dyco; + co= shi->gl; dx= shi->dxco; dy= shi->dyco; VECCOPY(shi->gl, shi->co); MTC_Mat4MulVecfl(R.viewinv, shi->gl); } @@ -2095,8 +2105,8 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) dx= dxt; dy= dyt; if(shi->osatex) { - VECCOPY(dxt, O.dxlv); - VECCOPY(dyt, O.dylv); + VECCOPY(dxt, shi->dxlv); + VECCOPY(dyt, shi->dylv); /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ MTC_Mat3MulVecfl(la->imat, dxt); MTC_Mat3MulVecfl(la->imat, dyt); @@ -2140,36 +2150,36 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) do_2d_mapping(mtex, texvec, NULL, dxt, dyt); } - rgb= multitex(tex, texvec, dxt, dyt, shi->osatex); + rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres); /* texture output */ if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { - Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); rgb= 0; } if(mtex->texflag & MTEX_NEGATIVE) { if(rgb) { - Tr= 1.0-Tr; - Tg= 1.0-Tg; - Tb= 1.0-Tb; + texres.tr= 1.0-texres.tr; + texres.tg= 1.0-texres.tg; + texres.tb= 1.0-texres.tb; } - else Tin= 1.0-Tin; + else texres.tin= 1.0-texres.tin; } if(mtex->texflag & MTEX_STENCIL) { if(rgb) { - fact= Ta; - Ta*= stencilTin; + fact= texres.ta; + texres.ta*= stencilTin; stencilTin*= fact; } else { - fact= Tin; - Tin*= stencilTin; + fact= texres.tin; + texres.tin*= stencilTin; stencilTin*= fact; } } else { - if(rgb) Ta*= stencilTin; - else Tin*= stencilTin; + if(rgb) texres.ta*= stencilTin; + else texres.tin*= stencilTin; } /* mapping */ @@ -2177,39 +2187,38 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi) float col[3]; if(rgb==0) { - Tr= mtex->r; - Tg= mtex->g; - Tb= mtex->b; + texres.tr= mtex->r; + texres.tg= mtex->g; + texres.tb= mtex->b; } else if(mtex->mapto & MAP_ALPHA) { - Tin= stencilTin; + texres.tin= stencilTin; } - else Tin= Ta; + else texres.tin= texres.ta; /* lamp colors were premultiplied with this */ - col[0]= Tr*la->energy; - col[1]= Tg*la->energy; - col[2]= Tb*la->energy; + col[0]= texres.tr*la->energy; + col[1]= texres.tg*la->energy; + col[2]= texres.tb*la->energy; - texture_rgb_blend(&la->r, col, &la_col->r, Tin, mtex->colfac, mtex->blendtype); - - la_col= la; /* makes sure first run uses la->org, then la */ + texture_rgb_blend(colf, col, colf, texres.tin, mtex->colfac, mtex->blendtype); } - } } } /* ------------------------------------------------------------------------- */ -void externtex(MTex *mtex, float *vec) +void externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) { Tex *tex; - float dxt[3], dyt[3], texvec[3], dummy[3]; + TexResult texr; + float dxt[3], dyt[3], texvec[3]; int rgb; tex= mtex->tex; - if(tex==0) return; + if(tex==NULL) return; + texr.nor= NULL; /* placement */ if(mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]); @@ -2224,85 +2233,68 @@ void externtex(MTex *mtex, float *vec) /* texture */ if(tex->type==TEX_IMAGE) { do_2d_mapping(mtex, texvec, NULL, dxt, dyt); - - if(mtex->mapto & MAP_NORM) { - /* the pointer defines if there's bump */ - tex->nor= dummy; - if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac; - else tex->norfac= mtex->norfac; - } - else tex->nor= NULL; } - rgb= multitex(tex, texvec, dxt, dyt, 0); + rgb= multitex(tex, texvec, dxt, dyt, 0, &texr); if(rgb) { - Tin= (0.35*Tr+0.45*Tg+0.2*Tb); + texr.tin= (0.35*texr.tr+0.45*texr.tg+0.2*texr.tb); } else { - Tr= mtex->r; - Tg= mtex->g; - Tb= mtex->b; + texr.tr= mtex->r; + texr.tg= mtex->g; + texr.tb= mtex->b; } -} - -/* ------------------------------------------------------------------------- */ - -void externtexcol(MTex *mtex, float *orco, char *col) -{ - int temp; - float b1; - - if(mtex->tex==0) return; - - externtex(mtex, orco); - - b1= 1.0-Tin; - - temp= 255*(Tin*Tr)+b1*col[0]; - if(temp>255) col[0]= 255; else col[0]= temp; - temp= 255*(Tin*Tg)+b1*col[1]; - if(temp>255) col[1]= 255; else col[1]= temp; - temp= 255*(Tin*Tb)+b1*col[2]; - if(temp>255) col[2]= 255; else col[2]= temp; + *tin= texr.tin; + *tr= texr.tr; + *tg= texr.tg; + *tb= texr.tb; + *ta= texr.ta; } + /* ------------------------------------------------------------------------- */ void render_realtime_texture(ShadeInput *shi) { - static Tex tex; + TexResult texr; + static Tex tex1, tex2; // threadsafe static int firsttime= 1; + Tex *tex; float texvec[2], dx[2], dy[2]; if(firsttime) { - default_tex(&tex); - tex.type= TEX_IMAGE; firsttime= 0; + default_tex(&tex1); + default_tex(&tex2); + tex1.type= TEX_IMAGE; + tex2.type= TEX_IMAGE; } - tex.ima = shi->vlr->tface->tpage; - if(tex.ima) { + if(((int)(shi->ys+0.5)) & 1) tex= &tex1; else tex= &tex2; // threadsafe + + tex->ima = shi->vlr->tface->tpage; + if(tex->ima) { texvec[0]= 0.5+0.5*shi->uv[0]; texvec[1]= 0.5+0.5*shi->uv[1]; if(shi->osatex) { - dx[0]= 0.5*O.dxuv[0]; - dx[1]= 0.5*O.dxuv[1]; - dy[0]= 0.5*O.dyuv[0]; - dy[1]= 0.5*O.dyuv[1]; + dx[0]= 0.5*shi->dxuv[0]; + dx[1]= 0.5*shi->dxuv[1]; + dy[0]= 0.5*shi->dyuv[0]; + dy[1]= 0.5*shi->dyuv[1]; } - if(shi->osatex) imagewraposa(&tex, texvec, dx, dy); - else imagewrap(&tex, texvec); + texr.nor= NULL; + + if(shi->osatex) imagewraposa(tex, texvec, dx, dy, &texr); + else imagewrap(tex, texvec, &texr); - shi->vcol[0]*= Tr; - shi->vcol[1]*= Tg; - shi->vcol[2]*= Tb; + shi->vcol[0]*= texr.tr; + shi->vcol[1]*= texr.tg; + shi->vcol[2]*= texr.tb; } - - } /* eof */ diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c index 6745d58aacb..f76a7e479e2 100644 --- a/source/blender/render/intern/source/vanillaRenderPipe.c +++ b/source/blender/render/intern/source/vanillaRenderPipe.c @@ -56,13 +56,14 @@ #include "DNA_camera_types.h" #include "DNA_object_types.h" #include "BKE_global.h" +#include "BKE_utildefines.h" +#include "BLI_arithb.h" #include "BLI_rand.h" /* local includes (from the render module) */ #include "RE_callbacks.h" #include "render.h" /* all kinds of stuff */ -#include "render_intern.h" #include "zbuf.h" /* for vergzvlak, zbufclip, zbufclipwire */ #include "edgeRender.h" /* all edge rendering stuff */ #include "pixelshading.h" /* painting the pixels */ @@ -76,14 +77,11 @@ /* own includes */ #include "vanillaRenderPipe.h" -#include "vanillaRenderPipe_int.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif +#include "SDL_thread.h" -/* crud */ -#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) +/* threshold for alpha */ +#define RE_FULL_ALPHA_FLOAT 0.9998 /* ------------------------------------------------------------------------- */ /* Debug defines: disable all for production level code. */ @@ -111,29 +109,20 @@ extern float Zjitx,Zjity; /* The x,y values for jitter offset */ extern float Zmulx, Zmuly; /* Some kind of scale? */ -extern unsigned int Zvlnr; /* Face rendering pointer and counter: these */ -extern VlakRen *Zvlr; /* are used for 'caching' render results. */ - - /* These function pointers are used for z buffer filling. */ -extern void (*zbuffunc)(float *, float *, float *); -extern void (*zbuflinefunc)(float *, float *); - extern char cmask[256]; /* When a pixel is supersampled, we must */ extern char *centmask; /* compute its colour on a point _on_ the face. */ /* These two are used to compute an offset to */ /* guarantee we use valid coordinates. */ -/* unsorted */ -extern float fmask[256]; -extern unsigned short usegamtab, shortcol[4], - *mask1[9], *mask2[9],/* *igamtab1, */ *igamtab2/*, *gamtab */; - extern RE_APixstrExt *APixbufExt;/*Zbuffer: linked list of face, halo indices*/ /* Globals : --------------------------------------------------------------- */ - /* we use three lines, for gaussian sample */ + /* we use 2 x three lines, for gaussian sample */ +RE_COLBUFTYPE *AColourBuffer0; /* Buffer for colours of 1 line of pixels */ RE_COLBUFTYPE *AColourBuffer1; /* Buffer for colours of 1 line of pixels */ RE_COLBUFTYPE *AColourBuffer2; /* Buffer for colours of 1 line of pixels */ +RE_COLBUFTYPE *AColourBuffer1a; /* Buffer for colours of 1 line of pixels */ +RE_COLBUFTYPE *AColourBuffer2a; /* Buffer for colours of 1 line of pixels */ RE_COLBUFTYPE *AColourBuffer3; /* Buffer for colours of 1 line of pixels */ static int Aminy; /* y value of first line in the accu buffer */ @@ -142,10 +131,6 @@ static int Amaxy; /* y value of last line in the accu buffer */ /* Buffer width refers to the size of the buffers we build. Image size is */ /* the same as R.rectx, R.recty. */ -static int imageHeight; /* image size in pixels in y direction */ -static int imageWidth; /* image size in pixels in x direction */ -static int bufferHeight; /* image size in pixels in y direction */ -static int bufferWidth; /* image size in pixels in x direction */ static int zBufferWidth; /* special width because zbuffer needs to be */ /* wider */ @@ -157,125 +142,24 @@ int alphaLUT[32]; /* alpha lookuptable, for oversampling */ int osaNr; /* The oversample number. I keep it */ /* separately here, because I treat no OSA */ /* as if it were osa=1. */ -RE_COLBUFTYPE collector[4]; /* used throughout as pixel colour accu */ -RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4]; /* subpixel accu buffer */ - -/* ------------------------------------------------------------------------- */ -/* Local (for now) */ -/* void integrateStack(struct RE_faceField* stack, */ -/* int ptr, */ -/* float x, */ -/* float y, */ -/* int osaNr); */ -void integratePerSubStack(struct RE_faceField* stack, - int ptr, - float x, - float y, - int osaNr); /* ------------------------------------------------------------------------- */ -void zBufShadeAdvanced() -{ - RE_COLBUFTYPE *cycle; - int y, keepLooping = 1; - float xjit = 0.0, yjit = 0.0; - - Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */ - - /* EDGE: for edge rendering we should compute a larger buffer, but this */ - /* may require modifications at a deeper level. For now, we just */ - /* 'ignore' edge pixels. */ - imageHeight = R.recty; - imageWidth = R.rectx; - bufferHeight = R.recty; - bufferWidth = R.rectx; - - /* Set osaNr. Treat 'no osa' as 'osa = 1' */ - if(R.r.mode & R_OSA) { - osaNr = R.osa; - if(osaNr > 16) { /* check was moved from calcZBufLine */ - printf("zBufShadeAdvanced> osa too large (internal error)\n"); - G.afbreek= 1; - return; - } - } else { - /* little hack */ - osaNr = 1; - xjit = jit[0][0]; - yjit = jit[0][1]; - jit[0][0] = 0.0; - jit[0][1] = 0.0; - } - - RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix */ - - initRenderBuffers(bufferWidth); - - /* ugh! should be converted sooner!! */ - switch (R.r.alphamode) { - case R_ALPHAKEY: - setSkyBlendingMode(RE_ALPHA_KEY); - break; - case R_ALPHAPREMUL: - setSkyBlendingMode(RE_ALPHA_PREMUL); - break; -/* not there... this is the default case */ -/* case R_ALPHASKY: */ -/* setSkyBlendingMode(RE_ALPHA_SKY); */ -/* break; */ - default: - setSkyBlendingMode(RE_ALPHA_SKY); - } - - y = 0; - while ( (y < bufferHeight) && keepLooping) { - calcZBufLine(y); - - renderZBufLine(y); - if(y) { - transferColourBufferToOutput(y-1); - - if((y & 1)==0) RE_local_render_display(y-2, y-1, imageWidth, imageHeight, R.rectot); - } - - /* buffer cycling */ - eraseColBuf(AColourBuffer3); - cycle= AColourBuffer3; - AColourBuffer3= AColourBuffer2; - AColourBuffer2= AColourBuffer1; - AColourBuffer1= cycle; - - if(RE_local_test_break()) keepLooping = 0; - y++; - } - if(keepLooping) transferColourBufferToOutput(y-1); - - freeRenderBuffers(); - - /* Edge rendering is done purely as a post-effect */ - if(R.r.mode & R_EDGE) { - addEdges((char*)R.rectot, imageWidth, imageHeight, - osaNr, - R.r.edgeint, R.r.same_mat_redux, - G.compat, G.notonlysolid, - R.r.edgeR, R.r.edgeG, R.r.edgeB); - } - - if (!(R.r.mode & R_OSA)) { - jit[0][0] = xjit; - jit[0][1] = yjit; - } - -} /* end of void zbufshadeAdvanced() */ - -/* ------------------------------------------------------------------------- */ - -void initRenderBuffers(int bwidth) +/** +* Z buffer initializer, for new pipeline. + * <LI> + * <IT> AColourBuffer : colour buffer for one line + * <IT> APixbufExt : pixel data buffer for one line, depth RE_ZBUFLEN + * </LI> + */ +static void initRenderBuffers(int bwidth) { /* bwidth+4, as in rendercore.c. I think it's too much, but yah (ton) */ + AColourBuffer0 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); AColourBuffer1 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); AColourBuffer2 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); + AColourBuffer1a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); + AColourBuffer2a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); AColourBuffer3 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); /* The +1 is needed because the fill-functions use a +1 offset when */ @@ -288,80 +172,353 @@ void initRenderBuffers(int bwidth) Aminy= -1000; /* indices of lines in the z buffer: no lines buffered */ Amaxy= -1000; - /* Use slider when the gamma button is pressed. */ - if (R.r.mode & R_GAMMA) { - makeGammaTables(R.r.gamma); - setDoGamma(1); - } else { - /* - Needed for spotlights! Maybe a separate gammatable would be - required here - */ - makeGammaTables(1.0); - setDoGamma(0); - } -} /* End of void initZBuffers(void) */ +} /* ------------------------------------------------------------------------- */ +/** + * Z buffer destructor, frees stuff from initZBuffers(). + */ -void freeRenderBuffers(void) { +static void freeRenderBuffers(void) { + if (AColourBuffer0) MEM_freeN(AColourBuffer0); if (AColourBuffer1) MEM_freeN(AColourBuffer1); if (AColourBuffer2) MEM_freeN(AColourBuffer2); + if (AColourBuffer1a) MEM_freeN(AColourBuffer1a); + if (AColourBuffer2a) MEM_freeN(AColourBuffer2a); if (AColourBuffer3) MEM_freeN(AColourBuffer3); freeZbuffer(); -} /* End of void freeZBuffers(void) */ - +} /* ------------------------------------------------------------------------- */ -void calcZBufLine(int y) +/** + * New fill function for z buffer, for edge-only rendering. + */ +static void zBufferFillFace(unsigned int zvlnr, float *v1, float *v2, float *v3) { + /* Coordinates of the vertices are specified in ZCS */ + int apteller, apoffsetteller; + double z0; /* used as temp var*/ + double xx1; + double zxd,zyd,zy0, tmp; + float *minv,*maxv,*midv; + register int zverg,zvlak,x; + int my0,my2,sn1,sn2,rectx,zd; + int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask; - int part; - int keepLooping = 1; + /* These used to be doubles. We may want to change them back if the */ + /* loss of accuracy proves to be a problem? There does not seem to be */ + /* any performance issues here, so I'll just keep the doubles. */ + /* float vec0[3], vec1[3], vec2[3]; */ + double vec0[3], vec1[3], vec2[3]; - if(y<0) return; + /* MIN MAX */ + /* sort vertices for min mid max y value */ + if(v1[1]<v2[1]) { + if(v2[1]<v3[1]) { minv=v1; midv=v2; maxv=v3;} + else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2;} + else { minv=v3; midv=v1; maxv=v2;} + } + else { + if(v1[1]<v3[1]) { minv=v2; midv=v1; maxv=v3;} + else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1;} + else { minv=v3; midv=v2; maxv=v1;} + } - /* zbuffer fix: here? */ - Zmulx= ((float) bufferWidth)/2.0; - Zmuly= ((float) bufferHeight)/2.0; + if(minv[1] == maxv[1]) return; /* security to remove 'zero' size faces */ - - /* use these buffer fill functions */ - zbuffunc = zBufferFillFace; - zbuflinefunc = zBufferFillEdge; - - /* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */ - if( (y < Aminy) || (y > Amaxy)) { - /* prepare buffer */ - part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */ - Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */ - Amaxy = Aminy + RE_ZBUFLEN - 1; -/* if(Amaxy >= R.recty) Amaxy = R.recty-1; */ - if(Amaxy >= bufferHeight) Amaxy = bufferHeight - 1; - resetZbuffer(); - - Zsample = 0; /* Zsample is used internally ! */ - while ( (Zsample < osaNr) && keepLooping ) { - /* Apply jitter to this pixel. The jitter offsets are globals. */ - /* They are added in zbufclip() */ - /* Negative: these offsets are added to the vertex coordinates */ - /* so it equals translating viewpoint over the positive vector. */ - Zjitx= -jit[Zsample][0]-0.5; - Zjity= -jit[Zsample][1]-0.5; + my0 = ceil(minv[1]); + my2 = floor(maxv[1]); + omsl = floor(midv[1]); - keepLooping = fillZBufDistances(); - - if(RE_local_test_break()) keepLooping = 0; - Zsample++; - } - }; - -} /*End of void calcZBufLine(int y) */ + /* outside the current z buffer slice: clip whole face */ + if( (my2 < Aminy) || (my0 > Amaxy)) return; + + if(my0<Aminy) my0= Aminy; + + /* EDGES : THE LONGEST */ + xx1= maxv[1]-minv[1]; + if(xx1>2.0/65536.0) { + z0= (maxv[0]-minv[0])/xx1; + + tmp= (-65536.0*z0); + dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); + + tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); + xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); + } + else { + dx0= 0; + xs0= 65536.0*(MIN2(minv[0],maxv[0])); + } + /* EDGES : THE TOP ONE */ + xx1= maxv[1]-midv[1]; + if(xx1>2.0/65536.0) { + z0= (maxv[0]-midv[0])/xx1; + + tmp= (-65536.0*z0); + dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); + + tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); + xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); + } + else { + dx1= 0; + xs1= 65536.0*(MIN2(midv[0],maxv[0])); + } + /* EDGES : THE BOTTOM ONE */ + xx1= midv[1]-minv[1]; + if(xx1>2.0/65536.0) { + z0= (midv[0]-minv[0])/xx1; + + tmp= (-65536.0*z0); + dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); + + tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); + xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); + } + else { + dx2= 0; + xs2= 65536.0*(MIN2(minv[0],midv[0])); + } + + /* ZBUF DX DY */ + /* xyz_1 = v_1 - v_2 */ + MTC_diff3DFF(vec1, v1, v2); + /* xyz_2 = v_2 - v_3 */ + MTC_diff3DFF(vec2, v2, v3); + /* xyz_0 = xyz_1 cross xyz_2 */ + MTC_cross3Double(vec0, vec1, vec2); + + /* cross product of two of the sides is 0 => this face is too small */ + if(vec0[2]==0.0) return; + + if(midv[1] == maxv[1]) omsl= my2; + if(omsl < Aminy) omsl= Aminy-1; /* make sure it takes the first loop entirely */ + + while (my2 > Amaxy) { /* my2 can be larger */ + xs0+=dx0; + if (my2<=omsl) { + xs2+= dx2; + } + else{ + xs1+= dx1; + } + my2--; + } + + xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2]; + + zxd= -vec0[0]/vec0[2]; + zyd= -vec0[1]/vec0[2]; + zy0= my2*zyd+xx1; + zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); + + /* start-ofset in rect */ + /* rectx= R.rectx; */ + /* I suspect this var needs very careful setting... When edge rendering */ + /* is on, this is strange */ + rectx = zBufferWidth; + apoffsetteller = rectx*(my2-Aminy); + + mask= 1<<Zsample; + zvlak= zvlnr; + + xs3= 0; /* flag */ + if(dx0>dx1) { + MTC_swapInt(&xs0, &xs1); + MTC_swapInt(&dx0, &dx1); + xs3= 1; /* flag */ + + } + + for(y=my2;y>omsl;y--) { + + sn1= xs0>>16; + xs0+= dx0; + + sn2= xs1>>16; + xs1+= dx1; + + sn1++; + + if(sn2>=rectx) sn2= rectx-1; + if(sn1<0) sn1= 0; + zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); + apteller = apoffsetteller + sn1; + x= sn2-sn1; + + zverg-= Azvoordeel; + + while(x>=0) { + insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask); + zverg+= zd; + apteller++; + x--; + } + zy0-= zyd; + apoffsetteller -= rectx; + } + + if(xs3) { + xs0= xs1; + dx0= dx1; + } + if(xs0>xs2) { + xs3= xs0; + xs0= xs2; + xs2= xs3; + xs3= dx0; + dx0= dx2; + dx2= xs3; + } + + for(; y>=my0; y--) { + + sn1= xs0>>16; + xs0+= dx0; + sn2= xs2>>16; + xs2+= dx2; + + sn1++; + + if(sn2>=rectx) sn2= rectx-1; + if(sn1<0) sn1= 0; + zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); + apteller = apoffsetteller + sn1; + x= sn2-sn1; + + zverg-= Azvoordeel; + + while(x>=0) { + insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, zverg, mask); + zverg+= zd; + apteller++; + x--; + } + + zy0-=zyd; + apoffsetteller -= rectx; + } +} /* ------------------------------------------------------------------------- */ -int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], +static void zBufferFillEdge(unsigned int zvlnr, float *vec1, float *vec2) +{ + int apteller; + int start, end, x, y, oldx, oldy, ofs; + int dz, vergz, mask; + float dx, dy; + float v1[3], v2[3]; + + dx= vec2[0]-vec1[0]; + dy= vec2[1]-vec1[1]; + + if(fabs(dx) > fabs(dy)) { + + /* all lines from left to right */ + if(vec1[0]<vec2[0]) { + VECCOPY(v1, vec1); + VECCOPY(v2, vec2); + } + else { + VECCOPY(v2, vec1); + VECCOPY(v1, vec2); + dx= -dx; dy= -dy; + } + + start= floor(v1[0]); + end= start+floor(dx); + if(end >= zBufferWidth) end = zBufferWidth - 1; + + oldy= floor(v1[1]); + dy/= dx; + + vergz= v1[2]; + vergz-= Azvoordeel; + dz= (v2[2]-v1[2])/dx; + + apteller = zBufferWidth*(oldy-Aminy) +start; + mask = 1<<Zsample; + + if(dy<0) ofs= -zBufferWidth; + else ofs= zBufferWidth; + + for(x= start; x<=end; x++, /* ap++, */ apteller++) { + + y= floor(v1[1]); + if(y!=oldy) { + oldy= y; + apteller += ofs; + } + + if(x>=0 && y>=Aminy && y<=Amaxy) { + insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask); + } + + v1[1]+= dy; + vergz+= dz; + } + } + else { + + /* all lines from top to bottom */ + if(vec1[1]<vec2[1]) { + VECCOPY(v1, vec1); + VECCOPY(v2, vec2); + } + else { + VECCOPY(v2, vec1); + VECCOPY(v1, vec2); + dx= -dx; dy= -dy; + } + + start= floor(v1[1]); + end= start+floor(dy); + + if(start>Amaxy || end<Aminy) return; + + if(end>Amaxy) end= Amaxy; + + oldx= floor(v1[0]); + dx/= dy; + + vergz= v1[2]; + vergz-= Azvoordeel; + dz= (v2[2]-v1[2])/dy; + + apteller = zBufferWidth*(start-Aminy) +oldx; + + mask= 1<<Zsample; + + if(dx<0) ofs= -1; + else ofs= 1; + + for(y= start; y<=end; y++, apteller += zBufferWidth) { + + x= floor(v1[0]); + if(x!=oldx) { + oldx= x; + apteller += ofs; + } + + if(x>=0 && y>=Aminy && (x < zBufferWidth)) { + insertObject(apteller, /* RE_treat_face_as_opaque, */ zvlnr, RE_POLY, vergz, mask); + } + + v1[0]+= dx; + vergz+= dz; + } + } +} +/* ------------------------------------------------------------------------- */ + +/** + * Count and sort the list behind ap into buf. Sorts on min. distance. + * Low index <=> high z + */ +static int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], RE_APixstrExt *ap) { int totvlak; /* face counter */ @@ -397,7 +554,7 @@ int countAndSortPixelFaces(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], } else if (totvlak != 1) qsort(zrow, totvlak, sizeof(int)*RE_PIXELFIELDSIZE, vergzvlak); return totvlak; -} /* end of int countAndSortPixelFaces(int* zrow,RE_APixstrExt *ap ) */ +} /* ------------------------------------------------------------------------- */ /* Oversampler v3 - check CVS for older versions */ @@ -421,9 +578,10 @@ static int VR_cbuf[RE_MAX_FACES_PER_PIXEL][2]; /** * Analyze the z-buffer, and pre-sample the colours. */ -int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], +static int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector, struct RE_faceField* stack, int ptr, - int totvlak, float x, float y, int osaNr) { + int totvlak, float x, float y, int osaNr) +{ VlakRen *vlr= NULL; float xs = 0.0; float ys = 0.0; /* coordinates for the render-spot */ @@ -446,7 +604,7 @@ int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], while ( (!saturated || (saturated && inconflict) ) && (totvlak > 0) ) { totvlak--; - + full_osa= 0; if(R.osa && (zrow[totvlak][RE_TYPE] & RE_POLY)) { vlr= RE_findOrAddVlak((zrow[totvlak][RE_INDEX]-1) & 0x7FFFFF); @@ -461,7 +619,7 @@ int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], if(mask & (1<<a)) { xs= (float)x + jit[a][0]; ys= (float)y + jit[a][1]; - renderPixel(xs, ys, zrow[totvlak], 1<<a); + renderPixel(collector, xs, ys, zrow[totvlak], 1<<a); accol[0] += collector[0]; accol[1] += collector[1]; accol[2] += collector[2]; accol[3] += collector[3]; div+= 1.0; } @@ -480,11 +638,11 @@ int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], /* stack face ----------- */ stack[ptr].mask = zrow[totvlak][RE_MASK]; - stack[ptr].data = renderPixel(xs, ys, zrow[totvlak], stack[ptr].mask); + stack[ptr].data = renderPixel(collector, xs, ys, zrow[totvlak], stack[ptr].mask); } stack[ptr].faceType = zrow[totvlak][RE_TYPE]; cpFloatColV(collector, stack[ptr].colour); - + /* This is done so that spothalos are properly overlayed on halos */ /* maybe we need to check the colour here... */ if(zrow[totvlak][RE_TYPE] & RE_POLY) VR_covered |= zrow[totvlak][RE_MASK]; @@ -541,7 +699,7 @@ int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], ys= (float)y; /* code identical for rendering empty sky pixel */ - renderSkyPixelFloat(xs, ys); + renderSkyPixelFloat(collector, xs, ys); cpFloatColV(collector, colbuf); if(R.flag & R_LAMPHALO) { @@ -561,120 +719,94 @@ int composeStack(int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE], return ptr; } -/* - Start resolving the conflict: the stack is primed to the top-most valid - layer on the stack. Call this layer n. Layer n has a conflict count of c. - This means layers [ n - c, ..., n ] +/* ------------------------------------------------------------------------- */ + +/** + * Calculate the view depth to this object on this location, with + * the current view parameters in R. */ -int resolveConflict(struct RE_faceField* stack, int ptr, float x, float y) { - int face; - int layer; - float dx, dy; - float xs = 0.0; - float ys = 0.0; /* coordinates for the render-spot */ - int i; - - for(i = 0; i< osaNr; i++) { /* per bin, buffer all faces */ - dx = jit[i][0]; - dy = jit[i][1]; - xs = (float)x + dx; - ys = (float)y + dy; - - face = 0; /* only counts covering faces ------------------- */ - layer = 0; /* counts all faces ----------------------------- */ - - while (layer < stack[ptr].conflictCount) { - if ( (1<<i) & stack[ptr - layer].mask) { - VR_cbuf[face][0] = - calcDepth(xs, ys, - stack[ptr - layer].data, - stack[ptr - layer].faceType); - VR_cbuf[face][1] = ptr - layer; - face++; - } - layer++; +static int calcDepth(float x, float y, void *data, int type) +{ + float view[3]; + + if (type & RE_POLY) { + VlakRen* vlr = (VlakRen*) data; + VertRen* v1; + float dvlak, deler, fac, hoco_z, hoco_w; + int zbuf_co; + + v1 = vlr->v1; + + /* vertex dot face normal: WCS */ + dvlak= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; + + /* jitter has been added to x, y ! */ + /* view vector view: screen coords */ + view[0]= (x+(R.xstart)+0.5); + + if(R.flag & R_SEC_FIELD) { + if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor; + else view[1]= (y + R.ystart + 1.0)*R.ycor; + } + else view[1]= (y + R.ystart + 0.5)*R.ycor; + + + /* for pano, another rotation in the xz plane is needed.... */ + + /* this is ok, in WCS */ + view[2]= -R.viewfac; /* distance to viewplane */ + + /* face normal dot view vector: but how can this work? */ + deler = MTC_dot3Float(vlr->n, view); + if (deler!=0.0) fac = dvlak/deler; + else fac = 0.0; + + /* indices are wrong.... but gives almost the right value? */ + hoco_z = (fac*view[2]) * R.winmat[2][2] + R.winmat[3][2]; + hoco_w = (fac*view[2]) * R.winmat[2][3] + R.winmat[3][3]; + + if(hoco_w!=0.0) zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w); + else zbuf_co= 0x7FFFFFFF; + + return zbuf_co; /* z component of R.co */ + } else if (type & RE_HALO) { + HaloRen* har = (HaloRen*) data; + return har->zBufDist; + } + return 0; +} + +/** + * Blend source over dest, and leave result in dest. 1 pixel. + */ +static void blendOverFloat(int type, float* dest, float* source, void* data) +{ + + if (type & RE_POLY) { + VlakRen *ver = (VlakRen*) data; + if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) { + char addf = (char) (ver->mat->add * 255.0); + addalphaAddfacFloat(dest, source, addf); } - qsort(VR_cbuf, face, sizeof(int)*2, vergzvlak); - for(layer = 0; layer < face; layer++) { - blendOverFloat(stack[VR_cbuf[layer][1]].faceType, /* type */ - sampcol + (4 * i), /* dest */ - stack[VR_cbuf[layer][1]].colour, /* src */ - stack[VR_cbuf[layer][1]].data); /* data */ - } + else + addAlphaOverFloat(dest, source); + } else if (type & RE_HALO) { + HaloRen *har= (HaloRen*) data; + addalphaAddfacFloat(dest, source, har->add); + } else if (type & RE_SKY) { + addAlphaOverFloat(dest, source); } - - /* The number of layers that were handled. This is how many layers the */ - /* top-level algorithm needs to skip. */ - return stack[ptr].conflictCount; + } -/* The colour stack is blended down in a pretty straight-forward manner, or */ -/* a part of the stack is re-evaluated to resolve the conflict. */ -/* About 25-30% of rendering time is eaten here! */ -void integrateStack(struct RE_faceField* stack, int ptr, - float x, - float y, - int osaNr) { - /* sample the colour stack: back to front ---------------------------- */ - /* is there a possible way to ignore alpha? this would save 25% work */ - ptr--; - /* Little different now: let ptr point to the topmost valid face.*/ - while (ptr >= 0) { - if (stack[ptr].conflictCount == 0) { - /* - No conflict: sample one colour into multiple bins - */ - blendOverFloatRow(stack[ptr].faceType, - sampcol, - stack[ptr].colour, - stack[ptr].data, - stack[ptr].mask, - osaNr); - ptr--; - } else { - /* - Recalc all z-values, and integrate per sub-pixel. - */ - ptr -= resolveConflict(stack, ptr, x, y); - } - } - - /* Done sampling. Now we still need to fill in pixels that were not */ - /* covered at all It seems strange that we have to check for empty alpha */ - /* but somehow this is necessary. Check out the cover condition :).... */ - - /* It is important that we find a more efficient algorithm here, because */ - /* this little loop eats _lots_ of cycles. */ - - /* Should be integrated in the rest of the rendering... */ - - if(R.flag & R_LAMPHALO) { - float halocol[4]; - int i; - - renderSpotHaloPixel(x, y, halocol); - /* test seems to be wrong? */ - if (halocol[3] > RE_EMPTY_COLOUR_FLOAT) { - for (i = 0; i < osaNr; i++) { - /* here's a pinch: if the pixel was only covered by a halo, */ - /* we still need to fill spothalo. How do we detect this? */ - if (!(VR_covered & (1 << i))) - /* maybe a copy is enough here... */ - addAlphaOverFloat(sampcol + (4 * i), halocol); - } - } - } -} /** * New approach: sample substacks. Each substack is first copied into * a stack buffer, and then blended down. * */ -void integratePerSubStack(struct RE_faceField* stack, - int ptr, - float x, - float y, - int osaNr) { +static void integratePerSubStack(float *sampcol, struct RE_faceField* stack, + int ptr, float x, float y, int osaNr) +{ int i = 0; int j = 0; int k = 0; @@ -838,38 +970,33 @@ void integratePerSubStack(struct RE_faceField* stack, /* an RE_APixstrExt* array */ /* - redo the numbering to something more logical */ -void renderZBufLine(int y) +static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3) { int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE]; RE_APixstrExt *ap; /* iterator for the face-lists */ + RE_COLBUFTYPE collector[4]; + RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4]; + RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */ int apteller; int x; /* pixel counter */ - RE_COLBUFTYPE *colbuf1; /* pointer into the line buffer */ - RE_COLBUFTYPE *colbuf2; /* pointer into the line buffer */ - RE_COLBUFTYPE *colbuf3; /* pointer into the line buffer */ - RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */ int i; /* yet another counter */ int stackDepth; /* faces-behind-this-pixel counter */ struct RE_faceField RE_OSAstack[RE_MAX_FACES_PER_PIXEL + 1]; int RE_OSAstack_ptr; /* Points to the lowest empty field. The indexed */ /* field is NOT readable. */ - /* Prepare buffers and iterators */ - colbuf1 = AColourBuffer1; - colbuf2 = AColourBuffer2; - colbuf3 = AColourBuffer3; - + /* Prepare iterators */ ap = APixbufExt + (zBufferWidth * (y - Aminy)); apteller = (zBufferWidth * (y - Aminy)); /* Rendering: give the right colour to this pixel (shade it) */ - for( x = 0; x < bufferWidth; x++, ap++, colbuf1+=4, colbuf2+=4, colbuf3+=4) { + for( x = 0; x < R.rectx; x++, ap++, colbuf1+=4, colbuf2+=4, colbuf3+=4) { if(ap->t[0]) { /* reset sample collector */ j = sampcol; for(i = 0; i < osaNr; i++, j+=4) { - j[0] = RE_ZERO_COLOUR_FLOAT; j[1] = RE_ZERO_COLOUR_FLOAT; - j[2] = RE_ZERO_COLOUR_FLOAT; j[3] = RE_ZERO_COLOUR_FLOAT; + j[0] = 0.0f; j[1] = 0.0f; + j[2] = 0.0f; j[3] = 0.0f; }; /* a. count and sort number of faces */ @@ -877,10 +1004,10 @@ void renderZBufLine(int y) /* b,c. oversample all subpixels, then integrate */ RE_OSAstack_ptr = 0; - RE_OSAstack_ptr = composeStack(zrow, + RE_OSAstack_ptr = composeStack(zrow, collector, RE_OSAstack, RE_OSAstack_ptr, stackDepth, x, y, osaNr); - integratePerSubStack(RE_OSAstack, RE_OSAstack_ptr, + integratePerSubStack(sampcol, RE_OSAstack, RE_OSAstack_ptr, x, y, osaNr); /* d. Gamma corrected blending and Gaussian */ @@ -891,7 +1018,7 @@ void renderZBufLine(int y) /* This is a bit dirty. Depending on sky-mode, the pixel is */ /* blended in differently. */ - renderSkyPixelFloat(x, y); + renderSkyPixelFloat(collector, x, y); j = sampcol; for(i = 0; i < osaNr; i++, j+=4) { @@ -910,22 +1037,40 @@ void renderZBufLine(int y) addAlphaOverFloat(colbuf2+4, collector); } } - } /* End of pixel loop */ - -} /* End of void renderZBufLine(int y) */ - - -/* ------------------------------------------------------------------------- */ - -int fillZBufDistances() -{ - int keepLooping = 1; + } +} - keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/ - keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/ - return keepLooping; -} /* End of void fillZBufDistances() */ +/** + * Fills in distances of faces in the z buffer. + * + * Halo z buffering ---------------------------------------------- + * + * A halo is treated here as a billboard: no z-extension, always + * oriented perpendicular to the viewer. The rest of the z-buffer + * stores face-numbers first, then calculates colours as the + * final image is rendered. We'll use the same approach here, + * which differs from the original method (which was add halos per + * scan line). This means that the z-buffer now also needs to + * store info about what sort of 'thing' the index refers to. + * + * Halo extension: + * h.maxy --------- + * | h.xs + h.rad + * | h.xs + * | h.xs - h.rad + * h.miny --------- + * + * These coordinates must be clipped to picture size. + * I'm not quite certain about halo numbering. + * + * Halos and jittering ------------------------------------------- + * + * Halos were not jittered previously. Now they are. I wonder + * whether this may have some adverse effects here. + + * @return 1 for succes, 0 if the operation was interrupted. + */ /* ------------------------------------------------------------------------- */ /* Transparent faces and the 'Azvoordeel' */ @@ -940,10 +1085,11 @@ int fillZBufDistances() /* static int RE_treat_face_as_opaque; */ -int zBufferAllFaces(void) +static int zBufferAllFaces(void) { + VlakRen *vlr=NULL; + unsigned int zvlnr, faceCounter; int keepLooping = 1; - int faceCounter; /* counter for face number */ float vec[3], hoco[4], mul, zval, fval; Material *ma=0; @@ -955,18 +1101,18 @@ int zBufferAllFaces(void) /* RE_treat_face_as_opaque = 1; */ while ( (faceCounter < R.totvlak) && keepLooping) { - if((faceCounter & 255)==0) { Zvlr= R.blovl[faceCounter>>8]; } - else Zvlr++; + if((faceCounter & 255)==0) { vlr= R.blovl[faceCounter>>8]; } + else vlr++; - ma= Zvlr->mat; + ma= vlr->mat; /* VERY dangerous construction... zoffs is set by a slide in the ui */ /* so it should be safe... */ if((ma->mode & (MA_ZTRA)) && (ma->zoffs != 0.0)) { mul= 0x7FFFFFFF; - zval= mul*(1.0+Zvlr->v1->ho[2]/Zvlr->v1->ho[3]); + zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]); - VECCOPY(vec, Zvlr->v1->co); + VECCOPY(vec, vlr->v1->co); /* z is negatief, wordt anders geclipt */ vec[2]-= ma->zoffs; RE_projectverto(vec, hoco); /* vec onto hoco */ @@ -977,18 +1123,18 @@ int zBufferAllFaces(void) Azvoordeel= 0; } /* face number is used in the fill functions */ - Zvlnr = faceCounter + 1; + zvlnr = faceCounter + 1; - if(Zvlr->flag & R_VISIBLE) { /* might test for this sooner... */ + if(vlr->flag & R_VISIBLE) { /* might test for this sooner... */ - if(ma->mode & (MA_WIRE)) zbufclipwire(Zvlr); + if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); else { - zbufclip(Zvlr->v1->ho, Zvlr->v2->ho, Zvlr->v3->ho, - Zvlr->v1->clip, Zvlr->v2->clip, Zvlr->v3->clip); - if(Zvlr->v4) { - Zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ - zbufclip(Zvlr->v1->ho, Zvlr->v3->ho, Zvlr->v4->ho, - Zvlr->v1->clip, Zvlr->v3->clip, Zvlr->v4->clip); + zbufclip(zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, + vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + if(vlr->v4) { + zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ + zbufclip(zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, + vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } @@ -997,7 +1143,12 @@ int zBufferAllFaces(void) } return keepLooping; -} /* End of int zBufferAllFaces(void) */ +} + +/** + * Fills in distances of halos in the z buffer. + * @return 1 for succes, 0 if the operation was interrupted. + */ /* ------------------------------------------------------------------------- */ /* We cheat a little here: we only fill the halo on the first pass, and we */ @@ -1005,7 +1156,7 @@ int zBufferAllFaces(void) /* halos to be flat (billboards), so we do not have to correct the z range */ /* every time we insert a halo. Also, halos fall off to zero at the edges, */ /* so we can safely render them in pixels where they do not exist. */ -int zBufferAllHalos(void) +static int zBufferAllHalos(void) { HaloRen *har = NULL; unsigned int haloCounter = 0; @@ -1065,334 +1216,34 @@ int zBufferAllHalos(void) } return keepLooping; -} /* end of int zbufferAllHalos(void) */ - -/* ------------------------------------------------------------------------- */ -void zBufferFillHalo(void) -{ - /* so far, intentionally empty */ -} /* end of void zBufferFillHalo(void) */ - -/* ------------------------------------------------------------------------- */ -void zBufferFillFace(float *v1, float *v2, float *v3) -{ - /* Coordinates of the vertices are specified in ZCS */ - int apteller, apoffsetteller; - double z0; /* used as temp var*/ - double xx1; - double zxd,zyd,zy0, tmp; - float *minv,*maxv,*midv; - register int zverg,zvlak,x; - int my0,my2,sn1,sn2,rectx,zd; - int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask; - - /* These used to be doubles. We may want to change them back if the */ - /* loss of accuracy proves to be a problem? There does not seem to be */ - /* any performance issues here, so I'll just keep the doubles. */ - /* float vec0[3], vec1[3], vec2[3]; */ - double vec0[3], vec1[3], vec2[3]; - - /* MIN MAX */ - /* sort vertices for min mid max y value */ - if(v1[1]<v2[1]) { - if(v2[1]<v3[1]) { minv=v1; midv=v2; maxv=v3;} - else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2;} - else { minv=v3; midv=v1; maxv=v2;} - } - else { - if(v1[1]<v3[1]) { minv=v2; midv=v1; maxv=v3;} - else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1;} - else { minv=v3; midv=v2; maxv=v1;} - } - - if(minv[1] == maxv[1]) return; /* security to remove 'zero' size faces */ - - my0 = ceil(minv[1]); - my2 = floor(maxv[1]); - omsl = floor(midv[1]); - - /* outside the current z buffer slice: clip whole face */ - if( (my2 < Aminy) || (my0 > Amaxy)) return; - - if(my0<Aminy) my0= Aminy; - - /* EDGES : THE LONGEST */ - xx1= maxv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); - xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx0= 0; - xs0= 65536.0*(MIN2(minv[0],maxv[0])); - } - /* EDGES : THE TOP ONE */ - xx1= maxv[1]-midv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-midv[0])/xx1; - - tmp= (-65536.0*z0); - dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); - xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx1= 0; - xs1= 65536.0*(MIN2(midv[0],maxv[0])); - } - /* EDGES : THE BOTTOM ONE */ - xx1= midv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (midv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); - xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx2= 0; - xs2= 65536.0*(MIN2(minv[0],midv[0])); - } - - /* ZBUF DX DY */ - /* xyz_1 = v_1 - v_2 */ - MTC_diff3DFF(vec1, v1, v2); - /* xyz_2 = v_2 - v_3 */ - MTC_diff3DFF(vec2, v2, v3); - /* xyz_0 = xyz_1 cross xyz_2 */ - MTC_cross3Double(vec0, vec1, vec2); - - /* cross product of two of the sides is 0 => this face is too small */ - if(vec0[2]==0.0) return; - - if(midv[1] == maxv[1]) omsl= my2; - if(omsl < Aminy) omsl= Aminy-1; /* make sure it takes the first loop entirely */ - - while (my2 > Amaxy) { /* my2 can be larger */ - xs0+=dx0; - if (my2<=omsl) { - xs2+= dx2; - } - else{ - xs1+= dx1; - } - my2--; - } - - xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2]; - - zxd= -vec0[0]/vec0[2]; - zyd= -vec0[1]/vec0[2]; - zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); - - /* start-ofset in rect */ - /* rectx= R.rectx; */ - /* I suspect this var needs very careful setting... When edge rendering */ - /* is on, this is strange */ - rectx = zBufferWidth; - apoffsetteller = rectx*(my2-Aminy); - - mask= 1<<Zsample; - zvlak= Zvlnr; - - xs3= 0; /* flag */ - if(dx0>dx1) { - MTC_swapInt(&xs0, &xs1); - MTC_swapInt(&dx0, &dx1); - xs3= 1; /* flag */ - - } - - for(y=my2;y>omsl;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs1>>16; - xs1+= dx1; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - apteller = apoffsetteller + sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, zverg, mask); - zverg+= zd; - apteller++; - x--; - } - zy0-= zyd; - apoffsetteller -= rectx; - } - - if(xs3) { - xs0= xs1; - dx0= dx1; - } - if(xs0>xs2) { - xs3= xs0; - xs0= xs2; - xs2= xs3; - xs3= dx0; - dx0= dx2; - dx2= xs3; - } - - for(; y>=my0; y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs2>>16; - xs2+= dx2; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - apteller = apoffsetteller + sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, zverg, mask); - zverg+= zd; - apteller++; - x--; - } - - zy0-=zyd; - apoffsetteller -= rectx; - } -} /* end of void zBufferFillFace(float *v1, float *v2, float *v3) */ - +} /* ------------------------------------------------------------------------- */ -void zBufferFillEdge(float *vec1, float *vec2) +/** +* Fills in distances of all faces in a z buffer, for given jitter settings. + */ +static int fillZBufDistances() { - int apteller; - int start, end, x, y, oldx, oldy, ofs; - int dz, vergz, mask; - float dx, dy; - float v1[3], v2[3]; + int keepLooping = 1; - dx= vec2[0]-vec1[0]; - dy= vec2[1]-vec1[1]; + keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/ + keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/ + return keepLooping; - if(fabs(dx) > fabs(dy)) { +} - /* all lines from left to right */ - if(vec1[0]<vec2[0]) { - VECCOPY(v1, vec1); - VECCOPY(v2, vec2); - } - else { - VECCOPY(v2, vec1); - VECCOPY(v1, vec2); - dx= -dx; dy= -dy; - } - start= floor(v1[0]); - end= start+floor(dx); - if(end >= zBufferWidth) end = zBufferWidth - 1; - - oldy= floor(v1[1]); - dy/= dx; - - vergz= v1[2]; - vergz-= Azvoordeel; - dz= (v2[2]-v1[2])/dx; - - apteller = zBufferWidth*(oldy-Aminy) +start; - mask = 1<<Zsample; - - if(dy<0) ofs= -zBufferWidth; - else ofs= zBufferWidth; - - for(x= start; x<=end; x++, /* ap++, */ apteller++) { - - y= floor(v1[1]); - if(y!=oldy) { - oldy= y; - apteller += ofs; - } - - if(x>=0 && y>=Aminy && y<=Amaxy) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, vergz, mask); - } - - v1[1]+= dy; - vergz+= dz; - } - } - else { - - /* all lines from top to bottom */ - if(vec1[1]<vec2[1]) { - VECCOPY(v1, vec1); - VECCOPY(v2, vec2); - } - else { - VECCOPY(v2, vec1); - VECCOPY(v1, vec2); - dx= -dx; dy= -dy; - } - start= floor(v1[1]); - end= start+floor(dy); - - if(start>Amaxy || end<Aminy) return; - - if(end>Amaxy) end= Amaxy; - - oldx= floor(v1[0]); - dx/= dy; - - vergz= v1[2]; - vergz-= Azvoordeel; - dz= (v2[2]-v1[2])/dy; - - apteller = zBufferWidth*(start-Aminy) +oldx; - - mask= 1<<Zsample; - - if(dx<0) ofs= -1; - else ofs= 1; - for(y= start; y<=end; y++, apteller += zBufferWidth) { - - x= floor(v1[0]); - if(x!=oldx) { - oldx= x; - apteller += ofs; - } - - if(x>=0 && y>=Aminy && (x < zBufferWidth)) { - insertObject(apteller, /* RE_treat_face_as_opaque, */ Zvlnr, RE_POLY, vergz, mask); - } - - v1[0]+= dx; - vergz+= dz; - } - } -} /* End of void zBufferFillEdge(float *vec1, float *vec2) */ +/* ------------------------------------------------------------------------- */ +/** + * One more filler: fill in halo data in z buffer. + * Empty so far, but may receive content of halo loop. + */ +void zBufferFillHalo(void) +{ + /* so far, intentionally empty */ +} /* ------------------------------------------------------------------------- */ @@ -1401,11 +1252,12 @@ void zBufferFillEdge(float *vec1, float *vec2) /* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd. */ /* This is the standard transformation, more elaborate tools are for later. */ /* ------------------------------------------------------------------------- */ -void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) +void std_floatcol_to_charcol( float *buf, char *target) { - float fval; - float dither_value; + float col[3]; + float dither_value; + dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0; /* alpha */ @@ -1415,23 +1267,11 @@ void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) if(R.r.postgamma==1.0) { /* r */ - fval= R.r.postmul*buf[0] + R.r.postadd + dither_value; - if(fval<=0.0) target[0]= 0; - else if(fval>1.0) target[0]= 255; - else target[0]= 255.0*fval; - + col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value; /* g */ - fval= R.r.postmul*buf[1] + R.r.postadd + dither_value; - if(fval<=0.0) target[1]= 0; - else if(fval>1.0) target[1]= 255; - else target[1]= 255.0*fval; - + col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value; /* b */ - fval= R.r.postmul*buf[2] + R.r.postadd + dither_value; - if(fval<=0.0) target[2]= 0; - else if(fval>1.0) target[2]= 255; - else target[2]= 255.0*fval; - + col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value; } else { /* putting the postmul within the pow() gives an @@ -1439,28 +1279,37 @@ void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) * are relevant then */ - /* r */ - fval= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value; - if(fval<=0.0) target[0]= 0; - else if(fval>1.0) target[0]= 255; - else target[0]= 255.0*fval; - + col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value; /* g */ - fval=pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value; - if(fval<=0.0) target[1]= 0; - else if(fval>1.0) target[1]= 255; - else target[1]= 255.0*fval; - + col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value; /* b */ - fval= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value; - if(fval<=0.0) target[2]= 0; - else if(fval>1.0) target[2]= 255; - else target[2]= 255.0*fval; + col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value; } -} /* end of void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, uchar *target) */ + if(R.r.posthue!=0.0 || R.r.postsat!=1.0) { + float hsv[3]; + + rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2); + hsv[0]+= R.r.posthue; + if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; + hsv[1]*= R.r.postsat; + if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; + hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); + } + + if(col[0]<=0.0) target[0]= 0; + else if(col[0]>1.0) target[0]= 255; + else target[0]= 255.0*col[0]; + + if(col[1]<=0.0) target[1]= 0; + else if(col[1]>1.0) target[1]= 255; + else target[1]= 255.0*col[1]; + if(col[2]<=0.0) target[2]= 0; + else if(col[2]>1.0) target[2]= 255; + else target[2]= 255.0*col[2]; +} /* ---------------------------------------------------------------------------- @@ -1485,26 +1334,26 @@ void std_transFloatColV2CharColV( RE_COLBUFTYPE *buf, char *target) without setting Osa or Gamme flags off (ton) ---------------------------------------------------------------------------- */ -void transferColourBufferToOutput(int y) +/* used external! */ +void transferColourBufferToOutput( float *buf, int y) { /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */ int x = 0; - RE_COLBUFTYPE *buf = AColourBuffer3+4; - char *target = (char*) (R.rectot + (y * imageWidth)); + char *target = (char*) (R.rectot + (y * R.rectx)); - /* Copy the first <imageWidth> pixels. We can do some more clipping on */ + /* Copy the first <R.rectx> pixels. We can do some more clipping on */ /* the z buffer, I think. */ - while (x < imageWidth) { + while (x < R.rectx) { /* invert gamma corrected additions */ - if(osaNr!=1 && doGamma()) { + if(do_gamma) { buf[0] = invGammaCorrect(buf[0]); buf[1] = invGammaCorrect(buf[1]); buf[2] = invGammaCorrect(buf[2]); } - std_transFloatColV2CharColV(buf, target); + std_floatcol_to_charcol(buf, target); /* Key-alpha mode: @@ -1522,118 +1371,225 @@ void transferColourBufferToOutput(int y) buf+=4; x++; } -} /* end of void transferColourBufferToOutput(int y) */ +} + +/* used for redisplay after render. assumes size globals to be set OK! */ +void RE_floatbuffer_to_output(void) +{ + float *buf= R.rectftot; + int pix= R.rectx*R.recty; + char *target = (char *)R.rectot; + + if(R.rectftot==NULL) return; + + while(pix--) { + std_floatcol_to_charcol(buf, target); + buf+= 4; + target+= 4; + } +} /* ------------------------------------------------------------------------- */ -void eraseColBuf(RE_COLBUFTYPE *buf) +static void eraseColBuf(RE_COLBUFTYPE *buf) { /* By definition, the buffer's length is 4 * R.rectx items */ int i = 0; - while (i < 4 * (bufferWidth+3)) { - *buf = RE_ZERO_COLOUR_FLOAT; + while (i < 4 * (R.rectx+3)) { + *buf = 0.0f; buf++; i++; } -} /* End of void eraseColBuf(RE_COLBUFTYPE *buf) */ +} /* ------------------------------------------------------------------------- */ -int calcDepth(float x, float y, void *data, int type) + +/** + * Fill the accumulation buffer APixbufExt with face and halo indices. + * Note: Uses globals. + * @param y the line number to set + */ +static void calcZBufLine(int y) { - float view[3]; + /* These function pointers are used for z buffer filling. */ + extern void (*zbuffunc)(unsigned int, float *, float *, float *); + extern void (*zbuflinefunc)(unsigned int, float *, float *); + int part; + int keepLooping = 1; - if (type & RE_POLY) { - VlakRen* vlr = (VlakRen*) data; - VertRen* v1; - float dvlak, deler, fac, hoco_z, hoco_w; - int zbuf_co; - - v1 = vlr->v1; - - /* vertex dot face normal: WCS */ - dvlak= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; - - /* jitter has been added to x, y ! */ - /* view vector view: screen coords */ - view[0]= (x+(R.xstart)+0.5); - - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor; - else view[1]= (y + R.ystart + 1.0)*R.ycor; - } - else view[1]= (y + R.ystart + 0.5)*R.ycor; + if(y<0) return; + + /* zbuffer fix: here? */ + Zmulx= ((float) R.rectx)/2.0; + Zmuly= ((float) R.recty)/2.0; + + + /* use these buffer fill functions */ + zbuffunc = zBufferFillFace; + zbuflinefunc = zBufferFillEdge; + + /* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */ + if( (y < Aminy) || (y > Amaxy)) { + /* prepare buffer */ + part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */ + Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */ + Amaxy = Aminy + RE_ZBUFLEN - 1; + /* if(Amaxy >= R.recty) Amaxy = R.recty-1; */ + if(Amaxy >= R.recty) Amaxy = R.recty - 1; + resetZbuffer(); + Zsample = 0; /* Zsample is used internally ! */ + while ( (Zsample < osaNr) && keepLooping ) { + /* Apply jitter to this pixel. The jitter offsets are globals. */ + /* They are added in zbufclip() */ + /* Negative: these offsets are added to the vertex coordinates */ + /* so it equals translating viewpoint over the positive vector. */ + Zjitx= -jit[Zsample][0]-0.5; + Zjity= -jit[Zsample][1]-0.5; + + keepLooping = fillZBufDistances(); + + if(RE_local_test_break()) keepLooping = 0; + Zsample++; + } + }; + +} - /* for pano, another rotation in the xz plane is needed.... */ - /* this is ok, in WCS */ - view[2]= -R.viewfac; /* distance to viewplane */ - - /* face normal dot view vector: but how can this work? */ - deler = MTC_dot3Float(vlr->n, view); - if (deler!=0.0) fac = dvlak/deler; - else fac = 0.0; - - /* indices are wrong.... but gives almost the right value? */ - hoco_z = (fac*view[2]) * R.winmat[2][2] + R.winmat[3][2]; - hoco_w = (fac*view[2]) * R.winmat[2][3] + R.winmat[3][3]; - - if(hoco_w!=0.0) zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w); - else zbuf_co= 0x7FFFFFFF; - - return zbuf_co; /* z component of R.co */ - } else if (type & RE_HALO) { - HaloRen* har = (HaloRen*) data; - return har->zBufDist; - } - return 0; -} /* end of int calcDepth(float x, float y, void* data, int type) */ +/* ------------------------------------------------------------------------- */ -/* Maybe these two should be in pixelblendeing.c---------------------------- */ +struct renderline { + RE_COLBUFTYPE *buf1, *buf2, *buf3; + int y; +}; -void blendOverFloat(int type, float* dest, float* source, void* data) +static int do_renderline(void *poin) { + struct renderline *rl= poin; + + renderZBufLine(rl->y, rl->buf1, rl->buf2, rl->buf3); + return 1; +} - if (type & RE_POLY) { - VlakRen *ver = (VlakRen*) data; - if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) { - char addf = (char) (ver->mat->add * 255.0); - addalphaAddfacFloat(dest, source, addf); - } - else - addAlphaOverFloat(dest, source); - } else if (type & RE_HALO) { - HaloRen *har= (HaloRen*) data; - addalphaAddfacFloat(dest, source, har->add); - } else if (type & RE_SKY) { - addAlphaOverFloat(dest, source); +void zBufShadeAdvanced() +{ + RE_COLBUFTYPE *cycle; + struct renderline rl1, rl2; + int y, keepLooping = 1; + float xjit = 0.0, yjit = 0.0; + + Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */ + + /* Set osaNr. Treat 'no osa' as 'osa = 1' */ + if(R.r.mode & R_OSA) { + osaNr = R.osa; + if(osaNr > 16) { /* check was moved from calcZBufLine */ + printf("zBufShadeAdvanced> osa too large (internal error)\n"); + G.afbreek= 1; + return; + } + } else { + /* little hack */ + osaNr = 1; + xjit = jit[0][0]; + yjit = jit[0][1]; + jit[0][0] = 0.0; + jit[0][1] = 0.0; + } + + RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix */ + + initRenderBuffers(R.rectx); + + y = 0; + while ( (y < R.recty) && keepLooping) { + + calcZBufLine(y); + + rl1.buf1= AColourBuffer1; + rl1.buf2= AColourBuffer2; + rl1.buf3= AColourBuffer3; + rl1.y= y; + + if(R.r.mode & R_THREADS) { + if((y & 1)==0) { + SDL_Thread *thread; + + thread = SDL_CreateThread(do_renderline, &rl1); + if ( thread == NULL ) { + fprintf(stderr, "Unable to create thread"); + G.afbreek= 1; + break; + } + + rl2.buf1= AColourBuffer0; + rl2.buf2= AColourBuffer1a; + rl2.buf3= AColourBuffer2a; + rl2.y= y+1; + + do_renderline(&rl2); + + SDL_WaitThread(thread, NULL); + + if(R.r.mode & R_GAUSS) { + float *rb1= AColourBuffer1, *rb2= AColourBuffer2, *rb1a= AColourBuffer1a, *rb2a= AColourBuffer2a; + int a= 4*(R.rectx + 4); + while(a--) { + *rb1 += *rb1a; + *rb2 += *rb2a; + *(rb1a++)= 0.0; rb1++; + *(rb2a++)= 0.0; rb2++; + } + } + else { + cycle= AColourBuffer1a; AColourBuffer1a= AColourBuffer1; AColourBuffer1= cycle; + } + } + } + else do_renderline(&rl1); + + if(y) { + transferColourBufferToOutput(AColourBuffer3+4, y-1); + + if((y & 1)==0) RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot); + } + + /* buffer cycling */ + eraseColBuf(AColourBuffer3); + cycle= AColourBuffer3; + AColourBuffer3= AColourBuffer2; + AColourBuffer2= AColourBuffer1; + AColourBuffer1= AColourBuffer0; + AColourBuffer0= cycle; + + if(RE_local_test_break()) keepLooping = 0; + y++; } + if(keepLooping) transferColourBufferToOutput(AColourBuffer3+4, y-1); -} /* end of void blendOverFloat(int , float*, float*, void*) */ + freeRenderBuffers(); -/* ------------------------------------------------------------------------- */ -void blendOverFloatRow(int type, float* dest, float* source, - void* data, int mask, int osaNr) -{ - - if (type & RE_POLY) { - VlakRen *ver = (VlakRen*) data; - if ((ver->mat != NULL) - && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) { - char addf = (ver->mat->add * 255.0); - addAddSampColF(dest, source, mask, osaNr, addf); - } else { - addOverSampColF(dest, source, mask, osaNr); - } - } else if (type & RE_HALO) { - HaloRen *har = (HaloRen*) data; - addAddSampColF(dest, source, mask, osaNr, har->add); - } else if (type & RE_SKY) { - addOverSampColF(dest, source, mask, osaNr); + /* Edge rendering is done purely as a post-effect */ + if(R.r.mode & R_EDGE) { + addEdges((char*)R.rectot, R.rectx, R.recty, + osaNr, + R.r.edgeint, R.r.same_mat_redux, + G.compat, G.notonlysolid, + R.r.edgeR, R.r.edgeG, R.r.edgeB); + } + + if (!(R.r.mode & R_OSA)) { + jit[0][0] = xjit; + jit[0][1] = yjit; } -} /* end of void blendOverFloatRow(int, float*, float*, void*) */ + +} /* ------------------------------------------------------------------------- */ + + + /* eof vanillaRenderPipe.c */ diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 145e9409c18..4da409a58c4 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -41,44 +41,35 @@ #include "MTC_matrixops.h" #include "MEM_guardedalloc.h" -#include "BKE_global.h" - #include "DNA_lamp_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_global.h" +#include "BKE_utildefines.h" + #include "radio_types.h" #include "radio.h" /* needs RG, some root data for radiosity */ +#include "SDL_thread.h" + #include "render.h" -#include "render_intern.h" #include "RE_callbacks.h" -#include "old_zbuffer_types.h" + /* local includes */ -/* can be removed when the old renderer disappears */ #include "rendercore.h" /* shade_pixel and count_mask */ #include "pixelblending.h" #include "jitter.h" /* own includes */ #include "zbuf.h" -#include "zbuf_int.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -/* crud */ -#define MIN2(x,y) ( (x)<(y) ? (x) : (y) ) /*-----------------------------------------------------------*/ /* Globals for this file */ +/* main reason for globals; unified zbuffunc() with simple args */ /*-----------------------------------------------------------*/ -extern float centLut[16]; -extern char *centmask; - -float *vlzp[32][3], labda[3][2], vez[400], *p[40]; - float Zmulx; /* Half the screenwidth, in pixels. (used in render.c, */ /* zbuf.c) */ float Zmuly; /* Half the screenheight, in pixels. (used in render.c,*/ @@ -88,13 +79,11 @@ float Zjitx; /* Jitter offset in x. When jitter is disabled, this */ float Zjity; /* Jitter offset in y. When jitter is disabled, this */ /* should be 0.5. (used in render.c, zbuf.c) */ -unsigned int Zvlnr, Zsample; -VlakRen *Zvlr; -void (*zbuffunc)(float *, float *, float *); -void (*zbuflinefunc)(float *, float *); +unsigned int Zsample; +void (*zbuffunc)(unsigned int, float *, float *, float *); +void (*zbuflinefunc)(unsigned int, float *, float *); APixstr *APixbuf; /* Zbuffer: linked list of face indices */ -unsigned short *Acolrow; /* Zbuffer: colour buffer, one line high */ int *Arectz; /* Zbuffer: distance buffer, almost obsolete */ int Aminy; /* y value of first line in the accu buffer */ int Amaxy; /* y value of last line in the accu buffer */ @@ -119,6 +108,63 @@ void fillrect(unsigned int *rect, int x, unsigned int y, unsigned int val) } } +/** +* Tests whether this coordinate is 'inside' or 'outside' of the view + * volume? By definition, this is in [0, 1]. + * @param p vertex z difference plus coordinate difference? + * @param q origin z plus r minus some coordinate? + * @param u1 [in/out] clip fraction for ? + * @param u2 [in/out] + * @return 0 if point is outside, or 1 if the point lies on the clip + * boundary + */ +static short cliptestf(float p, float q, float *u1, float *u2) +{ + float r; + + if(p<0.0) { + if(q<p) return 0; + else if(q<0.0) { + r= q/p; + if(r>*u2) return 0; + else if(r>*u1) *u1=r; + } + } + else { + if(p>0.0) { + if(q<0.0) return 0; + else if(q<p) { + r= q/p; + if(r<*u1) return 0; + else if(r<*u2) *u2=r; + } + } + else if(q<0.0) return 0; + } + return 1; +} + +int RE_testclip(float *v) +{ + float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/ + short c=0; + + abs4= fabs(v[3]); + + if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */ + else if(v[2]> abs4) c+= 32; + + if( v[0]>abs4) c+=2; + else if( v[0]< -abs4) c+=1; + + if( v[1]>abs4) c+=4; + else if( v[1]< -abs4) c+=8; + + return c; +} + + + /* ************* ACCUMULATION ZBUF ************ */ /*-APixstr---------------------(antialised pixel struct)------------------------------*/ @@ -176,8 +222,17 @@ APixstr *addpsA(void) return prev; } -/* fills in color, with window coordinate, from Aminy->Amaxy */ -void zbufinvulAc(float *v1, float *v2, float *v3) +/** + * Fill the z buffer for accumulation (transparency) + * + * This is one of the z buffer fill functions called in zbufclip() and + * zbufwireclip(). + * + * @param v1 [4 floats, world coordinates] first vertex + * @param v2 [4 floats, world coordinates] second vertex + * @param v3 [4 floats, world coordinates] third vertex + */ +void zbufinvulAc(unsigned int zvlnr, float *v1, float *v2, float *v3) { APixstr *ap, *apofs, *apn; double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; @@ -341,14 +396,14 @@ void zbufinvulAc(float *v1, float *v2, float *v3) if(zverg< *rz) { apn= ap; while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } - if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } - if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } - if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } - if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; } + if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } + if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } + if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } + if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } + if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } + if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } + if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } + if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } if(apn->next==0) apn->next= addpsA(); apn= apn->next; } @@ -399,14 +454,14 @@ void zbufinvulAc(float *v1, float *v2, float *v3) if(zverg< *rz) { apn= ap; while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } - if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } - if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } - if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } - if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; } + if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } + if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } + if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } + if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } + if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } + if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } + if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } + if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } if(apn->next==0) apn->next= addpsA(); apn= apn->next; } @@ -423,7 +478,7 @@ void zbufinvulAc(float *v1, float *v2, float *v3) } } -void zbuflineAc(float *vec1, float *vec2) +void zbuflineAc(unsigned int zvlnr, float *vec1, float *vec2) { APixstr *ap, *apn; unsigned int *rectz; @@ -480,14 +535,14 @@ void zbuflineAc(float *vec1, float *vec2) apn= ap; while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } - if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } - if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } - if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } - if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; } + if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } + if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } + if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } + if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } + if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } + if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } + if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } + if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } if(apn->next==0) apn->next= addpsA(); apn= apn->next; } @@ -547,14 +602,14 @@ void zbuflineAc(float *vec1, float *vec2) apn= ap; while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= Zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } - if(apn->p[0]==Zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= Zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } - if(apn->p[1]==Zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= Zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } - if(apn->p[2]==Zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= Zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } - if(apn->p[3]==Zvlnr) {apn->mask[3]|= mask; break; } + if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= vergz; apn->mask[0]= mask; break; } + if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } + if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= vergz; apn->mask[1]= mask; break; } + if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } + if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= vergz; apn->mask[2]= mask; break; } + if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } + if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } + if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } if(apn->next==0) apn->next= addpsA(); apn= apn->next; } @@ -572,7 +627,16 @@ void zbuflineAc(float *vec1, float *vec2) /* ************* NORMAL ZBUFFER ************ */ -void hoco_to_zco(float *zco, float *hoco) +/** + * Convert a homogenous coordinate to a z buffer coordinate. The + * function makes use of Zmulx, Zmuly, the x and y scale factors for + * the screen, and Zjitx, Zjity, the pixel offset. (These are declared + * in render.c) The normalised z coordinate must fall on [0, 1]. + * @param zco [3, 4 floats] pointer to the resulting z buffer coordinate + * @param hoco [4 floats] pointer to the homogenous coordinate of the + * vertex in world space. + */ +static void hoco_to_zco(float *zco, float *hoco) { float deler; @@ -582,8 +646,7 @@ void hoco_to_zco(float *zco, float *hoco) zco[2]= 0x7FFFFFFF *(hoco[2]/deler); } -void zbufline(vec1, vec2) -float *vec1, *vec2; +void zbufline(unsigned int zvlnr, float *vec1, float *vec2) { unsigned int *rectz, *rectp; int start, end, x, y, oldx, oldy, ofs; @@ -635,7 +698,7 @@ float *vec1, *vec2; if(x>=0 && y>=0 && y<R.recty) { if(vergz<*rectz) { *rectz= vergz; - *rectp= Zvlnr; + *rectp= zvlnr; } } @@ -684,7 +747,7 @@ float *vec1, *vec2; if(x>=0 && y>=0 && x<R.rectx) { if(vergz<*rectz) { *rectz= vergz; - *rectp= Zvlnr; + *rectp= zvlnr; } } @@ -694,10 +757,60 @@ float *vec1, *vec2; } } +static int clipline(float *v1, float *v2) /* return 0: do not draw */ +{ + float dz,dw, u1=0.0, u2=1.0; + float dx, dy, v13; + + dz= v2[2]-v1[2]; + dw= v2[3]-v1[3]; + + /* this 1.01 is for clipping x and y just a tinsy larger. that way it is + filled in with zbufwire correctly when rendering in parts. otherwise + you see line endings at edges... */ + + if(cliptestf(-dz-dw, v1[3]+v1[2], &u1,&u2)) { + if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) { + + dx= v2[0]-v1[0]; + dz= 1.01*(v2[3]-v1[3]); + v13= 1.01*v1[3]; + + if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) { + if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) { + + dy= v2[1]-v1[1]; + + if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) { + if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) { + + if(u2<1.0) { + v2[0]= v1[0]+u2*dx; + v2[1]= v1[1]+u2*dy; + v2[2]= v1[2]+u2*dz; + v2[3]= v1[3]+u2*dw; + } + if(u1>0.0) { + v1[0]= v1[0]+u1*dx; + v1[1]= v1[1]+u1*dy; + v1[2]= v1[2]+u1*dz; + v1[3]= v1[3]+u1*dw; + } + return 1; + } + } + } + } + } + } + + return 0; +} + -void zbufclipwire(VlakRen *vlr) +void zbufclipwire(unsigned int zvlnr, VlakRen *vlr) { - float *f1, *f2, *f3, *f4= 0, deler; + float vez[20], *f1, *f2, *f3, *f4= 0, deler; int c1, c2, c3, c4, ec, and, or; /* edgecode: 1= draw */ @@ -735,7 +848,7 @@ void zbufclipwire(VlakRen *vlr) if( clipline(vez, vez+4)) { hoco_to_zco(vez, vez); hoco_to_zco(vez+4, vez+4); - zbuflinefunc(vez, vez+4); + zbuflinefunc(zvlnr, vez, vez+4); } } if(ec & ME_V2V3) { @@ -744,7 +857,7 @@ void zbufclipwire(VlakRen *vlr) if( clipline(vez, vez+4)) { hoco_to_zco(vez, vez); hoco_to_zco(vez+4, vez+4); - zbuflinefunc(vez, vez+4); + zbuflinefunc(zvlnr, vez, vez+4); } } if(vlr->v4) { @@ -754,7 +867,7 @@ void zbufclipwire(VlakRen *vlr) if( clipline(vez, vez+4)) { hoco_to_zco(vez, vez); hoco_to_zco(vez+4, vez+4); - zbuflinefunc(vez, vez+4); + zbuflinefunc(zvlnr, vez, vez+4); } } if(ec & ME_V4V1) { @@ -763,7 +876,7 @@ void zbufclipwire(VlakRen *vlr) if( clipline(vez, vez+4)) { hoco_to_zco(vez, vez); hoco_to_zco(vez+4, vez+4); - zbuflinefunc(vez, vez+4); + zbuflinefunc(zvlnr, vez, vez+4); } } } @@ -774,7 +887,7 @@ void zbufclipwire(VlakRen *vlr) if( clipline(vez, vez+4)) { hoco_to_zco(vez, vez); hoco_to_zco(vez+4, vez+4); - zbuflinefunc(vez, vez+4); + zbuflinefunc(zvlnr, vez, vez+4); } } } @@ -804,24 +917,30 @@ void zbufclipwire(VlakRen *vlr) vez[13]= Zmuly*(1.0+f4[1]/deler)+ Zjity; vez[14]= 0x7FFFFFFF *(f4[2]/deler); - if(ec & ME_V3V4) zbuflinefunc(vez+8, vez+12); - if(ec & ME_V4V1) zbuflinefunc(vez+12, vez); + if(ec & ME_V3V4) zbuflinefunc(zvlnr, vez+8, vez+12); + if(ec & ME_V4V1) zbuflinefunc(zvlnr, vez+12, vez); } else { - if(ec & ME_V3V1) zbuflinefunc(vez+8, vez); + if(ec & ME_V3V1) zbuflinefunc(zvlnr, vez+8, vez); } - if(ec & ME_V1V2) zbuflinefunc(vez, vez+4); - if(ec & ME_V2V3) zbuflinefunc(vez+4, vez+8); - - + if(ec & ME_V1V2) zbuflinefunc(zvlnr, vez, vez+4); + if(ec & ME_V2V3) zbuflinefunc(zvlnr, vez+4, vez+8); } -void zbufinvulGLinv(v1,v2,v3) -float *v1,*v2,*v3; -/* fills in R.rectot the value of Zvlnr using R.rectz */ -/* INVERSE Z COMPARISION: BACKSIDE GETS VISIBLE */ +/** + * Fill the z buffer, but invert z order, and add the face index to + * the corresponing face buffer. + * + * This is one of the z buffer fill functions called in zbufclip() and + * zbufwireclip(). + * + * @param v1 [4 floats, world coordinates] first vertex + * @param v2 [4 floats, world coordinates] second vertex + * @param v3 [4 floats, world coordinates] third vertex + */ +static void zbufinvulGLinv(unsigned int zvlnr, float *v1, float *v2, float *v3) { double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; double zxd,zyd,zy0,tmp; @@ -947,7 +1066,7 @@ float *v1,*v2,*v3; rectx= R.rectx; rectzofs= (int *)(R.rectz+rectx*my2); rectpofs= (R.rectot+rectx*my2); - zvlak= Zvlnr; + zvlak= zvlnr; xs3= 0; /* flag */ if(dx0>dx1) { @@ -1038,7 +1157,20 @@ float *v1,*v2,*v3; } } -void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the value Zvlnr using R.rectz */ +/** +* Fill the z buffer, and add the face index to + * the corresponing face buffer. Writes into R.rectz and R.rectot. It + * assumes that zvlnr is set to the face index of the face under + * consideration. zvlnr is written into R.rectot. R.rectz + * + * This is one of the z buffer fill functions called in zbufclip() and + * zbufwireclip(). + * + * @param v1 [4 floats, world coordinates] first vertex + * @param v2 [4 floats, world coordinates] second vertex + * @param v3 [4 floats, world coordinates] third vertex + */ +static void zbufinvulGL(unsigned int zvlnr, float *v1, float *v2, float *v3) { double x0,y0,z0; double x1,y1,z1,x2,y2,z2,xx1; @@ -1155,7 +1287,7 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu rectx= R.rectx; rectzofs= (int *)(R.rectz+rectx*my2); rectpofs= (R.rectot+rectx*my2); - zvlak= Zvlnr; + zvlak= zvlnr; xs3= 0; /* flag */ if(dx0>dx1) { @@ -1248,8 +1380,18 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu } } +/** + * Fill the z buffer. The face buffer is not operated on! + * + * This is one of the z buffer fill functions called in zbufclip() and + * zbufwireclip(). + * + * @param v1 [4 floats, world coordinates] first vertex + * @param v2 [4 floats, world coordinates] second vertex + * @param v3 [4 floats, world coordinates] third vertex + */ -void zbufinvulGL_onlyZ(float *v1, float *v2, float *v3) /* only fills in R.rectz */ +static void zbufinvulGL_onlyZ(unsigned int zvlnr, float *v1, float *v2, float *v3) { double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; double zxd,zyd,zy0,tmp; @@ -1469,65 +1611,27 @@ void zbufinvulGL_onlyZ(float *v1, float *v2, float *v3) /* only fills in R.rec } } -void print3floats(float *v1, float *v2, float *v3) -{ - printf("1 %f %f %f %f\n", v1[0], v1[1], v1[2], v1[3]); - printf("2 %f %f %f %f\n", v2[0], v2[1], v2[2], v2[3]); - printf("3 %f %f %f %f\n", v3[0], v3[1], v3[2], v3[3]); -} - -static short cliptestf(float p, float q, float *u1, float *u2) -{ - float r; - - if(p<0.0) { - if(q<p) return 0; - else if(q<0.0) { - r= q/p; - if(r>*u2) return 0; - else if(r>*u1) *u1=r; - } - } - else { - if(p>0.0) { - if(q<0.0) return 0; - else if(q<p) { - r= q/p; - if(r<*u1) return 0; - else if(r<*u2) *u2=r; - } - } - else if(q<0.0) return 0; - } - return 1; -} - -int RE_testclip(float *v) -{ - float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/ - short c=0; - - abs4= fabs(v[3]); - - if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */ - else if(v[2]> abs4) c+= 32; - - if( v[0]>abs4) c+=2; - else if( v[0]< -abs4) c+=1; - - if( v[1]>abs4) c+=4; - else if( v[1]< -abs4) c+=8; - - return c; -} +/** + * (clip pyramid) + * Sets labda: flag, and parametrize the clipping of vertices in + * viewspace coordinates. labda = -1 means no clipping, labda in [0, + * 1] means a clipping. + * Note: uses globals. + * @param v1 start coordinate s + * @param v2 target coordinate t + * @param b1 + * @param b2 + * @param b3 + * @param a index for coordinate (x, y, or z) + */ -static void clipp(float *v1, float *v2, int b1, int *b2, int *b3, int a) +static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a) { float da,db,u1=0.0,u2=1.0; - labda[b1][0]= -1.0; - labda[b1][1]= -1.0; + labda[0]= -1.0; + labda[1]= -1.0; da= v2[a]-v1[a]; db= v2[3]-v1[3]; @@ -1543,92 +1647,58 @@ static void clipp(float *v1, float *v2, int b1, int *b2, int *b3, int a) if(cliptestf(da-db, v1[3]-v1[a], &u1,&u2)) { *b3=1; if(u2<1.0) { - labda[b1][1]= u2; + labda[1]= u2; *b2=1; } - else labda[b1][1]=1.0; /* u2 */ + else labda[1]=1.0; /* u2 */ if(u1>0.0) { - labda[b1][0]= u1; + labda[0]= u1; *b2=1; - } else labda[b1][0]=0.0; + } else labda[0]=0.0; } } } -static int clipline(float *v1, float *v2) /* return 0: do not draw */ -{ - float dz,dw, u1=0.0, u2=1.0; - float dx, dy, v13; - - dz= v2[2]-v1[2]; - dw= v2[3]-v1[3]; - - /* this 1.01 is for clipping x and y just a tinsy larger. that way it is - filled in with zbufwire correctly when rendering in parts. otherwise - you see line endings at edges... */ - - if(cliptestf(-dz-dw, v1[3]+v1[2], &u1,&u2)) { - if(cliptestf(dz-dw, v1[3]-v1[2], &u1,&u2)) { - - dx= v2[0]-v1[0]; - dz= 1.01*(v2[3]-v1[3]); - v13= 1.01*v1[3]; - - if(cliptestf(-dx-dz, v1[0]+v13, &u1,&u2)) { - if(cliptestf(dx-dz, v13-v1[0], &u1,&u2)) { - - dy= v2[1]-v1[1]; - - if(cliptestf(-dy-dz, v1[1]+v13, &u1,&u2)) { - if(cliptestf(dy-dz, v13-v1[1], &u1,&u2)) { - - if(u2<1.0) { - v2[0]= v1[0]+u2*dx; - v2[1]= v1[1]+u2*dy; - v2[2]= v1[2]+u2*dz; - v2[3]= v1[3]+u2*dw; - } - if(u1>0.0) { - v1[0]= v1[0]+u1*dx; - v1[1]= v1[1]+u1*dy; - v1[2]= v1[2]+u1*dz; - v1[3]= v1[3]+u1*dw; - } - return 1; - } - } - } - } - } - } - - return 0; -} - +/** + * (make vertex pyramide clip) + * Checks labda and uses this to make decision about clipping the line + * segment from v1 to v2. labda is the factor by which the vector is + * cut. ( calculate s + l * ( t - s )). The result is appended to the + * vertex list of this face. + * + * + * @param v1 start coordinate s + * @param v2 target coordinate t + * @param b1 + * @param b2 + * @param clve vertex vector. + */ -static void maakvertpira(float *v1, float *v2, int *b1, int b2, int *clve) +static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve) { - float l1,l2,*adr; + float l1, l2, *adr; - l1= labda[b2][0]; - l2= labda[b2][1]; + l1= labda[0]; + l2= labda[1]; if(l1!= -1.0) { if(l1!= 0.0) { adr= vez+4*(*clve); - p[*b1]=adr; + trias[*b1]=adr; (*clve)++; adr[0]= v1[0]+l1*(v2[0]-v1[0]); adr[1]= v1[1]+l1*(v2[1]-v1[1]); adr[2]= v1[2]+l1*(v2[2]-v1[2]); adr[3]= v1[3]+l1*(v2[3]-v1[3]); - } else p[*b1]= v1; + } + else trias[*b1]= v1; + (*b1)++; } if(l2!= -1.0) { if(l2!= 1.0) { adr= vez+4*(*clve); - p[*b1]=adr; + trias[*b1]=adr; (*clve)++; adr[0]= v1[0]+l2*(v2[0]-v1[0]); adr[1]= v1[1]+l2*(v2[1]-v1[1]); @@ -1672,10 +1742,13 @@ void projectvert(float *v1, float *adr) adr[3]= x*R.winmat[0][3]+ y*R.winmat[1][3]+ z*R.winmat[2][3]+ R.winmat[3][3]; } +/* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */ -void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) +void zbufclip(unsigned int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) { float deler; + float *vlzp[32][3], labda[3][2]; + float vez[400], *trias[40]; if(c1 | c2 | c3) { /* not in middle */ if(c1 & c2 & c3) { /* completely out */ @@ -1712,9 +1785,9 @@ void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) else if (b==1) arg= 0; else arg= 1; - clipp(vlzp[v][0],vlzp[v][1],0,&b2,&b3, arg); - clipp(vlzp[v][1],vlzp[v][2],1,&b2,&b3, arg); - clipp(vlzp[v][2],vlzp[v][0],2,&b2,&b3, arg); + clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg); + clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg); + clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg); if(b2==0 && b3==1) { /* completely 'in' */; @@ -1723,9 +1796,9 @@ void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) /* completely 'out' */; } else { b1=0; - maakvertpira(vlzp[v][0],vlzp[v][1],&b1,0,&clve); - maakvertpira(vlzp[v][1],vlzp[v][2],&b1,1,&clve); - maakvertpira(vlzp[v][2],vlzp[v][0],&b1,2,&clve); + makevertpyra(vez, labda[0], trias, vlzp[v][0],vlzp[v][1], &b1,&clve); + makevertpyra(vez, labda[1], trias, vlzp[v][1],vlzp[v][2], &b1,&clve); + makevertpyra(vez, labda[2], trias, vlzp[v][2],vlzp[v][0], &b1,&clve); /* after front clip done: now set clip flags */ if(b==0) { @@ -1742,9 +1815,9 @@ void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) vlzp[v][0]=0; if(b1>2) { for(b3=3; b3<=b1; b3++) { - vlzp[clvl][0]= p[0]; - vlzp[clvl][1]= p[b3-2]; - vlzp[clvl][2]= p[b3-1]; + vlzp[clvl][0]= trias[0]; + vlzp[clvl][1]= trias[b3-2]; + vlzp[clvl][2]= trias[b3-1]; clvl++; } } @@ -1768,7 +1841,7 @@ void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) } for(b=1;b<clvl;b++) { if(vlzp[b][0]) { - zbuffunc(vlzp[b][0],vlzp[b][1],vlzp[b][2]); + zbuffunc(zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2]); } } return; @@ -1792,7 +1865,7 @@ void zbufclip(float *f1, float *f2, float *f3, int c1, int c2, int c3) vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity; vez[10]= 0x7FFFFFFF *(f3[2]/deler); - zbuffunc(vez,vez+4,vez+8); + zbuffunc(zvlnr, vez,vez+4,vez+8); } /* ***************** ZBUFFER MAIN ROUTINES **************** */ @@ -1802,7 +1875,7 @@ void zbufferall(void) { VlakRen *vlr= NULL; Material *ma=0; - int v; + unsigned int v, zvlnr; short transp=0, env=0, wire=0; Zmulx= ((float)R.rectx)/2.0; @@ -1810,8 +1883,6 @@ void zbufferall(void) fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF); - Zvlnr= 0; - zbuffunc= zbufinvulGL; zbuflinefunc= zbufline; @@ -1832,15 +1903,15 @@ void zbufferall(void) } if(transp==0) { - if(env) Zvlnr= 0; - else Zvlnr= v+1; + if(env) zvlnr= 0; + else zvlnr= v+1; - if(wire) zbufclipwire(vlr); + if(wire) zbufclipwire(zvlnr, vlr); else { - zbufclip(vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + zbufclip(zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); if(vlr->v4) { - if(Zvlnr) Zvlnr+= 0x800000; - zbufclip(vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); + if(zvlnr) zvlnr+= 0x800000; + zbufclip(zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } @@ -1859,14 +1930,14 @@ static int hashlist_projectvert(float *v1, float *hoco) buck= &bucket[ (((long)v1)/16) & 255 ]; if(buck->vert==v1) { - COPY_16(hoco, buck->hoco); + QUATCOPY(hoco, buck->hoco); return buck->clip; } projectvert(v1, hoco); buck->clip = RE_testclip(hoco); buck->vert= v1; - COPY_16(buck->hoco, hoco); + QUATCOPY(buck->hoco, hoco); return buck->clip; } @@ -1874,7 +1945,7 @@ static int hashlist_projectvert(float *v1, float *hoco) void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) { float hoco[4][4]; - int a; + unsigned int a, zvlnr; int c1, c2, c3, c4= 0; unsigned int *rectoto, *rectzo; int rectxo, rectyo; @@ -1913,9 +1984,9 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) rn= *re; if( (rn->f & RAD_SHOOT)==0 ) { /* no shootelement */ - if( rn->f & RAD_TWOSIDED) Zvlnr= a; - else if( rn->f & RAD_BACKFACE) Zvlnr= 0xFFFFFF; - else Zvlnr= a; + if( rn->f & RAD_TWOSIDED) zvlnr= a; + else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF; + else zvlnr= a; c1= hashlist_projectvert(rn->v1, hoco[0]); c2= hashlist_projectvert(rn->v2, hoco[1]); @@ -1925,9 +1996,9 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) c4= hashlist_projectvert(rn->v4, hoco[3]); } - zbufclip(hoco[0], hoco[1], hoco[2], c1, c2, c3); + zbufclip(zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); if(rn->v4) { - zbufclip(hoco[0], hoco[2], hoco[3], c1, c3, c4); + zbufclip(zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4); } } } @@ -1944,9 +2015,9 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) rf= vlr->radface; if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */ - if( rf->flag & RAD_TWOSIDED) Zvlnr= totface; - else if( rf->flag & RAD_BACKFACE) Zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */ - else Zvlnr= totface; + if( rf->flag & RAD_TWOSIDED) zvlnr= totface; + else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */ + else zvlnr= totface; c1= hashlist_projectvert(vlr->v1->co, hoco[0]); c2= hashlist_projectvert(vlr->v2->co, hoco[1]); @@ -1956,9 +2027,9 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) c4= hashlist_projectvert(vlr->v4->co, hoco[3]); } - zbufclip(hoco[0], hoco[1], hoco[2], c1, c2, c3); + zbufclip(zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); if(vlr->v4) { - zbufclip(hoco[0], hoco[2], hoco[3], c1, c3, c4); + zbufclip(zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4); } } totface++; @@ -2002,8 +2073,8 @@ void zbuffershad(LampRen *lar) } if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) { - zbufclip(vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); - if(vlr->v4) zbufclip(vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); + zbufclip(0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + if(vlr->v4) zbufclip(0, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } @@ -2016,7 +2087,6 @@ void zbuffershad(LampRen *lar) void bgnaccumbuf(void) { - Acolrow= MEM_mallocN(4*sizeof(short)*R.rectx, "Acolrow"); Arectz= MEM_mallocN(sizeof(int)*ABUFPART*R.rectx, "Arectz"); APixbuf= MEM_mallocN(ABUFPART*R.rectx*sizeof(APixstr), "APixbuf"); @@ -2032,7 +2102,6 @@ void bgnaccumbuf(void) void endaccumbuf(void) { - MEM_freeN(Acolrow); MEM_freeN(Arectz); MEM_freeN(APixbuf); freepsA(); @@ -2040,7 +2109,11 @@ void endaccumbuf(void) /* ------------------------------------------------------------------------ */ -void copyto_abufz(int sample) +/** + * Copy results from the solid face z buffering to the transparent + * buffer. + */ +static void copyto_abufz(int sample) { PixStr *ps; int x, y, *rza; @@ -2078,11 +2151,16 @@ void copyto_abufz(int sample) /* ------------------------------------------------------------------------ */ -void zbuffer_abuf() +/** +* Do accumulation z buffering. + */ +static void zbuffer_abuf() { - float vec[3], hoco[4], mul, zval, fval; Material *ma=0; - int v, len; + VlakRen *vlr=NULL; + float vec[3], hoco[4], mul, zval, fval; + unsigned int v, zvlnr; + int len; Zjitx= Zjity= -0.5; Zmulx= ((float)R.rectx)/2.0; @@ -2106,20 +2184,20 @@ void zbuffer_abuf() for(v=0; v<R.totvlak; v++) { if((v & 255)==0) { - Zvlr= R.blovl[v>>8]; + vlr= R.blovl[v>>8]; } - else Zvlr++; + else vlr++; - ma= Zvlr->mat; + ma= vlr->mat; if(ma->mode & (MA_ZTRA)) { /* a little advantage for transp rendering (a z offset) */ if( ma->zoffs != 0.0) { mul= 0x7FFFFFFF; - zval= mul*(1.0+Zvlr->v1->ho[2]/Zvlr->v1->ho[3]); + zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]); - VECCOPY(vec, Zvlr->v1->co); + VECCOPY(vec, vlr->v1->co); /* z is negative, otherwise its being clipped */ vec[2]-= ma->zoffs; RE_projectverto(vec, hoco); @@ -2129,16 +2207,16 @@ void zbuffer_abuf() } else Azvoordeel= 0; - Zvlnr= v+1; + zvlnr= v+1; - if(Zvlr->flag & R_VISIBLE) { + if(vlr->flag & R_VISIBLE) { - if(ma->mode & (MA_WIRE)) zbufclipwire(Zvlr); + if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); else { - zbufclip(Zvlr->v1->ho, Zvlr->v2->ho, Zvlr->v3->ho, Zvlr->v1->clip, Zvlr->v2->clip, Zvlr->v3->clip); - if(Zvlr->v4) { - Zvlnr+= 0x800000; - zbufclip(Zvlr->v1->ho, Zvlr->v3->ho, Zvlr->v4->ho, Zvlr->v1->clip, Zvlr->v3->clip, Zvlr->v4->clip); + zbufclip(zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + if(vlr->v4) { + zvlnr+= 0x800000; + zbufclip(zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } @@ -2161,7 +2239,10 @@ int vergzvlak(const void *a1, const void *a2) return 0; } -void shadetrapixel(float x, float y, int face, int mask, unsigned short *shortcol) +/** +* Shade this face at this location in SCS. + */ +static void shadetrapixel(float x, float y, int face, int mask, float *fcol) { if( (face & 0x7FFFFF) > R.totvlak) { @@ -2170,44 +2251,64 @@ void shadetrapixel(float x, float y, int face, int mask, unsigned short *shortco } if(R.r.mode & R_OSA) { VlakRen *vlr= RE_findOrAddVlak( (face-1) & 0x7FFFFF); - int intcol[4]={0,0,0,0}; - int a, tot=0; + float accumcol[4]={0,0,0,0}, tot=0.0; + int a; if(vlr->flag & R_FULL_OSA) { for(a=0; a<R.osa; a++) { if(mask & (1<<a)) { - shadepixel_short(x+jit[a][0], y+jit[a][1], face, 1<<a, shortcol); - intcol[0]+= shortcol[0]; - intcol[1]+= shortcol[1]; - intcol[2]+= shortcol[2]; - intcol[3]+= shortcol[3]; - tot++; + shadepixel(x+jit[a][0], y+jit[a][1], face, 1<<a, fcol); + accumcol[0]+= fcol[0]; + accumcol[1]+= fcol[1]; + accumcol[2]+= fcol[2]; + accumcol[3]+= fcol[3]; + tot+= 1.0; } } - shortcol[0]= intcol[0]/tot; - shortcol[1]= intcol[1]/tot; - shortcol[2]= intcol[2]/tot; - shortcol[3]= intcol[3]/tot; + tot= 1.0/tot; + fcol[0]= accumcol[0]*tot; + fcol[1]= accumcol[1]*tot; + fcol[2]= accumcol[2]*tot; + fcol[3]= accumcol[3]*tot; } else { + extern float centLut[16]; + extern char *centmask; + int b= centmask[mask]; x= x+centLut[b & 15]; y= y+centLut[b>>4]; - shadepixel_short(x, y, face, mask, shortcol); + shadepixel(x, y, face, mask, fcol); } } - else shadepixel_short(x, y, face, mask, shortcol); + else shadepixel(x, y, face, mask, fcol); } -extern unsigned short usegamtab; -void abufsetrow(int y) +static int addtosampcol(float *sampcol, float *fcol, int mask) { + int a, retval = R.osa; + + for(a=0; a < R.osa; a++) { + if(mask & (1<<a)) addAlphaUnderFloat(sampcol, fcol); + if(sampcol[3]>0.999) retval--; + sampcol+= 4; + } + return retval; +} + +/* + * renders when needed the Abuffer with faces stored in pixels, returns 1 scanline rendered + */ + +void abufsetrow(float *acolrow, int y) +{ + extern SDL_mutex *render_abuf_lock; // initrender.c APixstr *ap, *apn; - float ys; - int x, part, a, zrow[100][3], totvlak, alpha[32], tempgam, nr, intcol[4]; - int sval, tempRf; - unsigned short *col, shortcol[4], tempcol[4], sampcol[16*4], *scol; + float *col, fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4]; + float ys, fac, alpha[32]; + int x, part, a, zrow[100][3], totvlak, nr; + int sval; if(y<0) return; if(R.osa>16) { @@ -2216,16 +2317,24 @@ void abufsetrow(int y) return; } - tempRf= R.flag; - R.flag &= ~R_LAMPHALO; + //R.flag &= ~R_LAMPHALO; /* alpha LUT */ if(R.r.mode & R_OSA ) { - x= (65536/R.osa); + fac= (1.0/(float)R.osa); for(a=0; a<=R.osa; a++) { - alpha[a]= a*x; + alpha[a]= (float)a*fac; } } + + if(R.r.mode & R_THREADS) { + /* lock thread if... */ + if(y>Aminy+2 && y<Amaxy-2); + else { + if(render_abuf_lock) SDL_mutexP(render_abuf_lock); + } + } + /* does a pixbuf has to be created? */ if(y<Aminy || y>Amaxy) { part= (y/ABUFPART); @@ -2237,12 +2346,10 @@ void abufsetrow(int y) } /* render row */ - col= Acolrow; - memset(col, 0, 2*4*R.rectx); - ap= APixbuf+R.rectx*(y-Aminy); + col= acolrow; + memset(col, 0, 4*sizeof(float)*R.rectx); + ap= APixbuf + R.rectx*(y-Aminy); ys= y; - tempgam= usegamtab; - usegamtab= 0; for(x=0; x<R.rectx; x++, col+=4, ap++) { if(ap->p[0]) { @@ -2264,21 +2371,21 @@ void abufsetrow(int y) } if(totvlak==1) { - shadetrapixel((float)x, (float)y, ap->p[0], ap->mask[0], shortcol); + shadetrapixel((float)x, (float)y, ap->p[0], ap->mask[0], fcol); nr= count_mask(ap->mask[0]); if( (R.r.mode & R_OSA) && nr<R.osa) { - a= alpha[ nr ]; - col[0]= (shortcol[0]*a)>>16; - col[1]= (shortcol[1]*a)>>16; - col[2]= (shortcol[2]*a)>>16; - col[3]= (shortcol[3]*a)>>16; + fac= alpha[ nr ]; + col[0]= (fcol[0]*fac); + col[1]= (fcol[1]*fac); + col[2]= (fcol[2]*fac); + col[3]= (fcol[3]*fac); } else { - col[0]= shortcol[0]; - col[1]= shortcol[1]; - col[2]= shortcol[2]; - col[3]= shortcol[3]; + col[0]= fcol[0]; + col[1]= fcol[1]; + col[2]= fcol[2]; + col[3]= fcol[3]; } } else { @@ -2300,13 +2407,13 @@ void abufsetrow(int y) while(totvlak>0) { totvlak--; - shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], shortcol); + shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], fcol); a= count_mask(zrow[totvlak][2]); if( (R.r.mode & R_OSA ) && a<R.osa) { if(totvlak>0) { - memset(sampcol, 0, 4*2*R.osa); - sval= addtosampcol(sampcol, shortcol, zrow[totvlak][2]); + memset(sampcol, 0, 4*sizeof(float)*R.osa); + sval= addtosampcol(sampcol, fcol, zrow[totvlak][2]); /* sval==0: alpha completely full */ while( (sval != 0) && (totvlak>0) ) { @@ -2314,44 +2421,48 @@ void abufsetrow(int y) if(a==R.osa) break; totvlak--; - shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], shortcol); - sval= addtosampcol(sampcol, shortcol, zrow[totvlak][2]); + shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], fcol); + sval= addtosampcol(sampcol, fcol, zrow[totvlak][2]); } scol= sampcol; - intcol[0]= scol[0]; intcol[1]= scol[1]; - intcol[2]= scol[2]; intcol[3]= scol[3]; + accumcol[0]= scol[0]; accumcol[1]= scol[1]; + accumcol[2]= scol[2]; accumcol[3]= scol[3]; scol+= 4; for(a=1; a<R.osa; a++, scol+=4) { - intcol[0]+= scol[0]; intcol[1]+= scol[1]; - intcol[2]+= scol[2]; intcol[3]+= scol[3]; + accumcol[0]+= scol[0]; accumcol[1]+= scol[1]; + accumcol[2]+= scol[2]; accumcol[3]+= scol[3]; } - tempcol[0]= intcol[0]/R.osa; - tempcol[1]= intcol[1]/R.osa; - tempcol[2]= intcol[2]/R.osa; - tempcol[3]= intcol[3]/R.osa; + tempcol[0]= accumcol[0]/R.osa; + tempcol[1]= accumcol[1]/R.osa; + tempcol[2]= accumcol[2]/R.osa; + tempcol[3]= accumcol[3]/R.osa; - addAlphaUnderShort(col, tempcol); + addAlphaUnderFloat(col, tempcol); } else { - a= alpha[a]; - shortcol[0]= (shortcol[0]*a)>>16; - shortcol[1]= (shortcol[1]*a)>>16; - shortcol[2]= (shortcol[2]*a)>>16; - shortcol[3]= (shortcol[3]*a)>>16; - addAlphaUnderShort(col, shortcol); + fac= alpha[a]; + fcol[0]= (fcol[0]*fac); + fcol[1]= (fcol[1]*fac); + fcol[2]= (fcol[2]*fac); + fcol[3]= (fcol[3]*fac); + addAlphaUnderFloat(col, fcol); } } - else addAlphaUnderShort(col, shortcol); + else addAlphaUnderFloat(col, fcol); - if(col[3]>=0xFFF0) break; + if(col[3]>=0.999) break; } } } } - usegamtab= tempgam; - R.flag= tempRf; + if(R.r.mode & R_THREADS) { + if(y>Aminy+2 && y<Amaxy-2); + else { + if(render_abuf_lock) SDL_mutexV(render_abuf_lock); + } + } } /* end of zbuf.c */ diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c index 78a5d29487e..319393290bd 100644 --- a/source/blender/render/intern/source/zbufferdatastruct.c +++ b/source/blender/render/intern/source/zbufferdatastruct.c @@ -62,7 +62,6 @@ #include "MEM_guardedalloc.h" #include "zbufferdatastruct.h" #include "render.h" -#include "render_intern.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -185,6 +184,11 @@ void insertObject(int apteller, RE_APixstrExt* apn = &APixbufExt[apteller]; int all_subpixels= 0; + //if(obtype==RE_POLY) { + // VlakRen *vlr= RE_findOrAddVlak( (obindex-1) & 0x7FFFFF); + // if(vlr->flag & R_FULL_OSA) all_subpixels= 1; + //} + while(apn) { if(apn->t[0] == RE_NONE) { apn->p[0] = obindex; apn->t[0] = obtype; diff --git a/source/blender/renderconverter/RE_renderconverter.h b/source/blender/renderconverter/RE_renderconverter.h index 450a4f7c764..272248f7066 100644 --- a/source/blender/renderconverter/RE_renderconverter.h +++ b/source/blender/renderconverter/RE_renderconverter.h @@ -86,7 +86,12 @@ extern "C" { void RE_make_stars(void (*initfunc)(void), void (*vertexfunc)(float*), void (*termfunc)(void)); - + + /** + * called by meshtools + */ + void RE_make_sticky(void); + #ifdef __cplusplus } diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index f7aa95b99dc..0108603e103 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -798,7 +798,7 @@ static void make_render_halos(Object *ob, Mesh *me, int totvert, MVert *mvert, M HaloRen *har; float xn, yn, zn, nor[3], view[3]; float *orco, vec[3], hasize, mat[4][4], imat[3][3]; - int start, end, a, ok; + int start, end, a, ok, seed= ma->seed1; MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat); MTC_Mat3CpyMat4(imat, ob->imat); @@ -813,8 +813,6 @@ static void make_render_halos(Object *ob, Mesh *me, int totvert, MVert *mvert, M mvert+= start; if(extverts) extverts+= 3*start; - ma->ren->seed1= ma->seed1; - for(a=start; a<end; a++, mvert++) { ok= 1; @@ -849,12 +847,12 @@ static void make_render_halos(Object *ob, Mesh *me, int totvert, MVert *mvert, M else hasize*= zn*zn*zn*zn; } - if(orco) har= RE_inithalo(ma, vec, 0, orco, hasize, 0); - else har= RE_inithalo(ma, vec, 0, mvert->co, hasize, 0); + if(orco) har= RE_inithalo(ma, vec, 0, orco, hasize, 0, seed); + else har= RE_inithalo(ma, vec, 0, mvert->co, hasize, 0, seed); if(har) har->lay= ob->lay; } if(orco) orco+= 3; - ma->ren->seed1++; + seed++; } } @@ -867,7 +865,7 @@ static void render_particle_system(Object *ob, PartEff *paf) HaloRen *har=0; Material *ma=0; float xn, yn, zn, imat[3][3], mat[4][4], hasize, ptime, ctime, vec[3], vec1[3], view[3], nor[3]; - int a, mat_nr=1; + int a, mat_nr=1, seed; pa= paf->keys; if(pa==NULL) { @@ -877,7 +875,6 @@ static void render_particle_system(Object *ob, PartEff *paf) } ma= give_render_material(ob, 1); - if(ma==NULL) ma= &defmaterial; MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat); MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */ @@ -890,7 +887,7 @@ static void render_particle_system(Object *ob, PartEff *paf) if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; else ptime= 0.0; ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime); - ma->ren->seed1= ma->seed1; + seed= ma->seed1; for(a=0; a<paf->totpart; a++, pa+=paf->totkey) { @@ -912,7 +909,6 @@ static void render_particle_system(Object *ob, PartEff *paf) if(pa->mat_nr != mat_nr) { mat_nr= pa->mat_nr; ma= give_render_material(ob, mat_nr); - if(ma==0) ma= &defmaterial; } if(ma->ipo) { @@ -943,9 +939,9 @@ static void render_particle_system(Object *ob, PartEff *paf) else hasize*= zn*zn*zn*zn; } - if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize); + if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed); else { - har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0); + har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0, seed); if(har && ma->mode & MA_HALO_SHADE) { VecSubf(har->no, vec, vec1); Normalise(har->no); @@ -954,7 +950,7 @@ static void render_particle_system(Object *ob, PartEff *paf) if(har) har->lay= ob->lay; } } - ma->ren->seed1++; + seed++; } /* restore material */ @@ -977,7 +973,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf) VlakRen *vlr; float xn, yn, zn, imat[3][3], mat[4][4], hasize; float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3]; - int a, mat_nr=1; + int a, mat_nr=1, seed; pa= paf->keys; if(pa==NULL || (paf->flag & PAF_ANIMATED)) { @@ -987,7 +983,6 @@ static void render_static_particle_system(Object *ob, PartEff *paf) } ma= give_render_material(ob, 1); - if(ma==NULL) ma= &defmaterial; MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat); MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ @@ -999,7 +994,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf) if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; else ptime= 0.0; ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, ptime); - ma->ren->seed1= ma->seed1; + seed= ma->seed1; for(a=0; a<paf->totpart; a++, pa+=paf->totkey) { @@ -1026,7 +1021,6 @@ static void render_static_particle_system(Object *ob, PartEff *paf) if(pa->mat_nr != mat_nr) { mat_nr= pa->mat_nr; ma= give_render_material(ob, mat_nr); - if(ma==0) ma= &defmaterial; } if(ma->mode & MA_WIRE) { @@ -1085,9 +1079,9 @@ static void render_static_particle_system(Object *ob, PartEff *paf) else hasize*= zn*zn*zn*zn; } - if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize); + if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize, seed); else { - har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0); + har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0, seed); if(har && (ma->mode & MA_HALO_SHADE)) { VecSubf(har->no, vec, vec1); Normalise(har->no); @@ -1099,7 +1093,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf) VECCOPY(vec1, vec); } - ma->ren->seed1++; + seed++; } } @@ -1167,7 +1161,9 @@ static void sort_halos(void) static Material *give_render_material(Object *ob, int nr) { + extern Material defmaterial; // initrender.c Object *temp; + Material *ma; if(ob->flag & OB_FROMDUPLI) { temp= (Object *)ob->id.newid; @@ -1176,7 +1172,10 @@ static Material *give_render_material(Object *ob, int nr) } } - return give_current_material(ob, nr); + ma= give_current_material(ob, nr); + if(ma==NULL) ma= &defmaterial; + + return ma; } /* ------------------------------------------------------------------------- */ @@ -1197,10 +1196,9 @@ static void init_render_mball(Object *ob) MTC_Mat3CpyMat4(imat, ob->imat); ma= give_render_material(ob, 1); - if(ma==0) ma= &defmaterial; need_orco= 0; - if(ma->ren->texco & TEXCO_ORCO) { + if(ma->texco & TEXCO_ORCO) { need_orco= 1; } @@ -1328,7 +1326,7 @@ static void init_render_mesh(Object *ob) for(a=1; a<=ob->totcol; a++) { ma= give_render_material(ob, a); if(ma) { - if(ma->ren->texco & TEXCO_ORCO) { + if(ma->texco & TEXCO_ORCO) { need_orco= 1; break; } @@ -1398,8 +1396,6 @@ static void init_render_mesh(Object *ob) orco= me->orco; ma= give_render_material(ob, 1); - if(ma==0) ma= &defmaterial; - if(ma->mode & MA_HALO) { make_render_halos(ob, me, totvert, mvert, ma, extverts); @@ -1444,7 +1440,6 @@ static void init_render_mesh(Object *ob) for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) { ma= give_render_material(ob, a1+1); - if(ma==0) ma= &defmaterial; /* test for 100% transparant */ ok= 1; @@ -1804,14 +1799,12 @@ void RE_add_render_lamp(Object *ob, int doshadbuf) lar->mode &= ~LA_SHAD_RAY; } } - - lar->org= MEM_dupallocN(lar); - } /* ------------------------------------------------------------------------- */ static void init_render_surf(Object *ob) { + extern Material defmaterial; // initrender.c Nurb *nu=0; Curve *cu; ListBase displist; @@ -1840,8 +1833,7 @@ static void init_render_surf(Object *ob) matar[0]= &defmaterial; for(a=0; a<ob->totcol; a++) { matar[a]= give_render_material(ob, a+1); - if(matar[a]==0) matar[a]= &defmaterial; - if(matar[a] && matar[a]->ren->texco & TEXCO_ORCO) { + if(matar[a] && matar[a]->texco & TEXCO_ORCO) { need_orco= 1; } } @@ -2185,8 +2177,8 @@ static void init_render_surf(Object *ob) static void init_render_curve(Object *ob) { + extern Material defmaterial; // initrender.c Ika *ika=0; - Lattice *lt=0; Curve *cu; VertRen *ver; @@ -2228,8 +2220,7 @@ static void init_render_curve(Object *ob) matar[0]= &defmaterial; for(a=0; a<ob->totcol; a++) { matar[a]= give_render_material(ob, a+1); - if(matar[a]==0) matar[a]= &defmaterial; - if(matar[a]->ren->texco & TEXCO_ORCO) { + if(matar[a]->texco & TEXCO_ORCO) { need_orco= 1; } } @@ -2681,7 +2672,6 @@ void RE_freeRotateBlenderScene(void) MEM_freeN(shb->cbuf); MEM_freeN(R.la[a]->shb); } - if(R.la[a]->org) MEM_freeN(R.la[a]->org); if(R.la[a]->jitter) MEM_freeN(R.la[a]->jitter); MEM_freeN(R.la[a]); } @@ -2898,9 +2888,6 @@ void RE_rotateBlenderScene(void) if(G.scene->camera==0) return; - O.dxwin[0]= 0.5/(float)R.r.xsch; - O.dywin[1]= 0.5/(float)R.r.ysch; - slurph_opt= 0; R.totvlak=R.totvert=R.totlamp=R.tothalo= 0; @@ -3123,6 +3110,78 @@ void RE_rotateBlenderScene(void) set_normalflags(); } +/* **************************************************************** */ +/* sticky texture coords */ +/* **************************************************************** */ + +void RE_make_sticky(void) +{ + Object *ob; + Base *base; + MVert *mvert; + Mesh *me; + MSticky *ms; + float ho[4], mat[4][4]; + int a; + + if(G.scene->camera==0) return; + + if(G.obedit) { + error("Unable to make sticky in Edit Mode"); + return; + } + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_MESH) { + ob= base->object; + + me= ob->data; + mvert= me->mvert; + if(me->msticky) MEM_freeN(me->msticky); + me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky"); + + /* like convert to render data */ + R.r= G.scene->r; + R.r.xsch= (R.r.size*R.r.xsch)/100; + R.r.ysch= (R.r.size*R.r.ysch)/100; + + R.afmx= R.r.xsch/2; + R.afmy= R.r.ysch/2; + + R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); + + R.rectx= R.r.xsch; + R.recty= R.r.ysch; + R.xstart= -R.afmx; + R.ystart= -R.afmy; + R.xend= R.xstart+R.rectx-1; + R.yend= R.ystart+R.recty-1; + + where_is_object(G.scene->camera); + Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); + Mat4Ortho(R.viewinv); + Mat4Invert(R.viewmat, R.viewinv); + + RE_setwindowclip(1, -1); + + where_is_object(ob); + Mat4MulMat4(mat, ob->obmat, R.viewmat); + + ms= me->msticky; + for(a=0; a<me->totvert; a++, ms++, mvert++) { + VECCOPY(ho, mvert->co); + Mat4MulVecfl(mat, ho); + RE_projectverto(ho, ho); + ms->co[0]= ho[0]/ho[3]; + ms->co[1]= ho[1]/ho[3]; + } + } + } + base= base->next; + } +} + /* **************************************************************** */ /* Displacement mapping */ @@ -3136,7 +3195,7 @@ static short test_for_displace(Object *ob) for (i=1; i<=ob->totcol; i++) { ma=give_render_material(ob, i); /* ma->mapto is ORed total of all mapto channels */ - if(ma && (ma->ren->mapto & MAP_DISPLACE)) return 1; + if(ma && (ma->mapto & MAP_DISPLACE)) return 1; } return 0; } @@ -3185,10 +3244,10 @@ static void displace_render_face(VlakRen *vlr, float *scale) shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */ shi.vlr= vlr; /* current render face */ shi.mat= vlr->mat; /* current input material */ - shi.matren= shi.mat->ren; /* material temp block where output is written into */ + /* UV coords must come from face */ - hasuv = vlr->tface && (shi.matren->texco & TEXCO_UV); + hasuv = vlr->tface && (shi.mat->texco & TEXCO_UV); if (hasuv) shi.uv[2]=0.0f; /* I don't think this is used, but seting it just in case */ @@ -3244,7 +3303,7 @@ static void displace_render_face(VlakRen *vlr, float *scale) static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale) { - short texco= shi->matren->texco; + short texco= shi->mat->texco; float sample=0; /* shi->co is current render coord, just make sure at least some vector is here */ VECCOPY(shi->co, vr->co); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 3aa41c0f7fc..6b27cf32113 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -153,6 +153,8 @@ #include "LOD_DependKludge.h" #include "LOD_decimation.h" +#include "RE_renderconverter.h" // make_sticky + #include "butspace.h" // own module static int decim_faces=0; @@ -441,6 +443,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an new_material_to_objectdata((G.scene->basact) ? (G.scene->basact->object) : 0); scrarea_queue_winredraw(curarea); BIF_undo_push("New material"); + allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWVIEW3D_Z, 0); allqueue(REDRAWOOPS, 0); break; @@ -448,6 +451,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an delete_material_index(); scrarea_queue_winredraw(curarea); BIF_undo_push("Delete material index"); + allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWVIEW3D_Z, 0); allqueue(REDRAWOOPS, 0); break; @@ -1899,7 +1903,8 @@ void do_meshbuts(unsigned short event) allqueue(REDRAWBUTSEDIT, 0); break; case B_MAKESTICKY: - make_sticky(); + RE_make_sticky(); + allqueue(REDRAWBUTSEDIT, 0); break; case B_MAKEEDGES: diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 98a856a731d..4561b183b7d 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -64,14 +64,15 @@ #include "BIF_gl.h" #include "BIF_graphics.h" +#include "BIF_glutil.h" +#include "BIF_interface.h" #include "BIF_keyval.h" #include "BIF_mainqueue.h" +#include "BIF_mywindow.h" #include "BIF_resources.h" +#include "BIF_renderwin.h" #include "BIF_screen.h" -#include "BIF_mywindow.h" #include "BIF_space.h" -#include "BIF_glutil.h" -#include "BIF_interface.h" #include "BIF_toolbox.h" #include "BIF_butspace.h" @@ -85,7 +86,6 @@ #include "DNA_image_types.h" #include "BKE_writeavi.h" #include "BKE_image.h" -#include "BIF_renderwin.h" #include "BIF_writeimage.h" #include "BIF_writeavicodec.h" #include "BIF_editsound.h" @@ -475,7 +475,7 @@ static void run_playanim(char *file) { char str[FILE_MAXDIR+FILE_MAXFILE]; int pos[2], size[2]; - calc_renderwin_rectangle(R.winpos, pos, size); + calc_renderwin_rectangle(G.winpos, pos, size); sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); system(str); @@ -793,6 +793,21 @@ void do_render_panels(unsigned short event) case B_CLEARSET: scene_change_set(G.scene, NULL); break; + case B_FBUF_REDO: + if(R.rectftot) { + /* copy is needed... not so nice, but how better? */ + R.r.postgamma= G.scene->r.postgamma; + R.r.postigamma= 1.0/R.r.postgamma; + R.r.postadd= G.scene->r.postadd; + R.r.postmul= G.scene->r.postmul; + R.r.posthue= G.scene->r.posthue; + R.r.postsat= G.scene->r.postsat; + R.r.dither_intensity= G.scene->r.dither_intensity; + + RE_floatbuffer_to_output(); + BIF_redraw_render_rect(); + } + break; } } @@ -843,14 +858,18 @@ static uiBlock *post_render_menu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "post render", UI_EMBOSS, UI_HELV, curarea->win); /* use this for a fake extra empy space around the buttons */ - uiDefBut(block, LABEL, 0, "", -10, 10, 200, 80, NULL, 0, 0, 0, 0, ""); - - uiDefButF(block, NUMSLI, 0,"Add:", 0,60,180,19, &G.scene->r.postadd, -1.0, 1.0, 0, 0, ""); - uiDefButF(block, NUMSLI, 0,"Mul:", 0,40,180,19, &G.scene->r.postmul, 0.01, 4.0, 0, 0, ""); - uiDefButF(block, NUMSLI, 0,"Gamma:", 0,20,180,19, &G.scene->r.postgamma, 0.2, 2.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "", -10, -10, 200, 120, NULL, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, 0, "Add:", 0,80,180,19, &G.scene->r.postadd, -1.0, 1.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0, "Mul:", 0,60,180,19, &G.scene->r.postmul, 0.01, 4.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0, "Gamma:", 0,40,180,19, &G.scene->r.postgamma, 0.1, 4.0, 0, 0, ""); + uiDefButF(block, NUMSLI, 0, "Hue:", 0,20,180,19, &G.scene->r.posthue, -0.5, 0.5, 0, 0, ""); + uiDefButF(block, NUMSLI, 0, "Sat:", 0, 0,180,19, &G.scene->r.postsat, 0.0, 4.0, 0, 0, ""); uiBlockSetDirection(block, UI_TOP); + addqueue(curarea->win, UI_BUT_EVENT, B_FBUF_REDO); + return block; } @@ -1039,41 +1058,47 @@ static void render_panel_output(void) uiBlockEndAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButS(block, TOG|BIT|0, 0,"Backbuf", 10, 94, 60, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); + uiDefButS(block, TOG|BIT|0, B_NOP,"Backbuf", 10, 94, 80, 20, &G.scene->r.bufflag, 0, 0, 0, 0, "Enable/Disable use of Backbuf image"); + uiDefButI(block, TOG|BIT|19, B_NOP,"Threads", 10, 68, 80, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable/Disable render in two threads"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); for(b=2; b>=0; b--) for(a=0; a<3; a++) - uiDefButS(block, TOG|BIT|(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &R.winpos, 0, 0, 0, 0, "Render window placement on screen"); + uiDefButS(block, TOG|BIT|(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen"); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButS(block, TOG|BIT|2, REDRAWVIEW3D, "Passepartout", 72, 30, 122, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Draws darkened passepartout in camera view"); - uiDefButS(block, ROW, B_REDR, "DispWin", 72, 10, 60, 20, &R.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a seperate window"); - uiDefButS(block, ROW, B_REDR, "DispView", 134, 10, 60, 20, &R.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view"); + uiDefButS(block, ROW, B_REDR, "DispWin", 72, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output to display in a seperate window"); + uiDefButS(block, ROW, B_REDR, "DispView", 134, 10, 60, 20, &G.displaymode, 0.0, (float)R_DISPLAYVIEW, 0, 0, "Sets render output to display in 3D view"); uiBlockEndAlign(block); - uiDefButS(block, TOG|BIT|4, 0, "Extensions", 250, 10, 60, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); + uiDefButS(block, TOG|BIT|4, 0, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); /* Dither control */ uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); /* Toon shading buttons */ uiBlockBeginAlign(block); - uiDefButI(block, TOG|BIT|5, 0,"Edge", 155, 94, 44, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon shading"); - uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 200, 94, 110, 20, "Display edge settings"); - uiBlockEndAlign(block); + uiDefButI(block, TOG|BIT|5, 0,"Edge", 100, 94, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading"); + uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 94, 140, 20, "Display edge settings"); - /* unified render buttons */ - if(G.scene->r.mode & R_UNIFIED) { - uiDefBlockBut(block, post_render_menu, NULL, "Post process", 200, 68, 110, 20, "Only for unified render"); - if (G.scene->r.mode & R_GAMMA) { - uiDefButF(block, NUMSLI, 0,"Gamma:", 10, 68, 142, 20, - &(G.scene->r.gamma), 0.2, 5.0, B_GAMMASLI, 0, - "The gamma value for blending oversampled images (1.0 = no correction)."); - } - } + /* postprocess render buttons */ + uiBlockBeginAlign(block); + if(R.rectftot) + uiDefIconTextButI(block, TOG|BIT|18, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available"); + else + uiDefButI(block, TOG|BIT|18, 0,"Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now"); + uiDefBlockBut(block, post_render_menu, NULL, "Post process", 170, 68, 140, 20, "Applies on RGBA floats while render or with Fbuf available"); + uiBlockEndAlign(block); + + /* removed, for time being unified and normal render will use same gamma for blending (2.0) */ + //if (G.scene->r.mode & R_GAMMA) { + // uiDefButF(block, NUMSLI, 0,"Gamma:", 10, 68, 142, 20, + // &(G.scene->r.gamma), 0.2, 5.0, B_GAMMASLI, 0, + // "The gamma value for blending oversampled images (1.0 = no correction)."); + //} } static void render_panel_render(void) diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 99fd85b2ed1..35dd0196fd0 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -53,6 +53,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_packedFile_types.h" +#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" @@ -82,7 +83,6 @@ /* Modules used */ #include "mydevice.h" #include "blendef.h" -#include "render.h" #include "butspace.h" // event codes diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index 6bd1dbe25c3..cc6c3ae7558 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -68,6 +68,7 @@ #include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_property.h" +#include "BKE_utildefines.h" #include "BIF_resources.h" #include "BIF_gl.h" @@ -785,7 +786,7 @@ static int set_gl_light(Object *ob) static Material *give_current_material_or_def(Object *ob, int matnr) { - extern Material defmaterial; + extern Material defmaterial; // render module abuse... Material *ma= give_current_material(ob, matnr); return ma?ma:&defmaterial; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index e9327f06a47..f3ea29b3056 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -127,7 +127,7 @@ static float matbuf[MAXMATBUF][2][4]; static void init_gl_materials(Object *ob) { - extern Material defmaterial; + extern Material defmaterial; // render module abuse... Material *ma; int a; diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index a5aba43f502..8f9b85a1ec1 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -56,9 +56,10 @@ #include "DNA_space_types.h" #include "DNA_view2d_types.h" -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_plugin_types.h" +#include "BKE_scene.h" +#include "BKE_utildefines.h" #include "BIF_gl.h" #include "BIF_mywindow.h" diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 9f60de5153d..f631d7851d1 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -126,14 +126,9 @@ #include "butspace.h" // event codes /* Modules used */ -#include "render.h" +#include "render.h" // for ogl render #include "radio.h" -/* for physics in animation playback */ -#ifdef NAN_LINEAR_PHYSICS -#include "sumo.h" -#endif - /* locals */ void drawname(Object *ob); void star_stuff_init_func(void); @@ -2234,253 +2229,6 @@ double key_to_swaptime(int key) return speed_to_swaptime(G.animspeed); } -#ifdef NAN_LINEAR_PHYSICS - -void sumo_callback(void *obp) -{ - Object *ob= obp; - SM_Vector3 vec; - float matf[3][3]; - int i, j; - - SM_GetMatrixf(ob->sumohandle, ob->obmat[0]); - - VECCOPY(ob->loc, ob->obmat[3]); - - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - matf[i][j] = ob->obmat[i][j]; - } - } - Mat3ToEul(matf, ob->rot); -} - -/* for test and fun, i've written the next functions to play with dynamics - using a variant of play-anim... was never released nor really tested (ton) */ - -void init_anim_sumo(void) -{ - extern Material defmaterial; - Base *base; - Mesh *me; - Object *ob; - Material *mat; - MFace *mface; - MVert *mvert; - float centre[3], size[3]; - int a; - SM_ShapeHandle shape; - SM_SceneHandle scene; - SM_Material material; - SM_MassProps massprops; - SM_Vector3 vec; - SM_Vector3 scaling; - - scene= SM_CreateScene(); - G.scene->sumohandle = scene; - - vec[0]= 0.0; - vec[1]= 0.0; - vec[2]= -9.8; - SM_SetForceField(scene, vec); - - /* ton: cylinders & cones are still Y-axis up, will be Z-axis later */ - /* ton: write location/rotation save and restore */ - - base= FIRSTBASE; - while (base) { - if (G.vd->lay & base->lay) { - ob= base->object; - - /* define shape, for now only meshes take part in physics */ - get_local_bounds(ob, centre, size); - - if (ob->type==OB_MESH) { - me= ob->data; - - if (ob->gameflag & OB_DYNAMIC) { - if (me->sumohandle) - shape= me->sumohandle; - else { - /* make new handle */ - switch(ob->boundtype) { - case OB_BOUND_BOX: - shape= SM_Box(2.0*size[0], 2.0*size[1], 2.0*size[2]); - break; - case OB_BOUND_SPHERE: - shape= SM_Sphere(size[0]); - break; - case OB_BOUND_CYLINDER: - shape= SM_Cylinder(size[0], 2.0*size[2]); - break; - case OB_BOUND_CONE: - shape= SM_Cone(size[0], 2.0*size[2]); - break; - } - - me->sumohandle= shape; - } - /* sumo material properties */ - mat= give_current_material(ob, 0); - if(mat==NULL) - mat= &defmaterial; - - material.restitution= mat->reflect; - material.static_friction= mat->friction; - material.dynamic_friction= mat->friction; - - /* sumo mass properties */ - massprops.mass= ob->mass; - massprops.center[0]= 0.0; - massprops.center[1]= 0.0; - massprops.center[2]= 0.0; - - massprops.inertia[0]= 0.5*ob->mass; - massprops.inertia[1]= 0.5*ob->mass; - massprops.inertia[2]= 0.5*ob->mass; - - massprops.orientation[0]= 0.0; - massprops.orientation[1]= 0.0; - massprops.orientation[2]= 0.0; - massprops.orientation[3]= 1.0; - - ob->sumohandle = SM_CreateObject(ob, shape, &material, - &massprops, sumo_callback); - SM_AddObject(scene, ob->sumohandle); - - scaling[0] = ob->size[0]; - scaling[1] = ob->size[1]; - scaling[2] = ob->size[2]; - SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); - SM_SetScaling(ob->sumohandle, scaling); - - } - else { - if(me->sumohandle) shape= me->sumohandle; - else { - /* make new handle */ - shape= SM_NewComplexShape(); - - mface= me->mface; - mvert= me->mvert; - for(a=0; a<me->totface; a++,mface++) { - if(mface->v3) { - SM_Begin(); - SM_Vertex( (mvert+mface->v1)->co[0], (mvert+mface->v1)->co[1], (mvert+mface->v1)->co[2]); - SM_Vertex( (mvert+mface->v2)->co[0], (mvert+mface->v2)->co[1], (mvert+mface->v2)->co[2]); - SM_Vertex( (mvert+mface->v3)->co[0], (mvert+mface->v3)->co[1], (mvert+mface->v3)->co[2]); - if(mface->v4) - SM_Vertex( (mvert+mface->v4)->co[0], (mvert+mface->v4)->co[1], (mvert+mface->v4)->co[2]); - SM_End(); - } - } - - SM_EndComplexShape(); - - me->sumohandle= shape; - } - /* sumo material properties */ - mat= give_current_material(ob, 0); - if(mat==NULL) - mat= &defmaterial; - material.restitution= mat->reflect; - material.static_friction= mat->friction; - material.dynamic_friction= mat->friction; - - /* sumo mass properties */ - massprops.mass= ob->mass; - massprops.center[0]= 0.0; - massprops.center[1]= 0.0; - massprops.center[2]= 0.0; - - massprops.inertia[0]= 0.5*ob->mass; - massprops.inertia[1]= 0.5*ob->mass; - massprops.inertia[2]= 0.5*ob->mass; - - massprops.orientation[0]= 0.0; - massprops.orientation[1]= 0.0; - massprops.orientation[2]= 0.0; - massprops.orientation[3]= 1.0; - - ob->sumohandle= SM_CreateObject(ob, shape, &material, NULL, NULL); - SM_AddObject(scene, ob->sumohandle); - - scaling[0] = ob->size[0]; - scaling[1] = ob->size[1]; - scaling[2] = ob->size[2]; - SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); - SM_SetScaling(ob->sumohandle, scaling); - } - } - } - base= base->next; - } -} - -/* update animated objects */ -void update_anim_sumo(void) -{ - SM_Vector3 scaling; - - Base *base; - Object *ob; - Mesh *me; - - base= FIRSTBASE; - while(base) { - if(G.vd->lay & base->lay) { - ob= base->object; - - if(ob->sumohandle) { - if((ob->gameflag & OB_DYNAMIC)==0) { - /* maybe: optimise, check for anim */ - scaling[0] = ob->size[0]; - scaling[1] = ob->size[1]; - scaling[2] = ob->size[2]; - SM_SetMatrixf(ob->sumohandle, ob->obmat[0]); - SM_SetScaling(ob->sumohandle, scaling); - } - } - } - base= base->next; - } - -} - -void end_anim_sumo(void) -{ - Base *base; - Object *ob; - Mesh *me; - - base= FIRSTBASE; - while(base) { - if(G.vd->lay & base->lay) { - ob= base->object; - - if(ob->type==OB_MESH) { - if(ob->sumohandle) { - SM_RemoveObject(G.scene->sumohandle, ob->sumohandle); - SM_DeleteObject(ob->sumohandle); - ob->sumohandle= NULL; - } - me= ob->data; - if(me->sumohandle) { - SM_DeleteShape(me->sumohandle); - me->sumohandle= NULL; - } - } - } - base= base->next; - } - if(G.scene->sumohandle) { - SM_DeleteScene(G.scene->sumohandle); - G.scene->sumohandle= NULL; - } -} - -#endif - void inner_play_anim_loop(int init, int mode) { ScrArea *sa; @@ -2494,9 +2242,7 @@ void inner_play_anim_loop(int init, int mode) swaptime= speed_to_swaptime(G.animspeed); tottime= 0.0; curmode= mode; -#ifdef NAN_LINEAR_PHYSICS - init_anim_sumo(); -#endif + return; } @@ -2511,11 +2257,7 @@ void inner_play_anim_loop(int init, int mode) update_for_newframe_muted(); //test_all_displists(); -#ifdef NAN_LINEAR_PHYSICS - update_anim_sumo(); - - SM_Proceed(G.scene->sumohandle, swaptime, 40, NULL); -#endif + sa= G.curscreen->areabase.first; while(sa) { if(sa==oldsa) { @@ -2639,9 +2381,7 @@ int play_anim(int mode) allqueue (REDRAWACTION, 0); /* for the time being */ update_for_newframe_muted(); -#ifdef NAN_LINEAR_PHYSICS - end_anim_sumo(); -#endif + waitcursor(0); G.f &= ~G_PLAYANIM; diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index bed71e1a398..32110fa88e5 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -61,16 +61,17 @@ #include "DNA_mesh_types.h" #include "DNA_lattice_types.h" +#include "BKE_action.h" #include "BKE_armature.h" #include "BKE_constraint.h" -#include "BKE_displist.h" #include "BKE_curve.h" -#include "BKE_ipo.h" +#include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_action.h" -#include "BKE_key.h" +#include "BKE_utildefines.h" #include "BIF_gl.h" #include "BIF_mywindow.h" diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index 16c44f5259f..efd5c30729e 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -57,6 +57,7 @@ #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" +#include "DNA_scene_types.h" #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" @@ -87,7 +88,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" #include "butspace.h" #include "TPT_DependKludge.h" diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index fa327316642..8bffeda1b0c 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -62,23 +62,24 @@ #include "DNA_constraint_types.h" #include "DNA_action_types.h" #include "DNA_armature_types.h" -#include "DNA_object_types.h" -#include "DNA_lamp_types.h" -#include "DNA_sequence_types.h" -#include "DNA_sound_types.h" #include "DNA_camera_types.h" -#include "DNA_material_types.h" -#include "DNA_texture_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_ika_types.h" +#include "DNA_ipo_types.h" #include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_scene_types.h" -#include "DNA_ipo_types.h" -#include "DNA_curve_types.h" #include "DNA_space_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" +#include "DNA_texture_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" -#include "DNA_group_types.h" -#include "DNA_ika_types.h" +#include "DNA_world_types.h" #include "BKE_utildefines.h" #include "BKE_action.h" @@ -118,7 +119,6 @@ #include "blendef.h" #include "mydevice.h" -#include "render.h" /* forwards */ #define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c index 581278809d8..1469cf97d11 100644 --- a/source/blender/src/editlattice.c +++ b/source/blender/src/editlattice.c @@ -58,6 +58,7 @@ #include "BKE_displist.h" #include "BKE_lattice.h" #include "BKE_global.h" +#include "BKE_utildefines.h" #include "BIF_space.h" #include "BIF_screen.h" @@ -74,8 +75,6 @@ #include "blendef.h" #include "mydevice.h" -#include "render.h" - #include "BKE_armature.h" /* ***************************** */ diff --git a/source/blender/src/editmball.c b/source/blender/src/editmball.c index 609fc166764..096c5049c71 100644 --- a/source/blender/src/editmball.c +++ b/source/blender/src/editmball.c @@ -47,6 +47,7 @@ #include "DNA_screen_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "DNA_view3d_types.h" #include "BKE_utildefines.h" @@ -67,7 +68,6 @@ #include "BSE_edit.h" #include "BSE_view.h" -#include "render.h" #include "blendef.h" #include "mydevice.h" diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 69a8320b638..a9b1c3bbb45 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -93,7 +93,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" /* own include */ #include "editmesh.h" diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 19b862074bd..7919c6d0d77 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -95,7 +95,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "mydevice.h" #include "blendef.h" -#include "render.h" // externtex, badlevel call (ton) +#include "render.h" // externtex #include "editmesh.h" @@ -2158,7 +2158,6 @@ void vertexsmooth(void) void vertexnoise(void) { EditMesh *em = G.editMesh; - extern float Tin; Material *ma; Tex *tex; EditVert *eve; @@ -2189,10 +2188,9 @@ void vertexnoise(void) VecAddf(eve->co, eve->co, vec); } else { - - externtex(ma->mtex[0], eve->co); - - eve->co[2]+= 0.05*Tin; + float tin, dum; + externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum); + eve->co[2]+= 0.05*tin; } } eve= eve->next; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 9a65370c69e..1e6eb0dbf4c 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -60,6 +60,7 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" +#include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_ika_types.h" @@ -68,6 +69,7 @@ #include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_meta_types.h" @@ -80,7 +82,6 @@ #include "DNA_userdef_types.h" #include "DNA_property_types.h" #include "DNA_vfont_types.h" -#include "DNA_constraint_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -153,7 +154,6 @@ #include "BDR_editcurve.h" #include "BDR_unwrapper.h" -#include "render.h" #include <time.h> #include "mydevice.h" #include "nla.h" diff --git a/source/blender/src/editoops.c b/source/blender/src/editoops.c index f6a26279c90..584d6a7b2d0 100644 --- a/source/blender/src/editoops.c +++ b/source/blender/src/editoops.c @@ -61,6 +61,7 @@ #include "BKE_scene.h" #include "BKE_library.h" #include "BKE_material.h" +#include "BKE_utildefines.h" #include "BIF_space.h" #include "BIF_screen.h" diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index 2134b45a840..9d5c290aa6c 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -101,7 +101,7 @@ #include "BPY_extern.h" #include "mydevice.h" #include "blendef.h" -#include "render.h" +#include "render.h" /* R.flag */ #include "winlay.h" diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index d3fac5f87d2..7de296bd7b6 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -70,6 +70,7 @@ #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "BIF_space.h" #include "BIF_interface.h" diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index b3436b70ba7..9c3b8f30033 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -63,6 +63,7 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_displist.h" +#include "BKE_utildefines.h" #include "BIF_gl.h" #include "BIF_interface.h" diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 43ca05840b8..4440ecaa86d 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -65,6 +65,7 @@ #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_vfont_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_texture_types.h" @@ -101,7 +102,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" #include "nla.h" diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index ba65c029362..2d86f7a44e2 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -74,6 +74,7 @@ #include "BKE_main.h" #include "BKE_constraint.h" #include "BKE_armature.h" +#include "BKE_utildefines.h" #include "BSE_drawipo.h" #include "BSE_editaction.h" diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 597b1985aa9..2987ca7e53f 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -67,6 +67,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_packedFile.h" +#include "BKE_utildefines.h" #include "BLI_blenlib.h" #include "BIF_drawimage.h" diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index 61a74d0ae2d..3221115931e 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -111,8 +111,6 @@ #include "BPY_extern.h" #include "BPY_menus.h" -#include "render.h" // for R - should use BKE_bad_level_calls.h instead? - #include "blendef.h" #include "mydevice.h" @@ -1524,7 +1522,7 @@ static void run_playanim(char *file) char str[FILE_MAXDIR+FILE_MAXFILE]; int pos[2], size[2]; - calc_renderwin_rectangle(R.winpos, pos, size); + calc_renderwin_rectangle(G.winpos, pos, size); sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); system(str); diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c index cdf2763eeab..1e821a14271 100644 --- a/source/blender/src/header_nla.c +++ b/source/blender/src/header_nla.c @@ -58,14 +58,17 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_utildefines.h" + #include "BIF_interface.h" #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_editnla.h" -#include "BKE_global.h" -#include "BKE_main.h" #include "BSE_drawipo.h" #include "BSE_headerbuttons.h" diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 20852aa1464..6a2d139f17d 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -173,7 +173,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" #include "nla.h" /* __NLA : To be removed later */ #include "butspace.h" // test_idbutton diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index bf832024d20..6279dba6c89 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -35,7 +35,6 @@ meshtools.c: no editmode, tools operating on meshes void join_mesh(void); -void make_sticky(void); void fasterdraw(void); void slowerdraw(void); @@ -91,8 +90,6 @@ void sort_faces(void); #include "mydevice.h" #include "blendef.h" -#include "render.h" // bad level call (ton) - /* * ********************** no editmode!!! *********** */ @@ -440,75 +437,6 @@ void join_mesh(void) } -void make_sticky(void) -{ - Object *ob; - Base *base; - MVert *mvert; - Mesh *me; - MSticky *ms; - float ho[4], mat[4][4]; - int a; - - if(G.scene->camera==0) return; - - if(G.obedit) { - error("Unable to make sticky in Edit Mode"); - return; - } - base= FIRSTBASE; - while(base) { - if TESTBASELIB(base) { - if(base->object->type==OB_MESH) { - ob= base->object; - - me= ob->data; - mvert= me->mvert; - if(me->msticky) MEM_freeN(me->msticky); - me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky"); - - /* like convert to render data */ - R.r= G.scene->r; - R.r.xsch= (R.r.size*R.r.xsch)/100; - R.r.ysch= (R.r.size*R.r.ysch)/100; - - R.afmx= R.r.xsch/2; - R.afmy= R.r.ysch/2; - - R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); - - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - R.xstart= -R.afmx; - R.ystart= -R.afmy; - R.xend= R.xstart+R.rectx-1; - R.yend= R.ystart+R.recty-1; - - where_is_object(G.scene->camera); - Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); - Mat4Ortho(R.viewinv); - Mat4Invert(R.viewmat, R.viewinv); - - RE_setwindowclip(1, -1); - - where_is_object(ob); - Mat4MulMat4(mat, ob->obmat, R.viewmat); - - ms= me->msticky; - for(a=0; a<me->totvert; a++, ms++, mvert++) { - VECCOPY(ho, mvert->co); - Mat4MulVecfl(mat, ho); - RE_projectverto(ho, ho); - ms->co[0]= ho[0]/ho[3]; - ms->co[1]= ho[1]/ho[3]; - } - } - } - base= base->next; - } - allqueue(REDRAWBUTSEDIT, 0); -} - void fasterdraw(void) { Base *base; diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 52cf6734e2d..970083f0a35 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -61,6 +61,7 @@ #include "DNA_world_types.h" #include "DNA_camera_types.h" #include "DNA_image_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_lamp_types.h" #include "DNA_space_types.h" @@ -407,7 +408,7 @@ static void sky_preview_pixel(float lens, int x, int y, char *rect) static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char *rect) { - float inpr, i, t, dist, distkw, vec[3]; + float inpr, i, t, dist, distkw, vec[3], lacol[3]; int col; shi->co[0]= (float)x/(PR_RECTX/4); @@ -420,7 +421,11 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char VECCOPY(shi->view, vec); dist= Normalise(shi->view); - if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi); + lacol[0]= la->r; + lacol[1]= la->g; + lacol[2]= la->b; + + if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi, lacol); if(la->type==LA_SUN || la->type==LA_HEMI) { dist= 1.0; @@ -471,13 +476,13 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char } else if ELEM(la->type, LA_LOCAL, LA_AREA) dist*= shi->view[2]; - col= 255.0*dist*la->r; + col= 255.0*dist*lacol[0]; if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col; - col= 255.0*dist*la->g; + col= 255.0*dist*lacol[1]; if(col<=0) rect[1]= 0; else if(col>=255) rect[1]= 255; else rect[1]= col; - col= 255.0*dist*la->b; + col= 255.0*dist*lacol[2]; if(col<=0) rect[2]= 0; else if(col>=255) rect[2]= 255; else rect[2]= col; } @@ -492,9 +497,9 @@ static void init_previewhalo(HaloRen *har, Material *mat) 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->r= mat->r; + har->g= mat->g; + har->b= mat->b; har->xs= PR_RECTX/2.0; har->ys= PR_RECTX/2.0; har->zs= har->zd= 0; @@ -520,7 +525,7 @@ static void init_previewhalo(HaloRen *har, Material *mat) static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char *rect) { - float dist, xn, yn, xsq, ysq; + float dist, xn, yn, xsq, ysq, colf[4]; int x; char front[4]; @@ -536,10 +541,8 @@ static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char * xsq= xn*xn; dist= xsq+ysq; - - if(dist<har->radsq) { - RE_shadehalo(har, front, 0, dist, xn, yn, har->flarec); + RE_shadehalo(har, front, colf, 0, dist, xn, yn, har->flarec); RE_addalphaAddfac(rect, front, har->add); } rect+= 4; @@ -591,12 +594,12 @@ static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) 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], dummy[3]; + float i, v1, xsq, ysq, texvec[3]; + float tin=1.0, tr, tg, tb, ta; int rgbnor, tracol, skip=0; - + if(tex->type==TEX_IMAGE) { v1= 1.0/PR_RECTX; @@ -637,12 +640,12 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) } else { skip= 1; - Ta= 0.0; + ta= 0.0; } } else { skip= 1; - Ta= 0.0; + ta= 0.0; } } else { @@ -653,44 +656,32 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) texvec[2]= 0.0; } - /* does not return Tin */ - if(tex->type==TEX_STUCCI) { - tex->nor= dummy; - dummy[0]= 1.0; - dummy[1]= dummy[2]= 0.0; - } - - if(skip==0) rgbnor= multitex(tex, texvec, NULL, NULL, 0); + if(skip==0) rgbnor= multitex_ext(tex, texvec, &tin, &tr, &tg, &tb, &ta); else rgbnor= 1; if(rgbnor & 1) { - v1= 255.0*Tr; + v1= 255.0*tr; rect[0]= CLAMPIS(v1, 0, 255); - v1= 255.0*Tg; + v1= 255.0*tg; rect[1]= CLAMPIS(v1, 0, 255); - v1= 255.0*Tb; + v1= 255.0*tb; rect[2]= CLAMPIS(v1, 0, 255); - if(Ta!=1.0) { + if(ta!=1.0) { tracol= 64+100*(abs(x)>abs(y)); - tracol= (1.0-Ta)*tracol; + tracol= (1.0-ta)*tracol; - rect[0]= tracol+ (rect[0]*Ta) ; - rect[1]= tracol+ (rect[1]*Ta) ; - rect[2]= tracol+ (rect[2]*Ta) ; + 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; + rect[0]= 255.0*tin; + rect[1]= 255.0*tin; + rect[2]= 255.0*tin; } } @@ -740,14 +731,23 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * int temp, a; char tracol; - mat= shi->matren; + mat= shi->mat; + // 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); + shi->xs= (float)x; + shi->ys= (float)y; + shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0; /* texture handling */ @@ -824,7 +824,7 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * } /* set it here, because ray_mirror will affect it */ - alpha= mat->alpha; + alpha= shi->alpha; if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */ shi->vn[0]-=2.0*shi->displace[2]; @@ -838,13 +838,13 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); if(mat->mode & MA_SHLESS) { - temp= 255.0*(mat->r); + 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*(mat->g); + 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*(mat->b); + temp= 255.0*(shi->b); if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp; } else { @@ -864,22 +864,22 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * is= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; if(is<0.0) is= 0.0; - if(mat->spec) { + if(shi->spec>0.0) { if(is>0.0) { /* specular shaders */ float specfac; if(mat->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(shi->vn, lv, shi->view, mat->har); + specfac= Phong_Spec(shi->vn, lv, shi->view, shi->har); else if(mat->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(shi->vn, lv, shi->view, mat->har); + specfac= CookTorr_Spec(shi->vn, lv, shi->view, shi->har); else if(mat->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(shi->vn, lv, shi->view, mat->refrac, (float)mat->har); + specfac= Blinn_Spec(shi->vn, lv, shi->view, mat->refrac, (float)shi->har); else specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3]); - inprspec= specfac*mat->spec; + inprspec= specfac*shi->spec; if(mat->mode & MA_RAMP_SPEC) { float spec[3]; @@ -889,9 +889,9 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * isb+= inprspec*spec[2]; } else { - isr+= inprspec*mat->specr; - isg+= inprspec*mat->specg; - isb+= inprspec*mat->specb; + isr+= inprspec*shi->specr; + isg+= inprspec*shi->specg; + isb+= inprspec*shi->specb; } } } @@ -900,7 +900,7 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(shi->vn, lv, shi->view, mat->param[0], mat->param[1]); // else Lambert - inp= (mat->ref*is + mat->emit); + inp= (shi->refl*is + shi->emit); if(a==0) la= pr1_col; else la= pr2_col; @@ -924,7 +924,7 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * /* scale */ div= (0.85*shi->ref[1]); - shi->refcol[0]= mat->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir); + 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]); @@ -953,40 +953,40 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, shi); if(shi->refcol[0]==0.0) { - a= 255.0*(diff[0] +mat->ambr +isr); + 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] +mat->ambg +isg); + 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] +mat->ambb +isb); + a= 255*(diff[2] +shi->ambb +isb); if(a>255) a=255; else if(a<0) a= 0; rect[2]= a; } else { - a= 255.0*( mat->mirr*shi->refcol[1] + (1.0 - mat->mirr*shi->refcol[0])*(diff[0] +mat->ambr) +isr); + 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*( mat->mirg*shi->refcol[2] + (1.0 - mat->mirg*shi->refcol[0])*(diff[1] +mat->ambg) +isg); + 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*( mat->mirb*shi->refcol[3] + (1.0 - mat->mirb*shi->refcol[0])*(diff[2] +mat->ambb) +isb); + 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(mat->spectra!=0.0) { + if(shi->spectra!=0.0) { inp = MAX3(isr, isg, isb); - inp *= mat->spectra; + inp *= shi->spectra; if(inp>1.0) inp= 1.0; alpha= (1.0-inp)*alpha+inp; } if(alpha!=1.0) { if(mat->mode & MA_RAYTRANSP) { - refraction_prv(&x, &y, shi->vn, mat->ang); + refraction_prv(&x, &y, shi->vn, shi->ang); } tracol= previewback(mat->pr_back, x, y) & 255; @@ -1091,8 +1091,8 @@ void BIF_previewrender(SpaceButs *sbuts) } } shi.vlr= 0; + shi.mat= mat; - shi.matren= mat->ren; if(mat->mode & MA_HALO) init_previewhalo(&har, mat); } @@ -1293,7 +1293,6 @@ void BIF_previewrender(SpaceButs *sbuts) } else if(la) { if(R.totlamp) { - if(R.la[0]->org) MEM_freeN(R.la[0]->org); MEM_freeN(R.la[0]); } R.totlamp= 0; diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 5fbe58523cb..19b7ee96a15 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -72,7 +72,9 @@ #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_mywindow.h" +#include "BIF_previewrender.h" #include "BIF_renderwin.h" +#include "BIF_resources.h" #include "BIF_toets.h" #include "BDR_editobject.h" @@ -111,6 +113,9 @@ /* forces draw of alpha */ #define RW_FLAGS_ALPHA (1<<4) +/* space for info text */ +#define RW_HEADERY 18 + typedef struct { Window *win; @@ -125,6 +130,8 @@ typedef struct { float pan_mouse_start[2], pan_ofs_start[2]; char *info_text; + char *render_text, *render_text_spare; + } RenderWin; static RenderWin *render_win= NULL; @@ -142,6 +149,7 @@ static RenderWin *renderwin_alloc(Window *win) rw->flags= 0; rw->zoomofs[0]= rw->zoomofs[1]= 0; rw->info_text= NULL; + rw->render_text= rw->render_text_spare= NULL; rw->lmouse[0]= rw->lmouse[1]= 0; rw->mbut[0]= rw->mbut[1]= rw->mbut[2]= 0; @@ -167,6 +175,7 @@ static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2]) int w, h; window_get_size(rw->win, &w, &h); + h-= RW_HEADERY; display_w= R.rectx*rw->zoom; display_h= R.recty*rw->zoom; @@ -204,6 +213,7 @@ static int renderwin_win_to_ndc(RenderWin *rw, int win_co[2], float ndc_r[2]) int w, h; window_get_size(rw->win, &w, &h); + h-= RW_HEADERY; ndc_r[0]= ((float)(win_co[0]*2)/(w-1) - 1.0); ndc_r[1]= ((float)(win_co[1]*2)/(h-1) - 1.0); @@ -225,6 +235,8 @@ static void renderwin_reset_view(RenderWin *rw) /* now calculate a zoom for when image is larger than window */ window_get_size(rw->win, &w, &h); + h-= RW_HEADERY; + /* at this point the r.rectx/y values are not correct yet */ rectx= (G.scene->r.size*G.scene->r.xsch)/100; recty= (G.scene->r.size*G.scene->r.ysch)/100; @@ -239,6 +251,34 @@ static void renderwin_reset_view(RenderWin *rw) renderwin_queue_redraw(rw); } +static void renderwin_draw_render_info(RenderWin *rw) +{ + /* render text is added to top */ + if(RW_HEADERY) { + float colf[3]; + rcti rect; + + window_get_size(rw->win, &rect.xmax, &rect.ymax); + rect.xmin= 0; + rect.ymin= rect.ymax-RW_HEADERY; + glEnable(GL_SCISSOR_TEST); + glaDefine2DArea(&rect); + + /* clear header rect */ + BIF_SetTheme(NULL); // sets view3d theme by default + BIF_GetThemeColor3fv(TH_HEADER, colf); + glClearColor(colf[0], colf[1], colf[2], 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if(rw->render_text) { + BIF_ThemeColor(TH_TEXT); + glRasterPos2i(12, 5); + BMF_DrawString(G.fonts, rw->render_text); + } + } + +} + static void renderwin_draw(RenderWin *rw, int just_clear) { float disprect[2][2]; @@ -246,10 +286,15 @@ static void renderwin_draw(RenderWin *rw, int just_clear) rect.xmin= rect.ymin= 0; window_get_size(rw->win, &rect.xmax, &rect.ymax); + rect.ymax-= RW_HEADERY; + renderwin_get_disprect(rw, disprect); window_make_active(rw->win); + /* do this first, so window ends with correct scissor */ + renderwin_draw_render_info(rw); + glEnable(GL_SCISSOR_TEST); glaDefine2DArea(&rect); @@ -279,6 +324,7 @@ static void renderwin_draw(RenderWin *rw, int just_clear) glPixelZoom(1.0, 1.0); } + /* info text is overlayed on bottom */ if (rw->info_text) { float w; glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); @@ -291,7 +337,7 @@ static void renderwin_draw(RenderWin *rw, int just_clear) glRasterPos2i(10, 10); BMF_DrawString(G.font, rw->info_text); } - + window_swap_buffers(rw->win); } @@ -330,6 +376,7 @@ static void renderwin_mouse_moved(RenderWin *rw) int w, h; window_get_size(rw->win, &w, &h); + h-= RW_HEADERY; renderwin_win_to_ndc(rw, rw->lmouse, ndc); rw->zoomofs[0]= -0.5*ndc[0]*(w-R.rectx*rw->zoom)/rw->zoom; @@ -370,6 +417,13 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val { RenderWin *rw= user_data; + // added this for safety, while render it's just creating bezerk results + if(R.flag & R_RENDERING) { + if(evt==ESCKEY && val) + rw->flags|= RW_FLAGS_ESCAPE; + return; + } + if (evt==RESHAPE) { renderwin_reshape(rw); } @@ -492,7 +546,7 @@ static void open_renderwin(int winpos[2], int winsize[2]) char *title; title= renderwin_get_title(0); /* 0 = no swap */ - win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1], 0); + win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY, 0); render_win= renderwin_alloc(win); @@ -504,7 +558,7 @@ static void open_renderwin(int winpos[2], int winsize[2]) winlay_process_events(0); /* mywindow has to know about it too */ - mywindow_build_and_set_renderwin(winpos[0], winpos[1], winsize[0], winsize[1]); + mywindow_build_and_set_renderwin(winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY); /* and we should be able to draw 3d in it */ init_gl_stuff(); @@ -561,7 +615,7 @@ static void renderwin_init_display_cb(void) if (G.afbreek == 0) { int rendersize[2], renderpos[2]; - calc_renderwin_rectangle(R.winpos, renderpos, rendersize); + calc_renderwin_rectangle(G.winpos, renderpos, rendersize); if (!render_win) { open_renderwin(renderpos, rendersize); @@ -572,6 +626,7 @@ static void renderwin_init_display_cb(void) window_get_position(render_win->win, &win_x, &win_y); window_get_size(render_win->win, &win_w, &win_h); + win_h-= RW_HEADERY; /* XXX, this is nasty and I guess bound to cause problems, * but to ensure the window is at the user specified position @@ -616,7 +671,9 @@ static void renderwin_clear_display_cb(short ignore) * ... better is to make this an optimization of a more clear * implementation. the bug shows up when you do something like * open the window, then draw part of the progress, then get -* a redraw event. whatever can go wrong will. +* a redraw event. whatever can go wrong will. -zr +* +* Note: blocked queue handling while rendering to prevent that (ton) */ /* in render window; display a couple of scanlines of rendered image (see callback below) */ @@ -627,9 +684,12 @@ static void renderwin_progress(RenderWin *rw, int start_y, int nlines, int rect_ win_rct.xmin= win_rct.ymin= 0; window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax); + win_rct.ymax-= RW_HEADERY; + renderwin_get_disprect(rw, disprect); - - window_make_active(rw->win); + + /* for efficiency & speed; not drawing in Blender UI while rendering */ + //window_make_active(rw->win); glEnable(GL_SCISSOR_TEST); glaDefine2DArea(&win_rct); @@ -717,29 +777,87 @@ static void renderview_progress_display_cb(int y1, int y2, int w, int h, unsigne } } +/* in 3d view; display stats of rendered image */ +static void renderview_draw_render_info(char *str) +{ + if (render_view3d) { + View3D *v3d= render_view3d; + rcti vb, win_rct; + + calc_viewborder(v3d, &vb); + + bwin_get_rect(v3d->area->win, &win_rct); + glaDefine2DArea(&win_rct); + + glDrawBuffer(GL_FRONT); + + /* clear header rect */ + BIF_ThemeColor(TH_HEADER); + glRecti(vb.xmin, vb.ymax, vb.xmax, vb.ymax+RW_HEADERY); + + if(str) { + BIF_ThemeColor(TH_TEXT); + glRasterPos2i(vb.xmin+12, vb.ymax+5); + BMF_DrawString(G.fonts, str); + } + + glFlush(); + glDrawBuffer(GL_BACK); + + v3d->area->win_swap= WIN_FRONT_OK; + + } +} + + /* -------------- callbacks for render loop: interactivity ----------------------- */ -/* callback for print info in top header in interface */ +/* callback for print info in top header of renderwin */ +/* time is only not zero on last call, we then don't update the other stats */ static void printrenderinfo_cb(double time, int sample) { extern int mem_in_use; - extern char info_time_str[32]; // header_info.c - float megs_used_memory= mem_in_use/(1024.0*1024.0); + static int totvert=0, totvlak=0, tothalo=0, totlamp=0; + static float megs_used_memory=0.0; char str[300], *spos= str; - timestr(time, info_time_str); - spos+= sprintf(spos, "RENDER Fra:%d Ve:%d Fa:%d La:%d", (G.scene->r.cfra), R.totvert, R.totvlak, R.totlamp); - spos+= sprintf(spos, "Mem:%.2fM Time:%s ", megs_used_memory, info_time_str); - - if (R.r.mode & R_FIELDS) { - spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A'); + if(time==0.0) { + megs_used_memory= mem_in_use/(1024.0*1024.0); + totvert= R.totvert; + totvlak= R.totvlak; + totlamp= R.totlamp; + tothalo= R.tothalo; + } + + if(tothalo) + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, tothalo, totlamp, megs_used_memory); + else + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, totlamp, megs_used_memory); + + if(time==0.0) { + if (R.r.mode & R_FIELDS) { + spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A'); + } + if (sample!=-1) { + spos+= sprintf(spos, "Sample: %d ", sample); + } } - if (sample!=-1) { - spos+= sprintf(spos, "Sample: %d ", sample); + else { + extern char info_time_str[32]; // header_info.c + timestr(time, info_time_str); + spos+= sprintf(spos, " Time:%s ", info_time_str); } - screen_draw_info_text(G.curscreen, str); + if(render_win) { + if(render_win->render_text) MEM_freeN(render_win->render_text); + render_win->render_text= BLI_strdup(str); + glDrawBuffer(GL_FRONT); + renderwin_draw_render_info(render_win); + glFlush(); + glDrawBuffer(GL_BACK); + } + else renderview_draw_render_info(str); } /* -------------- callback system to allow ESC from rendering ----------------------- */ @@ -854,7 +972,7 @@ static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin) /* we set this flag to prevent renderwindow queue to execute another render */ R.flag= R_RENDERING; - if (R.displaymode == R_DISPLAYWIN || force_dispwin) { + if (G.displaymode == R_DISPLAYWIN || force_dispwin) { RE_set_initrenderdisplay_callback(NULL); RE_set_clearrenderdisplay_callback(renderwin_clear_display_cb); RE_set_renderdisplay_callback(renderwin_progress_display_cb); @@ -895,10 +1013,8 @@ static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin) } if(anim) update_for_newframe_muted(); // only when anim, causes redraw event which frustrates dispview - R.flag= 0; if (render_win) window_set_cursor(render_win->win, CURSOR_STD); - waitcursor(0); free_filesel_spec(G.scene->r.pic); @@ -907,8 +1023,18 @@ static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin) /* in dispiew it will destroy the image otherwise window_make_active() raises window at osx and sends redraws */ - if(R.displaymode==R_DISPLAYWIN) mainwindow_make_active(); - + if(G.displaymode==R_DISPLAYWIN) { + mainwindow_make_active(); + + /* after an envmap creation... */ + if(R.flag & R_REDRAW_PRV) { + BIF_all_preview_changed(); + } + allqueue(REDRAWBUTSSCENE, 0); // visualize fbuf for example + } + + R.flag= 0; + waitcursor(0); // waitcursor checks rendering R.flag... } /* finds area with a 'dispview' set */ @@ -986,6 +1112,22 @@ void BIF_do_ogl_render(View3D *ogl_render_view3d, int anim) G.scene->r.scemode &= ~R_OGL; } +void BIF_redraw_render_rect(void) +{ + + /* redraw */ + if (G.displaymode == R_DISPLAYWIN) { + // don't open render_win if rendering has been + // canceled or the render_win has been actively closed + if (render_win) { + renderwin_queue_redraw(render_win); + } + } else { + renderview_init_display_cb(); + renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); + } +} + void BIF_swap_render_rects(void) { unsigned int *temp; @@ -1009,19 +1151,20 @@ void BIF_swap_render_rects(void) temp= R.rectot; R.rectot= R.rectspare; R.rectspare= temp; - - /* redraw */ - if (R.displaymode == R_DISPLAYWIN) { - // don't open render_win if rendering has been - // canceled or the render_win has been actively closed + + if (G.displaymode == R_DISPLAYWIN) { if (render_win) { + char *tmp= render_win->render_text_spare; + render_win->render_text_spare= render_win->render_text; + render_win->render_text= tmp; + window_set_title(render_win->win, renderwin_get_title(1)); - renderwin_queue_redraw(render_win); + } - } else { - renderview_init_display_cb(); - renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); } + + /* redraw */ + BIF_redraw_render_rect(); } /* called from usiblender.c too, to free and close renderwin */ @@ -1030,6 +1173,8 @@ void BIF_close_render_display(void) if (render_win) { if (render_win->info_text) MEM_freeN(render_win->info_text); + if (render_win->render_text) MEM_freeN(render_win->render_text); + if (render_win->render_text_spare) MEM_freeN(render_win->render_text_spare); window_destroy(render_win->win); /* ghost close window */ MEM_freeN(render_win); @@ -1045,7 +1190,7 @@ void BIF_toggle_render_display(void) ScrArea *sa= find_dispimage_v3d(); if(R.rectot==NULL); // do nothing - else if (render_win && R.displaymode==R_DISPLAYWIN) { + else if (render_win && G.displaymode==R_DISPLAYWIN) { if(render_win->active) { mainwindow_raise(); mainwindow_make_active(); @@ -1057,13 +1202,13 @@ void BIF_toggle_render_display(void) render_win->active= 1; } } - else if (sa && R.displaymode==R_DISPLAYVIEW) { + else if (sa && G.displaymode==R_DISPLAYVIEW) { View3D *vd= sa->spacedata.first; vd->flag &= ~V3D_DISPIMAGE; scrarea_queue_winredraw(sa); } else { - if (R.displaymode == R_DISPLAYWIN) { + if (G.displaymode == R_DISPLAYWIN) { renderwin_init_display_cb(); } else { if (render_win) { diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c index 4bef0da4d07..ead7577b0d0 100644 --- a/source/blender/src/resources.c +++ b/source/blender/src/resources.c @@ -52,6 +52,8 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BKE_utildefines.h" + #include "BIF_gl.h" #include "BIF_resources.h" diff --git a/source/blender/src/screendump.c b/source/blender/src/screendump.c index 114be17afa3..7e54791dbd2 100644 --- a/source/blender/src/screendump.c +++ b/source/blender/src/screendump.c @@ -48,6 +48,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -65,7 +66,6 @@ #include "BSE_filesel.h" -#include "render.h" #include "mydevice.h" static unsigned int *dumprect=0; diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index 4c6ca1a2226..6f7eede12e2 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -82,7 +82,7 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" +#include "render.h" // RE_make_existing_file() void audio_fill(void *mixdown, Uint8 *sstream, int len); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index d7b8f6c22ad..e30edf6b874 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -74,7 +74,7 @@ #include "BSE_sequence.h" #include "blendef.h" -#include "render.h" +#include "render.h" // talks to entire render API, and igamtab Sequence *seq_arr[MAXSEQ+1]; int seqrectx, seqrecty; @@ -628,7 +628,6 @@ void do_cross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1 void do_gammacross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) { -/* extern unsigned short *igamtab1, *gamtab; render.h */ int fac1, fac2, col; int xo; char *rt1, *rt2, *rt; @@ -1949,11 +1948,11 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) oldcfra= CFRA; CFRA= seq->sfra + se->nr; waitcursor(1); - rectot= R.rectot; R.rectot= 0; + rectot= R.rectot; R.rectot= NULL; oldx= R.rectx; oldy= R.recty; /* needed because current 3D window cannot define the layers, like in a background render */ vd= G.vd; - G.vd= 0; + G.vd= NULL; RE_initrender(NULL); if (!G.background) { @@ -1970,7 +1969,7 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) se->ibuf->zbuf= (int *)R.rectz; /* make sure ibuf frees it */ se->ibuf->mall |= IB_zbuf; - R.rectz= 0; + R.rectz= NULL; } /* and restore */ diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index dcef102e54c..fd9a35df17a 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -97,7 +97,7 @@ #include "BSE_headerbuttons.h" #include "blendef.h" -#include "render.h" +#include "render.h" // darn schrijfplaatje() (ton) #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -106,7 +106,7 @@ #include "BIF_poseobject.h" -/* only used in toets.c */ +/* only used in toets.c and initrender.c */ /* this function doesn't really belong here */ /* ripped from render module */ void schrijfplaatje(char *name); diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 48d6919da7b..aac377af9f9 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -109,7 +109,7 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" +#include "render.h" // R.flag static int tbx1, tbx2, tby1, tby2, tbfontyofs, tbmain=0; static int tbmemx=TBOXX/2, tbmemy=(TBOXEL-0.5)*TBOXH, tboldwin, addmode= 0; diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 9bc8a1a152a..43fd434ebf2 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -116,7 +116,7 @@ #include "blendef.h" #include "radio.h" -#include "render.h" +#include "render.h" // RE_ free stuff #include "datatoc.h" #include "SYS_System.h" @@ -616,7 +616,6 @@ void exit_usiblender(void) #endif RE_free_render_data(); - RE_free_filt_mask(); free_txt_data(); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index cc4fd82bc2f..f809d9bde1b 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -81,7 +81,7 @@ #include "blendef.h" /* Modules used */ -#include "render.h" +#include "render.h" /* R. stuff for ogl view render */ #define TRACKBALLSIZE (1.1) #define BL_NEAR_CLIP 0.001 diff --git a/source/blender/src/writeavicodec.c b/source/blender/src/writeavicodec.c index 582b1e6503f..d832e4bdc68 100644 --- a/source/blender/src/writeavicodec.c +++ b/source/blender/src/writeavicodec.c @@ -53,7 +53,7 @@ #include "DNA_userdef_types.h" #include "render_types.h" -#include "render.h" +#include "render.h" // lotsof R. stuff #include "BKE_global.h" #include "BKE_scene.h" diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c index c4dde911d49..75b215f70bd 100644 --- a/source/blender/src/writeimage.c +++ b/source/blender/src/writeimage.c @@ -42,7 +42,7 @@ #include "BIF_writeimage.h" -#include "render.h" // RE_make_existing_file +#include "render.h" // RE_make_existing_file, R. stuff #ifdef HAVE_CONFIG_H #include <config.h> diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index 6a3f9493b01..43b4f6298e9 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -1032,7 +1032,7 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li // Export orco coords test. // Previously was done by checking orco pointer, however this can be non-null but still not initialized. // Test the rendermaterial texco flag instead. - bool EXPORT_ORCO = ((face0mat->ren->texco & TEXCO_ORCO)!=0); + bool EXPORT_ORCO = ((face0mat->texco & TEXCO_ORCO)!=0); string has_orco = "off"; if (EXPORT_ORCO) has_orco = "on"; diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp index 9310abfa4d6..5463016ea65 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -1167,7 +1167,7 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_ // Export orco coords test. // Previously was done by checking orco pointer, however this can be non-null but still not initialized. // Test the rendermaterial texco flag instead. - bool has_orco = ((face0mat->ren->texco & TEXCO_ORCO)!=0); + bool has_orco = ((face0mat->texco & TEXCO_ORCO)!=0); bool no_auto = true; //in case non-mesh, or mesh has no autosmooth float sm_angle = 0.1f; |