diff options
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/CMakeLists.txt | 7 | ||||
-rw-r--r-- | source/blender/render/SConscript | 4 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 3 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 16 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 88 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 103 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 7 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 8 |
8 files changed, 234 insertions, 2 deletions
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index eb81e7f2049..effc564fdc9 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -144,6 +144,13 @@ if(WITH_MOD_SMOKE) add_definitions(-DWITH_SMOKE) endif() +if(WITH_FREESTYLE) + list(APPEND INC + ../freestyle + ) + add_definitions(-DWITH_FREESTYLE) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 992dd8c8262..c4309577ae9 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -83,6 +83,10 @@ if env['WITH_BF_QUICKTIME']: if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') +if env['WITH_BF_FREESTYLE']: + incs += ' ../freestyle' + defs.append('WITH_FREESTYLE') + if env['WITH_BF_GAMEENGINE']: defs.append('WITH_GAMEENGINE') diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index f97e5ac3c59..020fa57cf94 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -219,6 +219,9 @@ void RE_TileProcessor(struct Render *re); /* only RE_NewRender() needed, main Blender render calls */ void RE_BlenderFrame(struct Render *re, struct Main *bmain, struct Scene *scene, struct SceneRenderLayer *srl, struct Object *camera_override, unsigned int lay, int frame, const short write_still); void RE_BlenderAnim(struct Render *re, struct Main *bmain, struct Scene *scene, struct Object *camera_override, unsigned int lay, int sfra, int efra, int tfra); +#ifdef WITH_FREESTYLE +void RE_RenderFreestyleStrokes(struct Render *re, struct Main *bmain, struct Scene *scene); +#endif /* error reporting */ void RE_SetReports(struct Render *re, struct ReportList *reports); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index d65da586b9a..deba6d165f2 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -235,6 +235,10 @@ struct Render ListBase volumes; ListBase volume_precache_parts; +#ifdef WITH_FREESTYLE + ListBase freestyle_renders; +#endif + /* arena for allocating data for use during render, for * example dynamic TFaces to go in the VlakRen structure. */ @@ -390,6 +394,9 @@ typedef struct VlakRen { struct Material *mat; char puno; char flag, ec; +#ifdef WITH_FREESTYLE + char freestyle_edge_mark; +#endif int index; } VlakRen; @@ -622,6 +629,15 @@ typedef struct LampRen { #define R_TANGENT 64 #define R_TRACEBLE 128 +/* vlakren->freestyle_edge_mark */ +#ifdef WITH_FREESTYLE +# define R_EDGE_V1V2 1 +# define R_EDGE_V2V3 2 +# define R_EDGE_V3V4 4 +# define R_EDGE_V3V1 4 +# define R_EDGE_V4V1 8 +#endif + /* strandbuffer->flag */ #define R_STRAND_BSPLINE 1 #define R_STRAND_B_UNITS 2 diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 0dc6492fad1..9e9dff63c04 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -42,6 +42,9 @@ #include "BLI_memarena.h" #include "BLI_ghash.h" #include "BLI_linklist.h" +#ifdef WITH_FREESTYLE +# include "BLI_edgehash.h" +#endif #include "DNA_armature_types.h" #include "DNA_camera_types.h" @@ -2694,7 +2697,11 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, v2= mface->v2; v3= mface->v3; v4= mface->v4; - flag= mface->flag & ME_SMOOTH; +#ifdef WITH_FREESTYLE + flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE); +#else + flag = mface->flag & ME_SMOOTH; +#endif vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, vertofs+v1); @@ -3219,6 +3226,26 @@ static void add_volume(Render *re, ObjectRen *obr, Material *ma) BLI_addtail(&re->volumes, vo); } +#ifdef WITH_FREESTYLE +static EdgeHash *make_freestyle_edge_mark_hash(MEdge *medge, int totedge) +{ + EdgeHash *edge_hash= BLI_edgehash_new(); + int a; + + for(a=0; a<totedge; a++) { + if(medge[a].flag & ME_FREESTYLE_EDGE) + BLI_edgehash_insert(edge_hash, medge[a].v1, medge[a].v2, medge+a); + } + return edge_hash; +} + +static int has_freestyle_edge_mark(EdgeHash *edge_hash, int v1, int v2) +{ + MEdge *medge= BLI_edgehash_lookup(edge_hash, v1, v2); + return (!medge) ? 0 : 1; +} +#endif + static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) { Object *ob= obr->ob; @@ -3363,6 +3390,17 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) } if (!timeoffset) { +#ifdef WITH_FREESTYLE + EdgeHash *edge_hash; + MEdge *medge; + int totedge; + + /* create a hash table of Freestyle edge marks */ + medge = dm->getEdgeArray(dm); + totedge = dm->getNumEdges(dm); + edge_hash = make_freestyle_edge_mark_hash(medge, totedge); +#endif + /* store customdata names, because DerivedMesh is freed */ RE_set_customdata_names(obr, &dm->faceData); @@ -3411,7 +3449,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) v2= mface->v2; v3= reverse_verts==0 ? mface->v3 : mface->v1; v4= mface->v4; - flag= mface->flag & ME_SMOOTH; +#ifdef WITH_FREESTYLE + flag = mface->flag & (ME_SMOOTH | ME_FREESTYLE_FACE); +#else + flag = mface->flag & ME_SMOOTH; +#endif vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, vertofs+v1); @@ -3420,6 +3462,23 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if (v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4); else vlr->v4= 0; +#ifdef WITH_FREESTYLE + /* Freestyle edge marks */ + { + int edge_mark = 0; + + if(has_freestyle_edge_mark(edge_hash, v1, v2)) edge_mark |= R_EDGE_V1V2; + if(has_freestyle_edge_mark(edge_hash, v2, v3)) edge_mark |= R_EDGE_V2V3; + if (!v4) { + if(has_freestyle_edge_mark(edge_hash, v3, v1)) edge_mark |= R_EDGE_V3V1; + } else { + if(has_freestyle_edge_mark(edge_hash, v3, v4)) edge_mark |= R_EDGE_V3V4; + if(has_freestyle_edge_mark(edge_hash, v4, v1)) edge_mark |= R_EDGE_V4V1; + } + vlr->freestyle_edge_mark= edge_mark; + } +#endif + /* render normals are inverted in render */ if (use_original_normals) { MFace *mf= me->mface+a; @@ -3501,6 +3560,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) } } } + +#ifdef WITH_FREESTYLE + /* release the hash table of Freestyle edge marks */ + BLI_edgehash_free(edge_hash, NULL); +#endif /* exception... we do edges for wire mode. potential conflict when faces exist... */ end= dm->getNumEdges(dm); @@ -4300,6 +4364,26 @@ static void check_non_flat_quads(ObjectRen *obr) /* new normals */ normal_tri_v3(vlr->n, vlr->v3->co, vlr->v2->co, vlr->v1->co); normal_tri_v3(vlr1->n, vlr1->v3->co, vlr1->v2->co, vlr1->v1->co); + +#ifdef WITH_FREESTYLE + /* Freestyle edge marks */ + if (vlr->flag & R_DIVIDE_24) { + vlr1->freestyle_edge_mark= + ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V1V2 : 0) | + ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0); + vlr->freestyle_edge_mark= + ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | + ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); + } + else { + vlr1->freestyle_edge_mark= + ((vlr->freestyle_edge_mark & R_EDGE_V3V4) ? R_EDGE_V2V3 : 0) | + ((vlr->freestyle_edge_mark & R_EDGE_V4V1) ? R_EDGE_V3V1 : 0); + vlr->freestyle_edge_mark= + ((vlr->freestyle_edge_mark & R_EDGE_V1V2) ? R_EDGE_V1V2 : 0) | + ((vlr->freestyle_edge_mark & R_EDGE_V2V3) ? R_EDGE_V2V3 : 0); + } +#endif } /* clear the flag when not divided */ else vlr->flag &= ~R_DIVIDE_24; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 3e9f5996ddc..866932632c2 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -75,6 +75,11 @@ #include "RE_engine.h" #include "RE_pipeline.h" +#ifdef WITH_FREESTYLE +# include "BKE_library.h" +# include "FRS_freestyle.h" +#endif + /* internal */ #include "render_result.h" #include "render_types.h" @@ -942,6 +947,10 @@ void RE_TileProcessor(Render *re) /* ************ This part uses API, for rendering Blender scenes ********** */ +#ifdef WITH_FREESTYLE +static void add_freestyle(Render *re); +#endif + static void do_render_3d(Render *re) { float cfra; @@ -982,6 +991,13 @@ static void do_render_3d(Render *re) if (!re->test_break(re->tbh)) add_halo_flare(re); +#ifdef WITH_FREESTYLE + /* Freestyle */ + if( re->r.mode & R_EDGE_FRS) + if(!re->test_break(re->tbh)) + add_freestyle(re); +#endif + /* free all render verts etc */ RE_Database_Free(re); @@ -1421,6 +1437,74 @@ static void render_composit_stats(void *UNUSED(arg), char *str) R.i.infostr = NULL; } +#ifdef WITH_FREESTYLE +/* invokes Freestyle stroke rendering */ +static void add_freestyle(Render *re) +{ + SceneRenderLayer *srl, *actsrl; + LinkData *link; + + actsrl = BLI_findlink(&re->r.layers, re->r.actlay); + + FRS_init_stroke_rendering(re); + + for (srl= (SceneRenderLayer *)re->r.layers.first; srl; srl= srl->next) { + + link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render"); + BLI_addtail(&re->freestyle_renders, link); + + if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl) + continue; + if (FRS_is_freestyle_enabled(srl)) { + link->data = (void *)FRS_do_stroke_rendering(re, srl); + } + } + + FRS_finish_stroke_rendering(re); +} + +/* merges the results of Freestyle stroke rendering into a given render result */ +static void composite_freestyle_renders(Render *re, int sample) +{ + Render *freestyle_render; + SceneRenderLayer *srl, *actsrl; + LinkData *link; + + actsrl = BLI_findlink(&re->r.layers, re->r.actlay); + + link = (LinkData *)re->freestyle_renders.first; + for (srl= (SceneRenderLayer *)re->r.layers.first; srl; srl= srl->next) { + if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl) + continue; + if (FRS_is_freestyle_enabled(srl)) { + freestyle_render = (Render *)link->data; + render_result_exr_file_read(freestyle_render, sample); + FRS_composite_result(re, srl, freestyle_render); + RE_FreeRenderResult(freestyle_render->result); + freestyle_render->result = NULL; + } + link = link->next; + } +} + +/* releases temporary scenes and renders for Freestyle stroke rendering */ +static void free_all_freestyle_renders(Scene *scene) +{ + Render *re1, *freestyle_render; + LinkData *link; + + for (re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { + for (link = (LinkData *)re1->freestyle_renders.first; link; link = link->next) { + if (link->data) { + freestyle_render = (Render *)link->data; + BKE_scene_unlink(G.main, freestyle_render->scene, scene); + RE_FreeRender(freestyle_render); + } + } + BLI_freelistN( &re1->freestyle_renders ); + } +} +#endif /* reads all buffers, calls optional composite, merges in first result->rectf */ static void do_merge_fullsample(Render *re, bNodeTree *ntree) @@ -1462,6 +1546,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree) if (sample) { BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); render_result_exr_file_read(re1, sample); +#ifdef WITH_FREESTYLE + if( re1->r.mode & R_EDGE_FRS) + composite_freestyle_renders(re1, sample); +#endif BLI_rw_mutex_unlock(&re->resultmutex); } ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */ @@ -1664,6 +1752,10 @@ static void do_render_composite_fields_blur_3d(Render *re) do_merge_fullsample(re, NULL); } +#ifdef WITH_FREESTYLE + free_all_freestyle_renders(re->scene); +#endif + /* weak... the display callback wants an active renderlayer pointer... */ re->result->renlay = render_get_active_layer(re, re->result); re->display_draw(re->ddh, re->result, NULL); @@ -2140,6 +2232,17 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr G.is_rendering = FALSE; } +#ifdef WITH_FREESTYLE +void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene) +{ + re->result_ok= 0; + if(render_initialize_from_main(re, bmain, scene, NULL, NULL, scene->lay, 0, 0)) { + do_render_fields_blur_3d(re); + } + re->result_ok= 1; +} +#endif + static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override) { char name[FILE_MAX]; diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 35b06385ae6..62919297e73 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -57,6 +57,10 @@ #include "render_result.h" #include "render_types.h" +#ifdef WITH_FREESTYLE +# include "FRS_freestyle_config.h" +#endif + /********************************** Free *************************************/ void render_result_free(RenderResult *res) @@ -564,6 +568,9 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf rl->lay = (1 << 20) - 1; rl->layflag = 0x7FFF; /* solid ztra halo strand */ rl->passflag = SCE_PASS_COMBINED; +#ifdef WITH_FREESTYLE + FRS_add_freestyle_config( srl ); +#endif re->r.actlay = 0; } diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 2d26ebe2b91..003e74bd69a 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1713,6 +1713,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if (ma->mode & (MA_FACETEXTURE_ALPHA)) shi->alpha= shi->vcol[3]; } +#ifdef WITH_FREESTYLE + else if (ma->vcol_alpha) { + shi->r= shi->vcol[0]; + shi->g= shi->vcol[1]; + shi->b= shi->vcol[2]; + shi->alpha= shi->vcol[3]; + } +#endif else if (ma->mode & (MA_VERTEXCOLP)) { float neg_alpha = 1.0f - shi->vcol[3]; shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3]; |