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/render/intern/source/render_result.c')
-rw-r--r--source/blender/render/intern/source/render_result.c816
1 files changed, 557 insertions, 259 deletions
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 6486844bacf..19beec9a6fe 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -48,9 +48,8 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
-#ifdef WITH_CYCLES_DEBUG
-# include "BKE_scene.h"
-#endif
+#include "BKE_camera.h"
+#include "BKE_scene.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -63,14 +62,32 @@
/********************************** Free *************************************/
+static void render_result_views_free(RenderResult *res)
+{
+ while (res->views.first) {
+ RenderView *rv = res->views.first;
+ BLI_remlink(&res->views, rv);
+
+ if (rv->rect32)
+ MEM_freeN(rv->rect32);
+
+ if (rv->rectz)
+ MEM_freeN(rv->rectz);
+
+ if (rv->rectf)
+ MEM_freeN(rv->rectf);
+
+ MEM_freeN(rv);
+ }
+}
+
void render_result_free(RenderResult *res)
{
if (res == NULL) return;
while (res->layers.first) {
RenderLayer *rl = res->layers.first;
-
- if (rl->rectf) MEM_freeN(rl->rectf);
+
/* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
if (rl->acolrect) MEM_freeN(rl->acolrect);
if (rl->scolrect) MEM_freeN(rl->scolrect);
@@ -85,7 +102,9 @@ void render_result_free(RenderResult *res)
BLI_remlink(&res->layers, rl);
MEM_freeN(rl);
}
-
+
+ render_result_views_free(res);
+
if (res->rect32)
MEM_freeN(res->rect32);
if (res->rectz)
@@ -96,7 +115,9 @@ void render_result_free(RenderResult *res)
MEM_freeN(res->text);
if (res->error)
MEM_freeN(res->error);
-
+ if (res->stamp_data)
+ MEM_freeN(res->stamp_data);
+
MEM_freeN(res);
}
@@ -115,13 +136,44 @@ void render_result_free_list(ListBase *lb, RenderResult *rr)
}
}
-/********************************* Names *************************************/
+/********************************* multiview *************************************/
-/* NOTE: OpenEXR only supports 32 chars for layer+pass names
- * In blender we now use max 10 chars for pass, max 20 for layer */
-static const char *get_pass_name(int passtype, int channel)
+/* create a new views Listbase in rr without duplicating the memory pointers */
+void render_result_views_shallowcopy(RenderResult *dst, RenderResult *src)
+{
+ RenderView *rview;
+
+ if (dst == NULL || src == NULL)
+ return;
+
+ for (rview = src->views.first; rview; rview = rview->next) {
+ RenderView *rv;
+
+ rv = MEM_mallocN(sizeof(RenderView), "new render view");
+ BLI_addtail(&dst->views, rv);
+
+ BLI_strncpy(rv->name, rview->name, sizeof(rv->name));
+ rv->rectf = rview->rectf;
+ rv->rectz = rview->rectz;
+ rv->rect32 = rview->rect32;
+ }
+}
+
+/* free the views created temporarily */
+void render_result_views_shallowdelete(RenderResult *rr)
+{
+ if (rr == NULL)
+ return;
+
+ while (rr->views.first) {
+ RenderView *rv = rr->views.first;
+ BLI_remlink(&rr->views, rv);
+ MEM_freeN(rv);
+ }
+}
+
+static const char *name_from_passtype(int passtype, int channel)
{
-
if (passtype == SCE_PASS_COMBINED) {
if (channel == -1) return "Combined";
if (channel == 0) return "Combined.R";
@@ -308,122 +360,151 @@ static const char *get_pass_name(int passtype, int channel)
static int passtype_from_name(const char *str)
{
-
- if (STREQ(str, "Combined"))
+ if (STRPREFIX(str, "Combined"))
return SCE_PASS_COMBINED;
- if (STREQ(str, "Depth"))
+ if (STRPREFIX(str, "Depth"))
return SCE_PASS_Z;
- if (STREQ(str, "Vector"))
+ if (STRPREFIX(str, "Vector"))
return SCE_PASS_VECTOR;
- if (STREQ(str, "Normal"))
+ if (STRPREFIX(str, "Normal"))
return SCE_PASS_NORMAL;
- if (STREQ(str, "UV"))
+ if (STRPREFIX(str, "UV"))
return SCE_PASS_UV;
- if (STREQ(str, "Color"))
+ if (STRPREFIX(str, "Color"))
return SCE_PASS_RGBA;
- if (STREQ(str, "Emit"))
+ if (STRPREFIX(str, "Emit"))
return SCE_PASS_EMIT;
- if (STREQ(str, "Diffuse"))
+ if (STRPREFIX(str, "Diffuse"))
return SCE_PASS_DIFFUSE;
- if (STREQ(str, "Spec"))
+ if (STRPREFIX(str, "Spec"))
return SCE_PASS_SPEC;
- if (STREQ(str, "Shadow"))
+ if (STRPREFIX(str, "Shadow"))
return SCE_PASS_SHADOW;
- if (STREQ(str, "AO"))
+ if (STRPREFIX(str, "AO"))
return SCE_PASS_AO;
- if (STREQ(str, "Env"))
+ if (STRPREFIX(str, "Env"))
return SCE_PASS_ENVIRONMENT;
- if (STREQ(str, "Indirect"))
+ if (STRPREFIX(str, "Indirect"))
return SCE_PASS_INDIRECT;
- if (STREQ(str, "Reflect"))
+ if (STRPREFIX(str, "Reflect"))
return SCE_PASS_REFLECT;
- if (STREQ(str, "Refract"))
+ if (STRPREFIX(str, "Refract"))
return SCE_PASS_REFRACT;
- if (STREQ(str, "IndexOB"))
+ if (STRPREFIX(str, "IndexOB"))
return SCE_PASS_INDEXOB;
- if (STREQ(str, "IndexMA"))
+ if (STRPREFIX(str, "IndexMA"))
return SCE_PASS_INDEXMA;
- if (STREQ(str, "Mist"))
+ if (STRPREFIX(str, "Mist"))
return SCE_PASS_MIST;
- if (STREQ(str, "RayHits"))
+ if (STRPREFIX(str, "RayHits"))
return SCE_PASS_RAYHITS;
- if (STREQ(str, "DiffDir"))
+ if (STRPREFIX(str, "DiffDir"))
return SCE_PASS_DIFFUSE_DIRECT;
- if (STREQ(str, "DiffInd"))
+ if (STRPREFIX(str, "DiffInd"))
return SCE_PASS_DIFFUSE_INDIRECT;
- if (STREQ(str, "DiffCol"))
+ if (STRPREFIX(str, "DiffCol"))
return SCE_PASS_DIFFUSE_COLOR;
- if (STREQ(str, "GlossDir"))
+ if (STRPREFIX(str, "GlossDir"))
return SCE_PASS_GLOSSY_DIRECT;
- if (STREQ(str, "GlossInd"))
+ if (STRPREFIX(str, "GlossInd"))
return SCE_PASS_GLOSSY_INDIRECT;
- if (STREQ(str, "GlossCol"))
+ if (STRPREFIX(str, "GlossCol"))
return SCE_PASS_GLOSSY_COLOR;
- if (STREQ(str, "TransDir"))
+ if (STRPREFIX(str, "TransDir"))
return SCE_PASS_TRANSM_DIRECT;
- if (STREQ(str, "TransInd"))
+ if (STRPREFIX(str, "TransInd"))
return SCE_PASS_TRANSM_INDIRECT;
- if (STREQ(str, "TransCol"))
+ if (STRPREFIX(str, "TransCol"))
return SCE_PASS_TRANSM_COLOR;
- if (STREQ(str, "SubsurfaceDir"))
+ if (STRPREFIX(str, "SubsurfaceDir"))
return SCE_PASS_SUBSURFACE_DIRECT;
- if (STREQ(str, "SubsurfaceInd"))
+ if (STRPREFIX(str, "SubsurfaceInd"))
return SCE_PASS_SUBSURFACE_INDIRECT;
- if (STREQ(str, "SubsurfaceCol"))
+ if (STRPREFIX(str, "SubsurfaceCol"))
return SCE_PASS_SUBSURFACE_COLOR;
return 0;
}
+
+static void set_pass_name(char *passname, int passtype, int channel, const char *view)
+{
+ const char delims[] = {'.', '\0'};
+ const char *sep;
+ const char *token;
+ size_t len;
+
+ const char *passtype_name = name_from_passtype(passtype, channel);
+
+ if (view == NULL || view[0] == '\0') {
+ BLI_strncpy(passname, passtype_name, EXR_PASS_MAXNAME);
+ return;
+ }
+
+ len = BLI_str_rpartition(passtype_name, delims, &sep, &token);
+
+ if (sep) {
+ BLI_snprintf(passname, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passtype_name, view, token);
+ }
+ else {
+ BLI_snprintf(passname, EXR_PASS_MAXNAME, "%s.%s", passtype_name, view);
+ }
+}
+
/********************************** New **************************************/
-static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
+static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
{
- const char *typestr = get_pass_name(passtype, 0);
+ const size_t view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
+ const char *typestr = name_from_passtype(passtype, -1);
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
- int rectsize = rr->rectx * rr->recty * channels;
+ size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
BLI_addtail(&rl->passes, rpass);
rpass->passtype = passtype;
rpass->channels = channels;
rpass->rectx = rl->rectx;
rpass->recty = rl->recty;
- BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
+ rpass->view_id = view_id;
+
+ set_pass_name(rpass->name, rpass->passtype, -1, viewname);
+ BLI_strncpy(rpass->internal_name, typestr, sizeof(rpass->internal_name));
+ BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
if (rl->exrhandle) {
int a;
for (a = 0; a < channels; a++)
- IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
+ IMB_exr_add_channel(rl->exrhandle, rl->name, name_from_passtype(passtype, a), viewname, 0, 0, NULL, false);
}
else {
float *rect;
@@ -452,6 +533,10 @@ static const char *debug_pass_type_name_get(int debug_type)
switch (debug_type) {
case RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS:
return "BVH Traversal Steps";
+ case RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES:
+ return "BVH Traversed Instances";
+ case RENDER_PASS_DEBUG_RAY_BOUNCES:
+ return "Ray Bounces";
}
return "Unknown";
}
@@ -460,13 +545,15 @@ static RenderPass *render_layer_add_debug_pass(RenderResult *rr,
RenderLayer *rl,
int channels,
int pass_type,
- int debug_type)
+ int debug_type,
+ const char *view)
{
- RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type);
+ RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type, view);
rpass->debug_type = debug_type;
BLI_strncpy(rpass->name,
debug_pass_type_name_get(debug_type),
sizeof(rpass->name));
+ BLI_strncpy(rpass->internal_name, rpass->name, sizeof(rpass->internal_name));
return rpass;
}
#endif
@@ -475,12 +562,14 @@ static RenderPass *render_layer_add_debug_pass(RenderResult *rr,
/* will read info from Render *re to define layers */
/* called in threads */
/* re->winx,winy is coordinate space of entire image, partrct the part within */
-RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername)
+RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername, const char *viewname)
{
RenderResult *rr;
RenderLayer *rl;
+ RenderView *rv;
SceneRenderLayer *srl;
- int rectx, recty, nr;
+ int rectx, recty;
+ int nr;
rectx = BLI_rcti_size_x(partrct);
recty = BLI_rcti_size_y(partrct);
@@ -505,6 +594,8 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
rr->do_exr_tile = true;
}
+ render_result_views_new(rr, &re->r);
+
/* check renderdata for amount of layers */
for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
@@ -538,84 +629,90 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
if (rr->do_exr_tile) {
rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba");
-
rl->exrhandle = IMB_exr_get_handle();
-
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
}
- else
- rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
-
- if (srl->passflag & SCE_PASS_Z)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
- if (srl->passflag & SCE_PASS_VECTOR)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
- if (srl->passflag & SCE_PASS_NORMAL)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
- if (srl->passflag & SCE_PASS_UV)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
- if (srl->passflag & SCE_PASS_RGBA)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
- if (srl->passflag & SCE_PASS_EMIT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
- if (srl->passflag & SCE_PASS_DIFFUSE)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
- if (srl->passflag & SCE_PASS_SPEC)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
- if (srl->passflag & SCE_PASS_AO)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
- if (srl->passflag & SCE_PASS_ENVIRONMENT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
- if (srl->passflag & SCE_PASS_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
- if (srl->passflag & SCE_PASS_SHADOW)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
- if (srl->passflag & SCE_PASS_REFLECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
- if (srl->passflag & SCE_PASS_REFRACT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
- if (srl->passflag & SCE_PASS_INDEXOB)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
- if (srl->passflag & SCE_PASS_INDEXMA)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA);
- if (srl->passflag & SCE_PASS_MIST)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
- if (rl->passflag & SCE_PASS_RAYHITS)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
- if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT);
- if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT);
- if (srl->passflag & SCE_PASS_DIFFUSE_COLOR)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR);
- if (srl->passflag & SCE_PASS_GLOSSY_DIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT);
- if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT);
- if (srl->passflag & SCE_PASS_GLOSSY_COLOR)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR);
- if (srl->passflag & SCE_PASS_TRANSM_DIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT);
- if (srl->passflag & SCE_PASS_TRANSM_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT);
- if (srl->passflag & SCE_PASS_TRANSM_COLOR)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR);
- if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT);
- if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT);
- if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR);
+
+ for (rv = rr->views.first; rv; rv = rv->next) {
+ const char *view = rv->name;
+
+ if (viewname && viewname[0])
+ if (!STREQ(view, viewname))
+ continue;
+
+ if (rr->do_exr_tile)
+ IMB_exr_add_view(rl->exrhandle, view);
+
+ /* a renderlayer should always have a Combined pass*/
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
+
+ if (srl->passflag & SCE_PASS_Z)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_Z, view);
+ if (srl->passflag & SCE_PASS_VECTOR)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR, view);
+ if (srl->passflag & SCE_PASS_NORMAL)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL, view);
+ if (srl->passflag & SCE_PASS_UV)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_UV, view);
+ if (srl->passflag & SCE_PASS_RGBA)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA, view);
+ if (srl->passflag & SCE_PASS_EMIT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT, view);
+ if (srl->passflag & SCE_PASS_DIFFUSE)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE, view);
+ if (srl->passflag & SCE_PASS_SPEC)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC, view);
+ if (srl->passflag & SCE_PASS_AO)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_AO, view);
+ if (srl->passflag & SCE_PASS_ENVIRONMENT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT, view);
+ if (srl->passflag & SCE_PASS_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT, view);
+ if (srl->passflag & SCE_PASS_SHADOW)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW, view);
+ if (srl->passflag & SCE_PASS_REFLECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT, view);
+ if (srl->passflag & SCE_PASS_REFRACT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT, view);
+ if (srl->passflag & SCE_PASS_INDEXOB)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB, view);
+ if (srl->passflag & SCE_PASS_INDEXMA)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA, view);
+ if (srl->passflag & SCE_PASS_MIST)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST, view);
+ if (rl->passflag & SCE_PASS_RAYHITS)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS, view);
+ if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view);
+ if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view);
+ if (srl->passflag & SCE_PASS_DIFFUSE_COLOR)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view);
+ if (srl->passflag & SCE_PASS_GLOSSY_DIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view);
+ if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view);
+ if (srl->passflag & SCE_PASS_GLOSSY_COLOR)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view);
+ if (srl->passflag & SCE_PASS_TRANSM_DIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view);
+ if (srl->passflag & SCE_PASS_TRANSM_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view);
+ if (srl->passflag & SCE_PASS_TRANSM_COLOR)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view);
+ if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view);
#ifdef WITH_CYCLES_DEBUG
- if (BKE_scene_use_new_shading_nodes(re->scene)) {
- render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG,
- RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS);
- }
+ if (BKE_scene_use_new_shading_nodes(re->scene)) {
+ render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG,
+ re->r.debug_pass_type, view);
+ }
#endif
+ }
}
/* sss, previewrender and envmap don't do layers, so we make a default one */
if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
@@ -628,18 +725,23 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
/* duplicate code... */
if (rr->do_exr_tile) {
rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba");
-
rl->exrhandle = IMB_exr_get_handle();
-
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
- IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
}
- else {
- rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba");
+
+ for (rv = rr->views.first; rv; rv = rv->next) {
+ const char *view = rv->name;
+
+ if (viewname && viewname[0])
+ if (strcmp(view, viewname) != 0)
+ continue;
+
+ if (rr->do_exr_tile)
+ IMB_exr_add_view(rl->exrhandle, view);
+
+ /* a renderlayer should always have a Combined pass */
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
}
-
+
/* note, this has to be in sync with scene.c */
rl->lay = (1 << 20) - 1;
rl->layflag = 0x7FFF; /* solid ztra halo strand */
@@ -657,15 +759,15 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
}
/* allocate osa new results for samples */
-RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers)
+RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers, const char *viewname)
{
int a;
if (re->osa == 0)
- return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
+ return render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS, viewname);
for (a = 0; a < re->osa; a++) {
- RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS);
+ RenderResult *rr = render_result_new(re, partrct, crop, savebuffers, RR_ALL_LAYERS, viewname);
BLI_addtail(lb, rr);
rr->sample_nr = a;
}
@@ -686,28 +788,98 @@ static void *ml_addlayer_cb(void *base, const char *str)
return rl;
}
-static void ml_addpass_cb(void *UNUSED(base), void *lay, const char *str, float *rect, int totchan, const char *chan_id)
+static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view)
{
+ RenderResult *rr = base;
RenderLayer *rl = lay;
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
int a;
BLI_addtail(&rl->passes, rpass);
rpass->channels = totchan;
-
rpass->passtype = passtype_from_name(str);
if (rpass->passtype == 0) printf("unknown pass %s\n", str);
rl->passflag |= rpass->passtype;
- BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
/* channel id chars */
for (a = 0; a < totchan; a++)
rpass->chan_id[a] = chan_id[a];
-
+
rpass->rect = rect;
+ if (view[0] != '\0') {
+ BLI_snprintf(rpass->name, sizeof(rpass->name), "%s.%s", str, view);
+ rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name));
+ }
+ else {
+ BLI_strncpy(rpass->name, str, sizeof(rpass->name));
+ rpass->view_id = 0;
+ }
+
+ BLI_strncpy(rpass->view, view, sizeof(rpass->view));
+ BLI_strncpy(rpass->internal_name, str, sizeof(rpass->internal_name));
+}
+
+static void *ml_addview_cb(void *base, const char *str)
+{
+ RenderResult *rr = base;
+ RenderView *rv;
+
+ rv = MEM_callocN(sizeof(RenderView), "new render view");
+ BLI_strncpy(rv->name, str, EXR_VIEW_MAXNAME);
+
+ /* For stereo drawing we need to ensure:
+ * STEREO_LEFT_NAME == STEREO_LEFT_ID and
+ * STEREO_RIGHT_NAME == STEREO_RIGHT_ID */
+
+ if (STREQ(str, STEREO_LEFT_NAME)) {
+ BLI_addhead(&rr->views, rv);
+ }
+ else if (STREQ(str, STEREO_RIGHT_NAME)) {
+ RenderView *left_rv = BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name));
+
+ if (left_rv == NULL) {
+ BLI_addhead(&rr->views, rv);
+ }
+ else {
+ BLI_insertlinkafter(&rr->views, left_rv, rv);
+ }
+ }
+ else {
+ BLI_addtail(&rr->views, rv);
+ }
+
+ return rv;
+}
+
+static int order_render_passes(const void *a, const void *b)
+{
+ // 1 if a is after b
+ RenderPass *rpa = (RenderPass *) a;
+ RenderPass *rpb = (RenderPass *) b;
+
+ if (rpa->passtype > rpb->passtype)
+ return 1;
+ else if (rpa->passtype < rpb->passtype)
+ return 0;
+
+ /* they have the same type */
+ /* left first */
+ if (STREQ(rpa->view, STEREO_LEFT_NAME))
+ return 0;
+ else if (STREQ(rpb->view, STEREO_LEFT_NAME))
+ return 1;
+
+ /* right second */
+ if (STREQ(rpa->view, STEREO_RIGHT_NAME))
+ return 0;
+ else if (STREQ(rpb->view, STEREO_RIGHT_NAME))
+ return 1;
+
+ /* remaining in ascending id order */
+ return (rpa->view_id < rpb->view_id);
}
-/* from imbuf, if a handle was returned we convert this to render result */
+/* from imbuf, if a handle was returned and it's not a singlelayer multiview we convert this to render result */
RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
{
RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
@@ -718,13 +890,17 @@ RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace
rr->rectx = rectx;
rr->recty = recty;
- IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
+ IMB_exr_multilayer_convert(exrhandle, rr, ml_addview_cb, ml_addlayer_cb, ml_addpass_cb);
for (rl = rr->layers.first; rl; rl = rl->next) {
+ int c=0;
rl->rectx = rectx;
rl->recty = recty;
+ BLI_listbase_sort(&rl->passes, order_render_passes);
+
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
+ printf("%d: %s\n", c++, rpass->name);
rpass->rectx = rectx;
rpass->recty = recty;
@@ -738,26 +914,56 @@ RenderResult *render_result_new_from_exr(void *exrhandle, const char *colorspace
return rr;
}
+void render_result_view_new(RenderResult *rr, const char *viewname)
+{
+ RenderView *rv = MEM_callocN(sizeof(RenderView), "new render view");
+ BLI_addtail(&rr->views, rv);
+ BLI_strncpy(rv->name, viewname, sizeof(rv->name));
+}
+
+void render_result_views_new(RenderResult *rr, RenderData *rd)
+{
+ SceneRenderView *srv;
+
+ /* clear previously existing views - for sequencer */
+ render_result_views_free(rr);
+
+ /* check renderdata for amount of views */
+ if ((rd->scemode & R_MULTIVIEW)) {
+ for (srv = rd->views.first; srv; srv = srv->next) {
+ if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
+ continue;
+ render_result_view_new(rr, srv->name);
+ }
+ }
+
+ /* we always need at least one view */
+ if (BLI_listbase_count_ex(&rr->views, 1) == 0) {
+ render_result_view_new(rr, "");
+ }
+}
+
/*********************************** Merge ***********************************/
static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
{
- int y, ofs, copylen, tilex, tiley;
+ int y, tilex, tiley;
+ size_t ofs, copylen;
copylen = tilex = rrpart->rectx;
tiley = rrpart->recty;
if (rrpart->crop) { /* filters add pixel extra */
- tile += pixsize * (rrpart->crop + rrpart->crop * tilex);
+ tile += pixsize * (rrpart->crop + ((size_t)rrpart->crop) * tilex);
copylen = tilex - 2 * rrpart->crop;
tiley -= 2 * rrpart->crop;
- ofs = (rrpart->tilerect.ymin + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop);
+ ofs = (((size_t)rrpart->tilerect.ymin) + rrpart->crop) * rr->rectx + (rrpart->tilerect.xmin + rrpart->crop);
target += pixsize * ofs;
}
else {
- ofs = (rrpart->tilerect.ymin * rr->rectx + rrpart->tilerect.xmin);
+ ofs = (((size_t)rrpart->tilerect.ymin) * rr->rectx + rrpart->tilerect.xmin);
target += pixsize * ofs;
}
@@ -783,16 +989,19 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
for (rl = rr->layers.first; rl; rl = rl->next) {
rlp = RE_GetRenderLayer(rrpart, rl->name);
if (rlp) {
- /* combined */
- if (rl->rectf && rlp->rectf)
- do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
-
/* passes are allocated in sync */
for (rpass = rl->passes.first, rpassp = rlp->passes.first;
rpass && rpassp;
- rpass = rpass->next, rpassp = rpassp->next)
+ rpass = rpass->next)
{
+ /* renderresult have all passes, renderpart only the active view's passes */
+ if (strcmp(rpassp->name, rpass->name) != 0)
+ continue;
+
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
+
+ /* manually get next render pass */
+ rpassp = rpassp->next;
}
}
}
@@ -801,7 +1010,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
/* for passes read from files, these have names stored */
static char *make_pass_name(RenderPass *rpass, int chan)
{
- static char name[16];
+ static char name[EXR_PASS_MAXNAME];
int len;
BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
@@ -813,55 +1022,111 @@ static char *make_pass_name(RenderPass *rpass, int chan)
return name;
}
-/* filename already made absolute */
-/* called from within UI, saves both rendered result as a file-read result */
-bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
+/* called from within UI and render pipeline, saves both rendered result as a file-read result
+ * if multiview is true saves all views in a multiview exr
+ * else if view is not NULL saves single view
+ * else saves stereo3d
+ */
+bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, ImageFormatData *imf, const bool multiview, const char *view)
{
RenderLayer *rl;
RenderPass *rpass;
+ RenderView *rview;
void *exrhandle = IMB_exr_get_handle();
bool success;
-
- BLI_make_existing_file(filename);
-
- /* composite result */
- if (rr->rectf) {
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4 * rr->rectx, rr->rectf);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4 * rr->rectx, rr->rectf + 1);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4 * rr->rectx, rr->rectf + 2);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4 * rr->rectx, rr->rectf + 3);
+ int a, nr;
+ const char *chan_view = NULL;
+ int compress = (imf ? imf->exr_codec : 0);
+ size_t width, height;
+
+ const bool is_mono = view && !multiview;
+ const bool use_half_float = (imf->depth == R_IMF_CHAN_DEPTH_16);
+
+ width = rr->rectx;
+ height = rr->recty;
+
+ if (imf && imf->imtype == R_IMF_IMTYPE_OPENEXR && multiview) {
+ /* single layer OpenEXR */
+ const char *RGBAZ[] = {"R", "G", "B", "A", "Z"};
+ for (nr = 0, rview = rr->views.first; rview; rview = rview->next, nr++) {
+ IMB_exr_add_view(exrhandle, rview->name);
+
+ if (rview->rectf) {
+ for (a = 0; a < 4; a++) {
+ IMB_exr_add_channel(exrhandle, "", RGBAZ[a],
+ rview->name, 4, 4 * width, rview->rectf + a,
+ use_half_float);
+ }
+ if (rview->rectz) {
+ /* Z pass is always stored as float. */
+ IMB_exr_add_channel(exrhandle, "", RGBAZ[4],
+ rview->name, 1, width, rview->rectz,
+ false);
+ }
+ }
+ }
}
-
- /* add layers/passes and assign channels */
- for (rl = rr->layers.first; rl; rl = rl->next) {
-
- /* combined */
- if (rl->rectf) {
- int a, xstride = 4;
- for (a = 0; a < xstride; a++) {
- IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride * rr->rectx, rl->rectf + a);
+ else {
+ for (nr = 0, rview = rr->views.first; rview; rview = rview->next, nr++) {
+ if (is_mono) {
+ if (!STREQ(view, rview->name)) {
+ continue;
+ }
+ chan_view = "";
+ }
+ else {
+ /* if rendered only one view, we treat as a a non-view render */
+ chan_view = rview->name;
+ }
+
+ IMB_exr_add_view(exrhandle, rview->name);
+
+ if (rview->rectf) {
+ for (a = 0; a < 4; a++) {
+ IMB_exr_add_channel(exrhandle, "Composite", name_from_passtype(SCE_PASS_COMBINED, a),
+ chan_view, 4, 4 * width, rview->rectf + a,
+ use_half_float);
+ }
}
}
-
- /* passes are allocated in sync */
- for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
- int a, xstride = rpass->channels;
- for (a = 0; a < xstride; a++) {
- if (rpass->passtype) {
- IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
- xstride, xstride * rr->rectx, rpass->rect + a);
+
+ /* add layers/passes and assign channels */
+ for (rl = rr->layers.first; rl; rl = rl->next) {
+
+ /* passes are allocated in sync */
+ for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
+ const int xstride = rpass->channels;
+
+ if (is_mono) {
+ if (!STREQ(view, rpass->view)) {
+ continue;
+ }
+ chan_view = "";
}
else {
- IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
- xstride, xstride * rr->rectx, rpass->rect + a);
+ /* if rendered only one view, we treat as a a non-view render */
+ chan_view = (nr > 1 ? rpass->view :"");
+ }
+
+ for (a = 0; a < xstride; a++) {
+ if (rpass->passtype) {
+ IMB_exr_add_channel(exrhandle, rl->name, name_from_passtype(rpass->passtype, a), chan_view,
+ xstride, xstride * width, rpass->rect + a,
+ rpass->passtype == SCE_PASS_Z ? false : use_half_float);
+ }
+ else {
+ IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), chan_view,
+ xstride, xstride * width, rpass->rect + a,
+ use_half_float);
+ }
}
}
}
}
- /* when the filename has no permissions, this can fail */
- if (IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
+ BLI_make_existing_file(filename);
+
+ if (IMB_exr_begin_write(exrhandle, filename, width, height, compress, rr->stamp_data)) {
IMB_exr_write_channels(exrhandle);
success = true;
}
@@ -870,8 +1135,8 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
BKE_report(reports, RPT_ERROR, "Error writing render result (see console)");
success = false;
}
- IMB_exr_close(exrhandle);
+ IMB_exr_close(exrhandle);
return success;
}
@@ -932,7 +1197,7 @@ void render_result_single_layer_end(Render *re)
/************************* EXR Tile File Rendering ***************************/
-static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
+static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, const char *viewname)
{
RenderLayer *rlp, *rl;
RenderPass *rpassp;
@@ -955,21 +1220,17 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
else {
offs = 0;
}
-
- /* combined */
- if (rlp->rectf) {
- int a, xstride = 4;
- for (a = 0; a < xstride; a++) {
- IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride * rrpart->rectx, rlp->rectf + a + xstride * offs);
- }
- }
-
+
/* passes are allocated in sync */
for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
- int a, xstride = rpassp->channels;
+ const int xstride = rpassp->channels;
+ int a;
+ char passname[EXR_PASS_MAXNAME];
+
for (a = 0; a < xstride; a++) {
- IMB_exr_set_channel(rl->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
+ set_pass_name(passname, rpassp->passtype, a, rpassp->view);
+
+ IMB_exr_set_channel(rl->exrhandle, rlp->name, passname,
xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
}
}
@@ -988,13 +1249,13 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
continue;
}
- IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
+ IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, viewname);
}
BLI_unlock_thread(LOCK_IMAGE);
}
-static void save_empty_result_tiles(Render *re)
+void render_result_save_empty_result_tiles(Render *re)
{
RenderPart *pa;
RenderResult *rr;
@@ -1002,13 +1263,13 @@ static void save_empty_result_tiles(Render *re)
for (rr = re->result; rr; rr = rr->next) {
for (rl = rr->layers.first; rl; rl = rl->next) {
- IMB_exrtile_clear_channels(rl->exrhandle);
+ IMB_exr_clear_channels(rl->exrhandle);
for (pa = re->parts.first; pa; pa = pa->next) {
if (pa->status != PART_STATUS_READY) {
int party = pa->disprect.ymin - re->disprect.ymin + pa->crop;
int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop;
- IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0);
+ IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, re->viewname);
}
}
}
@@ -1037,8 +1298,6 @@ void render_result_exr_file_end(Render *re)
RenderResult *rr;
RenderLayer *rl;
- save_empty_result_tiles(re);
-
for (rr = re->result; rr; rr = rr->next) {
for (rl = rr->layers.first; rl; rl = rl->next) {
IMB_exr_close(rl->exrhandle);
@@ -1055,10 +1314,10 @@ void render_result_exr_file_end(Render *re)
}
/* save part into exr file */
-void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
+void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart, const char *viewname)
{
for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next)
- save_render_result_tile(rr, rrpart);
+ save_render_result_tile(rr, rrpart, viewname);
}
/* path to temporary exr file */
@@ -1088,7 +1347,7 @@ int render_result_exr_file_read_sample(Render *re, int sample)
bool success = true;
RE_FreeRenderResult(re->result);
- re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
+ re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
for (rl = re->result->layers.first; rl; rl = rl->next) {
render_result_exr_file_path(re->scene, rl->name, sample, str);
@@ -1129,23 +1388,20 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
for (rl = rr->layers.first; rl; rl = rl->next) {
if (rl_single && rl_single != rl)
continue;
-
- /* combined */
- if (rl->rectf) {
- int a, xstride = 4;
- for (a = 0; a < xstride; a++)
- IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride * rectx, rl->rectf + a);
- }
/* passes are allocated in sync */
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
- int a, xstride = rpass->channels;
- for (a = 0; a < xstride; a++)
- IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
+ const int xstride = rpass->channels;
+ int a;
+ char passname[EXR_PASS_MAXNAME];
+
+ for (a = 0; a < xstride; a++) {
+ set_pass_name(passname, rpass->passtype, a, rpass->view);
+ IMB_exr_set_channel(exrhandle, rl->name, passname,
xstride, xstride * rectx, rpass->rect + a);
+ }
- BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
+ set_pass_name(rpass->name, rpass->passtype, -1, rpass->view);
}
}
@@ -1191,7 +1447,8 @@ void render_result_exr_file_cache_write(Render *re)
render_result_exr_file_cache_path(re->scene, root, str);
printf("Caching exr file, %dx%d, %s\n", rr->rectx, rr->recty, str);
- RE_WriteRenderResult(NULL, rr, str, 0);
+
+ RE_WriteRenderResult(NULL, rr, str, NULL, true, NULL);
}
/* For cache, makes exact copy of render result */
@@ -1201,7 +1458,7 @@ bool render_result_exr_file_cache_read(Render *re)
char *root = U.render_cachedir;
RE_FreeRenderResult(re->result);
- re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
+ re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
/* First try cache. */
render_result_exr_file_cache_path(re->scene, root, str);
@@ -1216,15 +1473,16 @@ bool render_result_exr_file_cache_read(Render *re)
/*************************** Combined Pixel Rect *****************************/
-ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
+ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd, const int view_id)
{
ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
-
+ RenderView *rv = RE_RenderViewGetById(rr, view_id);
+
/* if not exists, BKE_imbuf_write makes one */
- ibuf->rect = (unsigned int *)rr->rect32;
- ibuf->rect_float = rr->rectf;
- ibuf->zbuf_float = rr->rectz;
-
+ ibuf->rect = (unsigned int *) rv->rect32;
+ ibuf->rect_float = rv->rectf;
+ ibuf->zbuf_float = rv->rectz;
+
/* float factor for random dither, imbuf takes care of it */
ibuf->dither = rd->dither_intensity;
@@ -1259,57 +1517,97 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
return ibuf;
}
-void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf)
+void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf, const int view_id)
{
+ RenderView *rv = RE_RenderViewGetById(rr, view_id);
+
if (ibuf->rect_float) {
- if (!rr->rectf)
- rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
+ if (!rv->rectf)
+ rv->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
- memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
+ memcpy(rv->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
/* TSK! Since sequence render doesn't free the *rr render result, the old rect32
* can hang around when sequence render has rendered a 32 bits one before */
- if (rr->rect32) {
- MEM_freeN(rr->rect32);
- rr->rect32 = NULL;
- }
+ MEM_SAFE_FREE(rv->rect32);
}
else if (ibuf->rect) {
- if (!rr->rect32)
- rr->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
+ if (!rv->rect32)
+ rv->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
- memcpy(rr->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
+ memcpy(rv->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
/* Same things as above, old rectf can hang around from previous render. */
- if (rr->rectf) {
- MEM_freeN(rr->rectf);
- rr->rectf = NULL;
- }
+ MEM_SAFE_FREE(rv->rectf);
}
}
-void render_result_rect_fill_zero(RenderResult *rr)
+void render_result_rect_fill_zero(RenderResult *rr, const int view_id)
{
- if (rr->rectf)
- memset(rr->rectf, 0, 4 * sizeof(float) * rr->rectx * rr->recty);
- else if (rr->rect32)
- memset(rr->rect32, 0, 4 * rr->rectx * rr->recty);
+ RenderView *rv = RE_RenderViewGetById(rr, view_id);
+
+ if (rv->rectf)
+ memset(rv->rectf, 0, 4 * sizeof(float) * rr->rectx * rr->recty);
+ else if (rv->rect32)
+ memset(rv->rect32, 0, 4 * rr->rectx * rr->recty);
else
- rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
+ rv->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
}
void render_result_rect_get_pixels(RenderResult *rr, unsigned int *rect, int rectx, int recty,
- const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
+ const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings,
+ const int view_id)
{
- if (rr->rect32) {
- memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
- }
- else if (rr->rectf) {
- IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
+ RenderView *rv = RE_RenderViewGetById(rr, view_id);
+
+ if (rv->rect32)
+ memcpy(rect, rv->rect32, sizeof(int) * rr->rectx * rr->recty);
+ else if (rv->rectf)
+ IMB_display_buffer_transform_apply((unsigned char *) rect, rv->rectf, rr->rectx, rr->recty, 4,
view_settings, display_settings, true);
- }
else
/* else fill with black */
memset(rect, 0, sizeof(int) * rectx * recty);
}
+
+/*************************** multiview functions *****************************/
+
+bool RE_HasFakeLayer(RenderResult *res)
+{
+ RenderView *rv;
+
+ if (res == NULL)
+ return false;
+
+ rv = res->views.first;
+ if (rv == NULL)
+ return false;
+
+ return (rv->rect32 || rv->rectf);
+}
+
+bool RE_RenderResult_is_stereo(RenderResult *res)
+{
+ if (! BLI_findstring(&res->views, STEREO_LEFT_NAME, offsetof(RenderView, name)))
+ return false;
+
+ if (! BLI_findstring(&res->views, STEREO_RIGHT_NAME, offsetof(RenderView, name)))
+ return false;
+
+ return true;
+}
+
+RenderView *RE_RenderViewGetById(RenderResult *res, const int view_id)
+{
+ RenderView *rv = BLI_findlink(&res->views, view_id);
+ BLI_assert(res->views.first);
+ return rv ? rv : res->views.first;
+}
+
+RenderView *RE_RenderViewGetByName(RenderResult *res, const char *viewname)
+{
+ RenderView *rv = BLI_findstring(&res->views, viewname, offsetof(RenderView, name));
+ BLI_assert(res->views.first);
+ return rv ? rv : res->views.first;
+}