Render API: first step in updating RenderEngine to work according to:

http://wiki.blender.org/index.php/Dev:2.5/Source/Render/RenderEngineAPI
This commit is contained in:
Brecht Van Lommel 2011-05-17 14:26:45 +00:00
parent 5f5e469110
commit 8da594c861
20 changed files with 614 additions and 376 deletions

@ -47,17 +47,30 @@ class CyclesRender(bpy.types.RenderEngine):
def __del__(self): def __del__(self):
engine.free(self) engine.free(self)
def render(self, scene): # final render
engine.create(self, scene, True) def update(self, data, scene):
engine.render(self, scene) engine.create(self, data, scene)
engine.update(self, data, scene)
def draw(self, scene): def render(self):
engine.render(self)
# preview render
# def preview_update(self, context, id):
# pass
#
# def preview_render(self):
# pass
# viewport render
def view_update(self, context):
if not self.session: if not self.session:
engine.create(self, scene, False) engine.create(self, context.blend_data, context.scene,
engine.draw(self, scene) context.region, context.space_data, context.region_data)
engine.update(self, context.blend_data, context.scene)
def update(self, scene): def view_draw(self, context):
engine.update(self, scene) engine.draw(self, context.region, context.space_data, context.region_data)
def register(): def register():
properties.register() properties.register()

@ -23,19 +23,17 @@ def init():
import os.path import os.path
lib.init(os.path.dirname(__file__)) lib.init(os.path.dirname(__file__))
def create(engine, scene, offline): def create(engine, data, scene, region = 0, v3d = 0, rv3d = 0):
from cycles import libcycles_blender as lib from cycles import libcycles_blender as lib
data = bpy.data.as_pointer()
scene = scene.as_pointer()
if not offline and bpy.context.area.type == 'VIEW_3D': data = data.as_pointer()
region = bpy.context.region.as_pointer() scene = scene.as_pointer()
v3d = bpy.context.space_data.as_pointer() if region:
rv3d = bpy.context.region_data.as_pointer() region = region.as_pointer()
else: if v3d:
region = 0 v3d = v3d.as_pointer()
v3d = 0 if rv3d:
rv3d = 0 rv3d = rv3d.as_pointer()
engine.session = lib.create(engine.as_pointer(), data, scene, region, v3d, rv3d) engine.session = lib.create(engine.as_pointer(), data, scene, region, v3d, rv3d)
@ -46,19 +44,18 @@ def free(engine):
lib.free(engine.session) lib.free(engine.session)
del engine.session del engine.session
def render(engine, scene): def render(engine):
from cycles import libcycles_blender as lib from cycles import libcycles_blender as lib
lib.render(engine.session) lib.render(engine.session)
def update(engine, scene): def update(engine, data, scene):
from cycles import libcycles_blender as lib from cycles import libcycles_blender as lib
lib.sync(engine.session) lib.sync(engine.session)
def draw(engine, scene): def draw(engine, region, v3d, rv3d):
from cycles import libcycles_blender as lib from cycles import libcycles_blender as lib
v3d = bpy.context.space_data.as_pointer() v3d = v3d.as_pointer()
rv3d = bpy.context.region_data.as_pointer() rv3d = rv3d.as_pointer()
region = bpy.context.region
# draw render image # draw render image
status, substatus = lib.draw(engine.session, v3d, rv3d) status, substatus = lib.draw(engine.session, v3d, rv3d)

@ -121,7 +121,8 @@ void DAG_ids_flush_update(struct Main *bmain, int time);
void DAG_id_tag_update(struct ID *id, short flag); void DAG_id_tag_update(struct ID *id, short flag);
/* flush all tagged updates */ /* flush all tagged updates */
void DAG_ids_flush_tagged(struct Main *bmain); void DAG_ids_flush_tagged(struct Main *bmain);
/* clear ID recalc flags */ /* check and clear ID recalc flags */
void DAG_ids_check_recalc(struct Main *bmain);
void DAG_ids_clear_recalc(struct Main *bmain); void DAG_ids_clear_recalc(struct Main *bmain);
/* test if any of this id type is tagged for update */ /* test if any of this id type is tagged for update */
int DAG_id_type_tagged(struct Main *bmain, short idtype); int DAG_id_type_tagged(struct Main *bmain, short idtype);

@ -90,6 +90,8 @@ int scene_check_setscene(struct Main *bmain, struct Scene *sce);
float BKE_curframe(struct Scene *scene); float BKE_curframe(struct Scene *scene);
void scene_update_tagged(struct Main *bmain, struct Scene *sce); void scene_update_tagged(struct Main *bmain, struct Scene *sce);
void scene_clear_tagged(struct Main *bmain, struct Scene *sce);
void scene_update_for_newframe(struct Main *bmain, struct Scene *sce, unsigned int lay); void scene_update_for_newframe(struct Main *bmain, struct Scene *sce, unsigned int lay);
void scene_add_render_layer(struct Scene *sce); void scene_add_render_layer(struct Scene *sce);

@ -2508,10 +2508,10 @@ void DAG_ids_flush_tagged(Main *bmain)
DAG_scene_flush_update(bmain, sce, lay, 0); DAG_scene_flush_update(bmain, sce, lay, 0);
} }
void DAG_ids_clear_recalc(Main *bmain) void DAG_ids_check_recalc(Main *bmain)
{ {
ListBase *lbarray[MAX_LIBARRAY]; ListBase *lbarray[MAX_LIBARRAY];
int a, first_tag = 1; int a;
/* loop over all ID types */ /* loop over all ID types */
a = set_listbasepointers(bmain, lbarray); a = set_listbasepointers(bmain, lbarray);
@ -2524,11 +2524,28 @@ void DAG_ids_clear_recalc(Main *bmain)
looping over all ID's in case there are no tags */ looping over all ID's in case there are no tags */
if(id && bmain->id_tag_update[id->name[0]]) { if(id && bmain->id_tag_update[id->name[0]]) {
/* do editors update */ /* do editors update */
if(first_tag) { dag_editors_update(bmain, NULL);
dag_editors_update(bmain, NULL); return;
first_tag = 0; }
} }
}
void DAG_ids_clear_recalc(Main *bmain)
{
ListBase *lbarray[MAX_LIBARRAY];
int a;
/* loop over all ID types */
a = set_listbasepointers(bmain, lbarray);
while(a--) {
ListBase *lb = lbarray[a];
ID *id = lb->first;
/* we tag based on first ID type character to avoid
looping over all ID's in case there are no tags */
if(id && bmain->id_tag_update[id->name[0]]) {
for(; id; id=id->next) for(; id; id=id->next)
if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA)) if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA))
id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);

@ -989,13 +989,18 @@ void scene_update_tagged(Main *bmain, Scene *scene)
if (scene->physics_settings.quick_cache_step) if (scene->physics_settings.quick_cache_step)
BKE_ptcache_quick_cache_all(bmain, scene); BKE_ptcache_quick_cache_all(bmain, scene);
DAG_ids_clear_recalc(bmain); DAG_ids_check_recalc(bmain);
/* in the future this should handle updates for all datablocks, not /* in the future this should handle updates for all datablocks, not
only objects and scenes. - brecht */ only objects and scenes. - brecht */
} }
void scene_clear_tagged(Main *bmain, Scene *scene)
{
DAG_ids_clear_recalc(bmain);
}
/* applies changes right away, does all sets too */ /* applies changes right away, does all sets too */
void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
{ {

@ -45,7 +45,7 @@ void ED_operatortypes_render(void);
void ED_render_id_flush_update(struct Main *bmain, struct ID *id); void ED_render_id_flush_update(struct Main *bmain, struct ID *id);
void ED_render_engine_changed(struct Main *bmain); void ED_render_engine_changed(struct Main *bmain);
void ED_render_engine_update_tagged(struct Main *bmain); void ED_render_engine_update_tagged(struct bContext *C, struct Main *bmain);
/* render_preview.c */ /* render_preview.c */

@ -41,6 +41,7 @@ set(SRC
render_ops.c render_ops.c
render_preview.c render_preview.c
render_shading.c render_shading.c
render_update.c
render_intern.h render_intern.h
) )

@ -88,244 +88,6 @@
#include "render_intern.h" // own include #include "render_intern.h" // own include
/***************************** Updates ***********************************
* ED_render_id_flush_update gets called from DAG_id_tag_update, to do *
* editor level updates when the ID changes. when these ID blocks are in *
* the dependency graph, we can get rid of the manual dependency checks */
static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
{
int a;
if(!mtex)
return 0;
for(a=0; a<tot; a++)
if(mtex[a] && mtex[a]->tex == tex)
return 1;
return 0;
}
static int nodes_use_tex(bNodeTree *ntree, Tex *tex)
{
bNode *node;
for(node=ntree->nodes.first; node; node= node->next) {
if(node->id) {
if(node->id == (ID*)tex) {
return 1;
}
else if(node->type==NODE_GROUP) {
if(nodes_use_tex((bNodeTree *)node->id, tex))
return 1;
}
}
}
return 0;
}
static void material_changed(Main *UNUSED(bmain), Material *ma)
{
/* icons */
BKE_icon_changed(BKE_icon_getid(&ma->id));
/* glsl */
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void texture_changed(Main *bmain, Tex *tex)
{
Material *ma;
Lamp *la;
World *wo;
/* icons */
BKE_icon_changed(BKE_icon_getid(&tex->id));
/* find materials */
for(ma=bmain->mat.first; ma; ma=ma->id.next) {
if(mtex_use_tex(ma->mtex, MAX_MTEX, tex));
else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&ma->id));
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
/* find lamps */
for(la=bmain->lamp.first; la; la=la->id.next) {
if(mtex_use_tex(la->mtex, MAX_MTEX, tex));
else if(la->nodetree && nodes_use_tex(la->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&la->id));
}
/* find worlds */
for(wo=bmain->world.first; wo; wo=wo->id.next) {
if(mtex_use_tex(wo->mtex, MAX_MTEX, tex));
else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&wo->id));
}
}
static void lamp_changed(Main *bmain, Lamp *la)
{
Object *ob;
Material *ma;
/* icons */
BKE_icon_changed(BKE_icon_getid(&la->id));
/* glsl */
for(ob=bmain->object.first; ob; ob=ob->id.next)
if(ob->data == la && ob->gpulamp.first)
GPU_lamp_free(ob);
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void world_changed(Main *bmain, World *wo)
{
Material *ma;
/* icons */
BKE_icon_changed(BKE_icon_getid(&wo->id));
/* glsl */
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void image_changed(Main *bmain, Image *ima)
{
Tex *tex;
/* icons */
BKE_icon_changed(BKE_icon_getid(&ima->id));
/* textures */
for(tex=bmain->tex.first; tex; tex=tex->id.next)
if(tex->ima == ima)
texture_changed(bmain, tex);
}
static void scene_changed(Main *bmain, Scene *UNUSED(scene))
{
Object *ob;
Material *ma;
/* glsl */
for(ob=bmain->object.first; ob; ob=ob->id.next)
if(ob->gpulamp.first)
GPU_lamp_free(ob);
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "RE_engine.h"
static void update_render_engines(Main *bmain, int tagged_only)
{
Scene *scene = bmain->scene.first;
bScreen *sc;
ScrArea *sa;
ARegion *ar;
for(sc=bmain->screen.first; sc; sc=sc->id.next) {
for(sa=sc->areabase.first; sa; sa=sa->next) {
if(sa->spacetype == SPACE_VIEW3D) {
for(ar=sa->regionbase.first; ar; ar=ar->next) {
if(ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
RenderEngine *engine = rv3d->render_engine;
if(engine && (!tagged_only || engine->do_update)) {
engine->do_update = 0;
engine->type->update(engine, scene);
}
}
}
}
}
}
}
void ED_render_engine_update_tagged(Main *bmain)
{
update_render_engines(bmain, 1);
}
void ED_render_engine_changed(Main *bmain)
{
bScreen *sc;
ScrArea *sa;
ARegion *ar;
for(sc=bmain->screen.first; sc; sc=sc->id.next) {
for(sa=sc->areabase.first; sa; sa=sa->next) {
if(sa->spacetype == SPACE_VIEW3D) {
for(ar=sa->regionbase.first; ar; ar=ar->next) {
if(ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
if(rv3d->render_engine) {
RE_engine_free(rv3d->render_engine);
rv3d->render_engine= NULL;
}
}
}
}
}
}
}
void ED_render_id_flush_update(Main *bmain, ID *id)
{
if(!id) {
update_render_engines(bmain, 0);
return;
}
switch(GS(id->name)) {
case ID_MA:
material_changed(bmain, (Material*)id);
break;
case ID_TE:
texture_changed(bmain, (Tex*)id);
break;
case ID_WO:
world_changed(bmain, (World*)id);
break;
case ID_LA:
lamp_changed(bmain, (Lamp*)id);
break;
case ID_IM:
image_changed(bmain, (Image*)id);
break;
case ID_SCE:
scene_changed(bmain, (Scene*)id);
break;
default:
break;
}
}
/********************** material slot operators *********************/ /********************** material slot operators *********************/
static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
@ -1332,3 +1094,4 @@ void TEXTURE_OT_slot_paste(wmOperatorType *ot)
/* flags */ /* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
} }

@ -0,0 +1,339 @@
/*
* $Id$
*
* ***** 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.
*
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/render/render_update.c
* \ingroup edrend
*/
#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
#include "BKE_world.h"
#include "GPU_material.h"
#include "RE_engine.h"
#include "ED_render.h"
#include "render_intern.h" // own include
/***************************** Render Engines ********************************/
void ED_render_engine_update_tagged(bContext *C, Main *bmain)
{
/* viewport rendering update on data changes, happens after depsgraph
* updates if there was any change. context is set to the 3d view */
bScreen *sc, *prev_sc= CTX_wm_screen(C);
ScrArea *sa, *prev_sa= CTX_wm_area(C);
ARegion *ar, *prev_ar= CTX_wm_region(C);
for(sc=bmain->screen.first; sc; sc=sc->id.next) {
for(sa=sc->areabase.first; sa; sa=sa->next) {
if(sa->spacetype != SPACE_VIEW3D)
continue;
for(ar=sa->regionbase.first; ar; ar=ar->next) {
RegionView3D *rv3d;
RenderEngine *engine;
if(ar->regiontype != RGN_TYPE_WINDOW)
continue;
rv3d= ar->regiondata;
engine= rv3d->render_engine;
if(engine && engine->do_update) {
CTX_wm_screen_set(C, sc);
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
engine->do_update= 0;
engine->type->view_update(engine, C);
}
}
}
}
CTX_wm_screen_set(C, prev_sc);
CTX_wm_area_set(C, prev_sa);
CTX_wm_region_set(C, prev_ar);
}
void ED_render_engine_changed(Main *bmain)
{
/* on changing the render engine type, clear all running render engines */
bScreen *sc;
ScrArea *sa;
ARegion *ar;
for(sc=bmain->screen.first; sc; sc=sc->id.next) {
for(sa=sc->areabase.first; sa; sa=sa->next) {
if(sa->spacetype != SPACE_VIEW3D)
continue;
for(ar=sa->regionbase.first; ar; ar=ar->next) {
RegionView3D *rv3d;
if(ar->regiontype != RGN_TYPE_WINDOW)
continue;
rv3d= ar->regiondata;
if(rv3d->render_engine) {
RE_engine_free(rv3d->render_engine);
rv3d->render_engine= NULL;
}
}
}
}
}
void tag_render_engines(Main *bmain)
{
/* tag running render engines for update later on */
bScreen *sc;
ScrArea *sa;
ARegion *ar;
for(sc=bmain->screen.first; sc; sc=sc->id.next) {
for(sa=sc->areabase.first; sa; sa=sa->next) {
if(sa->spacetype != SPACE_VIEW3D)
continue;
for(ar=sa->regionbase.first; ar; ar=ar->next) {
RegionView3D *rv3d;
if(ar->regiontype != RGN_TYPE_WINDOW)
continue;
rv3d= ar->regiondata;
if(rv3d->render_engine)
rv3d->render_engine->do_update= 1;
}
}
}
}
/***************************** Updates ***********************************
* ED_render_id_flush_update gets called from DAG_id_tag_update, to do *
* editor level updates when the ID changes. when these ID blocks are in *
* the dependency graph, we can get rid of the manual dependency checks */
static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
{
int a;
if(!mtex)
return 0;
for(a=0; a<tot; a++)
if(mtex[a] && mtex[a]->tex == tex)
return 1;
return 0;
}
static int nodes_use_tex(bNodeTree *ntree, Tex *tex)
{
bNode *node;
for(node=ntree->nodes.first; node; node= node->next) {
if(node->id) {
if(node->id == (ID*)tex) {
return 1;
}
else if(node->type==NODE_GROUP) {
if(nodes_use_tex((bNodeTree *)node->id, tex))
return 1;
}
}
}
return 0;
}
static void material_changed(Main *UNUSED(bmain), Material *ma)
{
/* icons */
BKE_icon_changed(BKE_icon_getid(&ma->id));
/* glsl */
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void texture_changed(Main *bmain, Tex *tex)
{
Material *ma;
Lamp *la;
World *wo;
/* icons */
BKE_icon_changed(BKE_icon_getid(&tex->id));
/* find materials */
for(ma=bmain->mat.first; ma; ma=ma->id.next) {
if(mtex_use_tex(ma->mtex, MAX_MTEX, tex));
else if(ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&ma->id));
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
/* find lamps */
for(la=bmain->lamp.first; la; la=la->id.next) {
if(mtex_use_tex(la->mtex, MAX_MTEX, tex));
else if(la->nodetree && nodes_use_tex(la->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&la->id));
}
/* find worlds */
for(wo=bmain->world.first; wo; wo=wo->id.next) {
if(mtex_use_tex(wo->mtex, MAX_MTEX, tex));
else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex));
else continue;
BKE_icon_changed(BKE_icon_getid(&wo->id));
}
}
static void lamp_changed(Main *bmain, Lamp *la)
{
Object *ob;
Material *ma;
/* icons */
BKE_icon_changed(BKE_icon_getid(&la->id));
/* glsl */
for(ob=bmain->object.first; ob; ob=ob->id.next)
if(ob->data == la && ob->gpulamp.first)
GPU_lamp_free(ob);
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void world_changed(Main *bmain, World *wo)
{
Material *ma;
/* icons */
BKE_icon_changed(BKE_icon_getid(&wo->id));
/* glsl */
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
static void image_changed(Main *bmain, Image *ima)
{
Tex *tex;
/* icons */
BKE_icon_changed(BKE_icon_getid(&ima->id));
/* textures */
for(tex=bmain->tex.first; tex; tex=tex->id.next)
if(tex->ima == ima)
texture_changed(bmain, tex);
}
static void scene_changed(Main *bmain, Scene *UNUSED(scene))
{
Object *ob;
Material *ma;
/* glsl */
for(ob=bmain->object.first; ob; ob=ob->id.next)
if(ob->gpulamp.first)
GPU_lamp_free(ob);
for(ma=bmain->mat.first; ma; ma=ma->id.next)
if(ma->gpumaterial.first)
GPU_material_free(ma);
}
void ED_render_id_flush_update(Main *bmain, ID *id)
{
if(!id) {
tag_render_engines(bmain);
return;
}
switch(GS(id->name)) {
case ID_MA:
material_changed(bmain, (Material*)id);
break;
case ID_TE:
texture_changed(bmain, (Tex*)id);
break;
case ID_WO:
world_changed(bmain, (World*)id);
break;
case ID_LA:
lamp_changed(bmain, (Lamp*)id);
break;
case ID_IM:
image_changed(bmain, (Image*)id);
break;
case ID_SCE:
scene_changed(bmain, (Scene*)id);
break;
default:
break;
}
}

@ -616,12 +616,6 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene
} }
} }
static void view3d_main_area_render_update(RegionView3D *rv3d)
{
if(rv3d->render_engine)
rv3d->render_engine->type->update(rv3d->render_engine, NULL);
}
static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
{ {
bScreen *sc; bScreen *sc;
@ -651,7 +645,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
case ND_LAYER_CONTENT: case ND_LAYER_CONTENT:
view3d_recalc_used_layers(ar, wmn, wmn->reference); view3d_recalc_used_layers(ar, wmn, wmn->reference);
ED_region_tag_redraw(ar); ED_region_tag_redraw(ar);
view3d_main_area_render_update(rv3d);
break; break;
case ND_FRAME: case ND_FRAME:
case ND_TRANSFORM: case ND_TRANSFORM:

@ -2313,10 +2313,11 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar)
if(strcmp(type->idname, scene->r.engine) == 0) if(strcmp(type->idname, scene->r.engine) == 0)
break; break;
if(!type || !type->draw) if(!type || !type->view_draw)
return 0; return 0;
rv3d->render_engine = RE_engine_create(type); rv3d->render_engine = RE_engine_create(type);
type->view_update(rv3d->render_engine, C);
} }
view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL);
@ -2327,7 +2328,7 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar)
ED_region_pixelspace(ar); ED_region_pixelspace(ar);
type = rv3d->render_engine->type; type = rv3d->render_engine->type;
type->draw(rv3d->render_engine, scene); type->view_draw(rv3d->render_engine, C);
return 1; return 1;
} }

@ -49,43 +49,6 @@
#include "BKE_context.h" #include "BKE_context.h"
#include "BKE_report.h" #include "BKE_report.h"
/* RenderEngine */
static RenderEngineType internal_render_type = {
NULL, NULL, "BLENDER_RENDER", "Blender Render", RE_INTERNAL, NULL, NULL, NULL, {NULL, NULL, NULL}};
#ifdef WITH_GAMEENGINE
static RenderEngineType internal_game_type = {
NULL, NULL, "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME, NULL, NULL, NULL, {NULL, NULL, NULL}};
#endif
ListBase R_engines = {NULL, NULL};
void RE_engines_init(void)
{
BLI_addtail(&R_engines, &internal_render_type);
#ifdef WITH_GAMEENGINE
BLI_addtail(&R_engines, &internal_game_type);
#endif
}
void RE_engines_exit(void)
{
RenderEngineType *type, *next;
for(type=R_engines.first; type; type=next) {
next= type->next;
BLI_remlink(&R_engines, type);
if(!(type->flag & RE_INTERNAL)) {
if(type->ext.free)
type->ext.free(type->ext.data);
MEM_freeN(type);
}
}
}
LIBEXPORT void engine_tag_redraw(RenderEngine *engine) LIBEXPORT void engine_tag_redraw(RenderEngine *engine)
{ {
engine->do_draw = 1; engine->do_draw = 1;
@ -96,39 +59,9 @@ LIBEXPORT void engine_tag_update(RenderEngine *engine)
engine->do_update = 1; engine->do_update = 1;
} }
static void engine_render(RenderEngine *engine, struct Scene *scene) /* RenderEngine Callbacks */
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
func= RNA_struct_find_function(&ptr, "render");
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "scene", &scene);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_draw(RenderEngine *engine, struct Scene *scene)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "draw");
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "scene", &scene);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_update(RenderEngine *engine, struct Scene *scene)
{ {
PointerRNA ptr; PointerRNA ptr;
ParameterList list; ParameterList list;
@ -138,13 +71,95 @@ static void engine_update(RenderEngine *engine, struct Scene *scene)
func= RNA_struct_find_function(&ptr, "update"); func= RNA_struct_find_function(&ptr, "update");
RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "data", &bmain);
RNA_parameter_set_lookup(&list, "scene", &scene); RNA_parameter_set_lookup(&list, "scene", &scene);
engine->type->ext.call(NULL, &ptr, func, &list); engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list); RNA_parameter_list_free(&list);
} }
static void rna_RenderEngine_unregister(const bContext *C, StructRNA *type) static void engine_render(RenderEngine *engine)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "render");
RNA_parameter_list_create(&list, &ptr, func);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_preview_update(RenderEngine *engine, const struct bContext *context, struct ID *id)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "preview_update");
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &context);
RNA_parameter_set_lookup(&list, "id", &id);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_preview_render(RenderEngine *engine)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "preview_render");
RNA_parameter_list_create(&list, &ptr, func);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_view_update(RenderEngine *engine, const struct bContext *context)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "view_update");
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &context);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
static void engine_view_draw(RenderEngine *engine, const struct bContext *context)
{
PointerRNA ptr;
ParameterList list;
FunctionRNA *func;
RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
func= RNA_struct_find_function(&ptr, "view_draw");
RNA_parameter_list_create(&list, &ptr, func);
RNA_parameter_set_lookup(&list, "context", &context);
engine->type->ext.call(NULL, &ptr, func, &list);
RNA_parameter_list_free(&list);
}
/* RenderEngine registration */
static void rna_RenderEngine_unregister(const struct bContext *C, StructRNA *type)
{ {
RenderEngineType *et= RNA_struct_blender_type_get(type); RenderEngineType *et= RNA_struct_blender_type_get(type);
@ -161,7 +176,7 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo
RenderEngineType *et, dummyet = {NULL}; RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine= {NULL}; RenderEngine dummyengine= {NULL};
PointerRNA dummyptr; PointerRNA dummyptr;
int have_function[3]; int have_function[6];
/* setup dummy engine & engine type to store static properties in */ /* setup dummy engine & engine type to store static properties in */
dummyengine.type= &dummyet; dummyengine.type= &dummyet;
@ -186,7 +201,7 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo
} }
/* create a new engine type */ /* create a new engine type */
et= MEM_callocN(sizeof(RenderEngineType), "python buttons engine"); et= MEM_callocN(sizeof(RenderEngineType), "python render engine");
memcpy(et, &dummyet, sizeof(dummyet)); memcpy(et, &dummyet, sizeof(dummyet));
et->ext.srna= RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine"); et->ext.srna= RNA_def_struct(&BLENDER_RNA, et->idname, "RenderEngine");
@ -195,9 +210,12 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo
et->ext.free= free; et->ext.free= free;
RNA_struct_blender_type_set(et->ext.srna, et); RNA_struct_blender_type_set(et->ext.srna, et);
et->render= (have_function[0])? engine_render: NULL; et->update= (have_function[0])? engine_update: NULL;
et->draw= (have_function[1])? engine_draw: NULL; et->render= (have_function[1])? engine_render: NULL;
et->update= (have_function[2])? engine_update: NULL; et->preview_update= (have_function[2])? engine_preview_update: NULL;
et->preview_render= (have_function[3])? engine_preview_render: NULL;
et->view_update= (have_function[4])? engine_view_update: NULL;
et->view_draw= (have_function[5])? engine_view_draw: NULL;
BLI_addtail(&R_engines, et); BLI_addtail(&R_engines, et);
@ -286,23 +304,39 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine"); RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine");
RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance"); RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance");
/* render */ /* final render callbacks */
func= RNA_def_function(srna, "render", NULL);
RNA_def_function_ui_description(func, "Render scene into an image.");
RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "scene", "Scene", "", "");
/* draw */
func= RNA_def_function(srna, "draw", NULL);
RNA_def_function_ui_description(func, "Draw progressive render into viewport.");
RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "scene", "Scene", "", "");
func= RNA_def_function(srna, "update", NULL); func= RNA_def_function(srna, "update", NULL);
RNA_def_function_ui_description(func, "Notify data has changed for progressive viewport render."); RNA_def_function_ui_description(func, "Export scene data for render");
RNA_def_function_flag(func, FUNC_REGISTER); RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "data", "BlendData", "", "");
RNA_def_pointer(func, "scene", "Scene", "", ""); RNA_def_pointer(func, "scene", "Scene", "", "");
func= RNA_def_function(srna, "render", NULL);
RNA_def_function_ui_description(func, "Execute render");
RNA_def_function_flag(func, FUNC_REGISTER);
/* preview render callbacks */
func= RNA_def_function(srna, "preview_update", NULL);
RNA_def_function_ui_description(func, "Export scene data for preview render of the given datablock");
RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_pointer(func, "id", "ID", "", "");
func= RNA_def_function(srna, "preview_render", NULL);
RNA_def_function_ui_description(func, "Execute preview render");
RNA_def_function_flag(func, FUNC_REGISTER);
/* viewport render callbacks */
func= RNA_def_function(srna, "view_update", NULL);
RNA_def_function_ui_description(func, "Update on data changes for viewport render");
RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "context", "Context", "", "");
func= RNA_def_function(srna, "view_draw", NULL);
RNA_def_function_ui_description(func, "Draw viewport render");
RNA_def_function_flag(func, FUNC_REGISTER);
RNA_def_pointer(func, "context", "Context", "", "");
/* tag for redraw */ /* tag for redraw */
RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");

@ -71,6 +71,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
static void rna_Scene_update_tagged(Scene *scene) static void rna_Scene_update_tagged(Scene *scene)
{ {
scene_update_tagged(G.main, scene); scene_update_tagged(G.main, scene);
scene_clear_tagged(G.main, scene);
} }
static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name) static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name)

@ -131,6 +131,10 @@ if(WITH_CODEC_QUICKTIME)
add_definitions(-DWITH_QUICKTIME) add_definitions(-DWITH_QUICKTIME)
endif() endif()
if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
if(APPLE) if(APPLE)
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64") if(CMAKE_OSX_ARCHITECTURES MATCHES "i386" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpmath=sse") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpmath=sse")

@ -54,6 +54,9 @@ if env['WITH_BF_QUICKTIME']:
if env['WITH_BF_OPENEXR']: if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR') defs.append('WITH_OPENEXR')
if env['WITH_BF_GAMEENGINE']:
defs.append('WITH_GAMEENGINE')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC'] incs += ' ' + env['BF_PTHREADS_INC']

@ -63,9 +63,14 @@ typedef struct RenderEngineType {
char name[64]; char name[64];
int flag; int flag;
void (*render)(struct RenderEngine *engine, struct Scene *scene); void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
void (*draw)(struct RenderEngine *engine, struct Scene *scene); void (*render)(struct RenderEngine *engine);
void (*update)(struct RenderEngine *engine, struct Scene *scene);
void (*preview_update)(struct RenderEngine *engine, const struct bContext *context, struct ID *id);
void (*preview_render)(struct RenderEngine *engine);
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
/* RNA integration */ /* RNA integration */
ExtensionRNA ext; ExtensionRNA ext;
@ -73,9 +78,11 @@ typedef struct RenderEngineType {
typedef struct RenderEngine { typedef struct RenderEngine {
RenderEngineType *type; RenderEngineType *type;
void *py_instance;
struct Render *re; struct Render *re;
ListBase fullresult; ListBase fullresult;
void *py_instance;
int do_draw; int do_draw;
int do_update; int do_update;
} RenderEngine; } RenderEngine;

@ -58,6 +58,52 @@
#include "render_types.h" #include "render_types.h"
#include "renderpipeline.h" #include "renderpipeline.h"
/* Render Engine Types */
static RenderEngineType internal_render_type = {
NULL, NULL,
"BLENDER_RENDER", "Blender Render", RE_INTERNAL,
NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}};
#ifdef WITH_GAMEENGINE
static RenderEngineType internal_game_type = {
NULL, NULL,
"BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME,
NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}};
#endif
ListBase R_engines = {NULL, NULL};
void RE_engines_init(void)
{
BLI_addtail(&R_engines, &internal_render_type);
#ifdef WITH_GAMEENGINE
BLI_addtail(&R_engines, &internal_game_type);
#endif
}
void RE_engines_exit(void)
{
RenderEngineType *type, *next;
for(type=R_engines.first; type; type=next) {
next= type->next;
BLI_remlink(&R_engines, type);
if(!(type->flag & RE_INTERNAL)) {
if(type->ext.free)
type->ext.free(type->ext.data);
MEM_freeN(type);
}
}
}
/* Create, Free */ /* Create, Free */
RenderEngine *RE_engine_create(RenderEngineType *type) RenderEngine *RE_engine_create(RenderEngineType *type)
@ -198,7 +244,14 @@ int RE_engine_render(Render *re, int do_all)
if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0) if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0)
scene_update_for_newframe(re->main, re->scene, re->lay); scene_update_for_newframe(re->main, re->scene, re->lay);
type->render(engine, re->scene); if(re->r.scemode & R_PREVIEWBUTS) {
//type->preview_update(engine, scene, id);
type->preview_render(engine);
}
else {
type->update(engine, re->main, re->scene);
type->render(engine);
}
free_render_result(&engine->fullresult, engine->fullresult.first); free_render_result(&engine->fullresult, engine->fullresult.first);

@ -320,7 +320,9 @@ void wm_event_do_notifiers(bContext *C)
scene_update_tagged(bmain, win->screen->scene); scene_update_tagged(bmain, win->screen->scene);
ED_render_engine_update_tagged(bmain); ED_render_engine_update_tagged(C, bmain);
scene_clear_tagged(bmain, win->screen->scene);
} }
} }

@ -375,6 +375,8 @@ void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr){}
void RE_ReleaseResult(struct Render *re){} void RE_ReleaseResult(struct Render *re){}
void RE_ReleaseResultImage(struct Render *re){} void RE_ReleaseResultImage(struct Render *re){}
int RE_engine_test_break(struct RenderEngine *engine){return 0;} int RE_engine_test_break(struct RenderEngine *engine){return 0;}
void RE_engines_init() {}
void RE_engines_exit() {}
/* python */ /* python */
struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}