Render API: first step in updating RenderEngine to work according to:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 17 May 2011 14:26:45 +0000 (14:26 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 17 May 2011 14:26:45 +0000 (14:26 +0000)
http://wiki.blender.org/index.php/Dev:2.5/Source/Render/RenderEngineAPI

20 files changed:
intern/cycles/blender/addon/__init__.py
intern/cycles/blender/addon/engine.py
source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/scene.c
source/blender/editors/include/ED_render.h
source/blender/editors/render/CMakeLists.txt
source/blender/editors/render/render_shading.c
source/blender/editors/render/render_update.c [new file with mode: 0644]
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene_api.c
source/blender/render/CMakeLists.txt
source/blender/render/SConscript
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/pipeline/engine.c
source/blender/windowmanager/intern/wm_event_system.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index 0a2e5cee14238eb5d2b3831fdcb754102b41dde7..e66d078f8c7b5d172fb6ad6e01762e9b95c4fd56 100644 (file)
@@ -47,17 +47,30 @@ class CyclesRender(bpy.types.RenderEngine):
        def __del__(self):
                engine.free(self)
 
-       def render(self, scene):
-               engine.create(self, scene, True)
-               engine.render(self, scene)
+       # final render
+       def update(self, data, 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:
-                       engine.create(self, scene, False)
-               engine.draw(self, scene)
+                       engine.create(self, context.blend_data, context.scene,
+                               context.region, context.space_data, context.region_data)
+               engine.update(self, context.blend_data, context.scene)
 
-       def update(self, scene):
-               engine.update(self, scene)
+       def view_draw(self, context):
+               engine.draw(self, context.region, context.space_data, context.region_data)
 
 def register():
        properties.register()
index fb98068766fc298cf7bb1a85436e3892112ab8ad..a78107735ebcf58af165703f0e625c228b72c766 100644 (file)
@@ -23,19 +23,17 @@ def init():
        import os.path
        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
-       data = bpy.data.as_pointer()
-       scene = scene.as_pointer()
 
-       if not offline and bpy.context.area.type == 'VIEW_3D':
-               region = bpy.context.region.as_pointer()
-               v3d = bpy.context.space_data.as_pointer()
-               rv3d = bpy.context.region_data.as_pointer()
-       else:
-               region = 0
-               v3d = 0
-               rv3d = 0
+       data = data.as_pointer()
+       scene = scene.as_pointer()
+       if region:
+               region = region.as_pointer()
+       if v3d:
+               v3d = v3d.as_pointer()
+       if rv3d:
+               rv3d = rv3d.as_pointer()
 
        engine.session = lib.create(engine.as_pointer(), data, scene, region, v3d, rv3d)
 
@@ -46,19 +44,18 @@ def free(engine):
                        lib.free(engine.session)
                del engine.session
 
-def render(engine, scene):
+def render(engine):
        from cycles import libcycles_blender as lib
        lib.render(engine.session)
 
-def update(engine, scene):
+def update(engine, data, scene):
        from cycles import libcycles_blender as lib
        lib.sync(engine.session)
 
-def draw(engine, scene):
+def draw(engine, region, v3d, rv3d):
        from cycles import libcycles_blender as lib
-       v3d = bpy.context.space_data.as_pointer()
-       rv3d = bpy.context.region_data.as_pointer()
-       region = bpy.context.region
+       v3d = v3d.as_pointer()
+       rv3d = rv3d.as_pointer()
 
        # draw render image
        status, substatus = lib.draw(engine.session, v3d, rv3d)
index 9b2c1d117f59ab1a3eeac8a4d6aecdb024117b40..37e547b668864078db6a7ee73087df31f133496b 100644 (file)
@@ -121,7 +121,8 @@ void        DAG_ids_flush_update(struct Main *bmain, int time);
 void   DAG_id_tag_update(struct ID *id, short flag);
                /* flush all tagged updates */
 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);
                /* test if any of this id type is tagged for update */
 int            DAG_id_type_tagged(struct Main *bmain, short idtype);
index 943712167c6f858564f064045068b1a8c097e10a..9164085e7b70452445ff6839d0829ca813be026d 100644 (file)
@@ -90,6 +90,8 @@ int scene_check_setscene(struct Main *bmain, struct Scene *sce);
 float BKE_curframe(struct Scene *scene);
 
 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_add_render_layer(struct Scene *sce);
index 72df926b9a7644c1030c7abf81910fdc311c6a4d..845f1bc13e888d2a7ecf1911206e5d626e7fb273 100644 (file)
@@ -2508,10 +2508,10 @@ void DAG_ids_flush_tagged(Main *bmain)
                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];
-       int a, first_tag = 1;
+       int a;
 
        /* loop over all ID types */
        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 */
                if(id && bmain->id_tag_update[id->name[0]]) {
                        /* do editors update */
-                       if(first_tag) {
-                               dag_editors_update(bmain, NULL);
-                               first_tag = 0;
-                       }
+                       dag_editors_update(bmain, NULL);
+                       return;
+               }
+       }
+}
+
+
+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)
                                if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA))
                                        id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);
index d4a1eb0330cc7346ce19eda4346f8a2da6785d8e..81cffe7a182df168455d41e8f268a0afd83e0543 100644 (file)
@@ -989,13 +989,18 @@ void scene_update_tagged(Main *bmain, Scene *scene)
        
        if (scene->physics_settings.quick_cache_step)
                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
           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 */
 void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
 {
index 623d5dff8a414605ed94dbfd3cf1b5a929515047..8c0fa3a89a37e52ec22c1ed16752ad4bb236767c 100644 (file)
@@ -45,7 +45,7 @@ void ED_operatortypes_render(void);
 
 void ED_render_id_flush_update(struct Main *bmain, struct ID *id);
 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 */
 
index 16cfca8dadb7b526734ac66adf744cf87dc9058f..af2dc5d64a2acd648108c91b0f28c12312b19787 100644 (file)
@@ -41,6 +41,7 @@ set(SRC
        render_ops.c
        render_preview.c
        render_shading.c
+       render_update.c
 
        render_intern.h
 )
index bc84edb3c2ef67376788051111ec3e2f0db46c21..178a15354fbc36cfc57cb94e84915b4f261da7bb 100644 (file)
 
 #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 *********************/
 
 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1332,3 +1094,4 @@ void TEXTURE_OT_slot_paste(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
new file mode 100644 (file)
index 0000000..c795c35
--- /dev/null
@@ -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;
+       }
+}
+
index 4f8d69958e8d305394ee5bf39fabf43bd4d83c7f..62f3d762e225a5462ff3adbf64ad18afd99f1a0c 100644 (file)
@@ -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)
 {
        bScreen *sc;
@@ -651,7 +645,6 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn)
                                case ND_LAYER_CONTENT:
                                        view3d_recalc_used_layers(ar, wmn, wmn->reference);
                                        ED_region_tag_redraw(ar);
-                                       view3d_main_area_render_update(rv3d);
                                        break;
                                case ND_FRAME:
                                case ND_TRANSFORM:
index c0352d30f47f20ada54e886a64108df0e0598d03..02432eb20980231c5a8c09eee107bab2c6177910 100644 (file)
@@ -2313,10 +2313,11 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar)
                        if(strcmp(type->idname, scene->r.engine) == 0)
                                break;
 
-               if(!type || !type->draw)
+               if(!type || !type->view_draw)
                        return 0;
 
                rv3d->render_engine = RE_engine_create(type);
+               type->view_update(rv3d->render_engine, C);
        }
 
        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);
 
        type = rv3d->render_engine->type;
-       type->draw(rv3d->render_engine, scene);
+       type->view_draw(rv3d->render_engine, C);
 
        return 1;
 }
index 842a5f49998649d297c0501ecbb600dfc96eae0e..ed7e99b9cb5fced98c0a30d76bf43462278d785e 100644 (file)
 #include "BKE_context.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)
+LIBEXPORT void engine_tag_redraw(RenderEngine *engine)
 {
-       BLI_addtail(&R_engines, &internal_render_type);
-#ifdef WITH_GAMEENGINE
-       BLI_addtail(&R_engines, &internal_game_type);
-#endif
+       engine->do_draw = 1;
 }
 
-void RE_engines_exit(void)
+LIBEXPORT void engine_tag_update(RenderEngine *engine)
 {
-       RenderEngineType *type, *next;
+       engine->do_update = 1;
+}
 
-       for(type=R_engines.first; type; type=next) {
-               next= type->next;
+/* RenderEngine Callbacks */
 
-               BLI_remlink(&R_engines, type);
+static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene)
+{
+       PointerRNA ptr;
+       ParameterList list;
+       FunctionRNA *func;
 
-               if(!(type->flag & RE_INTERNAL)) {
-                       if(type->ext.free)
-                               type->ext.free(type->ext.data);
+       RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+       func= RNA_struct_find_function(&ptr, "update");
 
-                       MEM_freeN(type);
-               }
-       }
+       RNA_parameter_list_create(&list, &ptr, func);
+       RNA_parameter_set_lookup(&list, "data", &bmain);
+       RNA_parameter_set_lookup(&list, "scene", &scene);
+       engine->type->ext.call(NULL, &ptr, func, &list);
+
+       RNA_parameter_list_free(&list);
 }
 
-LIBEXPORT void engine_tag_redraw(RenderEngine *engine)
+static void engine_render(RenderEngine *engine)
 {
-       engine->do_draw = 1;
+       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);
 }
 
-LIBEXPORT void engine_tag_update(RenderEngine *engine)
+static void engine_preview_update(RenderEngine *engine, const struct bContext *context, struct ID *id)
 {
-       engine->do_update = 1;
+       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_render(RenderEngine *engine, struct Scene *scene)
+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, "render");
+       func= RNA_struct_find_function(&ptr, "preview_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)
+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, "draw");
+       func= RNA_struct_find_function(&ptr, "view_update");
 
        RNA_parameter_list_create(&list, &ptr, func);
-       RNA_parameter_set_lookup(&list, "scene", &scene);
+       RNA_parameter_set_lookup(&list, "context", &context);
        engine->type->ext.call(NULL, &ptr, func, &list);
 
        RNA_parameter_list_free(&list);
 }
 
-static void engine_update(RenderEngine *engine, struct Scene *scene)
+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, "update");
+       func= RNA_struct_find_function(&ptr, "view_draw");
 
        RNA_parameter_list_create(&list, &ptr, func);
-       RNA_parameter_set_lookup(&list, "scene", &scene);
+       RNA_parameter_set_lookup(&list, "context", &context);
        engine->type->ext.call(NULL, &ptr, func, &list);
 
        RNA_parameter_list_free(&list);
 }
 
-static void rna_RenderEngine_unregister(const bContext *C, StructRNA *type)
+/* RenderEngine registration */
+
+static void rna_RenderEngine_unregister(const struct bContext *C, StructRNA *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};
        RenderEngine dummyengine= {NULL};
        PointerRNA dummyptr;
-       int have_function[3];
+       int have_function[6];
 
        /* setup dummy engine & engine type to store static properties in */
        dummyengine.type= &dummyet;
@@ -186,7 +201,7 @@ static StructRNA *rna_RenderEngine_register(bContext *C, ReportList *reports, vo
        }
        
        /* 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));
 
        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;
        RNA_struct_blender_type_set(et->ext.srna, et);
 
-       et->render= (have_function[0])? engine_render: NULL;
-       et->draw= (have_function[1])? engine_draw: NULL;
-       et->update= (have_function[2])? engine_update: NULL;
+       et->update= (have_function[0])? engine_update: NULL;
+       et->render= (have_function[1])? engine_render: 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);
 
@@ -286,22 +304,38 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine");
        RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance");
 
-       /* render */
-       func= RNA_def_function(srna, "render", NULL);
-       RNA_def_function_ui_description(func, "Render scene into an image.");
+       /* final render callbacks */
+       func= RNA_def_function(srna, "update", NULL);
+       RNA_def_function_ui_description(func, "Export scene data for render");
        RNA_def_function_flag(func, FUNC_REGISTER);
+       RNA_def_pointer(func, "data", "BlendData", "", "");
        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.");
+       func= RNA_def_function(srna, "render", NULL);
+       RNA_def_function_ui_description(func, "Execute render");
        RNA_def_function_flag(func, FUNC_REGISTER);
-       RNA_def_pointer(func, "scene", "Scene", "", "");
 
-       func= RNA_def_function(srna, "update", NULL);
-       RNA_def_function_ui_description(func, "Notify data has changed for progressive viewport render.");
+       /* 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, "scene", "Scene", "", "");
+       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 */
        RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
index c2194636cd332855dd460402c7e82d1335170b8f..23d34074ff42694cba8c49becf47754ce1875cb8 100644 (file)
@@ -71,6 +71,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
 static void rna_Scene_update_tagged(Scene *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)
index 2ffe3b360e98f1660f6cc0ae08c49045ae40b355..f9b629791d7a33e3d63d9245f4618561ccb4ea0c 100644 (file)
@@ -131,6 +131,10 @@ if(WITH_CODEC_QUICKTIME)
        add_definitions(-DWITH_QUICKTIME)
 endif()
 
+if(WITH_GAMEENGINE)
+       add_definitions(-DWITH_GAMEENGINE)
+endif()
+
 if(APPLE)
        if(CMAKE_OSX_ARCHITECTURES MATCHES "i386" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
                set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpmath=sse")
index 4eff9fe238da1d4a08fc31c4471a5193cbbd2950..2bf5da1982781616a5ccfb2c948d3327b8e158b1 100644 (file)
@@ -54,6 +54,9 @@ if env['WITH_BF_QUICKTIME']:
 if env['WITH_BF_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'):
     incs += ' ' + env['BF_PTHREADS_INC']
 
index 6793acb14827373b447cfe0e34c4c77c8eba5f51..e6680386064c18e618100aa1bb3585d4f41a3545 100644 (file)
@@ -63,9 +63,14 @@ typedef struct RenderEngineType {
        char name[64];
        int flag;
 
-       void (*render)(struct RenderEngine *engine, struct Scene *scene);
-       void (*draw)(struct RenderEngine *engine, struct Scene *scene);
-       void (*update)(struct RenderEngine *engine, struct Scene *scene);
+       void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
+       void (*render)(struct RenderEngine *engine);
+
+       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 */
        ExtensionRNA ext;
@@ -73,9 +78,11 @@ typedef struct RenderEngineType {
 
 typedef struct RenderEngine {
        RenderEngineType *type;
+       void *py_instance;
+
        struct Render *re;
        ListBase fullresult;
-       void *py_instance;
+
        int do_draw;
        int do_update;
 } RenderEngine;
index de99b6e8e7eafaa7ad2b1d5599f9c40ebab7a329..f6c9c326240acbf3f9c94946b3aef3e935c0700b 100644 (file)
 #include "render_types.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 */
 
 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)
                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);
 
index 723df06a125e8ba5de4cd2e240a73754b4999410..3f9aa2bcc82b9af53df058e2c46f8491e09af267 100644 (file)
@@ -320,7 +320,9 @@ void wm_event_do_notifiers(bContext *C)
 
                        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);
                }
        }
 
index 2f5d6702e3ec10e7e7f8160cf90a0915fdc0541a..901ec80a654060991bb9bef39089e0d604d2c036 100644 (file)
@@ -375,6 +375,8 @@ void RE_AcquireResultImage(struct Render *re, struct RenderResult *rr){}
 void RE_ReleaseResult(struct Render *re){}
 void RE_ReleaseResultImage(struct Render *re){}
 int RE_engine_test_break(struct RenderEngine *engine){return 0;}
+void RE_engines_init() {}
+void RE_engines_exit() {}
 
 /* python */
 struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}