RenderEngine api: support for viewport rendering, details here:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 18:20:53 +0000 (18:20 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 2 Nov 2011 18:20:53 +0000 (18:20 +0000)
http://wiki.blender.org/index.php/Dev:2.6/Source/Render/RenderEngineAPI

* This adds a Rendered draw type in the 3D view, only available when
  the render engine implements the view_draw callback.
* 3D view now stores a pointer to a RenderEngine.

* view_draw() callback will do OpenGL drawing instead of the viewport.
* view_update() callback is called after depsgraph updates.

16 files changed:
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_render.h
source/blender/editors/render/render_update.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_space.c
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/source/external_engine.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_event_system.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index bdc2583..b1a3182 100644 (file)
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
 
+#include "RE_engine.h"
+
 #include "readfile.h"
 
 #include "PIL_time.h"
@@ -5089,6 +5091,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                if(sl->spacetype==SPACE_VIEW3D) {
                                        View3D *v3d= (View3D*) sl;
                                        BGpic *bgpic;
+                                       ARegion *ar;
                                        
                                        if(v3d->scenelock)
                                                v3d->camera= NULL; /* always get from scene */
@@ -5124,6 +5127,15 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
                                        /* not very nice, but could help */
                                        if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay;
                                        
+                                       /* free render engines for now */
+                                       for(ar= sa->regionbase.first; ar; ar= ar->next) {
+                                               RegionView3D *rv3d= ar->regiondata;
+
+                                               if(rv3d && rv3d->render_engine) {
+                                                       RE_engine_free(rv3d->render_engine);
+                                                       rv3d->render_engine= NULL;
+                                               }
+                                       }
                                }
                                else if(sl->spacetype==SPACE_IPO) {
                                        SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -5262,6 +5274,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                        
                        rv3d->depths= NULL;
                        rv3d->ri= NULL;
+                       rv3d->render_engine= NULL;
                        rv3d->sms= NULL;
                        rv3d->smooth_timer= NULL;
                }
@@ -5403,6 +5416,10 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                                v3d->afterdraw_xray.first= v3d->afterdraw_xray.last= NULL;
                                v3d->afterdraw_xraytransp.first= v3d->afterdraw_xraytransp.last= NULL;
                                v3d->properties_storage= NULL;
+
+                               /* render can be quite heavy, set to wire on load */
+                               if(v3d->drawtype == OB_RENDER)
+                                       v3d->drawtype = OB_WIRE;
                                
                                view3d_split_250(v3d, &sl->regionbase);
                        }
@@ -10696,7 +10713,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        Object *ob=main->object.first;
                        while (ob) {
                                /* shaded mode disabled for now */
-                               if (ob->dt == OB_SHADED) ob->dt = OB_TEXTURE;
+                               if (ob->dt == OB_MATERIAL) ob->dt = OB_TEXTURE;
                                ob=ob->id.next;
                        }
                }
@@ -10711,7 +10728,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        for(sl= sa->spacedata.first; sl; sl= sl->next) {
                                                if(sl->spacetype==SPACE_VIEW3D) {
                                                        View3D *v3d = (View3D *)sl;
-                                                       if (v3d->drawtype == OB_SHADED) v3d->drawtype = OB_SOLID;
+                                                       if (v3d->drawtype == OB_MATERIAL) v3d->drawtype = OB_SOLID;
                                                }
                                        }
                                }
index 651c298..8c0fa3a 100644 (file)
@@ -44,6 +44,8 @@ void ED_operatortypes_render(void);
 /* render_shading.c */
 
 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 bContext *C, struct Main *bmain);
 
 /* render_preview.c */
 
index e80c3d8..c4ce695 100644 (file)
 
 #include "GPU_material.h"
 
+#include "RE_engine.h"
+
 #include "ED_node.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->flag & RE_ENGINE_DO_UPDATE)) {
+                                       CTX_wm_screen_set(C, sc);
+                                       CTX_wm_area_set(C, sa);
+                                       CTX_wm_region_set(C, ar);
+
+                                       engine->flag &= ~RE_ENGINE_DO_UPDATE;
+                                       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;
+                               }
+                       }
+               }
+       }
+}
+
+static 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->flag |= RE_ENGINE_DO_UPDATE;
+                       }
+               }
+       }
+}
+
 /***************************** 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 *
@@ -220,8 +319,10 @@ static void scene_changed(Main *bmain, Scene *UNUSED(scene))
 
 void ED_render_id_flush_update(Main *bmain, ID *id)
 {
-       if(!id)
+       if(!id) {
+               tag_render_engines(bmain);
                return;
+       }
 
        switch(GS(id->name)) {
                case ID_MA:
index a6424b1..593537f 100644 (file)
 
 /* this condition has been made more complex since editmode can draw textures */
 #define CHECK_OB_DRAWTEXTURE(vd, dt) \
-((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
+       ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
 static void draw_bounding_volume(Scene *scene, Object *ob);
@@ -2696,8 +2696,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        totface = dm->getNumFaces(dm);
        
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
-       if(dt!=OB_SHADED)
-               glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
+       glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
                // Unwanted combination.
        if (is_paint_sel) draw_wire = 0;
@@ -2814,7 +2813,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
                                dm->drawLooseEdges(dm);
                }
        }
-       else if(dt==OB_SHADED) {
+       else if(dt==OB_PAINT) {
                if(ob==OBACT) {
                        if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
                                /* enforce default material settings */
@@ -5955,7 +5954,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
 
        /* maximum drawtype */
-       dt= MIN2(v3d->drawtype, ob->dt);
+       dt= v3d->drawtype;
+       if(dt==OB_RENDER) dt= OB_SOLID;
+       dt= MIN2(dt, ob->dt);
        if(v3d->zbuf==0 && dt>OB_WIRE) dt= OB_WIRE;
        dtx= 0;
 
@@ -5970,7 +5971,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                                        dt= OB_SOLID;
                                }
                                else {
-                                       dt= OB_SHADED;
+                                       dt= OB_PAINT;
                                }
 
                                glEnable(GL_DEPTH_TEST);
index f868cda..ef806cb 100644 (file)
@@ -56,6 +56,7 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "RE_engine.h"
 
 #include "RNA_access.h"
 
@@ -344,6 +345,9 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
                v3do->lay= v3dn->localvd->lay;
                v3do->lay &= 0xFFFFFF;
        }
+
+       if(v3dn->drawtype == OB_RENDER)
+               v3dn->drawtype = OB_SOLID;
        
        /* copy or clear inside new stuff */
 
@@ -549,6 +553,9 @@ static void view3d_main_area_free(ARegion *ar)
                if(rv3d->ri) { 
                        // XXX          BIF_view3d_previewrender_free(rv3d);
                }
+
+               if(rv3d->render_engine)
+                       RE_engine_free(rv3d->render_engine);
                
                if(rv3d->depths) {
                        if(rv3d->depths->depths) MEM_freeN(rv3d->depths->depths);
@@ -573,6 +580,7 @@ static void *view3d_main_area_duplicate(void *poin)
                
                new->depths= NULL;
                new->ri= NULL;
+               new->render_engine= NULL;
                new->gpd= NULL;
                new->sms= NULL;
                new->smooth_timer= NULL;
index 6b5e779..96031a7 100644 (file)
@@ -62,6 +62,7 @@
 #include "BKE_screen.h"
 #include "BKE_unit.h"
 
+#include "RE_engine.h"
 #include "RE_pipeline.h"       // make_stars
 
 #include "IMB_imbuf_types.h"
@@ -2518,6 +2519,62 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar)
        BLF_draw_default_ascii(22,  ar->winy-17, 0.0f, printable, sizeof(printable)-1);
 }
 
+static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar)
+{
+       Scene *scene= CTX_data_scene(C);
+       View3D *v3d = CTX_wm_view3d(C);
+       RegionView3D *rv3d= CTX_wm_region_view3d(C);
+       RenderEngineType *type;
+
+       if(!rv3d->render_engine) {
+               type= RE_engines_find(scene->r.engine);
+
+               if(!(type->view_update && 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);
+
+       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+       glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+       ED_region_pixelspace(ar);
+
+       type= rv3d->render_engine->type;
+       type->view_draw(rv3d->render_engine, C);
+
+       return 1;
+}
+
+static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar)
+{
+       rcti rect;
+       const int header_height = 18;
+
+       if(!rv3d->render_engine || !rv3d->render_engine->text)
+               return;
+       
+       /* background box */
+       rect= ar->winrct;
+       rect.xmin= 0;
+       rect.ymin= ar->winrct.ymax - ar->winrct.ymin - header_height;
+       rect.xmax= ar->winrct.xmax - ar->winrct.xmin;
+       rect.ymax= ar->winrct.ymax - ar->winrct.ymin;
+
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+       glColor4f(0.0f, 0.0f, 0.0f, 0.25f);
+       glRecti(rect.xmin, rect.ymin, rect.xmax+1, rect.ymax+1);
+       glDisable(GL_BLEND);
+       
+       /* text */
+       UI_ThemeColor(TH_TEXT_HI);
+       UI_DrawString(12, rect.ymin + 5, rv3d->render_engine->text);
+}
+
 /* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */
 static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit)
 {
@@ -2728,6 +2785,11 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
        else    
                draw_view_icon(rv3d);
        
+       if(rv3d->render_engine) {
+               view3d_main_area_draw_engine_info(rv3d, ar);
+               return;
+       }
+
        if((U.uiflag & USER_SHOW_FPS) && screen->animtimer) {
                draw_viewport_fps(scene, ar);
        }
@@ -2755,9 +2817,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
        View3D *v3d = CTX_wm_view3d(C);
        const char *grid_unit= NULL;
 
-       view3d_main_area_draw_objects(C, ar, &grid_unit);
-
-       ED_region_pixelspace(ar);
+       /* draw viewport using external renderer? */
+       if(!(v3d->drawtype == OB_RENDER && view3d_main_area_draw_engine(C, ar))) {
+               /* draw viewport using opengl */
+               view3d_main_area_draw_objects(C, ar, &grid_unit);
+               ED_region_pixelspace(ar);
+       }
        
        view3d_main_area_draw_info(C, ar, grid_unit);
 
index 38daf8b..3e17d7f 100644 (file)
@@ -385,8 +385,11 @@ typedef struct DupliObject {
 #define OB_BOUNDBOX            1
 #define OB_WIRE                        2
 #define OB_SOLID               3
-#define OB_SHADED              4
+#define OB_MATERIAL            4
 #define OB_TEXTURE             5
+#define OB_RENDER              6
+
+#define OB_PAINT               100     /* temporary used in draw code */
 
 /* dtx: flags, char! */
 #define OB_AXIS                        2
index d94d431..aaf4186 100644 (file)
@@ -39,6 +39,7 @@ struct SpaceLink;
 struct Base;
 struct BoundBox;
 struct RenderInfo;
+struct RenderEngine;
 struct bGPdata;
 struct SmoothViewStore;
 struct wmTimer;
@@ -115,6 +116,7 @@ typedef struct RegionView3D {
        
        struct RegionView3D *localvd; /* allocated backup of its self while in localview */
        struct RenderInfo *ri;
+       struct RenderEngine *render_engine;
        struct ViewDepths *depths;
        
        /* animated smooth view */
@@ -164,8 +166,8 @@ typedef struct View3D {
        int layact;
        
        /**
-        * The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID,
-        * OB_SHADED or OB_TEXTURE */
+        * The drawing mode for the 3d display. Set to OB_BOUNDBOX, OB_WIRE, OB_SOLID,
+        * OB_TEXTURE, OB_MATERIAL or OB_RENDER */
        short drawtype;
        short ob_centre_cursor;         /* optional bool for 3d cursor to define center */
        short scenelock, around;
index 8f92831..2ed0651 100644 (file)
@@ -95,6 +95,40 @@ static void engine_render(RenderEngine *engine, struct Scene *scene)
        RNA_parameter_list_free(&list);
 }
 
+static void engine_view_update(RenderEngine *engine, const struct bContext *context)
+{
+       extern FunctionRNA rna_RenderEngine_view_update_func;
+       PointerRNA ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+       func= &rna_RenderEngine_view_update_func;
+
+       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)
+{
+       extern FunctionRNA rna_RenderEngine_view_draw_func;
+       PointerRNA ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+       func= &rna_RenderEngine_view_draw_func;
+
+       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(Main *UNUSED(bmain), StructRNA *type)
@@ -114,7 +148,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
        RenderEngineType *et, dummyet = {NULL};
        RenderEngine dummyengine= {NULL};
        PointerRNA dummyptr;
-       int have_function[2];
+       int have_function[4];
 
        /* setup dummy engine & engine type to store static properties in */
        dummyengine.type= &dummyet;
@@ -151,6 +185,8 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
 
        et->update= (have_function[0])? engine_update: NULL;
        et->render= (have_function[1])? engine_render: NULL;
+       et->view_update= (have_function[2])? engine_view_update: NULL;
+       et->view_draw= (have_function[3])? engine_view_draw: NULL;
 
        BLI_addtail(&R_engines, et);
 
@@ -251,6 +287,17 @@ static void rna_def_render_engine(BlenderRNA *brna)
        RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
        RNA_def_pointer(func, "scene", "Scene", "", "");
 
+       /* 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_OPTIONAL);
+       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_OPTIONAL);
+       RNA_def_pointer(func, "context", "Context", "", "");
+
        /* tag for redraw */
        RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
        RNA_def_function_ui_description(func, "Request redraw for viewport rendering");
index 7bdaa0a..ce62550 100644 (file)
@@ -40,6 +40,7 @@
 #include "BLI_math.h"
 
 /* Include for Bake Options */
+#include "RE_engine.h"
 #include "RE_pipeline.h"
 
 #ifdef WITH_QUICKTIME
@@ -55,6 +56,8 @@
 #include <libavformat/avformat.h>
 #endif
 
+#include "ED_render.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 
@@ -773,6 +776,11 @@ static int rna_RenderSettings_engine_get(PointerRNA *ptr)
        return 0;
 }
 
+static void rna_RenderSettings_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr))
+{
+       ED_render_engine_changed(bmain);
+}
+
 static void rna_Scene_glsl_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
        Scene *scene= (Scene*)ptr->id.data;
@@ -3212,7 +3220,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
        RNA_def_property_enum_funcs(prop, "rna_RenderSettings_engine_get", "rna_RenderSettings_engine_set",
                                    "rna_RenderSettings_engine_itemf");
        RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering");
-       RNA_def_property_update(prop, NC_WINDOW, NULL);
+       RNA_def_property_update(prop, NC_WINDOW, "rna_RenderSettings_engine_update");
 
        prop= RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_multiple_engines_get", NULL);
index 51faccc..5c494a3 100644 (file)
@@ -47,6 +47,9 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "RE_engine.h"
+#include "RE_pipeline.h"
+
 #include "RNA_enum_types.h"
 
 EnumPropertyItem space_type_items[] = {
@@ -98,8 +101,8 @@ EnumPropertyItem viewport_shade_items[] = {
        {OB_BOUNDBOX, "BOUNDBOX", ICON_BBOX, "Bounding Box", "Display the object's local bounding boxes only"},
        {OB_WIRE, "WIREFRAME", ICON_WIRE, "Wireframe", "Display the object as wire edges"},
        {OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid, lit with default OpenGL lights"},
-       //{OB_SHADED, "SHADED", ICON_SMOOTH, "Shaded", "Display the object solid, with preview shading interpolated at vertices"},
        {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Textured", "Display the object solid, with face-assigned textures"},
+       {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"},
        {0, NULL, 0, NULL, NULL}};
 
 #ifdef RNA_RUNTIME
@@ -313,6 +316,25 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin
        DAG_on_visible_update(bmain, FALSE);
 }
 
+static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       View3D *v3d= (View3D*)(ptr->data);
+       ScrArea *sa= rna_area_from_space(ptr);
+
+       if(v3d->drawtype != OB_RENDER) {
+               ARegion *ar;
+
+               for(ar=sa->regionbase.first; ar; ar=ar->next) {
+                       RegionView3D *rv3d = ar->regiondata;
+
+                       if(rv3d && rv3d->render_engine) {
+                               RE_engine_free(rv3d->render_engine);
+                               rv3d->render_engine= NULL;
+                       }
+               }
+       }
+}
+
 static void rna_SpaceView3D_pivot_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
 {
        if (U.uiflag & USER_LOCKAROUND) {
@@ -423,6 +445,29 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value
        ED_view3d_from_m4((float (*)[4])values, rv3d->ofs, rv3d->viewquat, &rv3d->dist);
 }
 
+static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+{
+       Scene *scene = ((bScreen*)ptr->id.data)->scene;
+       RenderEngineType *type = RE_engines_find(scene->r.engine);
+       
+       EnumPropertyItem *item= NULL;
+       int totitem= 0;
+
+       RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_BOUNDBOX);
+       RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_WIRE);
+       RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID);
+       RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE);
+       
+       if(type->view_draw) {
+               RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER);
+       }
+
+       RNA_enum_item_end(&item, &totitem);
+       *free= 1;
+
+       return item;
+}
+
 /* Space Image Editor */
 
 static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr)
@@ -1227,8 +1272,9 @@ static void rna_def_space_view3d(BlenderRNA *brna)
        prop= RNA_def_property(srna, "viewport_shade", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "drawtype");
        RNA_def_property_enum_items(prop, viewport_shade_items);
+       RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_SpaceView3D_viewport_shade_itemf");
        RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View");
-       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
+       RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, "rna_SpaceView3D_viewport_shade_update");
 
        prop= RNA_def_property(srna, "local_view", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "localvd");
index b848dc2..ef6c8a3 100644 (file)
@@ -71,6 +71,9 @@ typedef struct RenderEngineType {
        void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
        void (*render)(struct RenderEngine *engine, struct Scene *scene);
 
+       void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
+       void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
+
        /* RNA integration */
        ExtensionRNA ext;
 } RenderEngineType;
index 9d48e25..b37da67 100644 (file)
@@ -61,7 +61,7 @@
 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
@@ -69,7 +69,7 @@ static RenderEngineType internal_render_type = {
 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
index 8261198..389049d 100644 (file)
@@ -55,6 +55,8 @@
 #include "GPU_draw.h"
 #include "GPU_extensions.h"
 
+#include "RE_engine.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 #include "wm.h"
@@ -113,6 +115,19 @@ static int wm_area_test_invalid_backbuf(ScrArea *sa)
                return 1;
 }
 
+static void wm_region_test_render_do_draw(ScrArea *sa, ARegion *ar)
+{
+       if(sa->spacetype == SPACE_VIEW3D) {
+               RegionView3D *rv3d = ar->regiondata;
+               RenderEngine *engine = (rv3d)? rv3d->render_engine: NULL;
+
+               if(engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
+                       ar->do_draw = 1;
+                       engine->flag &= ~RE_ENGINE_DO_DRAW;
+               }
+       }
+}
+
 /********************** draw all **************************/
 /* - reference method, draw all each time                 */
 
@@ -205,7 +220,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
        for(sa= screen->areabase.first; sa; sa= sa->next)
                for(ar= sa->regionbase.first; ar; ar= ar->next)
                        if(ar->swinid && !wm_area_test_invalid_backbuf(sa))
-                                       ED_region_tag_redraw(ar);
+                               ED_region_tag_redraw(ar);
 
        /* flush overlapping regions */
        if(screen->regionbase.first) {
@@ -662,13 +677,28 @@ static int wm_draw_update_test_window(wmWindow *win)
 {
        ScrArea *sa;
        ARegion *ar;
+       int do_draw= 0;
 
        for(ar= win->screen->regionbase.first; ar; ar= ar->next) {
                if(ar->do_draw_overlay) {
                        wm_tag_redraw_overlay(win, ar);
                        ar->do_draw_overlay= 0;
                }
+               if(ar->swinid && ar->do_draw)
+                       do_draw= 1;
+       }
+
+       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+               for(ar=sa->regionbase.first; ar; ar= ar->next) {
+                       wm_region_test_render_do_draw(sa, ar);
+
+                       if(ar->swinid && ar->do_draw)
+                               do_draw = 1;
+               }
        }
+
+       if(do_draw)
+               return 1;
        
        if(win->screen->do_refresh)
                return 1;
@@ -681,15 +711,6 @@ static int wm_draw_update_test_window(wmWindow *win)
        if(win->screen->do_draw_drag)
                return 1;
        
-       for(ar= win->screen->regionbase.first; ar; ar= ar->next)
-               if(ar->swinid && ar->do_draw)
-                       return 1;
-               
-       for(sa= win->screen->areabase.first; sa; sa= sa->next)
-               for(ar=sa->regionbase.first; ar; ar= ar->next)
-                       if(ar->swinid && ar->do_draw)
-                               return 1;
-
        return 0;
 }
 
index 65e6545..0e22ccd 100644 (file)
@@ -59,6 +59,7 @@
 
 #include "ED_fileselect.h"
 #include "ED_info.h"
+#include "ED_render.h"
 #include "ED_screen.h"
 #include "ED_view3d.h"
 #include "ED_util.h"
@@ -311,6 +312,7 @@ void wm_event_do_notifiers(bContext *C)
                /* XXX make lock in future, or separated derivedmesh users in scene */
                if(!G.rendering) {
                        /* depsgraph & animation: update tagged datablocks */
+                       Main *bmain = CTX_data_main(C);
 
                        /* copied to set's in scene_update_tagged_recursive() */
                        win->screen->scene->customdata_mask= win_combine_v3d_datamask;
@@ -318,7 +320,9 @@ void wm_event_do_notifiers(bContext *C)
                        /* XXX, hack so operators can enforce datamasks [#26482], gl render */
                        win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal;
 
-                       scene_update_tagged(CTX_data_main(C), win->screen->scene);
+                       scene_update_tagged(bmain, win->screen->scene);
+
+                       ED_render_engine_update_tagged(C, bmain);
                }
        }
 
index 1dbed47..306a24f 100644 (file)
@@ -72,6 +72,7 @@ struct Object;
 struct PBVHNode;
 struct Render;
 struct RenderEngine;
+struct RenderEngineType;
 struct RenderLayer;
 struct RenderResult;
 struct ScrArea;
@@ -194,6 +195,7 @@ struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBu
 void ED_screen_set_scene(struct bContext *C, struct Scene *scene){}
 
 void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype){}
+void ED_render_engine_changed(struct Main *bmain) {}
 
 struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob){return (struct PTCacheEdit *) NULL;}
 void PE_current_changed(struct Scene *scene, struct Object *ob){}
@@ -387,6 +389,7 @@ void RE_engines_exit() {}
 void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) {}
 ListBase R_engines = {NULL, NULL};
 void RE_engine_free(struct RenderEngine *engine) {}
+struct RenderEngineType *RE_engines_find(const char *idname) {}
 
 /* python */
 struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}