Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2013-04-16 21:39:20 +0400
committerTon Roosendaal <ton@blender.org>2013-04-16 21:39:20 +0400
commitae58968e0a610d1b2551bdb5e4d489a8105fd812 (patch)
tree54036ce7a2ac86bb80542371de6952f1213970f5 /source
parent6dcee054bef7846d6a07f20ca2aa32cba94bab60 (diff)
Blender Internal Render in viewport
Because of our release soon, feature has been added behind the Debug Menu. CTRL+ALT+D and set it to -1. Or commandline --debug-value -1. When debug set to -1, you can put the viewport to 'render' mode, just like for Cycles. Notes for testers: (and please no bugs in tracker for this :) - It renders without AA, MBlur, Panorama, Sequence, Composite - Only active render layer gets rendered. Select another layer will re-render. - But yes: it works for FreeStyle renders! - Also does great for local view. - BI is not well suited for incremental renders on view changes. This only works for non-raytrace scenes, or zoom in ortho or camera mode, or for Material changes. In most cases a full re-render is being done. - ESC works to stop the preview render. - Borders render as well. (CTRL+B) - Force a refresh with arrow key left/right. A lot of settings don't trigger re-render yet. Tech notes: - FreeStyle is adding a lot of temp objects/meshes in the Main database. This caused DepsGraph to trigger changes (and redraws). I've prepended the names for these temp objects with char number 27 (ESC), and made these names be ignored for tag update checking. - Fixed some bugs that were noticable with such excessive re-renders, like for opening file window, quit during renders.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h2
-rw-r--r--source/blender/blenlib/intern/math_matrix.c10
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/editors/include/ED_render.h4
-rw-r--r--source/blender/editors/render/render_intern.h2
-rw-r--r--source/blender/editors/render/render_internal.c362
-rw-r--r--source/blender/editors/render/render_preview.c1
-rw-r--r--source/blender/editors/render/render_update.c40
-rw-r--r--source/blender/editors/space_api/spacetypes.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c3
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp8
-rw-r--r--source/blender/render/extern/include/RE_engine.h6
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h6
-rw-r--r--source/blender/render/intern/include/envmap.h1
-rw-r--r--source/blender/render/intern/include/initrender.h2
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/source/convertblender.c34
-rw-r--r--source/blender/render/intern/source/envmap.c41
-rw-r--r--source/blender/render/intern/source/external_engine.c12
-rw-r--r--source/blender/render/intern/source/pipeline.c64
-rw-r--r--source/blender/render/intern/source/render_result.c1
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c7
23 files changed, 565 insertions, 51 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 3a531cf32ae..0a4a15cca09 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2341,7 +2341,8 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time)
/* 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]]) {
+ /* XXX very weak... added check for '27' to ignore freestyle added objects */
+ if (id && id->name[2] > 27 && bmain->id_tag_update[id->name[0]]) {
updated = 1;
break;
}
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 97cd6a60862..9c5d3c5b93c 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -122,6 +122,8 @@ void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
void transpose_m3(float R[3][3]);
void transpose_m4(float R[4][4]);
+int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
+
void normalize_m3(float R[3][3]);
void normalize_m3_m3(float R[3][3], float A[3][3]);
void normalize_m4(float R[4][4]);
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index f116c9b8443..1ec63f11c3d 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -722,6 +722,16 @@ void transpose_m4(float mat[4][4])
mat[3][2] = t;
}
+int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit)
+{
+ if (compare_v4v4(mat1[0], mat2[0], limit))
+ if (compare_v4v4(mat1[1], mat2[1], limit))
+ if (compare_v4v4(mat1[2], mat2[2], limit))
+ if (compare_v4v4(mat1[3], mat2[3], limit))
+ return 1;
+ return 0;
+}
+
void orthogonalize_m3(float mat[3][3], int axis)
{
float size[3];
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fdbf2927464..e7e8d6f3b99 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6209,9 +6209,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->properties_storage = NULL;
v3d->defmaterial = NULL;
- /* render can be quite heavy, set to wire on load */
+ /* render can be quite heavy, set to solid on load */
if (v3d->drawtype == OB_RENDER)
- v3d->drawtype = OB_WIRE;
+ v3d->drawtype = OB_SOLID;
blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
}
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index 39e2c28a61a..c1ddd9a6294 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -38,6 +38,8 @@ struct Render;
struct RenderInfo;
struct Scene;
struct ScrArea;
+struct RegionView3D;
+struct RenderEngine;
/* render_ops.c */
@@ -85,4 +87,6 @@ void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *s
void ED_render_clear_mtex_copybuf(void);
+void ED_render_internal_init(void);
+
#endif
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index 88c00601933..edd61bfc5c3 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -83,6 +83,8 @@ void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot);
/* render_internal.c */
void RENDER_OT_render(struct wmOperatorType *ot);
+void render_view3d(struct RenderEngine *engine, const struct bContext *C);
+void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C);
/* render_opengl.c uses this */
void image_buffer_rect_update(struct Scene *scene, struct RenderResult *rr, struct ImBuf *ibuf, volatile struct rcti *renrect);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 6832cd5baa0..f599fa1bde8 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -42,9 +42,11 @@
#include "BLF_translation.h"
#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_freestyle.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -59,14 +61,23 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "ED_screen.h"
#include "ED_object.h"
+#include "ED_render.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
+
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "GPU_extensions.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -681,3 +692,352 @@ void RENDER_OT_render(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+
+/* ************** preview for 3d viewport ***************** */
+
+#define PR_UPDATE_VIEW 1
+#define PR_UPDATE_RENDERSIZE 2
+#define PR_UPDATE_MATERIAL 4
+
+typedef struct RenderPreview {
+ /* from wmJob */
+ void *owner;
+ short *stop, *do_update;
+
+ Scene *scene;
+ ScrArea *sa;
+ ARegion *ar;
+ View3D *v3d;
+ RegionView3D *rv3d;
+ Main *bmain;
+ RenderEngine *engine;
+
+ int keep_data;
+} RenderPreview;
+
+static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
+{
+ /* copied code from view3d_draw.c */
+ rctf viewborder;
+ int draw_border;
+
+ if (rv3d->persp == RV3D_CAMOB)
+ draw_border = (scene->r.mode & R_BORDER) != 0;
+ else
+ draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
+
+ if (draw_border) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+
+ disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
+ disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
+ disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
+ disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ }
+ else {
+ disprect->xmin = v3d->render_border.xmin * ar->winx;
+ disprect->xmax = v3d->render_border.xmax * ar->winx;
+ disprect->ymin = v3d->render_border.ymin * ar->winy;
+ disprect->ymax = v3d->render_border.ymax * ar->winy;
+ }
+
+ return 1;
+ }
+
+ BLI_rcti_init(disprect, 0, 0, 0, 0);
+ return 0;
+}
+
+/* returns 1 if OK */
+static int render_view3d_get_rects(ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine, float *clipsta, float *clipend, int *ortho)
+{
+
+ if (ar->winx < 4 || ar->winy < 4) return 0;
+
+ *ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, viewplane, clipsta, clipend);
+
+ engine->resolution_x = ar->winx;
+ engine->resolution_y = ar->winy;
+
+ return 1;
+}
+
+/* called by renderer, checks job value */
+static int render_view3d_break(void *rpv)
+{
+ RenderPreview *rp = rpv;
+
+ if (G.is_break)
+ return 1;
+
+ /* during render, rv3d->engine can get freed */
+ if (rp->rv3d->render_engine == NULL)
+ *rp->stop = 1;
+
+ return *(rp->stop);
+}
+
+static void render_view3d_draw_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
+{
+ RenderPreview *rp = rpv;
+
+ *(rp->do_update) = TRUE;
+}
+
+static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
+{
+ RenderPreview *rp = rjp;
+
+ /* during render, rv3d->engine can get freed */
+ if (rp->rv3d->render_engine == NULL)
+ *rp->stop = 1;
+ else if (rp->engine->text) {
+ make_renderinfo_string(rs, rp->scene, rp->engine->text);
+
+ /* make jobs timer to send notifier */
+ *(rp->do_update) = TRUE;
+ }
+}
+
+
+static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress))
+{
+ RenderPreview *rp = customdata;
+ Render *re;
+ RenderStats *rstats;
+ RenderData rdata;
+ rctf viewplane;
+ rcti cliprct;
+ float clipsta, clipend;
+ int orth, restore = 0;
+ char name[32];
+
+ G.is_break = FALSE;
+
+ if (0 == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &orth))
+ return;
+
+ rp->stop = stop;
+ rp->do_update = do_update;
+
+// printf("Enter previewrender\n");
+
+ /* ok, are we rendering all over? */
+ sprintf(name, "View3dPreview %p", (void *)rp->ar);
+ re= rp->engine->re = RE_GetRender(name);
+
+ if (rp->engine->re == NULL) {
+
+ re = rp->engine->re= RE_NewRender(name);
+
+ rp->keep_data = 0;
+ }
+
+ /* set this always, rp is different for each job */
+ RE_test_break_cb(re, rp, render_view3d_break);
+ RE_display_draw_cb(re, rp, render_view3d_draw_update);
+ RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb);
+
+ rstats= RE_GetStats(re);
+
+ if (rp->keep_data == 0 || rstats->convertdone == 0 || (rp->keep_data & PR_UPDATE_RENDERSIZE)) {
+ /* no osa, blur, seq, layers, etc for preview render */
+ rdata = rp->scene->r;
+ rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
+ rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE);
+ rdata.scemode |= R_PREVIEWBUTS;
+
+ /* we do use layers, but only active */
+ rdata.scemode |= R_SINGLE_LAYER;
+
+ /* initalize always */
+ if (render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct)) {
+ rdata.mode |= R_BORDER;
+ RE_InitState(re, NULL, &rdata, NULL, rp->sa->winx, rp->sa->winy, &cliprct);
+ }
+ else
+ RE_InitState(re, NULL, &rdata, NULL, rp->sa->winx, rp->sa->winy, NULL);
+ }
+
+ if (orth)
+ RE_SetOrtho(re, &viewplane, clipsta, clipend);
+ else
+ RE_SetWindow(re, &viewplane, clipsta, clipend);
+
+ /* database free can crash on a empty Render... */
+ if (rp->keep_data == 0 && rstats->convertdone)
+ RE_Database_Free(re);
+
+ if (rstats->convertdone == 0) {
+ unsigned int lay = rp->scene->lay;
+
+ /* allow localview render for objects with lights in normal layers */
+ if (rp->v3d->lay & 0xFF000000)
+ lay |= rp->v3d->lay;
+ else lay = rp->v3d->lay;
+
+ RE_SetView(re, rp->rv3d->viewmat);
+
+ RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view
+// printf("dbase update\n");
+ }
+ else {
+// printf("dbase rotate\n");
+ RE_DataBase_IncrementalView(re, rp->rv3d->viewmat, 0);
+ restore = 1;
+ }
+
+ RE_DataBase_ApplyWindow(re);
+
+ /* OK, can we enter render code? */
+ if (rstats->convertdone) {
+ RE_TileProcessor(re);
+// printf("tile processor\n");
+
+ if (restore)
+ RE_DataBase_IncrementalView(re, rp->rv3d->viewmat, 1);
+
+ rp->engine->flag &= ~RE_ENGINE_DO_UPDATE;
+ }
+
+// printf("done\n\n");
+}
+
+static void render_view3d_free(void *customdata)
+{
+ RenderPreview *rp = customdata;
+
+ MEM_freeN(rp);
+}
+
+static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_data)
+{
+ wmJob *wm_job;
+ RenderPreview *rp;
+ Scene *scene = CTX_data_scene(C);
+
+ if (CTX_wm_window(C) == NULL) {
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+
+ return;
+ }
+
+ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview",
+ WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
+ rp = MEM_callocN(sizeof(RenderPreview), "render preview");
+
+ /* customdata for preview thread */
+ rp->scene = scene;
+ rp->engine = engine;
+ rp->sa = CTX_wm_area(C);
+ rp->ar = CTX_wm_region(C);
+ rp->v3d = rp->sa->spacedata.first;
+ rp->rv3d = CTX_wm_region_view3d(C);
+ rp->bmain = CTX_data_main(C);
+ rp->keep_data = keep_data;
+
+ /* dont alloc in threads */
+ if (engine->text == NULL)
+ engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
+ WM_jobs_timer(wm_job, 0.1, NC_SPACE|ND_SPACE_VIEW3D, NC_SPACE|ND_SPACE_VIEW3D);
+ WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+
+ engine->flag &= ~RE_ENGINE_DO_UPDATE;
+
+}
+
+/* callback for render engine , on changes */
+void render_view3d(RenderEngine *engine, const bContext *C)
+{
+ render_view3d_do(engine, C, 0);
+}
+
+static int render_view3d_changed(RenderEngine *engine, const bContext *C)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Render *re;
+ int update = 0;
+ char name[32];
+
+ sprintf(name, "View3dPreview %p", (void *)ar);
+ re = RE_GetRender(name);
+
+ if (re) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ rctf viewplane, viewplane1;
+ rcti disprect, disprect1;
+ float mat[4][4];
+ float clipsta, clipend;
+ int orth;
+
+ if (engine->update_flag == RE_ENGINE_UPDATE_MA)
+ update |= PR_UPDATE_MATERIAL;
+ engine->update_flag = 0;
+
+ if (engine->resolution_x != ar->winx || engine->resolution_y != ar->winy)
+ update |= PR_UPDATE_RENDERSIZE;
+
+ /* view updating fails on raytrace */
+ RE_GetView(re, mat);
+ if (compare_m4m4(mat, rv3d->viewmat, 0.00001f) == 0) {
+ if ((scene->r.mode & R_RAYTRACE)==0)
+ update |= PR_UPDATE_VIEW;
+ else
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+ }
+
+ render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, &orth);
+ RE_GetViewPlane(re, &viewplane1, &disprect1);
+
+ if (BLI_rctf_compare(&viewplane, &viewplane1, 0.00001f) == 0)
+ update |= PR_UPDATE_VIEW;
+
+ render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
+ if (BLI_rcti_compare(&disprect, &disprect1) == 0)
+ update |= PR_UPDATE_RENDERSIZE;
+
+ if (update)
+ engine->flag |= RE_ENGINE_DO_UPDATE;
+// if (update)
+// printf("changed ma %d res %d view %d\n", update & PR_UPDATE_MATERIAL, update & PR_UPDATE_RENDERSIZE, update & PR_UPDATE_VIEW);
+
+ }
+
+ return update;
+}
+
+void render_view3d_draw(RenderEngine *engine, const bContext *C)
+{
+ Render *re = engine->re;
+ RenderResult rres;
+ int keep_data = render_view3d_changed(engine, C);
+
+ if (engine->flag & RE_ENGINE_DO_UPDATE)
+ render_view3d_do(engine, C, keep_data);
+
+ if (re == NULL) return;
+
+ RE_AcquireResultImage(re, &rres);
+ RE_ReleaseResultImage(re);
+
+ if (rres.rectf) {
+ unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
+
+ RE_ResultGet32(re, (unsigned int *)rect_byte);
+
+ glEnable(GL_BLEND);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, rect_byte);
+ glDisable(GL_BLEND);
+
+ MEM_freeN(rect_byte);
+ }
+}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 0caf4a7351f..7ef84b9d6eb 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -93,7 +93,6 @@
#include "RE_pipeline.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index f19ea08f381..5653d14e590 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -116,6 +116,7 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
engine = rv3d->render_engine;
if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
+
CTX_wm_screen_set(C, sc);
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
@@ -177,6 +178,32 @@ void ED_render_engine_changed(Main *bmain)
* 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 void render_engine_flag_changed(Main *bmain, int update_flag)
+{
+ 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->update_flag |= update_flag;
+
+ }
+ }
+ }
+}
+
static int mtex_use_tex(MTex **mtex, int tot, Tex *tex)
{
int a;
@@ -472,6 +499,7 @@ void ED_render_id_flush_update(Main *bmain, ID *id)
switch (GS(id->name)) {
case ID_MA:
material_changed(bmain, (Material *)id);
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_MA);
break;
case ID_TE:
texture_changed(bmain, (Tex *)id);
@@ -487,9 +515,21 @@ void ED_render_id_flush_update(Main *bmain, ID *id)
break;
case ID_SCE:
scene_changed(bmain, (Scene *)id);
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
break;
default:
+ render_engine_flag_changed(bmain, RE_ENGINE_UPDATE_OTHER);
break;
}
+
}
+
+void ED_render_internal_init(void)
+{
+ RenderEngineType *ret = RE_engines_find("BLENDER_RENDER");
+
+ ret->view_update = render_view3d;
+ ret->view_draw = render_view3d_draw;
+
+}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 35344f2c5a4..2739d41a73d 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -149,6 +149,8 @@ void ED_spacetypes_init(void)
type->dropboxes();
}
+ /* register internal render callbacks */
+ ED_render_internal_init();
}
/* called in wm.c */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b227d32d987..7552e09ebbd 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -199,7 +199,8 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
sms.to_camera = true; /* restore view3d values in end */
}
- if (C && U.smooth_viewtx) {
+ /* skip smooth viewing for render engine draw */
+ if (C && U.smooth_viewtx && v3d->drawtype != OB_RENDER) {
bool changed = false; /* zero means no difference */
if (oldcamera != camera)
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 0bd990ad03a..dd75e4d0dd5 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -478,9 +478,11 @@ Object *BlenderStrokeRenderer::NewMesh() const
char name[MAX_ID_NAME];
unsigned int mesh_id = get_stroke_mesh_id();
- BLI_snprintf(name, MAX_ID_NAME, "0%08xOB", mesh_id);
+ /* XXX this is for later review, for now we start names with 27 (DEL)
+ to allow ignoring them in DAG_ids_check_recalc() */
+ BLI_snprintf(name, MAX_ID_NAME, "%c0%08xOB", 27, mesh_id);
ob = BKE_object_add_only_object(G.main, OB_MESH, name);
- BLI_snprintf(name, MAX_ID_NAME, "0%08xME", mesh_id);
+ BLI_snprintf(name, MAX_ID_NAME, "%c0%08xME", 27, mesh_id);
ob->data = BKE_mesh_add(G.main, name);
ob->lay = 1;
@@ -491,7 +493,7 @@ Object *BlenderStrokeRenderer::NewMesh() const
#else
(void)base;
#endif
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ ob->recalc = OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
return ob;
}
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index cb35b0045f7..7c1bc4d12d6 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -66,6 +66,10 @@ struct Scene;
#define RE_ENGINE_HIGHLIGHT_TILES 32
#define RE_ENGINE_USED_FOR_VIEWPORT 64
+/* RenderEngine.update_flag, used by internal now */
+#define RE_ENGINE_UPDATE_MA 1
+#define RE_ENGINE_UPDATE_OTHER 2
+
extern ListBase R_engines;
typedef struct RenderEngineType {
@@ -92,7 +96,7 @@ typedef struct RenderEngine {
RenderEngineType *type;
void *py_instance;
- int flag;
+ int flag, update_flag;
struct Object *camera_override;
int tile_x;
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 96106296443..9a8b1620f71 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -197,12 +197,18 @@ void RE_SetPixelSize(struct Render *re, float pixsize);
/* option to set viewmatrix before making dbase */
void RE_SetView(struct Render *re, float mat[4][4]);
+/* get current view and window transform */
+void RE_GetView(struct Render *re, float mat[4][4]);
+void RE_GetViewPlane(struct Render *re, rctf *viewplane, rcti *disprect);
+
/* make or free the dbase */
void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view);
void RE_Database_Free(struct Render *re);
/* project dbase again, when viewplane/perspective changed */
void RE_DataBase_ApplyWindow(struct Render *re);
+/* rotate scene again, for incremental render */
+void RE_DataBase_IncrementalView(struct Render *re, float viewmat[4][4], int restore);
/* override the scene setting for amount threads, commandline */
void RE_set_max_threads(int threads);
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index a6c6d46e2e9..79233a5d625 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -48,6 +48,7 @@ struct ImagePool;
void make_envmaps(struct Render *re);
int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
+void env_rotate_scene(struct Render *re, float mat[4][4], int mode);
#endif /* __ENVMAP_H__ */
diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h
index 73dc29c8feb..69706ecc933 100644
--- a/source/blender/render/intern/include/initrender.h
+++ b/source/blender/render/intern/include/initrender.h
@@ -40,9 +40,9 @@ struct Object;
void free_sample_tables(Render *re);
void make_sample_tables(Render *re);
-void RE_parts_clamp(Render *re);
void RE_parts_init(Render *re, int do_crop);
void RE_parts_free(Render *re);
+void RE_parts_clamp(Render *re);
#endif /* __INITRENDER_H__ */
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index f3cd60d8031..eb2f1cb5826 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -166,6 +166,7 @@ struct Render
float grvec[3]; /* for world */
float imat[3][3]; /* copy of viewinv */
float viewmat[4][4], viewinv[4][4];
+ float viewmat_orig[4][4]; /* for incremental render */
float winmat[4][4];
/* clippping */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 76179b25871..d83df4e78b0 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4851,10 +4851,11 @@ void RE_Database_Free(Render *re)
/* free orco */
free_mesh_orco_hash(re);
- end_render_materials(re->main);
- end_render_textures(re);
-
- free_pointdensities(re);
+ if (re->main) {
+ end_render_materials(re->main);
+ end_render_textures(re);
+ free_pointdensities(re);
+ }
free_camera_inside_volumes(re);
@@ -5202,14 +5203,17 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int lay, int use_camera_view)
{
Scene *sce;
+ Object *camera;
float mat[4][4];
float amb[3];
- Object *camera= RE_GetCamera(re);
re->main= bmain;
re->scene= scene;
re->lay= lay;
+ /* scene needs to be set to get camera */
+ camera= RE_GetCamera(re);
+
/* per second, per object, stats print this */
re->i.infostr= "Preparing Scene data";
re->i.cfra= scene->r.cfra;
@@ -5246,6 +5250,9 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
camera->recalc= OB_RECALC_OB; /* force correct matrix for scaled cameras */
}
+ /* store for incremental render, viewmat rotates dbase */
+ copy_m4_m4(re->viewmat_orig, re->viewmat);
+
init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */
if (re->r.mode & R_RAYTRACE) {
init_render_qmcsampler(re);
@@ -5354,6 +5361,23 @@ void RE_DataBase_ApplyWindow(Render *re)
project_renderdata(re, projectverto, 0, 0, 0);
}
+/* exported call to rotate render data again, when viewmat changed */
+void RE_DataBase_IncrementalView(Render *re, float viewmat[4][4], int restore)
+{
+ float oldviewinv[4][4], tmat[4][4];
+
+ invert_m4_m4(oldviewinv, re->viewmat_orig);
+
+ /* we have to correct for the already rotated vertexcoords */
+ mult_m4_m4m4(tmat, viewmat, oldviewinv);
+
+ copy_m4_m4(re->viewmat, viewmat);
+ invert_m4_m4(re->viewinv, re->viewmat);
+
+ env_rotate_scene(re, tmat, !restore);
+}
+
+
void RE_DataBase_GetView(Render *re, float mat[4][4])
{
copy_m4_m4(mat, re->viewmat);
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index c5872c52e0f..6423bfa9486 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -246,10 +246,26 @@ static void envmap_transmatrix(float mat[4][4], int part)
NULL, NULL, NULL,
NULL, NULL, NULL);
}
+/* ------------------------------------------------------------------------- */
+
+static void env_set_imats(Render *re)
+{
+ Base *base;
+ float mat[4][4];
+
+ base = re->scene->base.first;
+ while (base) {
+ mult_m4_m4m4(mat, re->viewmat, base->object->obmat);
+ invert_m4_m4(base->object->imat, mat);
+
+ base = base->next;
+ }
+
+}
/* ------------------------------------------------------------------------- */
-static void env_rotate_scene(Render *re, float mat[4][4], int mode)
+void env_rotate_scene(Render *re, float mat[4][4], int mode)
{
GroupObject *go;
ObjectRen *obr;
@@ -328,6 +344,10 @@ static void env_rotate_scene(Render *re, float mat[4][4], int mode)
}
}
+ if (mode) {
+ init_render_world(re);
+ env_set_imats(re);
+ }
}
/* ------------------------------------------------------------------------- */
@@ -395,23 +415,6 @@ static void env_showobjects(Render *re)
/* ------------------------------------------------------------------------- */
-static void env_set_imats(Render *re)
-{
- Base *base;
- float mat[4][4];
-
- base = re->scene->base.first;
- while (base) {
- mult_m4_m4m4(mat, re->viewmat, base->object->obmat);
- invert_m4_m4(base->object->imat, mat);
-
- base = base->next;
- }
-
-}
-
-/* ------------------------------------------------------------------------- */
-
static void render_envmap(Render *re, EnvMap *env)
{
/* only the cubemap and planar map is implemented */
@@ -454,11 +457,9 @@ static void render_envmap(Render *re, EnvMap *env)
invert_m4_m4(env->imat, tmat);
env_rotate_scene(envre, tmat, 1);
- init_render_world(envre);
project_renderdata(envre, projectverto, 0, 0, 1);
env_layerflags(envre, env->notlay);
env_hideobject(envre, env->object);
- env_set_imats(envre);
if (re->test_break(re->tbh) == 0) {
RE_TileProcessor(envre);
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 90528fddc85..7ce5d9f72de 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -116,6 +116,18 @@ RenderEngineType *RE_engines_find(const char *idname)
if (!type)
type = &internal_render_type;
+ /* XXX Hack to make this a debug-only option, remove section to make it available default */
+ if (type == &internal_render_type) {
+ static RenderEngineType rtype;
+
+ if (type->view_update == NULL)
+ rtype = internal_render_type;
+ else if (G.debug_value != -1) {
+ type = &rtype;
+ }
+ }
+ /* XXX end hack */
+
return type;
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index da756447f96..7f2c3b5ad04 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -328,6 +328,9 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr)
rr->have_combined = (re->result->rectf != NULL);
rr->layers = re->result->layers;
+
+ rr->xof = re->disprect.xmin;
+ rr->yof = re->disprect.ymin;
}
}
}
@@ -402,7 +405,10 @@ void RE_FreeRender(Render *re)
BLI_rw_mutex_end(&re->resultmutex);
- free_renderdata_tables(re);
+ /* main dbase can already be invalid now, some database-free code checks it */
+ re->main = NULL;
+
+ RE_Database_Free(re); /* view render can still have full database */
free_sample_tables(re);
render_result_free(re->result);
@@ -564,13 +570,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if (re->r.scemode & R_PREVIEWBUTS) {
- if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) {
- /* pass */
- }
- else {
- render_result_free(re->result);
- re->result = NULL;
- }
+ /* always fresh, freestyle layers need it */
+ render_result_free(re->result);
+ re->result = NULL;
}
else {
@@ -580,6 +582,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->result->rectx = re->rectx;
re->result->recty = re->recty;
}
+
+ /* ensure renderdatabase can use part settings correct */
+ RE_parts_clamp(re);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -627,6 +632,22 @@ void RE_SetView(Render *re, float mat[4][4])
invert_m4_m4(re->viewinv, re->viewmat);
}
+void RE_GetViewPlane(Render *re, rctf *viewplane, rcti *disprect)
+{
+ *viewplane = re->viewplane;
+
+ /* make disprect zero when no border render, is needed to detect changes in 3d view render */
+ if (re->r.mode & R_BORDER)
+ *disprect = re->disprect;
+ else
+ BLI_rcti_init(disprect, 0, 0, 0, 0);
+}
+
+void RE_GetView(Render *re, float mat[4][4])
+{
+ copy_m4_m4(mat, re->viewmat);
+}
+
/* image and movie output has to move to either imbuf or kernel */
void RE_display_init_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr))
{
@@ -1035,18 +1056,37 @@ static void threaded_tile_processor(Render *re)
re->viewplane = viewplane; /* restore viewplane, modified by pano render */
}
+#ifdef WITH_FREESTYLE
+static void add_freestyle(Render *re);
+static void free_all_freestyle_renders(Scene *scene);
+#endif
+
/* currently only called by preview renders and envmap */
void RE_TileProcessor(Render *re)
{
threaded_tile_processor(re);
-}
-
-/* ************ This part uses API, for rendering Blender scenes ********** */
+
+ re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
+ re->stats_draw(re->sdh, &re->i);
#ifdef WITH_FREESTYLE
-static void add_freestyle(Render *re);
+ /* Freestyle */
+ if (re->r.mode & R_EDGE_FRS) {
+ if (!re->test_break(re->tbh)) {
+ add_freestyle(re);
+
+ free_all_freestyle_renders(re->scene);
+
+ re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime;
+ re->stats_draw(re->sdh, &re->i);
+ }
+ }
#endif
+}
+
+/* ************ This part uses API, for rendering Blender scenes ********** */
+
static void do_render_3d(Render *re)
{
float cfra;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 0fee1e41e32..f719e09769d 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -569,6 +569,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
}
/* border render; calculate offset for use in compositor. compo is centralized coords */
+ /* XXX obsolete? I now use it for drawing border render offset (ton) */
rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 9810d1ecf72..31f2b412a7f 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -438,6 +438,10 @@ void WM_exit_ext(bContext *C, const short do_python)
BKE_mball_cubeTable_free();
+ /* render code might still access databases */
+ RE_FreeAllRender();
+ RE_engines_exit();
+
ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */
if (C && wm)
@@ -468,9 +472,6 @@ void WM_exit_ext(bContext *C, const short do_python)
ANIM_keyingset_infos_exit();
- RE_FreeAllRender();
- RE_engines_exit();
-
// free_txt_data();