diff options
-rw-r--r-- | source/blender/blenlib/BLI_math_color.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_color.c | 34 | ||||
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 12 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 29 |
4 files changed, 67 insertions, 14 deletions
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index 72724c1c0f7..a297878ec20 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -75,6 +75,12 @@ float srgb_to_linearrgb(float c); float linearrgb_to_srgb(float c); void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from); void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from); + +/* rgba buffer convenience functions */ +void srgb_to_linearrgb_rgba_buf(float *col, int tot); +void linearrgb_to_srgb_rgba_buf(float *col, int tot); +void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot); +void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot); /************************** Other *************************/ diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 396f2c52058..693fd885b50 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -372,6 +372,40 @@ void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from) col_to[2] = linearrgb_to_srgb(col_from[2]); } +/* todo, should these be moved elsewhere?, they dont belong in imbuf */ +void srgb_to_linearrgb_rgba_buf(float *col, int tot) +{ + while(tot--) { + srgb_to_linearrgb_v3_v3(col, col); + col += 4; + } +} + +void linearrgb_to_srgb_rgba_buf(float *col, int tot) +{ + while(tot--) { + linearrgb_to_srgb_v3_v3(col, col); + col += 4; + } +} + +void srgb_to_linearrgb_rgba_rgba_buf(float *col_to, float *col_from, int tot) +{ + while(tot--) { + srgb_to_linearrgb_v3_v3(col_to, col_from); + col_to += 4; + col_from += 4; + } +} + +void linearrgb_to_srgb_rgba_rgba_buf(float *col_to, float *col_from, int tot) +{ + while(tot--) { + linearrgb_to_srgb_v3_v3(col_to, col_from); + col_to += 4; + col_from += 4; + } +} void minmax_rgb(short c[]) { diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index c0e6ea66bc4..de32efde452 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -116,6 +116,17 @@ static void screen_opengl_render_apply(OGLRender *oglrender) rr= RE_AcquireResultRead(oglrender->re); + /* note on color management: + * looked into how best to deal with color management here and found heres how it should work. + * + * OpenGL materials etc are color corrected, so a float buffer from the graphics card is + * color corrected, without running any conversion functions. + * + * With color correction disabled blender expects the rr->rectf to be non-color managed so + * just do a direct copy from the byte array to the rectf with no conversion too. + * notice IMB_float_from_rect has the profile set so no conversion is done. + */ + if(view_context) { GPU_offscreen_bind(oglrender->ofs); /* bind */ @@ -134,6 +145,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } else { ImBuf *ibuf_view= ED_view3d_draw_offscreen_imbuf_simple(scene, oglrender->sizex, oglrender->sizey, OB_SOLID); + ibuf_view->profile = IB_PROFILE_NONE; /* ensures no conversion!, see note above */ IMB_float_from_rect(ibuf_view); memcpy(rr->rectf, ibuf_view->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 502bd09c2de..44c6a6f008f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2473,20 +2473,21 @@ static void do_render_seq(Render * re) if(ibuf->rect_float) { if (!rr->rectf) rr->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); - - /* sequencer float buffer is not in linear color space, convert - * should always be true, use a fake ibuf for the colorspace conversion */ - if(ibuf->profile != IB_PROFILE_LINEAR_RGB) { - ImBuf ibuf_dummy; - memset(&ibuf_dummy, 0, sizeof(ImBuf)); - ibuf_dummy.profile= ibuf->profile; - ibuf_dummy.x= rr->rectx; - ibuf_dummy.y= rr->recty; - ibuf_dummy.rect_float= rr->rectf; - /* only touch the rr->rectf */ - IMB_convert_profile(&ibuf_dummy, IB_PROFILE_LINEAR_RGB); + + /* color management: when off ensure rectf is non-lin, since thats what the internal + * render engine delivers */ + if(re->r.color_mgt_flag & R_COLOR_MANAGEMENT) { + if(ibuf->profile == IB_PROFILE_LINEAR_RGB) + memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + else + srgb_to_linearrgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); + + } + else { + if(ibuf->profile != IB_PROFILE_LINEAR_RGB) + memcpy(rr->rectf, ibuf->rect_float, 4*sizeof(float)*rr->rectx*rr->recty); + else + linearrgb_to_srgb_rgba_rgba_buf(rr->rectf, ibuf->rect_float, rr->rectx*rr->recty); } /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 |