Fixed the full sample anti-aliasing support in Freestyle.

The render pipeline has been extended to better work with
Freestyle stroke rendering.  Struct Render has a new member
ListBase freestyle_renders to keep Render instances generated
through stroke rendering in Freestyle.  The number of
elements (LinkData instances with LinkData::data pointing to a
Render instance) in freestyle_renders is the same as the scene
render layers of the scene being rendered.  When the k-th scene
render layer has the Freestyle option enabled, the k-th element
of freestyle_renders refers to a Render instance that holds
Freestyle render results for the scene layer.  This association
between the scene render layer and the Render instance is used to
merge the Freestyle render results into the corresponding render
results for the scene render layer.
This commit is contained in:
2010-03-28 17:46:10 +00:00
parent 009d7819c1
commit 840ba8e8e7
8 changed files with 137 additions and 60 deletions

View File

@@ -19,7 +19,10 @@ extern "C" {
// Rendering // Rendering
void FRS_initialize(); void FRS_initialize();
void FRS_set_context(bContext* C); void FRS_set_context(bContext* C);
void FRS_add_Freestyle( struct Render* re); int FRS_is_freestyle_enabled(struct SceneRenderLayer* srl);
void FRS_init_stroke_rendering(struct Render* re);
struct Render* FRS_do_stroke_rendering(struct Render* re, struct SceneRenderLayer* srl);
void FRS_composite_result(struct Render* re, struct SceneRenderLayer* srl, struct Render* freestyle_render);
void FRS_exit(); void FRS_exit();
// Panel configuration // Panel configuration

View File

@@ -676,8 +676,13 @@ void Controller::DrawStrokes()
resetModified(); resetModified();
} }
void Controller::ResetRenderCount()
{
_render_count = 0;
}
Render* Controller::RenderStrokes(Render *re) { Render* Controller::RenderStrokes(Render *re) {
BlenderStrokeRenderer* blenderRenderer = new BlenderStrokeRenderer(re); BlenderStrokeRenderer* blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
_Canvas->Render( blenderRenderer ); _Canvas->Render( blenderRenderer );
Render* freestyle_render = blenderRenderer->RenderScene(re); Render* freestyle_render = blenderRenderer->RenderScene(re);
delete blenderRenderer; delete blenderRenderer;

View File

@@ -85,6 +85,7 @@ public:
void saveSteerableViewMapImages(); void saveSteerableViewMapImages();
void toggleEdgeTesselationNature(Nature::EdgeNature iNature); void toggleEdgeTesselationNature(Nature::EdgeNature iNature);
void DrawStrokes(); void DrawStrokes();
void ResetRenderCount();
Render* RenderStrokes(Render *re); Render* RenderStrokes(Render *re);
void SwapStyleModules(unsigned i1, unsigned i2); void SwapStyleModules(unsigned i1, unsigned i2);
void InsertStyleModule(unsigned index, const char *iFileName); void InsertStyleModule(unsigned index, const char *iFileName);
@@ -204,6 +205,7 @@ private:
real _EPSILON; real _EPSILON;
real _bboxDiag; real _bboxDiag;
int _render_count;
//AppStyleWindow *_pStyleWindow; //AppStyleWindow *_pStyleWindow;
//AppOptionsWindow *_pOptionsWindow; //AppOptionsWindow *_pOptionsWindow;

View File

@@ -32,7 +32,7 @@ extern "C" {
#endif #endif
BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re) BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re, int render_count)
:StrokeRenderer(){ :StrokeRenderer(){
// TEMPORARY - need a texture manager // TEMPORARY - need a texture manager
@@ -45,7 +45,9 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re)
objects.first = objects.last = NULL; objects.first = objects.last = NULL;
ListBase lb; ListBase lb;
freestyle_scene = add_scene("freestyle_strokes"); char name[22];
snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name+2);
freestyle_scene = add_scene(name);
lb = freestyle_scene->r.layers; lb = freestyle_scene->r.layers;
freestyle_scene->r= old_scene->r; freestyle_scene->r= old_scene->r;
freestyle_scene->r.layers= lb; freestyle_scene->r.layers= lb;
@@ -95,9 +97,6 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer(){
_textureManager = 0; _textureManager = 0;
} }
// release scene
free_libblock( &G.main->scene, freestyle_scene );
// release objects and data blocks // release objects and data blocks
LinkData *link = (LinkData *)objects.first; LinkData *link = (LinkData *)objects.first;
while(link) { while(link) {

View File

@@ -23,7 +23,7 @@ extern "C" {
class LIB_STROKE_EXPORT BlenderStrokeRenderer : public StrokeRenderer class LIB_STROKE_EXPORT BlenderStrokeRenderer : public StrokeRenderer
{ {
public: public:
BlenderStrokeRenderer(Render *re); BlenderStrokeRenderer(Render *re, int render_count);
virtual ~BlenderStrokeRenderer(); virtual ~BlenderStrokeRenderer();
/*! Renders a stroke rep */ /*! Renders a stroke rep */

View File

@@ -185,7 +185,7 @@ extern "C" {
controller->ComputeViewMap(); controller->ComputeViewMap();
} }
void composite_result(Render* re, SceneRenderLayer* srl, Render* freestyle_render) void FRS_composite_result(Render* re, SceneRenderLayer* srl, Render* freestyle_render)
{ {
RenderLayer *rl; RenderLayer *rl;
@@ -230,64 +230,66 @@ extern "C" {
} }
return count; return count;
} }
int FRS_is_freestyle_enabled(SceneRenderLayer* srl) {
return (!(srl->layflag & SCE_LAY_DISABLE) &&
srl->layflag & SCE_LAY_FRS &&
displayed_layer_count(srl) > 0);
}
void FRS_add_Freestyle(Render* re) { void FRS_init_stroke_rendering(Render* re) {
SceneRenderLayer *srl;
Render* freestyle_render = NULL;
// init
cout << "\n#===============================================================" << endl; cout << "\n#===============================================================" << endl;
cout << "# Freestyle" << endl; cout << "# Freestyle" << endl;
cout << "#===============================================================" << endl; cout << "#===============================================================" << endl;
init_view(re); init_view(re);
init_camera(re); init_camera(re);
freestyle_scene = re->scene;
controller->ResetRenderCount();
}
Render* FRS_do_stroke_rendering(Render* re, SceneRenderLayer *srl) {
for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) { Render* freestyle_render = NULL;
if( !(srl->layflag & SCE_LAY_DISABLE) &&
srl->layflag & SCE_LAY_FRS && cout << "\n----------------------------------------------------------" << endl;
displayed_layer_count(srl) > 0 ) cout << "| " << (re->scene->id.name+2) << "|" << srl->name << endl;
{ cout << "----------------------------------------------------------" << endl;
cout << "\n----------------------------------------------------------" << endl;
cout << "| " << (re->scene->id.name+2) << "|" << srl->name << endl; // prepare Freestyle:
cout << "----------------------------------------------------------" << endl; // - clear canvas
// - load mesh
// prepare Freestyle: // - add style modules
// - clear canvas // - set parameters
// - load mesh // - compute view map
// - add style modules prepare(re, srl);
// - set parameters
// - compute view map
prepare(re, srl);
if( re->test_break(re->tbh) ) { if( re->test_break(re->tbh) ) {
controller->CloseFile(); controller->CloseFile();
break; return NULL;
} }
// render and composite Freestyle result // render and composite Freestyle result
if( controller->_ViewMap ) { if( controller->_ViewMap ) {
// render strokes // render strokes
re->i.infostr= "Freestyle: Stroke rendering"; re->i.infostr= "Freestyle: Stroke rendering";
re->stats_draw(re->sdh, &re->i); re->stats_draw(re->sdh, &re->i);
re->i.infostr= NULL; re->i.infostr= NULL;
controller->DrawStrokes(); freestyle_scene = re->scene;
freestyle_render = controller->RenderStrokes(re); controller->DrawStrokes();
controller->CloseFile(); freestyle_render = controller->RenderStrokes(re);
controller->CloseFile();
// composite result freestyle_scene = NULL;
composite_result(re, srl, freestyle_render);
// composite result
// free resources FRS_composite_result(re, srl, freestyle_render);
RE_FreeRender(freestyle_render); RE_FreeRenderResult(freestyle_render->result);
} freestyle_render->result = NULL;
}
} }
freestyle_scene = NULL; return freestyle_render;
} }
//======================================================= //=======================================================

View File

@@ -219,6 +219,8 @@ struct Render
ListBase volumes; ListBase volumes;
ListBase volume_precache_parts; ListBase volume_precache_parts;
ListBase freestyle_renders;
/* arena for allocating data for use during render, for /* arena for allocating data for use during render, for
* example dynamic TFaces to go in the VlakRen structure. * example dynamic TFaces to go in the VlakRen structure.
*/ */

View File

@@ -1829,6 +1829,7 @@ void RE_TileProcessor(Render *re, int firsttile, int threaded)
/* ************ This part uses API, for rendering Blender scenes ********** */ /* ************ This part uses API, for rendering Blender scenes ********** */
static void external_render_3d(Render *re, RenderEngineType *type); static void external_render_3d(Render *re, RenderEngineType *type);
static void add_freestyle(Render *re);
static void do_render_3d(Render *re) static void do_render_3d(Render *re)
{ {
@@ -1864,7 +1865,7 @@ static void do_render_3d(Render *re)
/* Freestyle */ /* Freestyle */
if( re->r.mode & R_EDGE_FRS && re->r.renderer==R_INTERN) if( re->r.mode & R_EDGE_FRS && re->r.renderer==R_INTERN)
if(!re->test_break(re->tbh)) if(!re->test_break(re->tbh))
FRS_add_Freestyle(re); add_freestyle(re);
/* free all render verts etc */ /* free all render verts etc */
RE_Database_Free(re); RE_Database_Free(re);
@@ -2316,6 +2317,64 @@ static void render_composit_stats(void *unused, char *str)
} }
/* invokes Freestyle stroke rendering */
static void add_freestyle(Render *re)
{
SceneRenderLayer *srl;
LinkData *link;
FRS_init_stroke_rendering(re);
for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
BLI_addtail(&re->freestyle_renders, link);
if( FRS_is_freestyle_enabled(srl) ) {
link->data = (void *)FRS_do_stroke_rendering(re, srl);
}
}
}
/* 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;
LinkData *link;
link = (LinkData *)re->freestyle_renders.first;
for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
if( FRS_is_freestyle_enabled(srl) ) {
freestyle_render = (Render *)link->data;
read_render_result(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(void)
{
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;
free_libblock(&G.main->scene, freestyle_render->scene);
RE_FreeRender(freestyle_render);
}
}
BLI_freelistN( &re1->freestyle_renders );
}
}
/* reads all buffers, calls optional composite, merges in first result->rectf */ /* reads all buffers, calls optional composite, merges in first result->rectf */
static void do_merge_fullsample(Render *re, bNodeTree *ntree) static void do_merge_fullsample(Render *re, bNodeTree *ntree)
{ {
@@ -2339,9 +2398,12 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
tag_scenes_for_render(re); tag_scenes_for_render(re);
for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) { for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
if(re1->scene->id.flag & LIB_DOIT) if(re1->scene->id.flag & LIB_DOIT) {
if(re1->r.scemode & R_FULL_SAMPLE) if(re1->r.scemode & R_FULL_SAMPLE) {
read_render_result(re1, sample); read_render_result(re1, sample);
composite_freestyle_renders(re1, sample);
}
}
} }
} }
@@ -2491,6 +2553,8 @@ static void do_render_composite_fields_blur_3d(Render *re)
do_merge_fullsample(re, NULL); do_merge_fullsample(re, NULL);
} }
free_all_freestyle_renders();
/* weak... the display callback wants an active renderlayer pointer... */ /* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay= render_get_active_layer(re, re->result); re->result->renlay= render_get_active_layer(re, re->result);
re->display_draw(re->ddh, re->result, NULL); re->display_draw(re->ddh, re->result, NULL);
@@ -2824,7 +2888,7 @@ void RE_RenderFreestyleStrokes(Render *re, Scene *scene)
re->result_ok= 0; re->result_ok= 0;
scene->r.cfra= 1; scene->r.cfra= 1;
if(render_initialize_from_scene(re, scene, NULL, scene->lay, 0, 0)) { if(render_initialize_from_scene(re, scene, NULL, scene->lay, 0, 0)) {
do_render_all_options(re); do_render_fields_blur_3d(re);
} }
re->result_ok= 1; re->result_ok= 1;
} }