From aa939b859904fcfad5c6782e14621da74bbf8118 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sun, 4 Dec 2005 14:32:21 +0000 Subject: Orange branch feature; Material Layering (WIP, don't bugs for this in tracker yet please!) - New Panel "Layers" in Material buttons, allows to add unlimited amount of materials on top of each other. - Every Layer is actually just another Material, which gets rendered/shaded (including texture), and then added on top of previous layer with an operation like Mix, Add, Mult, etc. - Layers render fully independent, so bumpmaps are not passed on to next layers. - Per Layer you can set if it influences Diffuse, Specular or Alpha - If a Material returns alpha (like from texture), the alpha value is used for adding the layers too. - New texture "Map To" channel allows to have a texture work on a Layer - Each layer, including basis Material, can be turned on/off individually Notes: - at this moment, the full shading pass happens for each layer, including shadow, AO and raytraced mirror or transparency... - I had to remove old hacks from preview render, which corrected reflected normals for preview texturing. - still needs loadsa testing! --- source/blender/blenkernel/BKE_bad_level_calls.h | 1 - source/blender/blenkernel/BKE_material.h | 6 +- .../blenkernel/bad_level_call_stubs/stubs.c | 2 - source/blender/blenkernel/intern/displist.c | 14 - source/blender/blenkernel/intern/material.c | 102 ++-- source/blender/blenloader/intern/readfile.c | 35 +- source/blender/blenloader/intern/writefile.c | 5 + source/blender/include/butspace.h | 1 + source/blender/makesdna/DNA_material_types.h | 38 +- source/blender/render/extern/include/render.h | 7 +- .../blender/render/extern/include/render_types.h | 21 +- source/blender/render/intern/include/rendercore.h | 8 - source/blender/render/intern/source/initrender.c | 1 - source/blender/render/intern/source/rendercore.c | 196 ++++--- source/blender/render/intern/source/texture.c | 34 +- .../renderconverter/intern/convertBlenderScene.c | 2 - source/blender/src/buttons_shading.c | 303 +++++++++-- source/blender/src/drawview.c | 1 - source/blender/src/editobject.c | 60 ++- source/blender/src/header_buttonswin.c | 21 +- source/blender/src/headerbuttons.c | 11 + source/blender/src/interface_panel.c | 4 +- source/blender/src/previewrender.c | 583 +++++++++++---------- 23 files changed, 920 insertions(+), 536 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 905b6d3bf74..a8d9693f62f 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -158,7 +158,6 @@ void do_material_tex(ShadeInput *shi); 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); void RE_free_envmap(struct EnvMap *env); void RE_free_envmapdata(struct EnvMap *env); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index fcdbed10ffa..16a320010ec 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -48,16 +48,18 @@ void init_material(struct Material *ma); struct Material *add_material(char *name); struct Material *copy_material(struct Material *ma); void make_local_material(struct Material *ma); + struct Material ***give_matarar(struct Object *ob); short *give_totcolp(struct Object *ob); struct Material *give_current_material(struct Object *ob, int act); ID *material_from(struct Object *ob, int act); void assign_material(struct Object *ob, struct Material *ma, int act); void new_material_to_objectdata(struct Object *ob); + +struct Material *get_active_matlayer(struct Material *ma); void init_render_material(struct Material *ma); void init_render_materials(void); -void end_render_material(struct Material *ma); -void end_render_materials(void); + void automatname(struct Material *ma); void delete_material_index(void); diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 457c6a2d7e5..778cb71f99a 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -206,8 +206,6 @@ int BPY_call_importloader(char *name) void do_material_tex(ShadeInput *shi){} 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){} void RE_free_envmap(struct EnvMap *env){} struct EnvMap *RE_copy_envmap(struct EnvMap *env){ return env;} diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 9273bd8eb71..b143def9f32 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -726,15 +726,6 @@ static void init_fastshade_for_ob(Object *ob, int *need_orco_r, float mat[4][4], } } } -static void end_fastshade_for_ob(Object *ob) -{ - int a; - - for(a=0; atotcol; a++) { - Material *ma= give_current_material(ob, a+1); - if(ma) end_render_material(ma); - } -} void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r) { @@ -846,7 +837,6 @@ void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r if (dmNeedsFree) dm->release(dm); - end_fastshade_for_ob(ob); } void shadeDispList(Object *ob) @@ -986,8 +976,6 @@ void shadeDispList(Object *ob) dl= dl->next; } } - - end_fastshade_for_ob(ob); } void reshadeall_displist(void) @@ -1999,8 +1987,6 @@ void imagestodisplist(void) base= base->next; } - end_render_textures(); - allqueue(REDRAWVIEW3D, 0); } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index d303a7ed5bd..ef5a29020d4 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -36,33 +36,34 @@ #include #include "MEM_guardedalloc.h" +#include "DNA_curve_types.h" #include "DNA_material_types.h" -#include "DNA_texture_types.h" #include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_curve_types.h" #include "DNA_meta_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_texture_types.h" #include "BLI_blenlib.h" #include "BKE_bad_level_calls.h" -#include "BKE_utildefines.h" - +#include "BKE_blender.h" +#include "BKE_displist.h" #include "BKE_global.h" -#include "BKE_main.h" - -#include "BKE_mesh.h" #include "BKE_library.h" -#include "BKE_displist.h" +#include "BKE_main.h" #include "BKE_material.h" +#include "BKE_mesh.h" +#include "BKE_utildefines.h" #include "BPY_extern.h" +/* not material itself */ void free_material(Material *ma) { - int a; + MaterialLayer *ml; MTex *mtex; + int a; BPY_free_scriptlink(&ma->scriptlink); @@ -74,6 +75,11 @@ void free_material(Material *ma) if(ma->ramp_col) MEM_freeN(ma->ramp_col); if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); + + for(ml= ma->layers.first; ml; ml= ml->next) + if(ml->mat) ml->mat->id.us--; + + BLI_freelistN(&ma->layers); } void init_material(Material *ma) @@ -115,8 +121,9 @@ void init_material(Material *ma) ma->rampfac_col= 1.0; ma->rampfac_spec= 1.0; - ma->pr_lamp= 3; // two lamps, is bits - + ma->pr_lamp= 3; /* two lamps, is bits */ + ma->ml_flag= ML_RENDER; /* default render base material for layers */ + ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_TANGENT_STR; } @@ -134,6 +141,7 @@ Material *add_material(char *name) Material *copy_material(Material *ma) { Material *man; + MaterialLayer *ml; int a; man= copy_libblock(ma); @@ -149,9 +157,14 @@ Material *copy_material(Material *ma) } BPY_copy_scriptlink(&ma->scriptlink); + if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col); if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec); + duplicatelist(&man->layers, &ma->layers); + for(ml= man->layers.first; ml; ml= ml->next) + id_us_plus((ID *)ml->mat); + return man; } @@ -245,9 +258,25 @@ void make_local_material(Material *ma) new_id(0, (ID *)ma, 0); } else if(local && lib) { + Material *mat; + MaterialLayer *ml; + man= copy_material(ma); man->id.us= 0; + /* do material layers */ + for(mat= G.main->mat.first; mat; mat= mat->id.next) { + if(mat->id.lib==NULL) { + for(ml= mat->layers.first; ml; ml= ml->next) { + if(ml->mat==ma) { + ml->mat= man; + man->id.us++; + ma->id.us--; + } + } + } + } + /* do objects */ ob= G.main->object.first; while(ob) { @@ -534,6 +563,18 @@ void new_material_to_objectdata(Object *ob) ob->actcol= ob->totcol; } +Material *get_active_matlayer(Material *ma) +{ + MaterialLayer *ml; + + if(ma==NULL) return NULL; + + for(ml= ma->layers.first; ml; ml= ml->next) + if(ml->flag & ML_ACTIVE) break; + if(ml) + return ml->mat; + return ma; +} void init_render_material(Material *ma) { @@ -586,43 +627,30 @@ void init_render_material(Material *ma) ma->ambg= ma->amb*R.wrld.ambg; ma->ambb= ma->amb*R.wrld.ambb; + /* will become or-ed result of all layer modes */ + ma->mode_l= ma->mode; } void init_render_materials() { Material *ma; + MaterialLayer *ml; - ma= G.main->mat.first; - while(ma) { + /* two steps, first initialize, then or the flags for layers */ + for(ma= G.main->mat.first; ma; ma= ma->id.next) { if(ma->id.us) init_render_material(ma); - ma= ma->id.next; } -} - -void end_render_material(Material *ma) -{ - /* XXXX obsolete? check! */ - if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - if( !(ma->mode & MA_HALO) ) { - ma->r= ma->g= ma->b= 1.0; + for(ma= G.main->mat.first; ma; ma= ma->id.next) { + for(ml= ma->layers.first; ml; ml= ml->next) { + if(ml->mat) { + ma->texco |= ml->mat->texco; + ma->mode_l |= ml->mat->mode; + } } - } -} - -void end_render_materials() -{ - Material *ma; - - ma= G.main->mat.first; - while(ma) { - if(ma->id.us) end_render_material(ma); - ma= ma->id.next; - } - + } } - /* ****************** */ char colname_array[125][20]= { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1fb00163644..5207c79b0ca 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1,19 +1,12 @@ /* - * readfile.c - * - * .blend file reading - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** BEGIN GPL 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -31,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** * */ @@ -1983,6 +1976,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) static void lib_link_material(FileData *fd, Main *main) { Material *ma; + MaterialLayer *ml; MTex *mtex; int a; @@ -2000,6 +1994,10 @@ static void lib_link_material(FileData *fd, Main *main) } } lib_link_scriptlink(fd, &ma->id, &ma->scriptlink); + + for (ml=ma->layers.first; ml; ml=ml->next) + ml->mat= newlibadr_us(fd, ma->id.lib, ml->mat); + ma->id.flag -= LIB_NEEDLINK; } ma= ma->id.next; @@ -2010,8 +2008,6 @@ static void direct_link_material(FileData *fd, Material *ma) { int a; - direct_link_scriptlink(fd, &ma->scriptlink); - for(a=0; amtex[a]= newdataadr(fd, ma->mtex[a]); } @@ -2019,6 +2015,10 @@ 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); + direct_link_scriptlink(fd, &ma->scriptlink); + + link_list(fd, &ma->layers); + } /* ************ READ MESH ***************** */ @@ -5082,6 +5082,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF; ma->pad= 1; } + /* orange stuff, so should be done for 2.40 too */ + if(ma->layers.first==NULL) { + ma->ml_flag= ML_RENDER; + } } } @@ -5301,6 +5305,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) static void expand_material(FileData *fd, Main *mainvar, Material *ma) { + MaterialLayer *ml; int a; for(a=0; amtex[a]->object); } } + expand_doit(fd, mainvar, ma->ipo); + + for (ml=ma->layers.first; ml; ml=ml->next) { + if(ml->mat) + expand_doit(fd, mainvar, ml->mat); + } } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f941b5f77d2..0fd394428e3 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -994,6 +994,7 @@ static void write_textures(WriteData *wd, ListBase *idbase) static void write_materials(WriteData *wd, ListBase *idbase) { Material *ma; + MaterialLayer *ml; int a; ma= idbase->first; @@ -1010,6 +1011,10 @@ static void write_materials(WriteData *wd, ListBase *idbase) if(ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec); write_scriptlink(wd, &ma->scriptlink); + + for (ml=ma->layers.first; ml; ml=ml->next) + writestruct(wd, DATA, "MaterialLayer", 1, ml); + } ma= ma->id.next; } diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index e354b4b74d4..e62eb268ed9 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -180,6 +180,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); /* yafray: material preset menu event */ #define B_MAT_YF_PRESET 1217 +#define B_MAT_LAYERBROWSE 1218 /* *********************** */ #define B_TEXBUTS 1400 diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 5ef327502e1..395c438c6e3 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -34,10 +34,9 @@ #ifndef DNA_MATERIAL_TYPES_H #define DNA_MATERIAL_TYPES_H -/* #include "BLI_listBase.h" */ - #include "DNA_ID.h" #include "DNA_scriptlink_types.h" +#include "DNA_listBase.h" #ifndef MAX_MTEX #define MAX_MTEX 10 @@ -48,20 +47,32 @@ struct Ipo; struct Material; struct ColorBand; +typedef struct MaterialLayer { + struct MaterialLayer *next, *prev; + + struct Material *mat; + float blendfac; + short flag, blendmethod, menunr, pad; + int pad2; + +} MaterialLayer; + /* WATCH IT: change type? also make changes in ipo.h */ typedef struct Material { ID id; short colormodel, lay; /* lay: for dynamics (old engine, until 2.04) */ + /* note, keep this below synced with render_types.h */ 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, ref, spec, zoffs, add; float translucency; + /* end synced with render_types.h */ + float fresnel_mir, fresnel_mir_i; float fresnel_tra, fresnel_tra_i; float filter; /* filter added, for raytrace transparency */ @@ -69,16 +80,15 @@ typedef struct Material { short har; char seed1, seed2; - int mode; - int mode2; /* even more material settings :) */ + int mode, mode_l; /* mode_l is the or-ed result of all layer modes */ short flarec, starc, linec, ringc; float hasize, flaresize, subsize, flareboost; float strand_sta, strand_end, strand_ease; + float pad1; /* for buttons and render*/ char rgbsel, texact, pr_type, pad; - short pr_back, pr_lamp, septex, pad4; - int pad5; + short pr_back, pr_lamp, septex, ml_flag; /* ml_flag is for disable base material */ /* shaders */ short diff_shader, spec_shader; @@ -97,6 +107,7 @@ typedef struct Material { float rampfac_col, rampfac_spec; struct MTex *mtex[10]; + ListBase layers; struct Ipo *ipo; /* dynamic properties */ @@ -107,7 +118,7 @@ typedef struct Material { /* yafray: absorption color, dispersion parameters and material preset menu */ float YF_ar, YF_ag, YF_ab, YF_dscale, YF_dpwr; int YF_dsmp, YF_preset, YF_djit; - + ScriptLink scriptlink; } Material; @@ -161,7 +172,7 @@ typedef struct Material { #define MA_DIFF_LAMBERT 0 #define MA_DIFF_ORENNAYAR 1 #define MA_DIFF_TOON 2 -#define MA_DIFF_MINNAERT 3 +#define MA_DIFF_MINNAERT 3 /* spec_shader */ #define MA_SPEC_COOKTORR 0 @@ -224,6 +235,7 @@ typedef struct Material { #define MAP_AMB 2048 #define MAP_DISPLACE 4096 #define MAP_WARP 8192 +#define MAP_LAYER 16384 /* pr_type */ #define MA_FLAT 0 @@ -233,5 +245,13 @@ typedef struct Material { /* pr_back */ #define MA_DARK 1 +/* MaterialLayer flag */ +#define ML_ACTIVE 1 +#define ML_RENDER 2 +#define ML_NEG_NORMAL 4 +#define ML_DIFFUSE 8 +#define ML_SPECULAR 16 +#define ML_ALPHA 32 + #endif diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h index e3eb926192c..abde461a935 100644 --- a/source/blender/render/extern/include/render.h +++ b/source/blender/render/extern/include/render.h @@ -148,9 +148,7 @@ struct MTex; struct Tex; void init_render_textures(void); -void end_render_textures(void); void init_render_texture(struct Tex *tex); -void end_render_texture(struct Tex *tex); void do_material_tex(ShadeInput *shi); void do_lamp_tex(struct LampRen *la, float *lavec, ShadeInput *shi, float *fcol); @@ -162,7 +160,6 @@ void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, /* envmap (4) */ /* ------------------------------------------------------------------------- */ struct EnvMap; -struct Tex; void RE_free_envmapdata(struct EnvMap *env); void RE_free_envmap(struct EnvMap *env); @@ -173,6 +170,9 @@ struct EnvMap *RE_copy_envmap(struct EnvMap *env); /* --------------------------------------------------------------------- */ /* rendercore (12) */ /* --------------------------------------------------------------------- */ +struct MaterialLayer; +struct ShadeResult; + float Phong_Spec(float *n, float *l, float *v, int hard, int tangent); float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent); float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent); @@ -188,6 +188,7 @@ void ramp_diffuse_result(float *diff, ShadeInput *shi); void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec); void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi); +void matlayer_blend(struct MaterialLayer *ml, float blendfac, struct ShadeResult *target, struct ShadeResult *src); /* --------------------------------------------------------------------- */ /* ray.c (2) */ diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 8118e72f24a..ea3463f96ae 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** BEGIN GPL 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #ifndef RENDER_TYPES_H @@ -58,6 +55,15 @@ typedef struct TexResult { float *nor; } TexResult; +/* localized shade result data */ +typedef struct ShadeResult +{ + float diff[3]; + float spec[3]; + float alpha; + +} ShadeResult; + /* localized renderloop data */ typedef struct ShadeInput { @@ -79,10 +85,11 @@ typedef struct ShadeInput /* individual copies: */ int har; + float layerfac; /* texture coordinates */ float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; - float vn[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3]; + float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3]; /* dx/dy OSA coordinates */ float dxco[3], dyco[3]; diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 0859620982c..8f236c502f4 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -46,14 +46,6 @@ struct HaloRen; struct ShadeInput; -typedef struct ShadeResult -{ - float diff[3]; - float spec[3]; - float alpha; - -} ShadeResult; - typedef struct PixStr { struct PixStr *next; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 84eb9d9dfca..54cfc1742e8 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -536,7 +536,6 @@ void RE_free_render_data() R.rectz= NULL; R.rectspare= NULL; - end_render_material(&defmaterial); free_filt_mask(); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index b1ee0908eef..28eca24856e 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1107,65 +1107,84 @@ void shade_color(ShadeInput *shi, ShadeResult *shr) shr->alpha= shi->alpha; } -/* r g b = 1 value, col = vector */ -static void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) +/* r g b = current value, col = new value, fac==0 is no change */ +/* if g==NULL, it only does r channel */ +void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) { float tmp, facm= 1.0-fac; switch (type) { case MA_RAMP_BLEND: *r = facm*(*r) + fac*col[0]; - *g = facm*(*g) + fac*col[1]; - *b = facm*(*b) + fac*col[2]; + if(g) { + *g = facm*(*g) + fac*col[1]; + *b = facm*(*b) + fac*col[2]; + } break; case MA_RAMP_ADD: *r += fac*col[0]; - *g += fac*col[1]; - *b += fac*col[2]; + if(g) { + *g += fac*col[1]; + *b += fac*col[2]; + } break; case MA_RAMP_MULT: *r *= (facm + fac*col[0]); - *g *= (facm + fac*col[1]); - *b *= (facm + fac*col[2]); + if(g) { + *g *= (facm + fac*col[1]); + *b *= (facm + fac*col[2]); + } break; case MA_RAMP_SCREEN: - *r = 1.0-(facm + (1.0 - col[0]))*(1.0 - *r); - *g = 1.0-(facm + (1.0 - col[1]))*(1.0 - *g); - *b = 1.0-(facm + (1.0 - col[2]))*(1.0 - *b); + *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r); + if(g) { + *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g); + *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b); + } break; case MA_RAMP_SUB: *r -= fac*col[0]; - *g -= fac*col[1]; - *b -= fac*col[2]; + if(g) { + *g -= fac*col[1]; + *b -= fac*col[2]; + } break; case MA_RAMP_DIV: if(col[0]!=0.0) *r = facm*(*r) + fac*(*r)/col[0]; - if(col[1]!=0.0) - *g = facm*(*g) + fac*(*g)/col[1]; - if(col[2]!=0.0) - *b = facm*(*b) + fac*(*b)/col[2]; + if(g) { + if(col[1]!=0.0) + *g = facm*(*g) + fac*(*g)/col[1]; + if(col[2]!=0.0) + *b = facm*(*b) + fac*(*b)/col[2]; + } break; case MA_RAMP_DIFF: *r = facm*(*r) + fac*fabs(*r-col[0]); - *g = facm*(*g) + fac*fabs(*g-col[1]); - *b = facm*(*b) + fac*fabs(*b-col[2]); + if(g) { + *g = facm*(*g) + fac*fabs(*g-col[1]); + *b = facm*(*b) + fac*fabs(*b-col[2]); + } break; case MA_RAMP_DARK: tmp= fac*col[0]; if(tmp < *r) *r= tmp; - tmp= fac*col[1]; - if(tmp < *g) *g= tmp; - tmp= fac*col[2]; - if(tmp < *b) *b= tmp; + if(g) { + tmp= fac*col[1]; + if(tmp < *g) *g= tmp; + tmp= fac*col[2]; + if(tmp < *b) *b= tmp; + } break; case MA_RAMP_LIGHT: tmp= fac*col[0]; if(tmp > *r) *r= tmp; - tmp= fac*col[1]; - if(tmp > *g) *g= tmp; - tmp= fac*col[2]; - if(tmp > *b) *b= tmp; + if(g) { + tmp= fac*col[1]; + if(tmp > *g) *g= tmp; + tmp= fac*col[2]; + if(tmp > *b) *b= tmp; + } break; } @@ -1342,6 +1361,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) memset(shr, 0, sizeof(ShadeResult)); + /* copy all relevant material vars, note, keep this synced with render_types.h */ + memcpy(&shi->r, &ma->r, 23*sizeof(float)); + /* set special cases */ + shi->har= ma->har; + if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0; + /* separate loop */ if(ma->mode & MA_ONLYSHADOW) { float ir; @@ -1760,21 +1785,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) 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]+= 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]+= 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]+= 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); if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi); @@ -1796,7 +1814,7 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i VlakRen *vlr= shi->vlr; float l, dl; short texco= shi->mat->texco; - int mode= shi->mat->mode; + int mode= shi->mat->mode_l; /* or-ed result for all layers */ char p1, p2, p3; /* for rendering of quads, the following values are used to denote vertices: @@ -2135,7 +2153,20 @@ static float isec_view_line(float *view, float *v3, float *v4) } #endif - +void matlayer_blend(MaterialLayer *ml, float blendfac, ShadeResult *target, ShadeResult *src) +{ + + if(ml->flag & ML_DIFFUSE) + ramp_blend(ml->blendmethod, target->diff, target->diff+1, target->diff+2, blendfac*src->alpha, src->diff); + + if(ml->flag & ML_SPECULAR) + ramp_blend(ml->blendmethod, target->spec, target->spec+1, target->spec+2, blendfac*src->alpha, src->spec); + + if(ml->flag & ML_ALPHA) + ramp_blend(ml->blendmethod, &target->alpha, NULL, NULL, blendfac, &src->alpha); +} + + /* x,y: window coordinate from 0 to rectx,y */ /* return pointer to rendered face */ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, float *rco) @@ -2161,18 +2192,15 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa } else if( (facenr & 0x7FFFFF) <= R.totvlak) { VertRen *v1, *v2, *v3; + Material *mat; + MaterialLayer *ml; float alpha, fac, zcor; vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF); shi.vlr= vlr; - shi.mat= vlr->mat; + mat= 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); /* copy the face normal (needed because it gets flipped for tracing */ @@ -2338,31 +2366,77 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa } } - /* ------ main shading loop */ - shade_lamp_loop(&shi, &shr); + /* ------ main shading loop -------- */ + VECCOPY(shi.vno, shi.vn); + + if(shi.mat->ml_flag & ML_RENDER) { + + shade_lamp_loop(&shi, &shr); /* clears shr */ - if(shi.translucency!=0.0) { - ShadeResult shr_t; + if(shi.translucency!=0.0) { + ShadeResult shr_t; + + VECCOPY(shi.vn, shi.vno); + VecMulf(shi.vn, -1.0); + VecMulf(shi.facenor, -1.0); + shade_lamp_loop(&shi, &shr_t); + 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.facenor, -1.0); + } - VecMulf(shi.vn, -1.0); - VecMulf(shi.facenor, -1.0); - shade_lamp_loop(&shi, &shr_t); - 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.facenor, -1.0); - } - - if(R.r.mode & R_RAYTRACE) { - if(shi.ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { - ray_trace(&shi, &shr); + if(R.r.mode & R_RAYTRACE) { + if(shi.ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { + ray_trace(&shi, &shr); + } + } + else { + /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */ + if(shi.mat->mode & MA_RAYTRANSP) shr.alpha= 1.0; } } else { - // doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this - if(shi.mat->mode & MA_RAYTRANSP) shr.alpha= 1.0; + memset(&shr, 0, sizeof(ShadeResult)); + shr.alpha= 1.0f; + } + + for(ml= shi.mat->layers.first; ml; ml= ml->next) { + if(ml->mat && (ml->flag & ML_RENDER)) { + ShadeResult shrlay; + + shi.mat= ml->mat; + shi.layerfac= ml->blendfac; + VECCOPY(shi.vn, shi.vno); + if(ml->flag & ML_NEG_NORMAL) + VecMulf(shi.vn, -1.0); + + shade_lamp_loop(&shi, &shrlay); /* clears shrlay */ + + if(R.r.mode & R_RAYTRACE) { + if(shi.ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { + ray_trace(&shi, &shr); + } + } + else { + /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */ + if(shi.mat->mode & MA_RAYTRANSP) shr.alpha= 1.0; + } + + matlayer_blend(ml, shi.layerfac, &shr, &shrlay); + } } + shi.mat= mat; + + /* after shading and composit layers */ + if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f; + if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f; + if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f; + + if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f; + if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f; + if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f; VECADD(col, shr.diff, shr.spec); diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 3653b82f581..344957608fe 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -218,27 +218,6 @@ void init_render_textures() /* ------------------------------------------------------------------------- */ -void end_render_texture(Tex *tex) -{ - - -} - -/* ------------------------------------------------------------------------- */ - -void end_render_textures() -{ - Tex *tex; - - tex= G.main->tex.first; - while(tex) { - if(tex->id.us) end_render_texture(tex); - tex= tex->id.next; - } - -} - -/* ------------------------------------------------------------------------- */ /* this allows colorbanded textures to control normals as well */ static void tex_normal_derivate(Tex *tex, TexResult *texres) @@ -1292,9 +1271,9 @@ static void texture_rgb_blend(float *in, float *tex, float *out, float fact, flo case MTEX_SCREEN: fact*= facg; facm= 1.0-facg; - in[0]= 1.0-(facm+fact*(1.0-tex[0]))*(1.0-out[0]); - in[1]= 1.0-(facm+fact*(1.0-tex[1]))*(1.0-out[1]); - in[2]= 1.0-(facm+fact*(1.0-tex[2]))*(1.0-out[2]); + in[0]= 1.0 - (facm+fact*(1.0-tex[0])) * (1.0-out[0]); + in[1]= 1.0 - (facm+fact*(1.0-tex[1])) * (1.0-out[1]); + in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]); break; case MTEX_SUB: @@ -1825,6 +1804,13 @@ void do_material_tex(ShadeInput *shi) if(shi->translucency<0.0) shi->translucency= 0.0; else if(shi->translucency>1.0) shi->translucency= 1.0; } + if(mtex->mapto & MAP_LAYER) { + int flip= mtex->maptoneg & MAP_LAYER; + + shi->layerfac= texture_value_blend(mtex->def_var, shi->layerfac, texres.tin, varfac, mtex->blendtype, flip); + if(shi->layerfac<0.0) shi->layerfac= 0.0; + else if(shi->layerfac>1.0) shi->layerfac= 1.0; + } if(mtex->mapto & MAP_AMB) { int flip= mtex->maptoneg & MAP_AMB; diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 07ae6dbcdd2..665bd3ce6de 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -2424,8 +2424,6 @@ void RE_freeRotateBlenderScene(void) free_mesh_orco_hash(); - end_render_textures(); - end_render_materials(); end_radio_render(); if(R.wrld.aosphere) { MEM_freeN(R.wrld.aosphere); diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 73243750841..c37544e911a 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -376,17 +376,20 @@ static void drawcolorband_cb(void) { ID *id, *idfrom; - buttons_active_id(&id, &idfrom); + buttons_active_id(&id, &idfrom); /* base material, not the matlayer! */ if( GS(id->name)==ID_TE) { Tex *tex= (Tex *)id; drawcolorband(tex->coba, 10,145,300,30); } else if( GS(id->name)==ID_MA) { Material *ma= (Material *)id; - if(ma->ramp_show==0) - drawcolorband(ma->ramp_col, 10,110,300,30); - else - drawcolorband(ma->ramp_spec, 10,110,300,30); + ma= get_active_matlayer(ma); + if(ma) { + if(ma->ramp_show==0) + drawcolorband(ma->ramp_col, 10,110,300,30); + else + drawcolorband(ma->ramp_spec, 10,110,300,30); + } } } @@ -756,7 +759,7 @@ void do_texbuts(unsigned short event) do_colorbandbuts(tex->coba, event); } else { - ma= (Material *)id; + ma= get_active_matlayer((Material *)id); if(ma->ramp_show==0) do_colorbandbuts(ma->ramp_col, event); else do_colorbandbuts(ma->ramp_spec, event); } @@ -1422,7 +1425,10 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l if(uiNewPanel(curarea, block, "Texture", "Texture", 320, 0, 318, 204)==0) return; /* first do the browse but */ - buttons_active_id(&id, &idfrom); + id= (ID *)mtex->tex; + if(ma) idfrom= &ma->id; + else if(wrld) idfrom= &wrld->id; + else idfrom= &la->id; uiBlockSetCol(block, TH_BUT_SETTING2); if(ma) { @@ -2012,16 +2018,12 @@ static void world_panel_amb_occ(World *wrld) static void world_panel_world(World *wrld) { uiBlock *block; - ID *id, *idfrom; block= uiNewBlock(&curarea->uiblocks, "world_panel_world", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "World", "World", 320, 0, 318, 204)==0) return; - /* first do the browse but */ - buttons_active_id(&id, &idfrom); - uiBlockSetCol(block, TH_BUT_SETTING2); - std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, id, idfrom, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA); + std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, (ID *)wrld, (ID *)G.scene, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA); if(wrld==NULL) return; @@ -2455,7 +2457,6 @@ static void lamp_panel_yafray(Object *ob, Lamp *la) static void lamp_panel_lamp(Object *ob, Lamp *la) { uiBlock *block; - ID *id, *idfrom; float grid= 0.0; short xco; @@ -2467,11 +2468,8 @@ static void lamp_panel_lamp(Object *ob, Lamp *la) uiSetButLock(la->id.lib!=0, "Can't edit library data"); - /* first do the browse but */ - buttons_active_id(&id, &idfrom); - uiBlockSetCol(block, TH_BUT_SETTING2); - xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, id, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0); + xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, (ID *)la, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0); uiBlockSetCol(block, TH_AUTO); uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:", xco,180,300-xco,20,&la->dist, 0.01, 5000.0*grid, 100, 0, "Sets the distance value at which light intensity is half"); @@ -2563,9 +2561,11 @@ void do_matbuts(unsigned short event) Material *ma; MTex *mtex; + /* all operations default on active material layer here */ + ma = get_active_matlayer(G.buts->lockpoin); + switch(event) { case B_MAT_YF_PRESET: { - ma = G.buts->lockpoin; switch (ma->YF_preset) { case 0: /* normal mode, no reflection/refraction */ @@ -2645,7 +2645,6 @@ void do_matbuts(unsigned short event) case B_MATHALO: /* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE */ /* same for 'xtreme alpha' which is 'only shadow' */ - ma= G.buts->lockpoin; if((ma->mode & MA_HALO)==0) { ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV); } @@ -2654,7 +2653,6 @@ void do_matbuts(unsigned short event) shade_buttons_change_3d(); break; case B_TEXCLEAR: - ma= G.buts->lockpoin; mtex= ma->mtex[(int) ma->texact ]; if(mtex) { if(mtex->tex) mtex->tex->id.us--; @@ -2667,7 +2665,6 @@ void do_matbuts(unsigned short event) } break; case B_MTEXCOPY: - ma= G.buts->lockpoin; if(ma && ma->mtex[(int)ma->texact] ) { mtex= ma->mtex[(int)ma->texact]; if(mtex->tex==0) { @@ -2680,7 +2677,6 @@ void do_matbuts(unsigned short event) } break; case B_MTEXPASTE: - ma= G.buts->lockpoin; if(ma && mtexcopied && mtexcopybuf.tex) { if(ma->mtex[(int)ma->texact]==0 ) ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); @@ -2696,14 +2692,12 @@ void do_matbuts(unsigned short event) } break; case B_MATLAY: - ma= G.buts->lockpoin; if(ma && ma->lay==0) { ma->lay= 1; scrarea_queue_winredraw(curarea); } break; case B_MATZTRANSP: - ma= G.buts->lockpoin; if(ma) { ma->mode &= ~MA_RAYTRANSP; allqueue(REDRAWBUTSSHADING, 0); @@ -2711,7 +2705,6 @@ void do_matbuts(unsigned short event) } break; case B_MATRAYTRANSP: - ma= G.buts->lockpoin; if(ma) { ma->mode &= ~MA_ZTRA; allqueue(REDRAWBUTSSHADING, 0); @@ -2719,7 +2712,6 @@ void do_matbuts(unsigned short event) } break; case B_MATCOLORBAND: - ma= G.buts->lockpoin; if(ma) { if(ma->mode & MA_RAMP_COL) if(ma->ramp_col==NULL) ma->ramp_col= add_colorband(); @@ -2731,7 +2723,33 @@ void do_matbuts(unsigned short event) shade_buttons_change_3d(); } break; - + case B_MAT_LAYERBROWSE: + ma= G.buts->lockpoin; /* use base material instead */ + if(ma) { + MaterialLayer *ml; + + /* the one with a menu set is the browser */ + for(ml= ma->layers.first; ml; ml= ml->next) { + if(ml->menunr) { + if(ml->menunr==32767) { + if(ml->mat) { + ml->mat->id.us--; + ml->mat= copy_material(ml->mat); + } + else ml->mat= add_material("Layer"); + } + else { + ml->mat= BLI_findlink(&G.main->mat, ml->menunr-1); + ml->mat->id.us++; + } + allqueue(REDRAWBUTSSHADING, 0); + BIF_all_preview_changed(); + + break; + } + } + } + break; } } @@ -2792,7 +2810,7 @@ static void material_panel_map_to(Material *ma) uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir", 60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value"); uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha", 110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value"); uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value"); - uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "Translu", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value"); + uiDefButBitS(block, TOG3, MAP_LAYER, B_MATPRV, "Layer", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value"); uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp", 265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface"); uiBlockEndAlign(block); @@ -3155,9 +3173,188 @@ static void material_panel_shading(Material *ma) uiDefButBitI(block, TOG, MA_RADIO, 0, "Radio", 245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering"); } +} + +static void matlayer_add(void *ma_v, void *ml_v) +{ + Material *ma= ma_v; + MaterialLayer *ml= ml_v, *mlnew; + + mlnew= MEM_callocN(sizeof(MaterialLayer), "mat layer"); + + if(ml==NULL) + BLI_addhead(&ma->layers, mlnew); + else + BLI_insertlink(&ma->layers, ml, mlnew); + + mlnew->blendfac= 0.5f; + mlnew->flag= ML_RENDER|ML_DIFFUSE|ML_SPECULAR; + + BIF_undo_push("Add Material Layer"); + allqueue(REDRAWBUTSSHADING, 0); +} + +static void matlayer_moveUp(void *ma_v, void *ml_v) +{ + Material *ma= ma_v; + MaterialLayer *ml= ml_v; + + if (ml->prev) { + BLI_remlink(&ma->layers, ml); + BLI_insertlink(&ma->layers, ml->prev->prev, ml); + } + + BIF_undo_push("Move Material Layer"); +} +static void matlayer_moveDown(void *ma_v, void *ml_v) +{ + Material *ma= ma_v; + MaterialLayer *ml= ml_v; + + if (ml->next) { + BLI_remlink(&ma->layers, ml); + BLI_insertlink(&ma->layers, ml->next, ml); + } + + BIF_undo_push("Move Material Layer"); } +static void matlayer_del(void *ma_v, void *ml_v) +{ + Material *ma= ma_v; + MaterialLayer *ml= ml_v; + + BLI_remlink(&ma->layers, ml); + if(ml->mat) ml->mat->id.us--; + MEM_freeN(ml); + + BIF_undo_push("Delete Material Layer"); +} + +static void matlayer_active(void *ma_v, void *ml_v) +{ + Material *ma= ma_v; + MaterialLayer *ml; + + for(ml= ma->layers.first; ml; ml= ml->next) { + if(ml==ml_v) + ml->flag |= ML_ACTIVE; + else + ml->flag &= ~ML_ACTIVE; + } + BIF_undo_push("Activate Material Layer"); +} + +static void material_panel_layers(Material *ma) +{ + uiBlock *block; + uiBut *but; + MaterialLayer *ml; + int yco= 155, rb_col; + char *strp; + + block= uiNewBlock(&curarea->uiblocks, "material_panel_layers", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Preview", "Material"); + if(uiNewPanel(curarea, block, "Layers", "Material", 0, 0, 318, 204)==0) return; + + uiNewPanelHeight(block, 204); + + /* Active button for current material */ + uiBlockBeginAlign(block); + for(ml= ma->layers.first; ml; ml= ml->next) + if(ml->flag & ML_ACTIVE) break; + + if(ml==NULL) + but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL, 10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material"); + else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ", 10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material"); + uiButSetFunc(but, matlayer_active, ma, NULL); + + /* Enable/disable for current material */ + if(ma->ml_flag & ML_RENDER) + uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT, 30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material"); + else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material"); + + uiBlockEndAlign(block); + /* label */ + uiDefBut(block, LABEL, B_NOP, ma->id.name+2, 60, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* add layer */ + but= uiDefBut(block, BUT, B_NOP, "Add Layer", 200, 180,110,20, NULL, 0, 0, 0, 0, "Add a new Material Layer"); + uiButSetFunc(but, matlayer_add, ma, NULL); + + + for(ml= ma->layers.first; ml; ml= ml->next) { + + /* rounded header */ + rb_col= (ml->flag & ML_ACTIVE)?40:20; + uiDefBut(block, ROUNDBOX, B_DIFF, "", 8, yco-48, 304, 71, NULL, 5.0, 0.0, 3 , rb_col-20, ""); + + /* Active button */ + uiBlockBeginAlign(block); + if(ml->flag & ML_ACTIVE) + but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL, 10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer"); + else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ", 10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer"); + uiButSetFunc(but, matlayer_active, ma, ml); + + /* enable/disable button */ + if(ml->flag & ML_RENDER) + uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT, 30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer"); + else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer"); + + uiBlockBeginAlign(block); + + /* browse button */ + IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), (ID *)ma, NULL); + ml->menunr= 0; + uiDefButS(block, MENU, B_MAT_LAYERBROWSE, strp, 60,yco,20,20, &ml->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW"); + if(strp) MEM_freeN(strp); + + /* name */ + if(ml->mat) { + but= uiDefBut(block, TEX, B_IDNAME, "MA:",80, yco, 120, 20, ml->mat->id.name+2, 0.0, 19.0, 0, 0, "Rename Material"); + uiButSetFunc(but, test_idbutton_cb, ml->mat->id.name, NULL); + } + else + uiDefBut(block, LABEL, B_NOP, "No Material",80, yco, 120, 20, NULL, 0.0, 0.0, 0, 0, ""); + + /* add new */ + but= uiDefBut(block, BUT, B_NOP, "Add", 200, yco,50,20, NULL, 0, 0, 0, 0, "Add a new Material Layer"); + uiButSetFunc(but, matlayer_add, ma, ml); + + /* move up/down/delete */ + but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_UP, 250, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer up"); + uiButSetFunc(but, matlayer_moveUp, ma, ml); + + but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_DOWN, 270, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer down"); + uiButSetFunc(but, matlayer_moveDown, ma, ml); + + but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_X, 290, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete material layer"); + uiButSetFunc(but, matlayer_del, ma, ml); + + /* blend slider and operation */ + uiBlockBeginAlign(block); + yco-= 25; + uiDefButS(block, MENU, B_MATPRV, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8", + 35,yco,100,20, &ml->blendmethod, 0, 0, 0, 0, "Blending method for Ramp (uses alpha in Colorband)"); + uiDefButF(block, NUMSLI, B_MATPRV, "Blend:",135,yco,175,20, &ml->blendfac, 0.0, 1.0, 100, 0, "Blending factor"); + + /* output */ + yco-=20; + uiDefButBitS(block, TOG, ML_DIFFUSE, B_MATPRV, "Diff", 35,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Diffuse"); + uiDefButBitS(block, TOG, ML_SPECULAR, B_MATPRV, "Spec", 85,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Specular"); + uiDefButBitS(block, TOG, ML_ALPHA, B_MATPRV, "Alpha", 135,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Alpha"); + uiDefButBitS(block, TOG, ML_NEG_NORMAL, B_MATPRV, "Negate Normal", 185,yco,125,20, &ml->flag, 0, 0, 0, 0, "Negate normal for this layer"); + + yco-= 30; + + uiBlockEndAlign(block); + } + + if(yco < 0) uiNewPanelHeight(block, 204-yco); + +} + + static void material_panel_ramps(Material *ma) { uiBlock *block; @@ -3240,7 +3437,7 @@ static void material_panel_material(Object *ob, Material *ma) if(uiNewPanel(curarea, block, "Material", "Material", 320, 0, 318, 204)==0) return; /* first do the browse but */ - buttons_active_id(&id, &idfrom); + buttons_active_id(&id, &idfrom); /* base material, not the matlayer! */ uiBlockSetCol(block, TH_BUT_SETTING2); std_libbuttons(block, 8, 200, 0, NULL, B_MATBROWSE, id, idfrom, &(G.buts->menunr), B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA); @@ -3281,8 +3478,8 @@ static void material_panel_material(Object *ob, Material *ma) if(ob->totcol==0) return; uiSetButLock(id->lib!=0, "Can't edit library data"); - ma= give_current_material(ob, ob->actcol); - if(ma==0) return; + ma= get_active_matlayer(ma); + if(ma==NULL) return; if(ma->dynamode & MA_DRAW_DYNABUTS) { uiBlockBeginAlign(block); @@ -3401,23 +3598,30 @@ void material_panels() material_panel_material(ob, ma); if(ma) { - material_panel_ramps(ma); - material_panel_shading(ma); - if (G.scene->r.renderer==R_INTERN) - material_panel_tramir(ma); - else { - if (ma->YF_ar==0.f) { - ma->YF_ar = ma->YF_ag = ma->YF_ab = 1; - ma->YF_dscale = 1; - } - material_panel_tramir_yafray(ma); - } - material_panel_texture(ma); + material_panel_layers(ma); - mtex= ma->mtex[ ma->texact ]; - if(mtex && mtex->tex) { - material_panel_map_input(ob, ma); - material_panel_map_to(ma); + ma= get_active_matlayer(ma); + if(ma) { + material_panel_ramps(ma); + material_panel_shading(ma); + + if (G.scene->r.renderer==R_INTERN) + material_panel_tramir(ma); + else { + if(ma->YF_ar==0.f) { + ma->YF_ar = ma->YF_ag = ma->YF_ab = 1; + ma->YF_dscale = 1; + } + material_panel_tramir_yafray(ma); + } + + material_panel_texture(ma); + + mtex= ma->mtex[ ma->texact ]; + if(mtex && mtex->tex) { + material_panel_map_input(ob, ma); + material_panel_map_to(ma); + } } } } @@ -3478,6 +3682,7 @@ void texture_panels() if(G.buts->texfrom==0) { if(ob) { ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma) mtex= ma->mtex[ ma->texact ]; } } @@ -3601,8 +3806,8 @@ void clever_numbuts_buts() break; case TAB_SHADING_MAT: - ma= G.buts->lockpoin; - + ma= get_active_matlayer(G.buts->lockpoin); + /* Build a hex value */ if (ma){ sprintf(hexrgb, "%02X%02X%02X", (int)(ma->r*255), (int)(ma->g*255), (int)(ma->b*255)); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index b470d2ab6af..d4654dd6718 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -343,7 +343,6 @@ static void draw_bgpic(void) init_render_texture(bgpic->tex); free_unused_animimages(); ima= bgpic->tex->ima; - end_render_texture(bgpic->tex); } else { ima= bgpic->ima; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 811dbd79f23..bb5f66e4932 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -3994,6 +3994,40 @@ void single_user(void) /* ************************************************************* */ +/* helper for below, ma was checked to be not NULL */ +static void make_local_makelocalmaterial(Material *ma) +{ + MaterialLayer *ml; + ID *id; + int b; + + make_local_material(ma); + + for(b=0; bmtex[b] && ma->mtex[b]->tex) { + make_local_texture(ma->mtex[b]->tex); + } + } + + id= (ID *)ma->ipo; + if(id && id->lib) make_local_ipo(ma->ipo); + + for(ml=ma->layers.first; ml; ml= ml->next) { + if(ml->mat) { + make_local_material(ml->mat); + + for(b=0; bmat->mtex[b] && ml->mat->mtex[b]->tex) { + make_local_texture(ml->mat->mtex[b]->tex); + } + } + + id= (ID *)ml->mat->ipo; + if(id && id->lib) make_local_ipo(ml->mat->ipo); + } + + } +} void make_local(void) { @@ -4116,34 +4150,16 @@ void make_local(void) for(a=0; atotcol; a++) { ma= ob->mat[a]; - if(ma) { - make_local_material(ma); - - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - make_local_texture(ma->mtex[b]->tex); - } - } - id= (ID *)ma->ipo; - if(id && id->lib) make_local_ipo(ma->ipo); - } + if(ma) + make_local_makelocalmaterial(ma); } matarar= (Material ***)give_matarar(ob); for(a=0; atotcol; a++) { ma= (*matarar)[a]; - if(ma) { - make_local_material(ma); - - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - make_local_texture(ma->mtex[b]->tex); - } - } - id= (ID *)ma->ipo; - if(id && id->lib) make_local_ipo(ma->ipo); - } + if(ma) + make_local_makelocalmaterial(ma); } } } diff --git a/source/blender/src/header_buttonswin.c b/source/blender/src/header_buttonswin.c index 7b992263bb7..9d8f05aa835 100644 --- a/source/blender/src/header_buttonswin.c +++ b/source/blender/src/header_buttonswin.c @@ -62,6 +62,7 @@ #include "BIF_butspace.h" #include "BKE_armature.h" +#include "BKE_blender.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" @@ -72,6 +73,7 @@ #include "BSE_headerbuttons.h" #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" #include "blendef.h" #include "mydevice.h" @@ -98,9 +100,12 @@ void free_matcopybuf(void) if(matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col); if(matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec); + matcopybuf.ramp_col= NULL; matcopybuf.ramp_spec= NULL; + BLI_freelistN(&matcopybuf.layers); + default_mtex(&mtexcopybuf); } @@ -109,6 +114,7 @@ void do_buts_buttons(short event) static short matcopied=0; MTex *mtex; Material *ma; + MaterialLayer *ml; ID id; int a; float dx, dy; @@ -143,9 +149,10 @@ void do_buts_buttons(short event) break; case B_MATCOPY: if(G.buts->lockpoin) { + ma= G.buts->lockpoin; if(matcopied) free_matcopybuf(); - memcpy(&matcopybuf, G.buts->lockpoin, sizeof(Material)); + memcpy(&matcopybuf, ma, sizeof(Material)); if(matcopybuf.ramp_col) matcopybuf.ramp_col= MEM_dupallocN(matcopybuf.ramp_col); if(matcopybuf.ramp_spec) matcopybuf.ramp_spec= MEM_dupallocN(matcopybuf.ramp_spec); @@ -155,12 +162,15 @@ void do_buts_buttons(short event) matcopybuf.mtex[a]= MEM_dupallocN(mtex); } } + duplicatelist(&matcopybuf.layers, &ma->layers); + matcopied= 1; } break; case B_MATPASTE: if(matcopied && G.buts->lockpoin) { ma= G.buts->lockpoin; + /* free current mat */ if(ma->ramp_col) MEM_freeN(ma->ramp_col); if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); @@ -169,6 +179,10 @@ void do_buts_buttons(short event) if(mtex && mtex->tex) mtex->tex->id.us--; if(mtex) MEM_freeN(mtex); } + for(ml= ma->layers.first; ml; ml= ml->next) + if(ml->mat) ml->mat->id.us--; + + BLI_freelistN(&ma->layers); id= (ma->id); memcpy(G.buts->lockpoin, &matcopybuf, sizeof(Material)); @@ -184,6 +198,11 @@ void do_buts_buttons(short event) if(mtex->tex) id_us_plus((ID *)mtex->tex); } } + duplicatelist(&ma->layers, &matcopybuf.layers); + + for(ml= ma->layers.first; ml; ml= ml->next) + if(ml->mat) ml->mat->id.us++; + BIF_preview_changed(G.buts); BIF_undo_push("Paste material settings"); scrarea_queue_winredraw(curarea); diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index c9383d2dded..d05904c74a8 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -809,6 +809,7 @@ void do_global_buttons(unsigned short event) else { if(G.buts->texfrom==0) { /* from mat */ ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) { @@ -861,6 +862,7 @@ void do_global_buttons(unsigned short event) if(event==B_EXTEXBROWSE) { id= NULL; ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) id= (ID *)mtex->tex; @@ -879,6 +881,7 @@ void do_global_buttons(unsigned short event) id= NULL; ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) id= (ID *)mtex->tex; @@ -1717,7 +1720,13 @@ void do_global_buttons2(short event) ma= give_current_material(ob, ob->actcol); if(ma && ma->id.lib) { if(okee("Make local")) { + MaterialLayer *ml; + make_local_material(ma); + for(ml= ma->layers.first; ml; ml= ml->next) { + if(ml->mat) + make_local_material(ml->mat); + } } } } @@ -1790,6 +1799,7 @@ void do_global_buttons2(short event) if(G.buts->texfrom==0) { /* from mat */ if(ob==0) return; ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma && ma->id.lib==0) { mtex= ma->mtex[ ma->texact ]; if(mtex->tex && mtex->tex->id.us>1) { @@ -1830,6 +1840,7 @@ void do_global_buttons2(short event) if(G.buts->texfrom==0) { /* from mat */ if(ob==0) return; ma= give_current_material(ob, ob->actcol); + ma= get_active_matlayer(ma); if(ma && ma->id.lib==0) { mtex= ma->mtex[ ma->texact ]; if(mtex->tex && mtex->tex->id.lib) { diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c index 54bab5703a3..c9892ed7f1e 100644 --- a/source/blender/src/interface_panel.c +++ b/source/blender/src/interface_panel.c @@ -652,7 +652,7 @@ void uiSetPanel_view2d(ScrArea *sa) pa= sa->panels.first; while(pa) { - if(pa->active) { + if(pa->active && pa->paneltab==NULL) { done= 1; if(pa->ofsx < minx) minx= pa->ofsx; if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex; @@ -696,7 +696,7 @@ void uiMatchPanel_view2d(ScrArea *sa) pa= sa->panels.first; while(pa) { - if(pa->active) { + if(pa->active && pa->paneltab==NULL) { done= 1; if(pa->ofsx < G.v2d->tot.xmin) G.v2d->tot.xmin= pa->ofsx; if(pa->ofsx+pa->sizex > G.v2d->tot.xmax) diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 5761d0af36c..759baa72e5c 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -1,7 +1,4 @@ -/* previewrender.c GRAPHICS - * - * maart 95 - * +/* * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -130,26 +127,26 @@ static short snijpunt(float *v1, float *v2, float *v3, float *rtlabda, float x2= t10*t21-t11*t20; deeldet= t00*x0+t01*x1+t02*x2; - if(deeldet!=0.0) { + if(deeldet!=0.0f) { m0= ray1[0]-v3[0]; m1= ray1[1]-v3[1]; m2= ray1[2]-v3[2]; det1= m0*x0+m1*x1+m2*x2; rtu= det1/deeldet; - if(rtu<=0.0) { + if(rtu<=0.0f) { det2= t00*(m1*t22-m2*t21); det2+= t01*(m2*t20-m0*t22); det2+= t02*(m0*t21-m1*t20); rtv= det2/deeldet; - if(rtv<=0.0) { - if(rtu+rtv>= -1.0) { + if(rtv<=0.0f) { + if(rtu+rtv>= -1.0f) { det3= m0*(t12*t01-t11*t02); det3+= m1*(t10*t02-t12*t00); det3+= m2*(t11*t00-t10*t01); *rtlabda= det3/deeldet; - if(*rtlabda>=0.0 && *rtlabda<=1.0) { + if(*rtlabda>=0.0f && *rtlabda<=1.0f) { return 1; } } @@ -176,7 +173,7 @@ static int rcubi[3][4]= { static int ray_previewrender(int x, int y, float *vec, float *vn) { - float scalef= 10.0/100.0; + float scalef= 10.0f/100.0f; float ray1[3], ray2[3]; float minlabda, labda; int totface= 3, hitface= -1; @@ -184,10 +181,10 @@ static int ray_previewrender(int x, int y, float *vec, float *vn) ray1[0]= ray2[0]= x*scalef; ray1[1]= ray2[1]= y*scalef; - ray1[2]= -10.0; - ray2[2]= 10.0; + ray1[2]= -10.0f; + ray2[2]= 10.0f; - minlabda= 1.0; + minlabda= 1.0f; for(a=0; awinrct.xmin; @@ -277,7 +274,7 @@ static void end_previewrect(void) glMatrixMode(GL_MODELVIEW); glPopMatrix(); - glPixelZoom(1.0, 1.0); + glPixelZoom(1.0f, 1.0f); // restore viewport / scissor which was set by glaDefine2DArea glViewport(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy); @@ -309,10 +306,10 @@ static void draw_tex_crop(Tex *tex) if(tex==0) return; if(tex->type==TEX_IMAGE) { - if(tex->cropxmin==0.0) ret++; - if(tex->cropymin==0.0) ret++; - if(tex->cropxmax==1.0) ret++; - if(tex->cropymax==1.0) ret++; + if(tex->cropxmin==0.0f) ret++; + if(tex->cropymin==0.0f) ret++; + if(tex->cropxmax==1.0f) ret++; + if(tex->cropymax==1.0f) ret++; if(ret==4) return; rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4); @@ -405,7 +402,7 @@ static void sky_preview_pixel(float lens, int x, int y, char *rect) if(R.wrld.skytype & WO_SKYPAPER) { view[0]= (2*x)/(float)PR_RECTX; view[1]= (2*y)/(float)PR_RECTY; - view[2]= 0.0; + view[2]= 0.0f; } else { view[0]= x; @@ -425,9 +422,9 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char shi->co[1]= (float)y/(PR_RECTX/4); shi->co[2]= 0; - vec[0]= 0.02*x; - vec[1]= 0.02*y; - vec[2]= 0.005*PR_RECTX; + vec[0]= 0.02f*x; + vec[1]= 0.02f*y; + vec[2]= 0.005f*PR_RECTX; VECCOPY(shi->view, vec); dist= Normalise(shi->view); @@ -438,16 +435,16 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi, lacol); if(la->type==LA_SUN || la->type==LA_HEMI) { - dist= 1.0; + dist= 1.0f; } else { if(la->mode & LA_QUAD) { - t= 1.0; - if(la->ld1>0.0) + t= 1.0f; + if(la->ld1>0.0f) t= la->dist/(la->dist+la->ld1*dist); - if(la->ld2>0.0) { + if(la->ld2>0.0f) { distkw= la->dist*la->dist; t= t*distkw/(t*distkw+la->ld2*dist*dist); } @@ -471,10 +468,10 @@ static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char } t= la->spotsi; - if(inprspotbl && la->spotbl!=0.0) { + if(tspotbl && la->spotbl!=0.0f) { /* soft area */ i= t/la->spotbl; t= i*i; @@ -577,9 +574,9 @@ static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) afmy= R.afmy; rectot= R.rectot; - R.r.postmul= R.r.postgamma= R.r.postsat= 1.0; - R.r.posthue= R.r.postadd= 0.0; - R.ycor= 1.0; + R.r.postmul= R.r.postgamma= R.r.postsat= 1.0f; + R.r.posthue= R.r.postadd= 0.0f; + R.ycor= 1.0f; R.rectx= PR_RECTX; R.recty= PR_RECTY; R.afmx= PR_RECTX/2; @@ -609,11 +606,11 @@ static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) { float i, v1, xsq, ysq, texvec[3]; - float tin=1.0, tr, tg, tb, ta; + float tin=1.0f, tr, tg, tb, ta; int rgbnor, tracol, skip=0; if(tex->type==TEX_IMAGE) { - v1= 1.0/PR_RECTX; + v1= 1.0f/PR_RECTX; texvec[0]= 0.5+v1*x; texvec[1]= 0.5+v1*y; @@ -622,11 +619,11 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) if(tex->extend==TEX_REPEAT) { if(tex->xrepeat>1) { texvec[0] *= tex->xrepeat; - if(texvec[0]>1.0) texvec[0] -= (int)(texvec[0]); + if(texvec[0]>1.0f) texvec[0] -= (int)(texvec[0]); } if(tex->yrepeat>1) { texvec[1] *= tex->yrepeat; - if(texvec[1]>1.0) texvec[1] -= (int)(texvec[1]); + if(texvec[1]>1.0f) texvec[1] -= (int)(texvec[1]); } } else if(tex->extend==TEX_CHECKER) { @@ -647,17 +644,17 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) i= 2.0*(texvec[2]); texvec[0]= (i*texvec[0]); texvec[1]= (i*texvec[1]); - texvec[2]= (-1.0+i*texvec[2]); + texvec[2]= (-1.0f+i*texvec[2]); } else { skip= 1; - tr= tg= tb= ta= 0.0; + tr= tg= tb= ta= 0.0f; } } else { skip= 1; - tr= tg= tb= ta= 0.0; + tr= tg= tb= ta= 0.0f; } } else { @@ -665,7 +662,7 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) texvec[0]= v1*x; texvec[1]= v1*y; - texvec[2]= 0.0; + texvec[2]= 0.0f; } if(skip==0) rgbnor= multitex_ext(tex, texvec, &tin, &tr, &tg, &tb, &ta); @@ -680,9 +677,9 @@ static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) v1= 255.0*tb; rect[2]= CLAMPIS(v1, 0, 255); - if(ta!=1.0) { + if(ta!=1.0f) { tracol= 64+100*(abs(x)>abs(y)); - tracol= (1.0-ta)*tracol; + tracol= (1.0f-ta)*tracol; rect[0]= tracol+ (rect[0]*ta) ; rect[1]= tracol+ (rect[1]*ta) ; @@ -706,24 +703,24 @@ static void refraction_prv(int *x, int *y, float *n, float index) { float dot, fac, view[3], len; - index= 1.0/index; + index= 1.0f/index; view[0]= index*(float)*x; view[1]= ((float)*y)/index; - view[2]= 20.0; + view[2]= 20.0f; len= Normalise(view); dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2]; - if(dot>0.0) { - fac= 1.0 - (1.0 - dot*dot)*index*index; - if(fac<= 0.0) return; + if(dot>0.0f) { + fac= 1.0f - (1.0f - dot*dot)*index*index; + if(fac<= 0.0f) return; fac= -dot*index + sqrt(fac); } else { - index = 1.0/index; - fac= 1.0 - (1.0 - dot*dot)*index*index; - if(fac<= 0.0) return; + index = 1.0f/index; + fac= 1.0f - (1.0f - dot*dot)*index*index; + if(fac<= 0.0f) return; fac= -dot*index - sqrt(fac); } @@ -731,157 +728,62 @@ static void refraction_prv(int *x, int *y, float *n, float index) *y= (int)(len*(index*view[1] + fac*n[1])); } - -static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *rect, int smooth) +static void shade_lamp_loop_preview(ShadeInput *shi, ShadeResult *shr, int pr_lamp) { extern float fresnel_fac(float *view, float *vn, float ior, float fac); - Material *mat; - float v1,inp, is, inprspec=0, isr=0.0, isb=0.0, isg=0.0; - float diff[3]={0.0, 0.0, 0.0}; - float lv[3], *la, alpha; - float eul[3], tmat[3][3], imat[3][3]; - int temp, a; - char tracol; - - mat= shi->mat; - + Material *mat= shi->mat; + float inp, is, inprspec=0; + float lv[3], *la; + int a; + // copy all relevant material vars, note, keep this synced with render_types.h memcpy(&shi->r, &mat->r, 23*sizeof(float)); // set special cases: shi->har= mat->har; - if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0; - v1= 1.0/PR_RECTX; - shi->view[0]= v1*x; - shi->view[1]= v1*y; - shi->view[2]= 1.0; - Normalise(shi->view); + if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0f; + memset(shr, 0, sizeof(ShadeResult)); - shi->xs= (float)x; - shi->ys= (float)y; + /* normals flipped in render for smooth... */ + if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0f); - shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0; - - /* texture handling */ - if(mat->texco) { - - VECCOPY(shi->lo, vec); - - if(mat->pr_type==MA_CUBE) { - - eul[0]= (297)*M_PI/180.0; - eul[1]= 0.0; - eul[2]= (45)*M_PI/180.0; - EulToMat3(eul, tmat); - - MTC_Mat3MulVecfl(tmat, shi->lo); - MTC_Mat3MulVecfl(tmat, shi->vn); - /* hack for cubemap, why!!! */ - SWAP(float, shi->vn[0], shi->vn[1]); - } - /* textures otherwise upside down */ - if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE) - shi->lo[2]= -shi->lo[2]; - - if(mat->texco & TEXCO_GLOB) { - VECCOPY(shi->gl, shi->lo); - } - if(mat->texco & TEXCO_WINDOW) { - VECCOPY(shi->winco, shi->lo); - } - if(mat->texco & TEXCO_STICKY) { - VECCOPY(shi->sticky, shi->lo); - } - if(mat->texco & TEXCO_UV) { - VECCOPY(shi->uv, shi->lo); - } - if(mat->texco & TEXCO_STRAND) { - shi->strand= shi->lo[0]; - } - if(mat->texco & TEXCO_OBJECT) { - VECCOPY(shi->co, shi->lo); - } - if(mat->texco & (TEXCO_NORM)) { - shi->orn[0]= shi->vn[0]; - shi->orn[1]= shi->vn[1]; - shi->orn[2]= shi->vn[2]; - } - if(mat->texco & TEXCO_REFL) { - - inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]); - shi->ref[0]= (shi->view[0]+inp*shi->vn[0]); - shi->ref[1]= (shi->view[1]+inp*shi->vn[1]); - shi->ref[2]= (shi->view[2]+inp*shi->vn[2]); - } - - /* Clear displase vec for preview */ - shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; - - /* normals flipped in render for smooth... */ - if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0); - - do_material_tex(shi); - - /* normals flipped in render... */ - if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0); + do_material_tex(shi); + + /* normals flipped in render... */ + if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0f); + + shr->alpha= shi->alpha; - if(mat->texco & TEXCO_REFL) { - /* normals in render are pointing different... rhm */ - if(smooth) shi->ref[1]= -shi->ref[1]; - } - - if(mat->pr_type==MA_CUBE) { - /* rotate normal back for normals texture */ - SWAP(float, shi->vn[0], shi->vn[1]); - MTC_Mat3Inv(imat, tmat); - MTC_Mat3MulVecfl(imat, shi->vn); - } - - } - /* set it here, because ray_mirror will affect it */ - alpha= shi->alpha; - - if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */ - shi->vn[0]-=2.0*shi->displace[2]; - shi->vn[1]-=2.0*shi->displace[0]; - shi->vn[2]+=2.0*shi->displace[1]; - Normalise(shi->vn); - } - if(mat->mode & (MA_ZTRA|MA_RAYTRANSP)) - if(mat->fresnel_tra!=0.0) - alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); - + if(mat->fresnel_tra!=0.0f) + shr->alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); + if(mat->mode & MA_SHLESS) { - temp= 255.0*(shi->r); - if(temp>255) rect[0]= 255; else if(temp<0) rect[0]= 0; else rect[0]= temp; - - temp= 255.0*(shi->g); - if(temp>255) rect[1]= 255; else if(temp<0) rect[1]= 0; else rect[1]= temp; - - temp= 255.0*(shi->b); - if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp; + shr->diff[0]= shi->r; + shr->diff[1]= shi->g; + shr->diff[2]= shi->b; + } else { for(a=0; a<2; a++) { - if((mat->pr_lamp & (1<co[0]-la[0]; + lv[1]= shi->co[1]-la[1]; + lv[2]= shi->co[2]-la[2]; Normalise(lv); is= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; - if(is<0.0) is= 0.0; + if(is<0.0f) is= 0.0f; - if(shi->spec>0.0) { + if(shi->spec>0.0f) { - if(is>0.0) { + if(is>0.0f) { /* specular shaders */ float specfac; @@ -895,20 +797,20 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * specfac= WardIso_Spec(shi->vn, lv, shi->view, mat->rms, 0); else specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3], 0); - + inprspec= specfac*shi->spec; if(mat->mode & MA_RAMP_SPEC) { float spec[3]; do_specular_ramp(shi, specfac, inprspec, spec); - isr+= inprspec*spec[0]; - isg+= inprspec*spec[1]; - isb+= inprspec*spec[2]; + shr->spec[0]+= inprspec*spec[0]; + shr->spec[1]+= inprspec*spec[1]; + shr->spec[2]+= inprspec*spec[2]; } else { - isr+= inprspec*shi->specr; - isg+= inprspec*shi->specg; - isb+= inprspec*shi->specb; + shr->spec[0]+= inprspec*shi->specr; + shr->spec[1]+= inprspec*shi->specg; + shr->spec[2]+= inprspec*shi->specb; } } } @@ -922,12 +824,10 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * if(a==0) la= pr1_col; else la= pr2_col; - - add_to_diffuse(diff, shi, is, inp*la[0], inp*la[1], inp*la[2]); - //ir+= inp*la[0]; - //ig+= inp*la[1]; - //ib+= inp*la[2]; + + add_to_diffuse(shr->diff, shi, is, inp*la[0], inp*la[1], inp*la[2]); } + /* end lamp loop */ /* drawing checkerboard and sky */ if(mat->mode & MA_RAYMIRROR) { @@ -940,93 +840,240 @@ static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char * shi->ref[2]= 0.17*y + 0.98*z; /* scale */ - div= (0.85*shi->ref[1]); + div= (0.85f*shi->ref[1]); shi->refcol[0]= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir); /* not real 'alpha', but mirror overriding transparency */ if(mat->mode & MA_RAYTRANSP) { float fac= sqrt(shi->refcol[0]); - alpha= alpha*(1.0-fac) + fac; + shr->alpha= shr->alpha*(1.0f-fac) + fac; } - else alpha= alpha*(1.0-shi->refcol[0]) + shi->refcol[0]; + else shr->alpha= shr->alpha*(1.0f-shi->refcol[0]) + shi->refcol[0]; - if(div<0.0) { + if(div<0.0f) { /* minus 0.5 prevents too many small tiles in distance */ - fac= (int)(shi->ref[0]/(div-0.1) ) + (int)(shi->ref[2]/(div-0.1) ); - if(fac & 1) col= 0.8; - else col= 0.3; - + fac= (int)(shi->ref[0]/(div-0.1f) ) + (int)(shi->ref[2]/(div-0.1f) ); + if(fac & 1) col= 0.8f; + else col= 0.3f; + shi->refcol[1]= shi->refcol[0]*col; shi->refcol[2]= shi->refcol[1]; shi->refcol[3]= shi->refcol[2]; } else { - shi->refcol[1]= 0.0; - shi->refcol[2]= shi->refcol[0]*0.3*div; - shi->refcol[3]= shi->refcol[0]*0.8*div; + shi->refcol[1]= 0.0f; + shi->refcol[2]= shi->refcol[0]*0.3f*div; + shi->refcol[3]= shi->refcol[0]*0.8f*div; } } - if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(diff, shi); - if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, shi); + shr->diff[0]+= shi->ambr; + shr->diff[1]+= shi->ambg; + shr->diff[2]+= shi->ambb; + + if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi); + if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi); - if(shi->refcol[0]==0.0) { - a= 255.0*(diff[0] +shi->ambr +isr); - if(a>255) a=255; else if(a<0) a= 0; - rect[0]= a; - a= 255.0*(diff[1] +shi->ambg +isg); - if(a>255) a=255; else if(a<0) a= 0; - rect[1]= a; - a= 255*(diff[2] +shi->ambb +isb); - if(a>255) a=255; else if(a<0) a= 0; - rect[2]= a; + /* refcol */ + if(shi->refcol[0]!=0.0f) { + shr->diff[0]= shi->mirr*shi->refcol[1] + (1.0f - shi->mirr*shi->refcol[0])*shr->diff[0]; + shr->diff[1]= shi->mirg*shi->refcol[2] + (1.0f - shi->mirg*shi->refcol[0])*shr->diff[1]; + shr->diff[2]= shi->mirb*shi->refcol[3] + (1.0f - shi->mirb*shi->refcol[0])*shr->diff[2]; } - else { - a= 255.0*( shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*(diff[0] +shi->ambr) +isr); - if(a>255) a=255; else if(a<0) a= 0; - rect[0]= a; - a= 255.0*( shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*(diff[1] +shi->ambg) +isg); - if(a>255) a=255; else if(a<0) a= 0; - rect[1]= a; - a= 255.0*( shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*(diff[2] +shi->ambb) +isb); - if(a>255) a=255; else if(a<0) a= 0; - rect[2]= a; + + /* ztra shade */ + if(shi->spectra!=0.0f) { + inp = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]); + inp *= shi->spectra; + if(inp>1.0f) inp= 1.0f; + shr->alpha= (1.0f-inp)*shr->alpha+inp; } + } +} + +static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y, char *rect, int smooth) +{ + Material *mat; + MaterialLayer *ml; + ShadeResult shr; + float v1, inp; + float eul[3], tmat[3][3], imat[3][3], col[3]; + char tracol; + + mat= shi->mat; + + v1= 1.0/PR_RECTX; + shi->view[0]= v1*x; + shi->view[1]= v1*y; + shi->view[2]= 1.0f; + Normalise(shi->view); + + shi->xs= (float)x; + shi->ys= (float)y; + + shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0f; + VECCOPY(shi->co, vec); + + /* texture handling */ + if(mat->texco) { + + VECCOPY(shi->lo, vec); + + if(mat->pr_type==MA_CUBE) { + + eul[0]= (297)*M_PI/180.0; + eul[1]= 0.0; + eul[2]= (45)*M_PI/180.0; + EulToMat3(eul, tmat); + + MTC_Mat3MulVecfl(tmat, shi->lo); + MTC_Mat3MulVecfl(tmat, shi->vn); + /* hack for cubemap, why!!! */ + SWAP(float, shi->vn[0], shi->vn[1]); + } + /* textures otherwise upside down */ + if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE) + shi->lo[2]= -shi->lo[2]; + + if(mat->texco & TEXCO_GLOB) { + VECCOPY(shi->gl, shi->lo); + } + if(mat->texco & TEXCO_WINDOW) { + VECCOPY(shi->winco, shi->lo); + } + if(mat->texco & TEXCO_STICKY) { + VECCOPY(shi->sticky, shi->lo); + } + if(mat->texco & TEXCO_UV) { + VECCOPY(shi->uv, shi->lo); + } + if(mat->texco & TEXCO_STRAND) { + shi->strand= shi->lo[0]; + } + if(mat->texco & TEXCO_OBJECT) { + /* nothing */ + } + if(mat->texco & (TEXCO_NORM)) { + shi->orn[0]= shi->vn[0]; + shi->orn[1]= shi->vn[1]; + shi->orn[2]= shi->vn[2]; + } + if(mat->texco & TEXCO_REFL) { + + inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]); + shi->ref[0]= (shi->view[0]+inp*shi->vn[0]); + shi->ref[1]= (shi->view[1]+inp*shi->vn[1]); + shi->ref[2]= (shi->view[2]+inp*shi->vn[2]); + } + + /* Clear displase vec for preview */ + shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; + + if(mat->texco & TEXCO_REFL) { + /* normals in render are pointing different... rhm */ + if(smooth) shi->ref[1]= -shi->ref[1]; + } + + if(mat->pr_type==MA_CUBE) { + /* rotate normal back for normals texture */ + SWAP(float, shi->vn[0], shi->vn[1]); + MTC_Mat3Inv(imat, tmat); + MTC_Mat3MulVecfl(imat, shi->vn); + } + } - /* ztra shade */ - if(shi->spectra!=0.0) { - inp = MAX3(isr, isg, isb); - inp *= shi->spectra; - if(inp>1.0) inp= 1.0; - alpha= (1.0-inp)*alpha+inp; + if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */ +// shi->vn[0]-=2.0*shi->displace[2]; +// shi->vn[1]-=2.0*shi->displace[0]; +// shi->vn[2]+=2.0*shi->displace[1]; +// Normalise(shi->vn); + } + + /* ------ main shading loop with material layers */ + VECCOPY(shi->vno, shi->vn); + if(mat->ml_flag & ML_RENDER) + shade_lamp_loop_preview(shi, &shr, mat->pr_lamp); + else { + memset(&shr, 0, sizeof(ShadeResult)); + shr.alpha= 1.0f; } - if(alpha!=1.0) { + for(ml= mat->layers.first; ml; ml= ml->next) { + if(ml->mat && (ml->flag & ML_RENDER)) { + ShadeResult shrlay; + + shi->mat= ml->mat; + shi->layerfac= ml->blendfac; + VECCOPY(shi->vn, shi->vno); + if(ml->flag & ML_NEG_NORMAL) + VecMulf(shi->vn, -1.0); + + shade_lamp_loop_preview(shi, &shrlay, mat->pr_lamp); + matlayer_blend(ml, shi->layerfac, &shr, &shrlay); + } + } + + shi->mat= mat; /* restore, shade input is re-used! */ + + /* after shading and composit layers */ + if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f; + if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f; + if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f; + + if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f; + if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f; + if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f; + + VECADD(col, shr.diff, shr.spec); + if(col[0]<=0.0f) rect[0]= 0; else if(col[0]>=1.0f) rect[0]= 255; else rect[0]= (char)(255.0*col[0]); + if(col[1]<=0.0f) rect[1]= 0; else if(col[1]>=1.0f) rect[1]= 255; else rect[1]= (char)(255.0*col[1]); + if(col[2]<=0.0f) rect[2]= 0; else if(col[2]>=1.0f) rect[2]= 255; else rect[2]= (char)(255.0*col[2]); + + if(shr.alpha!=1.0f) { if(mat->mode & MA_RAYTRANSP) { refraction_prv(&x, &y, shi->vn, shi->ang); } tracol= previewback(mat->pr_back, x, y) & 255; - tracol= (1.0-alpha)*tracol; + tracol= (1.0f-shr.alpha)*tracol; if((mat->mode & MA_RAYTRANSP) && mat->filter!=0.0) { - float fr= 1.0+ mat->filter*(shi->r-1.0); - rect[0]= fr*tracol+ (rect[0]*alpha) ; - fr= 1.0+ mat->filter*(shi->g-1.0); - rect[1]= fr*tracol+ (rect[1]*alpha) ; - fr= 1.0+ mat->filter*(shi->b-1.0); - rect[2]= fr*tracol+ (rect[2]*alpha) ; + float fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f); + rect[0]= fr*tracol+ (rect[0]*shr.alpha) ; + fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f); + rect[1]= fr*tracol+ (rect[1]*shr.alpha) ; + fr= 1.0f+ mat->filter*(shr.diff[0]-1.0f); + rect[2]= fr*tracol+ (rect[2]*shr.alpha) ; } else { - rect[0]= tracol+ (rect[0]*alpha) ; - rect[1]= tracol+ (rect[1]*alpha) ; - rect[2]= tracol+ (rect[2]*alpha) ; + rect[0]= tracol+ (rect[0]*shr.alpha) ; + rect[1]= tracol+ (rect[1]*shr.alpha) ; + rect[2]= tracol+ (rect[2]*shr.alpha) ; } } } +static void preview_init_render_textures(MTex **mtex) +{ + int x; + + for(x=0; xtex) { + init_render_texture(mtex[x]->tex); + + if(mtex[x]->tex->env && mtex[x]->tex->env->object) + MTC_Mat4One(mtex[x]->tex->env->object->imat); + + } + if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat); + if(mtex[x]->object) MTC_Mat4One(mtex[x]->object->imat); + } + } + +} void BIF_previewrender(SpaceButs *sbuts) { @@ -1100,27 +1147,23 @@ void BIF_previewrender(SpaceButs *sbuts) shi.osatex= 0; if(mat) { + MaterialLayer *ml; + /* rendervars */ init_render_world(); init_render_material(mat); + /* also clears imats */ + preview_init_render_textures(mat->mtex); - /* clear imats, flip normal... (hack because everything is inverted here) */ - for(x=0; xmtex[x]) { - if(mat->mtex[x]->tex) { - init_render_texture(mat->mtex[x]->tex); - - if(mat->mtex[x]->tex->env && mat->mtex[x]->tex->env->object) - MTC_Mat4One(mat->mtex[x]->tex->env->object->imat); - - mat->mtex[x]->maptoneg ^= MAP_NORM; - } - if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); - if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + for(ml= mat->layers.first; ml; ml= ml->next) { + if(ml->mat && (ml->flag & ML_RENDER)) { + init_render_material(ml->mat); + preview_init_render_textures(ml->mat->mtex); + mat->texco |= ml->mat->texco; } } - shi.vlr= 0; + shi.vlr= NULL; shi.mat= mat; if(mat->mode & MA_HALO) init_previewhalo(&har, mat); @@ -1141,15 +1184,15 @@ void BIF_previewrender(SpaceButs *sbuts) else if(la) { init_render_world(); - init_render_textures(); /* do not do it twice!! (brightness) */ + preview_init_render_textures(la->mtex); R.totlamp= 0; RE_add_render_lamp(ob, 0); /* 0=no shadbuf or tables */ lar= R.la[0]; /* exceptions: */ - lar->spottexfac= 1.0; - lar->spotsi= cos( M_PI/3.0 ); - lar->spotbl= (1.0-lar->spotsi)*la->spotblend; + lar->spottexfac= 1.0f; + lar->spotsi= cos( M_PI/3.0f ); + lar->spotbl= (1.0f-lar->spotsi)*la->spotblend; MTC_Mat3One(lar->imat); } @@ -1165,7 +1208,7 @@ void BIF_previewrender(SpaceButs *sbuts) MTC_Mat4Invert(R.viewmat, R.viewinv); } init_render_world(); - init_render_textures(); /* dont do it twice!! (brightness) */ + preview_init_render_textures(wrld->mtex); } uiPanelPush(block); // sets UImat @@ -1258,12 +1301,12 @@ void BIF_previewrender(SpaceButs *sbuts) } } else { - vec[0]= x*(2.0/PR_RECTX); - vec[1]= y*(2.0/PR_RECTX); + vec[0]= x*(2.0f/PR_RECTX); + vec[1]= y*(2.0f/PR_RECTX); vec[2]= 0.0; - shi.vn[0]= shi.vn[1]= 0.0; - shi.vn[2]= 1.0; + shi.vn[0]= shi.vn[1]= 0.0f; + shi.vn[2]= 1.0f; shade_preview_pixel(&shi, vec, x, y, (char *)rect, 0); } @@ -1317,27 +1360,11 @@ void BIF_previewrender(SpaceButs *sbuts) uiPanelPop(block); - if(mat) { - end_render_material(mat); - for(x=0; xmtex[x] && mat->mtex[x]->tex) { - end_render_texture(mat->mtex[x]->tex); - mat->mtex[x]->maptoneg ^= MAP_NORM; - } - } - } - else if(tex) { - end_render_texture(tex); - } - else if(la) { + if(la) { if(R.totlamp) { MEM_freeN(R.la[0]); } R.totlamp= 0; - end_render_textures(); - } - else if(wrld) { - end_render_textures(); } } -- cgit v1.2.3