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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r--source/blender/editors/render/render_intern.h8
-rw-r--r--source/blender/editors/render/render_internal.c47
-rw-r--r--source/blender/editors/render/render_opengl.c380
-rw-r--r--source/blender/editors/render/render_ops.c4
-rw-r--r--source/blender/editors/render/render_preview.c191
-rw-r--r--source/blender/editors/render/render_shading.c151
-rw-r--r--source/blender/editors/render/render_update.c36
-rw-r--r--source/blender/editors/render/render_view.c10
8 files changed, 582 insertions, 245 deletions
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index f9377d576bf..54429f9f066 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -32,9 +32,9 @@
#ifndef __RENDER_INTERN_H__
#define __RENDER_INTERN_H__
+struct bContext;
+struct RenderEngine;
struct wmOperatorType;
-struct RenderResult;
-struct Scene;
struct ScrArea;
/* render_shading.c */
@@ -44,6 +44,7 @@ void OBJECT_OT_material_slot_assign(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_select(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_deselect(struct wmOperatorType *ot);
void OBJECT_OT_material_slot_copy(struct wmOperatorType *ot);
+void OBJECT_OT_material_slot_move(struct wmOperatorType *ot);
void MATERIAL_OT_new(struct wmOperatorType *ot);
void TEXTURE_OT_new(struct wmOperatorType *ot);
@@ -55,6 +56,9 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot);
void SCENE_OT_render_layer_add(struct wmOperatorType *ot);
void SCENE_OT_render_layer_remove(struct wmOperatorType *ot);
+void SCENE_OT_render_view_add(struct wmOperatorType *ot);
+void SCENE_OT_render_view_remove(struct wmOperatorType *ot);
+
#ifdef WITH_FREESTYLE
void SCENE_OT_freestyle_module_add(struct wmOperatorType *ot);
void SCENE_OT_freestyle_module_remove(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 8fcd91b7791..dc4c2c71878 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -48,6 +48,7 @@
#include "DNA_userdef_types.h"
#include "BKE_blender.h"
+#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
@@ -116,7 +117,7 @@ typedef struct RenderJob {
} RenderJob;
/* called inside thread! */
-static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect)
+static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect, const char *viewname)
{
Scene *scene = rj->scene;
const float *rectf = NULL;
@@ -187,12 +188,16 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
* - sergey -
*/
/* TODO(sergey): Need to check has_combined here? */
- if (iuser->pass == 0) {
+ if (iuser->passtype == SCE_PASS_COMBINED) {
+ RenderView *rv;
+ size_t view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
+ rv = RE_RenderViewGetById(rr, view_id);
+
/* find current float rect for display, first case is after composite... still weak */
- if (rr->rectf)
- rectf = rr->rectf;
+ if (rv->rectf)
+ rectf = rv->rectf;
else {
- if (rr->rect32) {
+ if (rv->rect32) {
/* special case, currently only happens with sequencer rendering,
* which updates the whole frame, so we can only mark display buffer
* as invalid here (sergey)
@@ -201,8 +206,8 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
return;
}
else {
- if (rr->renlay == NULL || rr->renlay->rectf == NULL) return;
- rectf = rr->renlay->rectf;
+ if (rr->renlay == NULL) return;
+ rectf = RE_RenderLayerGetPass(rr->renlay, SCE_PASS_COMBINED, viewname);
}
}
if (rectf == NULL) return;
@@ -518,7 +523,6 @@ static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr,
}
}
- iuser->pass = sima->iuser.pass;
iuser->layer = sima->iuser.layer;
RE_ReleaseResult(rj->re);
@@ -531,6 +535,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
Image *ima = rj->image;
ImBuf *ibuf;
void *lock;
+ const char *viewname = RE_GetActiveRenderView(rj->re);
/* only update if we are displaying the slot being rendered */
if (ima->render_slot != ima->last_render_slot) {
@@ -563,7 +568,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
ibuf->channels == 1 ||
U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
{
- image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect);
+ image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
}
/* make jobs timer to send notifier */
@@ -891,6 +896,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->write_still = is_write_still && !is_animation;
rj->iuser.scene = scene;
rj->iuser.ok = 1;
+ rj->iuser.passtype = SCE_PASS_COMBINED;
rj->reports = op->reports;
rj->orig_layer = 0;
rj->last_layer = 0;
@@ -1227,10 +1233,10 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
RenderData rdata;
- /* no osa, blur, seq, layers, etc for preview render */
+ /* no osa, blur, seq, layers, savebuffer 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_DOSEQ | R_DOCOMP | R_FREE_IMAGE | R_EXR_TILE_FILE | R_FULL_SAMPLE);
rdata.scemode |= R_VIEWPORT_PREVIEW;
/* we do use layers, but only active */
@@ -1487,7 +1493,8 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
if (re == NULL) return;
}
- RE_AcquireResultImage(re, &rres);
+ /* Viewport render preview doesn't support multiview, view hardcoded to 0 */
+ RE_AcquireResultImage(re, &rres, 0);
if (rres.rectf) {
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1545,8 +1552,8 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glPixelZoom(scale_x, scale_y);
glaDrawPixelsAuto(xof, yof, rres.rectx, rres.recty,
- GL_RGBA, GL_UNSIGNED_BYTE,
- GL_NEAREST, display_buffer);
+ GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
+ 1.0f, display_buffer);
glPixelZoom(1.0f, 1.0f);
glDisable(GL_BLEND);
@@ -1617,7 +1624,17 @@ Scene *ED_render_job_get_scene(const bContext *C)
RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
if (rj)
- return rj->current_scene;
+ return rj->scene;
return NULL;
}
+
+Scene *ED_render_job_get_current_scene(const bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
+ if (rj) {
+ return rj->current_scene;
+ }
+ return NULL;
+}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 9fb83557dc2..c265913f113 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -39,6 +39,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_jitter.h"
+#include "BLI_threads.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -103,11 +104,17 @@ typedef struct OGLRender {
bMovieHandle *mh;
int cfrao, nfra;
+ size_t totvideos;
+
+ /* quick lookup */
+ int view_id;
+
/* wm vars for timer and progress cursor */
wmWindowManager *wm;
wmWindow *win;
wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/
+ void **movie_ctx_arr;
} OGLRender;
/* added because v3d is not always valid */
@@ -121,25 +128,144 @@ static unsigned int screen_opengl_layers(OGLRender *oglrender)
}
}
-static void screen_opengl_render_apply(OGLRender *oglrender)
+static bool screen_opengl_is_multiview(OGLRender *oglrender)
+{
+ View3D *v3d = oglrender->v3d;
+ RegionView3D *rv3d = oglrender->rv3d;
+ RenderData *rd = &oglrender->scene->r;
+
+ if ((rd == NULL) || ((!oglrender->is_sequencer) && ((rv3d == NULL) || (v3d == NULL))))
+ return false;
+
+ return (rd->scemode & R_MULTIVIEW) && ((oglrender->is_sequencer) || (rv3d->persp == RV3D_CAMOB && v3d->camera));
+}
+
+static void screen_opengl_views_setup(OGLRender *oglrender)
+{
+ RenderResult *rr;
+ RenderView *rv;
+ SceneRenderView *srv;
+ bool is_multiview;
+ Object *camera;
+ View3D *v3d = oglrender->v3d;
+
+ RenderData *rd = &oglrender->scene->r;
+
+ rr = RE_AcquireResultWrite(oglrender->re);
+
+ is_multiview = screen_opengl_is_multiview(oglrender);
+
+ if (!is_multiview) {
+ /* we only have one view when multiview is off */
+ rv = rr->views.first;
+
+ if (rv == NULL) {
+ rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
+ BLI_addtail(&rr->views, rv);
+ }
+
+ while (rv->next) {
+ RenderView *rv_del = rv->next;
+ BLI_remlink(&rr->views, rv_del);
+
+ if (rv_del->rectf)
+ MEM_freeN(rv_del->rectf);
+
+ if (rv_del->rectz)
+ MEM_freeN(rv_del->rectz);
+
+ MEM_freeN(rv_del);
+ }
+ }
+ else {
+ if (!oglrender->is_sequencer)
+ RE_SetOverrideCamera(oglrender->re, V3D_CAMERA_SCENE(oglrender->scene, v3d));
+
+ /* remove all the views that are not needed */
+ rv = rr->views.last;
+ while (rv) {
+ srv = BLI_findstring(&rd->views, rv->name, offsetof(SceneRenderView, name));
+ if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
+ if (rv->rectf == NULL)
+ rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect");
+ rv = rv->prev;
+ }
+ else {
+ RenderView *rv_del = rv;
+ rv = rv_del->prev;
+
+ BLI_remlink(&rr->views, rv_del);
+
+ if (rv_del->rectf)
+ MEM_freeN(rv_del->rectf);
+
+ if (rv_del->rectz)
+ MEM_freeN(rv_del->rectz);
+
+ MEM_freeN(rv_del);
+ }
+ }
+
+ /* create all the views that are needed */
+ for (srv = rd->views.first; srv; srv = srv->next) {
+ if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
+ continue;
+
+ rv = BLI_findstring(&rr->views, srv->name, offsetof(SceneRenderView, name));
+
+ if (rv == NULL) {
+ rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
+ BLI_strncpy(rv->name, srv->name, sizeof(rv->name));
+ BLI_addtail(&rr->views, rv);
+ }
+ }
+ }
+
+ for (rv = rr->views.first; rv; rv = rv->next) {
+ if (rv->rectf == NULL) {
+ rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect");
+ }
+ }
+
+ BLI_lock_thread(LOCK_DRAW_IMAGE);
+ if (is_multiview && BKE_scene_multiview_is_stereo3d(rd)) {
+ oglrender->ima->flag |= IMA_IS_STEREO;
+ }
+ else {
+ oglrender->ima->flag &= ~IMA_IS_STEREO;
+ oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
+ }
+ BLI_unlock_thread(LOCK_DRAW_IMAGE);
+
+ /* will only work for non multiview correctly */
+ if (v3d) {
+ camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, "new opengl render view");
+ BKE_render_result_stamp_info(oglrender->scene, camera, rr);
+ }
+ else {
+ BKE_render_result_stamp_info(oglrender->scene, oglrender->scene->camera, rr);
+ }
+
+ RE_ReleaseResult(oglrender->re);
+}
+
+static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
{
Scene *scene = oglrender->scene;
ARegion *ar = oglrender->ar;
View3D *v3d = oglrender->v3d;
RegionView3D *rv3d = oglrender->rv3d;
- RenderResult *rr;
Object *camera = NULL;
ImBuf *ibuf;
- void *lock;
float winmat[4][4];
+ float *rectf = RE_RenderViewGetById(rr, oglrender->view_id)->rectf;
int sizex = oglrender->sizex;
int sizey = oglrender->sizey;
const short view_context = (v3d != NULL);
bool draw_bgpic = true;
- bool draw_sky = (scene->r.alphamode == R_ADDSKY) && v3d && (v3d->flag3 & V3D_SHOW_WORLD);
+ bool draw_sky = (scene->r.alphamode == R_ADDSKY);
unsigned char *rect = NULL;
-
- rr = RE_AcquireResultRead(oglrender->re);
+ const char *viewname = RE_GetActiveRenderView(oglrender->re);
if (oglrender->is_sequencer) {
SeqRenderData context;
@@ -152,6 +278,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
oglrender->sizex, oglrender->sizey, 100.0f,
&context);
+ context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
ibuf = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
if (ibuf) {
@@ -175,7 +302,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BKE_sequencer_imbuf_from_sequencer_space(scene, linear_ibuf);
}
- memcpy(rr->rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
+ memcpy(rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
IMB_freeImBuf(linear_ibuf);
}
@@ -199,10 +326,12 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
+ BLI_assert(rectf != NULL);
+
for (i = 0; i < sizex * sizey * 4; i += 4) {
float col_src[4];
rgba_uchar_to_float(col_src, &gp_rect[i]);
- blend_color_mix_float(&rr->rectf[i], &rr->rectf[i], col_src);
+ blend_color_mix_float(&rectf[i], &rectf[i], col_src);
}
GPU_offscreen_unbind(oglrender->ofs, true);
@@ -220,10 +349,17 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
- /*int is_ortho = scene->r.mode & R_ORTHO;*/
- camera = v3d->camera;
+#if 0
+ const bool is_ortho = (scene->r.mode & R_ORTHO) != 0;
+#endif
+ camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, viewname);
RE_GetCameraWindow(oglrender->re, camera, scene->r.cfra, winmat);
- is_persp = true;
+ if (camera->type == OB_CAMERA) {
+ Camera *cam = camera->data;
+ is_persp = cam->type == CAM_PERSP;
+ }
+ else
+ is_persp = true;
BKE_camera_to_gpu_dof(camera, &fx_settings);
}
@@ -244,7 +380,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
draw_bgpic, draw_sky, is_persp,
- oglrender->ofs, oglrender->fx, &fx_settings);
+ oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
}
else {
@@ -260,7 +396,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
draw_bgpic, draw_sky, is_persp,
- oglrender->ofs, oglrender->fx, &fx_settings);
+ oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -276,7 +412,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
draw_bgpic, draw_sky, is_persp,
- oglrender->ofs, oglrender->fx, &fx_settings);
+ oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -296,7 +432,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
char err_out[256] = "unknown";
ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
IB_rect, OB_SOLID, false, true, true,
- (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, err_out);
+ (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, viewname, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -321,7 +457,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
if (rect) {
int profile_to;
-
+ float *rectf = RE_RenderViewGetById(rr, oglrender->view_id)->rectf;
+
if (BKE_scene_check_color_management_enabled(scene))
profile_to = IB_PROFILE_LINEAR_RGB;
else
@@ -329,47 +466,68 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* sequencer has got trickier conversion happened above
* also assume opengl's space matches byte buffer color space */
- IMB_buffer_float_from_byte(rr->rectf, rect,
+ IMB_buffer_float_from_byte(rectf, rect,
profile_to, IB_PROFILE_SRGB, true,
oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
+
+ /* rr->rectf is now filled with image data */
+
+ if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW))
+ BKE_image_stamp_buf(scene, camera, rect, rectf, rr->rectx, rr->recty, 4);
+
+ MEM_freeN(rect);
}
+}
- /* rr->rectf is now filled with image data */
+static void screen_opengl_render_write(OGLRender *oglrender)
+{
+ Scene *scene = oglrender->scene;
+ RenderResult *rr;
+ bool ok;
+ char name[FILE_MAX];
+
+ rr = RE_AcquireResultRead(oglrender->re);
+
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false, NULL);
+
+ /* write images as individual images or stereo */
+ BKE_render_result_stamp_info(scene, scene->camera, rr);
+ ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, false, name);
+
+ RE_ReleaseResultImage(oglrender->re);
+
+ if (ok) printf("OpenGL Render written to '%s'\n", name);
+ else printf("OpenGL Render failed to write '%s'\n", name);
+}
+
+static void screen_opengl_render_apply(OGLRender *oglrender)
+{
+ RenderResult *rr;
+ RenderView *rv;
+ int view_id;
+ ImBuf *ibuf;
+ void *lock;
- if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
- BKE_image_stamp_buf(scene, camera, rect, rr->rectf, rr->rectx, rr->recty, 4);
+ rr = RE_AcquireResultRead(oglrender->re);
+ for (rv = rr->views.first, view_id = 0; rv; rv = rv->next, view_id++) {
+ RE_SetActiveRenderView(oglrender->re, rv->name);
+ oglrender->view_id = view_id;
+ screen_opengl_render_doit(oglrender, rr);
}
RE_ReleaseResult(oglrender->re);
- /* update byte from float buffer */
ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
-
if (ibuf) {
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- /* write file for animation */
- if (oglrender->write_still) {
- char name[FILE_MAX];
- int ok;
-
- if (scene->r.im_format.planes == R_IMF_CHAN_DEPTH_8) {
- IMB_color_to_bw(ibuf);
- }
-
- BKE_image_path_from_imformat(
- name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
- ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, true); /* no need to stamp here */
- if (ok) printf("OpenGL Render written to '%s'\n", name);
- else printf("OpenGL Render failed to write '%s'\n", name);
- }
}
-
BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
- if (rect)
- MEM_freeN(rect);
+ if (oglrender->write_still) {
+ screen_opengl_render_write(oglrender);
+ }
}
static bool screen_opengl_render_init(bContext *C, wmOperator *op)
@@ -381,7 +539,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ScrArea *prevsa = CTX_wm_area(C);
ARegion *prevar = CTX_wm_region(C);
- RenderResult *rr;
GPUOffScreen *ofs;
OGLRender *oglrender;
int sizex, sizey;
@@ -454,7 +611,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->sseq = CTX_wm_space_seq(C);
}
-
oglrender->prevsa = prevsa;
oglrender->prevar = prevar;
@@ -488,15 +644,17 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* create render result */
RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
- rr = RE_AcquireResultWrite(oglrender->re);
- if (rr->rectf == NULL)
- rr->rectf = MEM_callocN(sizeof(float) * 4 * sizex * sizey, "screen_opengl_render_init rect");
- RE_ReleaseResult(oglrender->re);
+ /* create render views */
+ screen_opengl_views_setup(oglrender);
/* wm vars */
oglrender->wm = wm;
oglrender->win = win;
+ oglrender->totvideos = 0;
+ oglrender->mh = NULL;
+ oglrender->movie_ctx_arr = NULL;
+
return true;
}
@@ -504,10 +662,19 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
Main *bmain = CTX_data_main(C);
Scene *scene = oglrender->scene;
+ size_t i;
if (oglrender->mh) {
- if (BKE_imtype_is_movie(scene->r.im_format.imtype))
- oglrender->mh->end_movie();
+ if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
+ for (i = 0; i < oglrender->totvideos; i++) {
+ oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]);
+ oglrender->mh->context_free(oglrender->movie_ctx_arr[i]);
+ }
+ }
+
+ if (oglrender->movie_ctx_arr) {
+ MEM_freeN(oglrender->movie_ctx_arr);
+ }
}
if (oglrender->timer) { /* exec will not have a timer */
@@ -548,13 +715,27 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
oglrender = op->customdata;
scene = oglrender->scene;
+ oglrender->totvideos = BKE_scene_multiview_num_videos_get(&scene->r);
oglrender->reports = op->reports;
- oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
+
if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
- if (!oglrender->mh->start_movie(scene, &scene->r, oglrender->sizex, oglrender->sizey, oglrender->reports)) {
- screen_opengl_render_end(C, oglrender);
- return 0;
+ size_t i, width, height;
+
+ BKE_scene_multiview_videos_dimensions_get(&scene->r, oglrender->sizex, oglrender->sizey, &width, &height);
+ oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies");
+ oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
+
+ for (i = 0; i < oglrender->totvideos; i++) {
+ const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
+
+ oglrender->movie_ctx_arr[i] = oglrender->mh->context_create();
+ if (!oglrender->mh->start_movie(oglrender->movie_ctx_arr[i], scene, &scene->r, oglrender->sizex,
+ oglrender->sizey, oglrender->reports, PRVRANGEON != 0, suffix))
+ {
+ screen_opengl_render_end(C, oglrender);
+ return 0;
+ }
}
}
@@ -564,18 +745,17 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
return 1;
}
+
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
OGLRender *oglrender = op->customdata;
Scene *scene = oglrender->scene;
- ImBuf *ibuf, *ibuf_save = NULL;
- void *lock;
char name[FILE_MAX];
bool ok = false;
const bool view_context = (oglrender->v3d != NULL);
- Object *camera = NULL;
bool is_movie;
+ RenderResult *rr;
/* go to next frame */
if (CFRA < oglrender->nfra)
@@ -595,7 +775,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (!is_movie) {
BKE_image_path_from_imformat(
name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
@@ -615,89 +795,41 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
if (BKE_scene_camera_switch_update(scene)) {
oglrender->v3d->camera = scene->camera;
}
-
- camera = oglrender->v3d->camera;
}
}
else {
BKE_scene_camera_switch_update(scene);
-
- camera = scene->camera;
}
/* render into offscreen buffer */
screen_opengl_render_apply(oglrender);
/* save to disk */
- ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
-
- if (ibuf) {
- bool needs_free = false;
-
- ibuf_save = ibuf;
-
- if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
- ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, true, true, &scene->view_settings,
- &scene->display_settings, &scene->r.im_format);
-
- needs_free = true;
- }
-
- /* color -> grayscale */
- /* editing directly would alter the render view */
- if (scene->r.im_format.planes == R_IMF_PLANES_BW) {
- ImBuf *ibuf_bw = IMB_dupImBuf(ibuf_save);
- IMB_color_to_bw(ibuf_bw);
-
- if (needs_free)
- IMB_freeImBuf(ibuf_save);
-
- ibuf_save = ibuf_bw;
- }
- else {
- /* this is lightweight & doesnt re-alloc the buffers, only do this
- * to save the correct bit depth since the image is always RGBA */
- ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf_save->x, ibuf_save->y, scene->r.im_format.planes, 0);
-
- ibuf_cpy->rect = ibuf_save->rect;
- ibuf_cpy->rect_float = ibuf_save->rect_float;
- ibuf_cpy->zbuf_float = ibuf_save->zbuf_float;
-
- if (needs_free) {
- ibuf_cpy->mall = ibuf_save->mall;
- ibuf_save->mall = 0;
- IMB_freeImBuf(ibuf_save);
- }
+ rr = RE_AcquireResultRead(oglrender->re);
- ibuf_save = ibuf_cpy;
+ if (is_movie) {
+ ok = RE_WriteRenderViewsMovie(oglrender->reports, rr, scene, &scene->r, oglrender->mh, oglrender->sizex,
+ oglrender->sizey, oglrender->movie_ctx_arr, oglrender->totvideos, PRVRANGEON != 0);
+ if (ok) {
+ printf("Append frame %d", scene->r.cfra);
+ BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
}
-
- if (is_movie) {
- ok = oglrender->mh->append_movie(&scene->r, PSFRA, CFRA, (int *)ibuf_save->rect,
- oglrender->sizex, oglrender->sizey, oglrender->reports);
- if (ok) {
- printf("Append frame %d", scene->r.cfra);
- BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
- }
+ }
+ else {
+ BKE_render_result_stamp_info(scene, scene->camera, rr);
+ ok = RE_WriteRenderViewsImage(op->reports, rr, scene, true, name);
+ if (ok) {
+ printf("Saved: %s", name);
+ BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
}
else {
- ok = BKE_imbuf_write_stamp(scene, camera, ibuf_save, name, &scene->r.im_format);
-
- if (ok == 0) {
- printf("Write error: cannot save %s\n", name);
- BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
- }
- else {
- printf("Saved: %s", name);
- BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
- }
+ printf("Write error: cannot save %s\n", name);
+ BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
}
-
- if (needs_free)
- IMB_freeImBuf(ibuf_save);
}
- BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
+ RE_ReleaseResult(oglrender->re);
+
/* movie stats prints have no line break */
printf("\n");
diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c
index 0d334082a2b..f98083f7e74 100644
--- a/source/blender/editors/render/render_ops.c
+++ b/source/blender/editors/render/render_ops.c
@@ -47,6 +47,7 @@ void ED_operatortypes_render(void)
WM_operatortype_append(OBJECT_OT_material_slot_select);
WM_operatortype_append(OBJECT_OT_material_slot_deselect);
WM_operatortype_append(OBJECT_OT_material_slot_copy);
+ WM_operatortype_append(OBJECT_OT_material_slot_move);
WM_operatortype_append(MATERIAL_OT_new);
WM_operatortype_append(TEXTURE_OT_new);
@@ -58,6 +59,9 @@ void ED_operatortypes_render(void)
WM_operatortype_append(SCENE_OT_render_layer_add);
WM_operatortype_append(SCENE_OT_render_layer_remove);
+ WM_operatortype_append(SCENE_OT_render_view_add);
+ WM_operatortype_append(SCENE_OT_render_view_remove);
+
#ifdef WITH_FREESTYLE
WM_operatortype_append(SCENE_OT_freestyle_module_add);
WM_operatortype_append(SCENE_OT_freestyle_module_remove);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 99edaff759e..9ed0cec5545 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -79,7 +79,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-
+#include "IMB_thumbs.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -128,7 +128,7 @@ ImBuf *get_brush_icon(Brush *brush)
}
if (brush->icon_imbuf)
- BKE_icon_changed(BKE_icon_getid(&brush->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&brush->id));
}
}
}
@@ -161,6 +161,7 @@ typedef struct ShaderPreview {
unsigned int *pr_rect;
int pr_method;
+ Main *bmain;
Main *pr_main;
} ShaderPreview;
@@ -171,6 +172,7 @@ typedef struct IconPreviewSize {
} IconPreviewSize;
typedef struct IconPreview {
+ Main *bmain;
Scene *scene;
void *owner;
ID *id;
@@ -261,12 +263,14 @@ static Scene *preview_get_scene(Main *pr_main)
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
-static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp)
+static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp)
{
Scene *sce;
Base *base;
Main *pr_main = sp->pr_main;
-
+
+ memcpy(pr_main->name, bmain->name, sizeof(pr_main->name));
+
sce = preview_get_scene(pr_main);
if (sce) {
@@ -423,7 +427,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
Tex *tex = NULL, *origtex = (Tex *)id;
if (origtex) {
- tex = localize_texture(origtex);
+ tex = BKE_texture_localize(origtex);
sp->texcopy = tex;
BLI_addtail(&pr_main->tex, tex);
}
@@ -525,6 +529,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
+ RenderView *rv;
RenderResult rres;
char name[32];
int offx = 0;
@@ -548,9 +553,16 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
/* test if something rendered ok */
re = RE_GetRender(name);
- RE_AcquireResultImage(re, &rres);
- if (rres.rectf) {
+ if (re == NULL)
+ return false;
+
+ RE_AcquireResultImageViews(re, &rres);
+
+ /* material preview only needs monoscopy (view 0) */
+ rv = RE_RenderViewGetById(&rres, 0);
+
+ if (rv->rectf) {
if (ABS(rres.rectx - newx) < 2 && ABS(rres.recty - newy) < 2) {
@@ -561,9 +573,11 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
float fx = rect->xmin + offx;
float fy = rect->ymin;
+
+ /* material preview only needs monoscopy (view 0) */
if (re)
- RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte);
-
+ RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0);
+
glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
MEM_freeN(rect_byte);
@@ -573,7 +587,7 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
}
}
- RE_ReleaseResultImage(re);
+ RE_ReleaseResultImageViews(re, &rres);
return ok;
}
@@ -702,7 +716,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
/* get the stuff from the builtin preview dbase */
- sce = preview_prepare_scene(sp->scene, id, idtype, sp);
+ sce = preview_prepare_scene(sp->bmain, sp->scene, id, idtype, sp);
if (sce == NULL) return;
if (!split || first) sprintf(name, "Preview %p", sp->owner);
@@ -757,7 +771,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
}
/* unassign the pointers, reset vars */
- preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
+ preview_prepare_scene(sp->bmain, sp->scene, NULL, GS(id->name), sp);
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
// if (idtype == ID_TE) {
@@ -925,65 +939,87 @@ static void set_alpha(char *cp, int sizex, int sizey, char alpha)
static void icon_preview_startjob(void *customdata, short *stop, short *do_update)
{
ShaderPreview *sp = customdata;
- ID *id = sp->id;
- short idtype = GS(id->name);
-
- if (idtype == ID_IM) {
- Image *ima = (Image *)id;
- ImBuf *ibuf = NULL;
- ImageUser iuser = {NULL};
- /* ima->ok is zero when Image cannot load */
- if (ima == NULL || ima->ok == 0)
- return;
+ if (sp->pr_method == PR_ICON_DEFERRED) {
+ PreviewImage *prv = sp->owner;
+ ImBuf *thumb;
+ char *deferred_data = PRV_DEFERRED_DATA(prv);
+ int source = deferred_data[0];
+ char *path = &deferred_data[1];
- /* setup dummy image user */
- iuser.ok = iuser.framenr = 1;
- iuser.scene = sp->scene;
-
- /* elubie: this needs to be changed: here image is always loaded if not
- * already there. Very expensive for large images. Need to find a way to
- * only get existing ibuf */
- ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- return;
- }
-
- icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
+// printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path);
- *do_update = true;
+ thumb = IMB_thumb_manage(path, THB_LARGE, source);
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ if (thumb) {
+ /* PreviewImage assumes premultiplied alhpa... */
+ IMB_premultiply_alpha(thumb);
+
+ icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect);
+ IMB_freeImBuf(thumb);
+ }
}
- else if (idtype == ID_BR) {
- Brush *br = (Brush *)id;
+ else {
+ ID *id = sp->id;
+ short idtype = GS(id->name);
+
+ if (idtype == ID_IM) {
+ Image *ima = (Image *)id;
+ ImBuf *ibuf = NULL;
+ ImageUser iuser = {NULL};
+
+ /* ima->ok is zero when Image cannot load */
+ if (ima == NULL || ima->ok == 0)
+ return;
+
+ /* setup dummy image user */
+ iuser.ok = iuser.framenr = 1;
+ iuser.scene = sp->scene;
+
+ /* elubie: this needs to be changed: here image is always loaded if not
+ * already there. Very expensive for large images. Need to find a way to
+ * only get existing ibuf */
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
+ }
- br->icon_imbuf = get_brush_icon(br);
+ icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect);
- memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
+ *do_update = true;
- if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
- return;
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+ else if (idtype == ID_BR) {
+ Brush *br = (Brush *)id;
- icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+ br->icon_imbuf = get_brush_icon(br);
- *do_update = true;
- }
- else {
- /* re-use shader job */
- shader_preview_startjob(customdata, stop, do_update);
+ memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int));
+
+ if (!(br->icon_imbuf) || !(br->icon_imbuf->rect))
+ return;
- /* world is rendered with alpha=0, so it wasn't displayed
- * this could be render option for sky to, for later */
- if (idtype == ID_WO) {
- set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect);
+
+ *do_update = true;
}
- else if (idtype == ID_MA) {
- Material *ma = (Material *)id;
+ else {
+ /* re-use shader job */
+ shader_preview_startjob(customdata, stop, do_update);
- if (ma->material_type == MA_TYPE_HALO)
+ /* world is rendered with alpha=0, so it wasn't displayed
+ * this could be render option for sky to, for later */
+ if (idtype == ID_WO) {
set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
+ else if (idtype == ID_MA) {
+ Material *ma = (Material *)id;
+
+ if (ma->material_type == MA_TYPE_HALO)
+ set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255);
+ }
}
}
}
@@ -995,7 +1031,7 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd
{
ShaderPreview *sp = customdata;
- if (sp->pr_method == PR_ICON_RENDER)
+ if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED))
icon_preview_startjob(customdata, stop, do_update);
else
shader_preview_startjob(customdata, stop, do_update);
@@ -1031,29 +1067,35 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene);
while (cur_size) {
+ PreviewImage *prv = ip->owner;
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
+ const bool is_render = !prv->use_deferred;
/* construct shader preview from image size and previewcustomdata */
sp->scene = ip->scene;
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
- sp->pr_method = PR_ICON_RENDER;
+ sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
-
- if (use_new_shading) {
- /* texture icon rendering is hardcoded to use BI,
- * so don't even think of using cycle's bmain for
- * texture icons
- */
- if (GS(ip->id->name) != ID_TE)
- sp->pr_main = G_pr_main_cycles;
- else
+ sp->bmain = ip->bmain;
+
+ if (is_render) {
+ BLI_assert(ip->id);
+ if (use_new_shading) {
+ /* texture icon rendering is hardcoded to use BI,
+ * so don't even think of using cycle's bmain for
+ * texture icons
+ */
+ if (GS(ip->id->name) != ID_TE)
+ sp->pr_main = G_pr_main_cycles;
+ else
+ sp->pr_main = G_pr_main;
+ }
+ else {
sp->pr_main = G_pr_main;
- }
- else {
- sp->pr_main = G_pr_main;
+ }
}
common_preview_startjob(sp, stop, do_update, progress);
@@ -1098,12 +1140,13 @@ static void icon_preview_free(void *customdata)
MEM_freeN(ip);
}
-void ED_preview_icon_render(Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
+void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
{
IconPreview ip = {NULL};
short stop = false, update = false;
float progress = 0.0f;
+ ip.bmain = bmain;
ip.scene = scene;
ip.owner = id;
ip.id = id;
@@ -1134,8 +1177,9 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
BLI_movelisttolist(&ip->sizes, &old_ip->sizes);
/* customdata for preview thread */
+ ip->bmain = CTX_data_main(C);
ip->scene = CTX_data_scene(C);
- ip->owner = id;
+ ip->owner = owner;
ip->id = id;
icon_preview_add_size(ip, rect, sizex, sizey);
@@ -1175,6 +1219,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
sp->id = id;
sp->parent = parent;
sp->slot = slot;
+ sp->bmain = CTX_data_main(C);
/* hardcoded preview .blend for cycles/internal, this should be solved
* once with custom preview .blend path for external engines */
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index ff90f48d705..3b8b874a462 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -41,8 +41,9 @@
#include "DNA_space_types.h"
#include "DNA_world_types.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
#include "BLF_translation.h"
@@ -202,7 +203,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
if (nurbs) {
for (nu = nurbs->first; nu; nu = nu->next)
if (isNurbsel(nu))
- nu->mat_nr = nu->charidx = ob->actcol - 1;
+ nu->mat_nr = ob->actcol - 1;
}
}
else if (ob->type == OB_FONT) {
@@ -381,6 +382,74 @@ void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
+static int material_slot_move_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+
+ unsigned int *slot_remap;
+ int index_pair[2];
+
+ int dir = RNA_enum_get(op->ptr, "direction");
+
+ if (!ob || ob->totcol < 2) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* up */
+ if (dir == 1 && ob->actcol > 1) {
+ index_pair[0] = ob->actcol - 2;
+ index_pair[1] = ob->actcol - 1;
+ ob->actcol--;
+ }
+ /* down */
+ else if (dir == -1 && ob->actcol < ob->totcol) {
+ index_pair[0] = ob->actcol - 1;
+ index_pair[1] = ob->actcol - 0;
+ ob->actcol++;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+
+ slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
+
+ range_vn_u(slot_remap, ob->totcol, 0);
+
+ slot_remap[index_pair[0]] = index_pair[1];
+ slot_remap[index_pair[1]] = index_pair[0];
+
+ BKE_material_remap_object(ob, slot_remap);
+
+ MEM_freeN(slot_remap);
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | ND_DATA, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_material_slot_move(wmOperatorType *ot)
+{
+ static EnumPropertyItem material_slot_move[] = {
+ {1, "UP", 0, "Up", ""},
+ {-1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Move Material";
+ ot->idname = "OBJECT_OT_material_slot_move";
+ ot->description = "Move the active material up/down in the list";
+
+ /* api callbacks */
+ ot->exec = material_slot_move_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
/********************** new material operator *********************/
static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
@@ -450,7 +519,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
tex = BKE_texture_copy(tex);
}
else {
- tex = add_texture(bmain, DATA_("Texture"));
+ tex = BKE_texture_add(bmain, DATA_("Texture"));
}
/* hook into UI */
@@ -605,6 +674,70 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
+/********************** render view operators *********************/
+
+static int render_view_remove_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ /* don't allow user to remove "left" and "right" views */
+ return scene->r.actview > 1;
+}
+
+static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+
+ BKE_scene_add_render_view(scene, NULL);
+ scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_render_view_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Render View";
+ ot->idname = "SCENE_OT_render_view_add";
+ ot->description = "Add a render view";
+
+ /* api callbacks */
+ ot->exec = render_view_add_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
+
+ if (!BKE_scene_remove_render_view(scene, rv))
+ return OPERATOR_CANCELLED;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_render_view_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Render View";
+ ot->idname = "SCENE_OT_render_view_remove";
+ ot->description = "Remove the selected render view";
+
+ /* api callbacks */
+ ot->exec = render_view_remove_exec;
+ ot->poll = render_view_remove_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
#ifdef WITH_FREESTYLE
static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
@@ -731,10 +864,11 @@ void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
- BKE_freestyle_lineset_add(&srl->freestyleConfig, NULL);
+ BKE_freestyle_lineset_add(bmain, &srl->freestyleConfig, NULL);
DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
@@ -893,6 +1027,7 @@ void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
@@ -903,10 +1038,10 @@ static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
}
if (lineset->linestyle) {
lineset->linestyle->id.us--;
- lineset->linestyle = BKE_linestyle_copy(lineset->linestyle);
+ lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
}
else {
- lineset->linestyle = BKE_linestyle_new("LineStyle", NULL);
+ lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
}
DAG_id_tag_update(&lineset->linestyle->id, 0);
WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
@@ -1490,7 +1625,7 @@ static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
- BKE_free_envmapdata(tex->env);
+ BKE_texture_envmap_free_data(tex->env);
WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
@@ -1533,7 +1668,7 @@ static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op))
for (tex = bmain->tex.first; tex; tex = tex->id.next)
if (tex->env)
- BKE_free_envmapdata(tex->env);
+ BKE_texture_envmap_free_data(tex->env);
WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index be42e2ed518..dedcbb144aa 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -61,6 +61,7 @@
#include "ED_node.h"
#include "ED_render.h"
+#include "ED_view3d.h"
#include "render_intern.h" // own include
@@ -141,26 +142,19 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
recursive_check = false;
}
-void ED_render_engine_area_exit(ScrArea *sa)
+void ED_render_engine_area_exit(Main *bmain, ScrArea *sa)
{
/* clear all render engines in this area */
ARegion *ar;
+ wmWindowManager *wm = bmain->wm.first;
if (sa->spacetype != SPACE_VIEW3D)
return;
for (ar = sa->regionbase.first; ar; ar = ar->next) {
- RegionView3D *rv3d;
-
if (ar->regiontype != RGN_TYPE_WINDOW || !(ar->regiondata))
continue;
-
- rv3d = ar->regiondata;
-
- if (rv3d->render_engine) {
- RE_engine_free(rv3d->render_engine);
- rv3d->render_engine = NULL;
- }
+ ED_view3d_stop_render_preview(wm, ar);
}
}
@@ -173,7 +167,7 @@ void ED_render_engine_changed(Main *bmain)
for (sc = bmain->screen.first; sc; sc = sc->id.next)
for (sa = sc->areabase.first; sa; sa = sa->next)
- ED_render_engine_area_exit(sa);
+ ED_render_engine_area_exit(bmain, sa);
RE_FreePersistentData();
@@ -276,7 +270,7 @@ static void material_changed(Main *bmain, Material *ma)
int texture_draw = false;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&ma->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
/* glsl */
if (ma->gpumaterial.first)
@@ -291,7 +285,7 @@ static void material_changed(Main *bmain, Material *ma)
continue;
}
- BKE_icon_changed(BKE_icon_getid(&parent->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&parent->id));
if (parent->gpumaterial.first)
GPU_material_free(&parent->gpumaterial);
@@ -306,7 +300,7 @@ static void material_changed(Main *bmain, Material *ma)
}
/* find textured objects */
- if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ if (texture_draw) {
for (ob = bmain->object.first; ob; ob = ob->id.next) {
DerivedMesh *dm = ob->derivedFinal;
Material ***material = give_matarar(ob);
@@ -331,7 +325,7 @@ static void lamp_changed(Main *bmain, Lamp *la)
Material *ma;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&la->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&la->id));
/* glsl */
for (ob = bmain->object.first; ob; ob = ob->id.next)
@@ -367,7 +361,7 @@ static void texture_changed(Main *bmain, Tex *tex)
bool texture_draw = false;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&tex->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&tex->id));
/* paint overlays */
for (scene = bmain->scene.first; scene; scene = scene->id.next)
@@ -378,7 +372,7 @@ static void texture_changed(Main *bmain, Tex *tex)
if (!material_uses_texture(ma, tex))
continue;
- BKE_icon_changed(BKE_icon_getid(&ma->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ma->id));
if (ma->gpumaterial.first)
GPU_material_free(&ma->gpumaterial);
@@ -409,7 +403,7 @@ static void texture_changed(Main *bmain, Tex *tex)
continue;
}
- BKE_icon_changed(BKE_icon_getid(&wo->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
if (wo->gpumaterial.first)
GPU_material_free(&wo->gpumaterial);
@@ -429,7 +423,7 @@ static void texture_changed(Main *bmain, Tex *tex)
}
/* find textured objects */
- if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) {
+ if (texture_draw) {
for (ob = bmain->object.first; ob; ob = ob->id.next) {
DerivedMesh *dm = ob->derivedFinal;
Material ***material = give_matarar(ob);
@@ -457,7 +451,7 @@ static void world_changed(Main *bmain, World *wo)
Material *ma;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&wo->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&wo->id));
/* glsl */
for (ma = bmain->mat.first; ma; ma = ma->id.next)
@@ -476,7 +470,7 @@ static void image_changed(Main *bmain, Image *ima)
Tex *tex;
/* icons */
- BKE_icon_changed(BKE_icon_getid(&ima->id));
+ BKE_icon_changed(BKE_icon_id_ensure(&ima->id));
/* textures */
for (tex = bmain->tex.first; tex; tex = tex->id.next)
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index fe357a7a0e2..f5260b8a568 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -63,7 +63,7 @@ static ScrArea *biggest_non_image_area(bContext *C)
for (sa = sc->areabase.first; sa; sa = sa->next) {
if (sa->winx > 30 && sa->winy > 30) {
size = sa->winx * sa->winy;
- if (sa->spacetype == SPACE_BUTS) {
+ if (!sa->full && sa->spacetype == SPACE_BUTS) {
if (foundwin == 0 && size > bwmaxsize) {
bwmaxsize = size;
big = sa;
@@ -245,6 +245,11 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
ScrArea *sa = CTX_wm_area(C);
SpaceImage *sima = sa->spacedata.first;
+ /* ensure image editor fullscreen and area fullscreen states are in sync */
+ if ((sima->flag & SI_FULLWINDOW) && !sa->full) {
+ sima->flag &= ~SI_FULLWINDOW;
+ }
+
/* test if we have a temp screen in front */
if (win->screen->temp) {
wm_window_lower(win);
@@ -258,8 +263,9 @@ static int render_view_cancel_exec(bContext *C, wmOperator *UNUSED(op))
sima->flag &= ~SI_FULLWINDOW;
ED_screen_full_prevspace(C, sa);
}
- else
+ else {
ED_area_prevspace(C, sa);
+ }
return OPERATOR_FINISHED;
}