From d8955d1b33e8a5bfc17fc4a61721ca144702be81 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 23 Sep 2003 21:05:51 +0000 Subject: - Recursive environment map render Multiple environments now can be rendered in one pass. Previously the other objects with environment maps didn't show up in a reflection. Like this: http://www.blender.org/bf/dep.jpg By default, Blender renders now this result: http://www.blender.org/bf/dep0.jpg For a further 'recursive ray-tracing effect' you can give each EnvMap texture a higher "Depth" value. Here is a result with depth set at '2': http://www.blender.org/bf/dep2.jpg Related new options: - in (F10) DisplayButtons, environment map rendering can be turned on and off. - in EnvMap texture buttons you can free all environment maps - Environment map sizes are also reduced with the (F10) 'percentage' option. Tech note: with this commit the VlakRen struct has on *ob pointer! --- source/blender/blenkernel/intern/texture.c | 4 -- source/blender/blenloader/intern/readfile.c | 1 + source/blender/makesdna/DNA_scene_types.h | 4 +- source/blender/makesdna/DNA_texture_types.h | 4 +- .../blender/render/extern/include/render_types.h | 2 + source/blender/render/intern/source/envmap.c | 80 ++++++++++++++++------ .../renderconverter/intern/convertBlenderScene.c | 8 +++ source/blender/src/buttons.c | 44 ++++++++---- 8 files changed, 108 insertions(+), 39 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 7bb863d8c37..5f73bc10ef6 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -629,10 +629,6 @@ void init_render_texture(Tex *tex) tex->extend= TEX_CLIP; if(tex->env) { - /* temporal solution: layer 21 is to indicate an anvmap object */ - tex->env->notlay |= (1<<20); - if(tex->env->object) tex->env->object->lay |= (1<<20); - if(R.flag & R_RENDERING) { if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1bd41a82428..f33dc498227 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3703,6 +3703,7 @@ static void do_versions(Main *main) for (sce= main->scene.first; sce; sce= sce->id.next) { sce->audio.mixrate = 44100; sce->audio.flag |= AUDIO_SCRUB; + sce->r.mode |= R_ENVMAP; } // init new shader vars for (ma= main->mat.first; ma; ma= ma->id.next) { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a6241f8d607..ca482800917 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -166,7 +166,7 @@ typedef struct RenderData { * 1: do shadows * 2: do gamma correction * 3: ortho (not used?) - * 4: trace (not used?) + * 4: do envmap * 5: edge shading * 6: field rendering * 7: Disables time difference in field calculations @@ -268,7 +268,7 @@ typedef struct Scene { #define R_SHADOW 0x0002 #define R_GAMMA 0x0004 #define R_ORTHO 0x0008 -#define R_TRACE 0x0010 +#define R_ENVMAP 0x0010 #define R_EDGE 0x0020 #define R_FIELDS 0x0040 #define R_FIELDSTILL 0x0080 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 32559fe7d80..7872e384079 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -113,8 +113,10 @@ typedef struct EnvMap { short type, stype; float clipsta, clipend; unsigned int notlay; - int cuberes; + short cuberes, depth; short ok, lastframe; + short recalc, lastsize; + int pad1; } EnvMap; typedef struct Tex { diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 6b790c66936..9777393685c 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -35,6 +35,7 @@ #include "DNA_scene_types.h" #include "DNA_world_types.h" +#include "DNA_object_types.h" /* Definitely weird: this equals 1<<21... so wtf?*/ #define MAXVERT (2<<20) @@ -190,6 +191,7 @@ typedef struct VlakRen char flag, ec; unsigned int lay; RadFace *radface; + Object *ob; } VlakRen; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 58d6fcce56c..be52592aa87 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -203,13 +203,16 @@ void envmap_renderdata(EnvMap *env) { static RE_Render envR; static Object *camera; + int cuberes; if(env) { envR= R; camera= G.scene->camera; - env->cuberes &= 0xFFFC; - R.rectx= R.r.xsch= R.recty= R.r.ysch= env->cuberes; + cuberes = (env->cuberes * R.r.size) / 100; + cuberes &= 0xFFFC; + env->lastsize= R.r.size; + R.rectx= R.r.xsch= R.recty= R.r.ysch= cuberes; R.afmx= R.afmy= R.r.xsch/2; R.xstart= R.ystart= -R.afmx; R.xend= R.yend= R.xstart+R.rectx-1; @@ -381,6 +384,18 @@ void env_layerflags(unsigned int notlay) } } +void env_hideobject(Object *ob) +{ + VlakRen *vlr = NULL; + int a; + + for(a=0; a>8]; + else vlr++; + if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE; + } +} + /* ------------------------------------------------------------------------- */ void env_set_imats() @@ -443,6 +458,7 @@ void render_envmap(EnvMap *env) init_render_world(); setzbufvlaggen(RE_projectverto); env_layerflags(env->notlay); + env_hideobject(env->object); env_set_imats(); if(RE_local_test_break()==0) { @@ -492,29 +508,53 @@ void render_envmap(EnvMap *env) void make_envmaps() { Tex *tex; - int do_init= 0; - - tex= G.main->tex.first; - while(tex) { - if(tex->id.us && tex->type==TEX_ENVMAP) { - if(tex->env && tex->env->object) { - if(tex->env->object->lay & G.scene->lay) { - if(tex->env->stype!=ENV_LOAD) { - - if(tex->env->ok==0) { - do_init= 1; - render_envmap(tex->env); - } - else if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL) { - do_init= 1; - RE_free_envmapdata(tex->env); - render_envmap(tex->env); + int do_init= 0, depth= 0; + + if (!(R.r.mode & R_ENVMAP)) return; + + + /* 5 = hardcoded max recursion level */ + while(depth<5) { + tex= G.main->tex.first; + while(tex) { + if(tex->id.us && tex->type==TEX_ENVMAP) { + if(tex->env && tex->env->object) { + if(tex->env->object->lay & G.scene->lay) { + if(tex->env->stype!=ENV_LOAD) { + + /* decide if to render an envmap (again) */ + if(tex->env->depth >= depth) { + + /* set 'recalc' to make sure it does an entire loop of recalcs */ + + if(tex->env->ok) { + /* free when OSA, and old one isn't OSA */ + if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL) + RE_free_envmapdata(tex->env); + /* free when size larger */ + else if(tex->env->lastsize < R.r.size) + RE_free_envmapdata(tex->env); + /* free when env is in recalcmode */ + else if(tex->env->recalc) + RE_free_envmapdata(tex->env); + } + + if(tex->env->ok==0 && depth==0) tex->env->recalc= 1; + + if(tex->env->ok==0) { + do_init= 1; + render_envmap(tex->env); + + if(depth==tex->env->depth) tex->env->recalc= 0; + } + } } } } } + tex= tex->id.next; } - tex= tex->id.next; + depth++; } if(do_init) { diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 074d13321a5..f2d1e738073 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -1194,6 +1194,7 @@ static void init_render_displist_mesh(Object *ob) flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1); if(flen!=0.0) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= v1; vlr->v2= v3; vlr->v3= v4; @@ -1272,6 +1273,7 @@ static void init_render_displist_mesh(Object *ob) if(flen!=0.0) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; @@ -1445,6 +1447,7 @@ static void init_render_mball(Object *ob) for(a=0; aparts; a++, index+=4) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= RE_findOrAddVert(startvert+index[0]); vlr->v2= RE_findOrAddVert(startvert+index[1]); vlr->v3= RE_findOrAddVert(startvert+index[2]); @@ -1648,6 +1651,7 @@ static void init_render_mesh(Object *ob) if(mface->v3) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= RE_findOrAddVert(vertofs+mface->v1); vlr->v2= RE_findOrAddVert(vertofs+mface->v2); vlr->v3= RE_findOrAddVert(vertofs+mface->v3); @@ -1727,6 +1731,7 @@ static void init_render_mesh(Object *ob) } else if(mface->v2 && (ma->mode & MA_WIRE)) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= RE_findOrAddVert(vertofs+mface->v1); vlr->v2= RE_findOrAddVert(vertofs+mface->v2); vlr->v3= vlr->v2; @@ -2119,6 +2124,7 @@ static void init_render_surf(Object *ob) // if(flen!=0.0) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4; VECCOPY(vlr->n, n1); vlr->len= flen; @@ -2255,6 +2261,7 @@ static void init_render_surf(Object *ob) flen= CalcNormFloat4(v1->co, v3->co, v4->co, v2->co, n1); if(flen!=0.0) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= v1; vlr->v2= v3; vlr->v3= v4; @@ -2492,6 +2499,7 @@ static void init_render_curve(Object *ob) for(; bnr; b++) { vlr= RE_findOrAddVlak(R.totvlak++); + vlr->ob= ob; vlr->v1= RE_findOrAddVert(p2); vlr->v2= RE_findOrAddVert(p1); vlr->v3= RE_findOrAddVert(p3); diff --git a/source/blender/src/buttons.c b/source/blender/src/buttons.c index d7071430846..b5f1e8d3fbd 100644 --- a/source/blender/src/buttons.c +++ b/source/blender/src/buttons.c @@ -272,6 +272,8 @@ char texstr[15][8]= {"None" , "Clouds" , "Wood", #define B_PACKIMA 1355 #define B_TEXSETFRAMES 1356 +#define B_ENV_FREE_ALL 1357 + /* *********************** */ #define B_ANIMBUTS 1500 @@ -3560,6 +3562,19 @@ void do_texbuts(unsigned short event) BIF_preview_changed(G.buts); } break; + case B_ENV_FREE_ALL: + tex= G.main->tex.first; + while(tex) { + if(tex->id.us && tex->type==TEX_ENVMAP) { + if(tex->env) { + if(tex->env->stype!=ENV_LOAD) RE_free_envmapdata(tex->env); + } + } + tex= tex->id.next; + } + allqueue(REDRAWBUTSTEX, 0); + BIF_preview_changed(G.buts); + break; case B_ENV_SAVE: if(tex->env && tex->env->ok) { sa= closest_bigger_area(); @@ -3917,8 +3932,10 @@ void texbuts(void) } else if(tex->type==TEX_ENVMAP) { - if(tex->env==0) tex->env= RE_add_envmap(); - + if(tex->env==0) { + tex->env= RE_add_envmap(); + tex->env->object= OBACT; + } if(tex->env) { env= tex->env; @@ -3957,15 +3974,17 @@ void texbuts(void) uiDefBut(block, BUT, B_ENV_FREE, "Free Data", 350,137,107,24, 0, 0, 0, 0, 0, "Release all images associated with environment map"); uiBlockSetCol(block, BUTGREY); uiDefBut(block, BUT, B_ENV_SAVE, "Save EnvMap", 461,137,115,24, 0, 0, 0, 0, 0, "Save environment map"); + uiBlockSetCol(block, BUTSALMON); + uiDefBut(block, BUT, B_ENV_FREE_ALL, "Free all EnvMaps", 600,137,160,24, 0, 0, 0, 0, 0, "Frees all rendered environment maps"); } uiBlockSetCol(block, BUTGREY); - uiDefIDPoinBut(block, test_obpoin_but, B_ENV_OB, "Ob:", 350,95,206,24, &(env->object), "Object name"); - uiBlockSetCol(block, BUTGREY); - uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 350,68,122,24, &env->clipsta, 0.01, 50.0, 100, 0, "Set start value for clipping"); - uiDefButF(block, NUM, 0, "ClipEnd", 475,68,142,24, &env->clipend, 0.1, 5000.0, 1000, 0, "Set end value for clipping"); - if(env->stype!=ENV_LOAD) uiDefButI(block, NUM, B_ENV_FREE, "CubeRes", 620,68,140,24, &env->cuberes, 50, 1000.0, 0, 0, "Set the resolution in pixels"); - - uiDefButF(block, NUM, B_MATPRV, "Filter :", 558,95,201,24, &tex->filtersize, 0.1, 25.0, 0, 0, "Adjust sharpness or blurriness of the reflection"), + uiDefIDPoinBut(block, test_obpoin_but, B_ENV_OB, "Ob:", 350,95,166,24, &(env->object), "Object name"); + uiDefButF(block, NUM, B_MATPRV, "Filter :", 518,95,121,24, &tex->filtersize, 0.1, 25.0, 0, 0, "Adjust sharpness or blurriness of the reflection"), + uiDefButS(block, NUM, B_ENV_FREE, "Depth:", 639,95,120,24, &env->depth, 0, 5.0, 0, 0, "Number of times a map gets rendered again, for recursive mirror effect"), + + uiDefButF(block, NUM, REDRAWVIEW3D, "ClipSta", 350,68,122,24, &env->clipsta, 0.01, 50.0, 100, 0, "Set start value for clipping"); + uiDefButF(block, NUM, 0, "ClipEnd", 475,68,142,24, &env->clipend, 0.1, 5000.0, 1000, 0, "Set end value for clipping"); + if(env->stype!=ENV_LOAD) uiDefButS(block, NUM, B_ENV_FREE, "CubeRes", 620,68,140,24, &env->cuberes, 50, 2048.0, 0, 0, "Set the resolution in pixels"); uiDefBut(block, LABEL, 0, "Don't render layer:", 772,100,140,22, 0, 0.0, 0.0, 0, 0, ""); xco= 772; @@ -6628,9 +6647,10 @@ void renderbuts(void) uiDefBut(block, BUT,B_DORENDER,"RENDER", 369,142,192,47, 0, 0, 0, 0, 0, "Start the rendering"); uiBlockSetCol(block, BUTGREY); - uiDefButS(block, TOG|BIT|1,0,"Shadows", 565,167,122,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation"); - uiDefButS(block, TOG|BIT|10,0,"Pano",565,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)"); - uiDefButS(block, TOG|BIT|8,0,"Radio",626,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering"); + uiDefButS(block, TOG|BIT|1,0,"Shadow", 565,167,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation"); + uiDefButS(block, TOG|BIT|4,0,"EnvMap", 626,167,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation"); + uiDefButS(block, TOG|BIT|10,0,"Pano", 565,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)"); + uiDefButS(block, TOG|BIT|8,0,"Radio", 626,142,61,22, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering"); uiDefButS(block, ROW,B_DIFF,"100%", 565,114,121,20,&G.scene->r.size,1.0,100.0, 0, 0, "Set render size to defined size"); uiDefButS(block, ROW,B_DIFF,"75%", 565,90,36,20,&G.scene->r.size,1.0,75.0, 0, 0, "Set render size to 3/4 of defined size"); -- cgit v1.2.3