diff options
30 files changed, 273 insertions, 159 deletions
diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py index eb2a73d1790..50fc0a7ded9 100644 --- a/release/scripts/ui/properties_material.py +++ b/release/scripts/ui/properties_material.py @@ -495,7 +495,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel): col.prop(sss, "ior") col.prop(sss, "scale") col.prop(sss, "color", text="") - col.prop(sss, "radius", text="RGB Radius") + col.prop(sss, "radius", text="RGB Radius", expand=True) if wide_ui: col = split.column() diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index ebeec31c984..7bbcb63a7f5 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 7 +#define BLENDER_SUBVERSION 8 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index c83a260690b..c571688737a 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -34,12 +34,6 @@ struct CurveMap; struct ImBuf; struct rctf; -void gamma_correct_rec709(float *c, float gamma); -void gamma_correct(float *c, float gamma); -float srgb_to_linearrgb(float c); -float linearrgb_to_srgb(float c); -void color_manage_linearize(float *col_to, float *col_from); - void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index f3448a60b5a..48e42bc539f 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -58,52 +58,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -/* ********************************* color transforms ********************************* */ - -/*Transform linear RGB values to nonlinear RGB values. Rec. - 709 is ITU-R Recommendation BT. 709 (1990) ``Basic - Parameter Values for the HDTV Standard for the Studio and - for International Programme Exchange'', formerly CCIR Rec. - 709.*/ -void gamma_correct_rec709(float *c, float gamma) -{ - /* Rec. 709 gamma correction. */ - const float cc = 0.018f; - - if (*c < cc) - *c *= ((1.099f * (float)powf(cc, gamma)) - 0.099f) * (1.0f/cc); - else - *c = (1.099f * (float)powf(*c, gamma)) - 0.099f; -} - -void gamma_correct(float *c, float gamma) -{ - *c = powf((*c), gamma); -} - -float srgb_to_linearrgb(float c) -{ - if (c < 0.04045f) - return (c < 0.0f)? 0.0f: c*(1.0f/12.92f); - else - return powf((c + 0.055f)*(1.0f/1.055f), 2.4f); -} - -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308f) - return (c < 0.0f)? 0.0f: c * 12.92f; - else - return 1.055f * powf(c, 1.0f/2.4f) - 0.055f; -} - -/* utility function convert an RGB triplet from sRGB to linear RGB color space */ -void color_manage_linearize(float *col_to, float *col_from) -{ - col_to[0] = srgb_to_linearrgb(col_from[0]); - col_to[1] = srgb_to_linearrgb(col_from[1]); - col_to[2] = srgb_to_linearrgb(col_from[2]); -} void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1e047380641..41255415b67 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -795,7 +795,7 @@ void *add_lamp(char *name) la->sun_intensity = 1.0f; la->skyblendtype= MA_RAMP_ADD; la->skyblendfac= 1.0f; - la->sky_colorspace= BLI_CS_CIE; + la->sky_colorspace= BLI_XYZ_CIE; la->sky_exposure= 1.0f; curvemapping_initialize(la->curfalloff); diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index b2d14f3ecbd..7444e01c3a6 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -32,10 +32,16 @@ extern "C" { #endif -#define BLI_CS_SMPTE 0 -#define BLI_CS_REC709 1 -#define BLI_CS_CIE 2 +/* primaries */ +#define BLI_XYZ_SMPTE 0 +#define BLI_XYZ_REC709_SRGB 1 +#define BLI_XYZ_CIE 2 +/* built-in profiles */ +#define BLI_PR_NONE 0 +#define BLI_PR_SRGB 1 +#define BLI_PR_REC709 2 + /******************* Conversion to RGB ********************/ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b); @@ -53,6 +59,16 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); unsigned int rgb_to_cpack(float r, float g, float b); unsigned int hsv_to_cpack(float h, float s, float v); +/***************** Profile Transformations ********************/ + +void gamma_correct(float *c, float gamma); +float rec709_to_linearrgb(float c); +float linearrgb_to_rec709(float c); +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); + /************************** Other *************************/ int constrain_rgb(float *r, float *g, float *b); diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 7ae380a1dde..6dbd9c1381f 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -208,17 +208,17 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int colorspace) { switch (colorspace) { - case BLI_CS_SMPTE: + case BLI_XYZ_SMPTE: *r = (3.50570f * xc) + (-1.73964f * yc) + (-0.544011f * zc); *g = (-1.06906f * xc) + (1.97781f * yc) + (0.0351720f * zc); *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f * zc); break; - case BLI_CS_REC709: + case BLI_XYZ_REC709_SRGB: *r = (3.240476f * xc) + (-1.537150f * yc) + (-0.498535f * zc); *g = (-0.969256f * xc) + (1.875992f * yc) + (0.041556f * zc); *b = (0.055648f * xc) + (-0.204043f * yc) + (1.057311f * zc); break; - case BLI_CS_CIE: + case BLI_XYZ_CIE: *r = (2.28783848734076f * xc) + (-0.833367677835217f * yc) + (-0.454470795871421f * zc); *g = (-0.511651380743862f * xc) + (1.42275837632178f * yc) + (0.0888930017552939f * zc); *b = (0.00572040983140966f * xc) + (-0.0159068485104036f * yc) + (1.0101864083734f * zc); @@ -274,6 +274,61 @@ void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) *b /= 255.0f; } +/* ********************************* color transforms ********************************* */ + + +void gamma_correct(float *c, float gamma) +{ + *c = powf((*c), gamma); +} + +float rec709_to_linearrgb(float c) +{ + if (c < 0.081f) + return (c < 0.0f)? 0.0f: c * (1.0f/4.5f); + else + return powf((c + 0.099f)*(1.0f/1.099f), (1.0f/0.45f)); +} + +float linearrgb_to_rec709(float c) +{ + if (c < 0.018f) + return (c < 0.0f)? 0.0f: c * 4.5f; + else + return 1.099f * powf(c, 0.45f) - 0.099f; +} + +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045f) + return (c < 0.0f)? 0.0f: c * (1.0f/12.92f); + else + return powf((c + 0.055f)*(1.0f/1.055f), 2.4f); +} + +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308f) + return (c < 0.0f)? 0.0f: c * 12.92f; + else + return 1.055f * powf(c, 1.0f/2.4f) - 0.055f; +} + +void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from) +{ + col_to[0] = srgb_to_linearrgb(col_from[0]); + col_to[1] = srgb_to_linearrgb(col_from[1]); + col_to[2] = srgb_to_linearrgb(col_from[2]); +} + +void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from) +{ + col_to[0] = linearrgb_to_srgb(col_from[0]); + col_to[1] = linearrgb_to_srgb(col_from[1]); + col_to[2] = linearrgb_to_srgb(col_from[2]); +} + + void minmax_rgb(short c[]) { if(c[0]>255) c[0]=255; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ce760643b3d..6103c582da0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10064,7 +10064,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } - /* put 2.50 compatibility code here until next subversion bump */ + if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 8)) { { Scene *sce= main->scene.first; @@ -10108,7 +10108,47 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob=ob->id.next; } } + + /* only convert old 2.50 files with color management */ + if (main->versionfile == 250) { + Scene *sce=main->scene.first; + Material *ma=main->mat.first; + World *wo=main->world.first; + int convert=0; + + /* convert to new color management system: + while previously colors were stored as srgb, + now they are stored as linear internally, + with screen gamma correction in certain places in the UI. */ + + /* don't know what scene is active, so we'll convert if any scene has it enabled... */ + while (sce) { + if(sce->r.color_mgt_flag & R_COLOR_MANAGEMENT) + convert=1; + sce=sce->id.next; + } + + if (convert) { + while(ma) { + srgb_to_linearrgb_v3_v3(&ma->r, &ma->r); + srgb_to_linearrgb_v3_v3(&ma->specr, &ma->specr); + srgb_to_linearrgb_v3_v3(&ma->mirr, &ma->mirr); + srgb_to_linearrgb_v3_v3(ma->sss_col, ma->sss_col); + ma=ma->id.next; + } + + while(wo) { + srgb_to_linearrgb_v3_v3(&wo->ambr, &wo->ambr); + srgb_to_linearrgb_v3_v3(&wo->horr, &wo->horr); + srgb_to_linearrgb_v3_v3(&wo->zenr, &wo->zenr); + wo=wo->id.next; + } + } + } } + + /* put 2.50 compatibility code here until next subversion bump */ + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 70bef5534a1..f0d09c505ac 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1790,14 +1790,17 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor { uiBlock *block; wmWindow *window; + Scene *scn; int getsizex, getsizey; window= CTX_wm_window(C); + scn = CTX_data_scene(C); block= MEM_callocN(sizeof(uiBlock), "uiBlock"); block->active= 1; block->dt= dt; block->evil_C= (void*)C; // XXX + if (scn) block->color_profile= (scn->r.color_mgt_flag & R_COLOR_MANAGEMENT); BLI_strncpy(block->name, name, sizeof(block->name)); if(region) @@ -2295,6 +2298,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short if(ELEM(but->type, HSVCUBE, HSVCIRCLE)) { /* hsv buttons temp storage */ float rgb[3]; ui_get_but_vectorf(but, rgb); + rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2); } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 762ec541bff..e6e5cb198aa 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -736,6 +736,8 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *wcol, rcti *rect) for( a = 1; a < sizex; a++ ) { pos = ((float)a) / (sizex-1); do_colorband( coba, pos, colf ); + if (but->block->color_profile != BLI_PR_NONE) + linearrgb_to_srgb_v3_v3(colf, colf); v1[0]=v2[0]= x1 + a; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 6d65a2a57a1..a51824f10e9 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2697,7 +2697,13 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, { float x, y; int changed= 1; - + int color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = BLI_PR_NONE; + } + /* relative position within box */ x= ((float)mx-but->x1)/(but->x2-but->x1); y= ((float)my-but->y1)/(but->y2-but->y1); @@ -2719,8 +2725,12 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, else if(but->a1==3) { but->hsv[0]= x; } - else + else { + /* vertical 'value' strip */ but->hsv[2]= y; + if (color_profile) + but->hsv[2] = srgb_to_linearrgb(but->hsv[2]); + } ui_set_but_hsv(but); // converts to rgb diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 21425bbb261..97ef1f1ea17 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -303,6 +303,8 @@ struct uiBlock { int active; // to keep blocks while drawing and free them afterwards int puphash; // popup menu hash for memory + + int color_profile; // color profile for correcting linear colors for display void *evil_C; // XXX hack for dynamic operator enums }; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index d46cb4df1c0..175f1ff1e2a 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -409,10 +409,10 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon } } else { - if(ELEM(subtype, PROP_COLOR, PROP_RGB)) + if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y); - if(!ELEM(subtype, PROP_COLOR, PROP_RGB) || expand) { + if(!ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) || expand) { /* layout for known array subtypes */ char str[3]; @@ -439,7 +439,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon but->type= TOG; } } - else if(ELEM(subtype, PROP_COLOR, PROP_RGB) && len == 4) { + else if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && len == 4) { but= uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, w, UI_UNIT_Y); if(slider && but->type==NUM) but->type= NUMSLI; diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index c3eac3f3893..55b908a44ce 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1902,9 +1902,16 @@ static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, static short colormode= 0; /* temp? 0=rgb, 1=hsv, 2=hex */ uiBut *bt; int width; + static char tip[50]; VECCOPY(old, col); // old color stored there, for palette_cb to work + /* existence of profile means storage is in linear colour space, with display correction */ + if (block->color_profile == BLI_PR_NONE) + sprintf(tip, "Value in Display Color Space"); + else + sprintf(tip, "Value in Linear RGB Color Space"); + /* HS circle */ bt= uiDefButF(block, HSVCIRCLE, retval, "", 0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, ""); uiButSetFunc(bt, do_picker_small_cb, bt, hsv); @@ -1930,11 +1937,11 @@ static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0)); uiBlockBeginAlign(block); - bt= uiDefButF(block, NUMSLI, 0, "R ", 0, -60, width, 19, col, 0.0, 1.0, 10, 3, ""); + bt= uiDefButF(block, NUMSLI, 0, "R ", 0, -60, width, 19, col, 0.0, 1.0, 10, 3, tip); uiButSetFunc(bt, do_palette1_cb, bt, hsv); - bt= uiDefButF(block, NUMSLI, 0, "G ", 0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, ""); + bt= uiDefButF(block, NUMSLI, 0, "G ", 0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, tip); uiButSetFunc(bt, do_palette1_cb, bt, hsv); - bt= uiDefButF(block, NUMSLI, 0, "B ", 0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, ""); + bt= uiDefButF(block, NUMSLI, 0, "B ", 0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, tip); uiButSetFunc(bt, do_palette1_cb, bt, hsv); uiBlockEndAlign(block); @@ -2000,6 +2007,13 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS); + /* XXX ideally the colour picker buttons would reference the rna property itself */ + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + block->color_profile = BLI_PR_NONE; + } + } + uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); VECCOPY(handle->retvec, but->editvec); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index ecd8c9720c8..7aaa6cbb42b 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -80,7 +80,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind case PROP_INT: case PROP_FLOAT: if(arraylen && index == -1) { - if(RNA_property_subtype(prop) == PROP_COLOR) + if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL); } else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index e148fd9217f..4c9698974b4 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -44,6 +44,8 @@ #include "BKE_global.h" #include "BKE_utildefines.h" +#include "RNA_access.h" + #include "BIF_gl.h" #include "BIF_glutil.h" @@ -1693,6 +1695,17 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) uiWidgetBase wtb; float rad= 0.5f*(rect->xmax - rect->xmin); float x, y; + float v = but->hsv[2]; + int color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + color_profile = BLI_PR_NONE; + } + } + + if (color_profile) + v = linearrgb_to_srgb(v); widget_init(&wtb); @@ -1709,8 +1722,8 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) widgetbase_draw(&wtb, &wcol_tmp); /* cursor */ - x= rect->xmin + 0.5f*(rect->xmax-rect->xmin); - y= rect->ymin + but->hsv[2]*(rect->ymax-rect->ymin); + x= rect->xmin + 0.5f * (rect->xmax-rect->xmin); + y= rect->ymin + v * (rect->ymax-rect->ymin); CLAMP(y, rect->ymin+3.0, rect->ymax-3.0); ui_hsv_cursor(x, y); @@ -2005,6 +2018,12 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat { uiWidgetBase wtb; float col[4]; + int color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = BLI_PR_NONE; + } widget_init(&wtb); @@ -2012,6 +2031,10 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat round_box_edges(&wtb, roundboxalign, rect, 5.0f); ui_get_but_vectorf(but, col); + + if (color_profile) + linearrgb_to_srgb_v3_v3(col, col); + wcol->inner[0]= FTOCHAR(col[0]); wcol->inner[1]= FTOCHAR(col[1]); wcol->inner[2]= FTOCHAR(col[2]); diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index bf73e70367c..51c7ba1a4bd 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -341,8 +341,9 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac struct TextureDrawState { Object *ob; int islit, istex; + int color_profile; unsigned char obcol[4]; -} Gtexdraw = {NULL, 0, 0, {0, 0, 0, 0}}; +} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}}; static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) { @@ -371,6 +372,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O Gtexdraw.ob = ob; Gtexdraw.istex = istex; + Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; memcpy(Gtexdraw.obcol, obcol, sizeof(obcol)); set_draw_settings_cached(1, 0, 0, Gtexdraw.islit, 0, 0, 0); glShadeModel(GL_SMOOTH); @@ -413,7 +415,13 @@ static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr) if (tface) glColor3f(1.0, 1.0, 1.0); else { Material *ma= give_current_material(Gtexdraw.ob, matnr+1); - if(ma) glColor3f(ma->r, ma->g, ma->b); + if(ma) { + float col[3]; + if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); + else copy_v3_v3(col, &ma->r); + + glColor3fv(col); + } else glColor3f(1.0, 1.0, 1.0); } return 2; /* Don't set color */ @@ -478,13 +486,19 @@ static void add_tface_color_layer(DerivedMesh *dm) } } else { + float col[3]; Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1); - if(ma) + + if(ma) { + if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); + else copy_v3_v3(col, &ma->r); + for(j=0;j<4;j++) { - finalCol[i*4+j].b = ma->b; - finalCol[i*4+j].g = ma->g; - finalCol[i*4+j].r = ma->r; + finalCol[i*4+j].b = col[2]; + finalCol[i*4+j].g = col[1]; + finalCol[i*4+j].r = col[0]; } + } else for(j=0;j<4;j++) { finalCol[i*4+j].b = 255; diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 75e8073aafd..c2cf4dfa9fd 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -34,6 +34,8 @@ #include "GL/glew.h" +#include "BLI_math.h" + #include "DNA_image_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -856,6 +858,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GPUMaterial *gpumat; GPUBlendMode blendmode; int a; + int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; /* initialize state */ memset(&GMS, 0, sizeof(GMS)); @@ -930,6 +933,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GMS.matbuf[a][0][0]= ma->r; GMS.matbuf[a][0][1]= ma->g; GMS.matbuf[a][0][2]= ma->b; + if(gamma) linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]); } else { GMS.matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r; GMS.matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g; @@ -939,6 +943,11 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GMS.matbuf[a][1][1]= ma->spec*ma->specg; GMS.matbuf[a][1][2]= ma->spec*ma->specb; GMS.matbuf[a][1][3]= 1.0; + + if(gamma) { + linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][0][0], &GMS.matbuf[a][0][0]); + linearrgb_to_srgb_v3_v3(&GMS.matbuf[a][1][0], &GMS.matbuf[a][1][0]); + } } blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index ff01f76fe71..27dd1069c1c 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -115,7 +115,7 @@ typedef enum PropertySubType { PROP_QUATERNION = 27, PROP_AXISANGLE = 28, PROP_XYZ = 29, - PROP_RGB = 30, + PROP_COLOR_GAMMA = 30, /* booleans */ PROP_LAYER = 40, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 3d4e128c3ac..543e1f3ecc0 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1430,7 +1430,7 @@ static const char *rna_property_subtypename(PropertyType type) case PROP_VELOCITY: return "PROP_VELOCITY"; case PROP_ACCELERATION: return "PROP_ACCELERATION"; case PROP_XYZ: return "PROP_XYZ"; - case PROP_RGB: return "PROP_RGB"; + case PROP_COLOR_GAMMA: return "PROP_COLOR_GAMMA"; case PROP_LAYER: return "PROP_LAYER"; case PROP_LAYER_MEMBER: return "PROP_LAYER_MEMBER"; default: { diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 6c0a3c57f65..5ee811d4c46 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -693,7 +693,7 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index) return quatitem[index]; else if((index < 4) && ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) return vectoritem[index]; - else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_RGB)) + else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) return coloritem[index]; return '\0'; @@ -731,7 +731,7 @@ int RNA_property_array_item_index(PropertyRNA *prop, char name) return 3; } } - else if (ELEM(subtype, PROP_COLOR, PROP_RGB)) { + else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) { switch (name) { case 'R': return 0; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index e9744c7f5ed..28f546c07f1 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -203,7 +203,7 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Rate", "Number of paints per second for Airbrush."); RNA_def_property_update(prop, 0, "rna_Brush_update"); - prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); + prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "rgb"); RNA_def_property_ui_text(prop, "Color", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 2a97eb78382..c4edd00045b 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -216,13 +216,13 @@ static void rna_def_curvemapping(BlenderRNA *brna) RNA_def_property_struct_type(prop, "CurveMap"); RNA_def_property_ui_text(prop, "Curves", ""); - prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_RGB); + prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "black"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Black Level", "For RGB curves, the color that black is mapped to"); RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_black_level_set", NULL); - prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_RGB); + prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "white"); RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "White Level", "For RGB curves, the color that white is mapped to"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 5ff8bffe715..85007482dc4 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1239,7 +1239,7 @@ static void rna_def_material_sss(BlenderRNA *brna) RNA_def_struct_nested(brna, srna, "Material"); RNA_def_struct_ui_text(srna, "Material Subsurface Scattering", "Diffuse subsurface scattering settings for a Material datablock."); - prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_RGB|PROP_UNIT_LENGTH); + prop= RNA_def_property(srna, "radius", PROP_FLOAT, PROP_COLOR|PROP_UNIT_LENGTH); RNA_def_property_float_sdna(prop, NULL, "sss_radius"); RNA_def_property_range(prop, 0.001, FLT_MAX); RNA_def_property_ui_range(prop, 0.001, 10000, 1, 3); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index f8adb1a79d8..5997867030d 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -869,7 +869,7 @@ static void rna_def_property(BlenderRNA *brna) {PROP_EULER, "EULER", 0, "Euler", ""}, {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""}, {PROP_XYZ, "XYZ", 0, "XYZ", ""}, - {PROP_RGB, "RGB", 0, "RGB", ""}, + {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Gamma Corrected Color", ""}, {PROP_LAYER, "LAYER", 0, "Layer", ""}, {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 32c2e18197f..8f8e083523b 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4848,8 +4848,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) /* still bad... doing all */ init_render_textures(re); - if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr); - else VECCOPY(amb, &re->wrld.ambr); + VECCOPY(amb, &re->wrld.ambr); init_render_materials(re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); @@ -5538,8 +5537,7 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) /* still bad... doing all */ init_render_textures(re); - if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(amb, &re->wrld.ambr); - else VECCOPY(amb, &re->wrld.ambr); + VECCOPY(amb, &re->wrld.ambr); init_render_materials(re->r.mode, amb); set_node_shader_lamp_loop(shade_material_loop); diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index d4b7c403f50..6fef8279c7e 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -537,15 +537,9 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short th /* the fraction of how far we are above the bottom of the screen */ blend= fabs(0.5+ view[1]); } - - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(hor, &R.wrld.horr); - color_manage_linearize(zen, &R.wrld.zenr); - } - else { - VECCOPY(hor, &R.wrld.horr); - VECCOPY(zen, &R.wrld.zenr); - } + + VECCOPY(hor, &R.wrld.horr); + VECCOPY(zen, &R.wrld.zenr); /* Careful: SKYTEX and SKYBLEND are NOT mutually exclusive! If */ /* SKYBLEND is active, the texture and color blend are added. */ @@ -633,10 +627,7 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread) } else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { /* 2. solid color */ - if(R.r.color_mgt_flag & R_COLOR_MANAGEMENT) - color_manage_linearize(collector, &R.wrld.horr); - else - VECCOPY(collector, &R.wrld.horr); + VECCOPY(collector, &R.wrld.horr); collector[3] = 0.0f; } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 396c713cfb7..fd1e27ab28a 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -91,42 +91,16 @@ extern struct Render R; * doing inverse gamma correction where applicable */ void shade_input_init_material(ShadeInput *shi) { - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(&shi->r, &shi->mat->r); - color_manage_linearize(&shi->specr, &shi->mat->specr); - color_manage_linearize(&shi->mirr, &shi->mat->mirr); - - /* material ambr / ambg / ambb is overwritten from world - color_manage_linearize(shi->ambr, shi->mat->ambr); - */ - - /* note, keep this synced with render_types.h */ - memcpy(&shi->amb, &shi->mat->amb, 11*sizeof(float)); - shi->har= shi->mat->har; - } else { - /* note, keep this synced with render_types.h */ - memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); - shi->har= shi->mat->har; - } - -} - -static void shadeinput_colors_linearize(ShadeInput *shi) -{ - color_manage_linearize(&shi->r, &shi->r); - color_manage_linearize(&shi->specr, &shi->specr); - color_manage_linearize(&shi->mirr, &shi->mirr); + /* note, keep this synced with render_types.h */ + memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); + shi->har= shi->mat->har; } /* also used as callback for nodes */ /* delivers a fully filled in ShadeResult, for all passes */ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) { - /* because node materials don't have access to rendering context, - * inverse gamma correction must happen here. evil. */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT && shi->nodes == 1) - shadeinput_colors_linearize(shi); - + shade_lamp_loop(shi, shr); /* clears shr */ if(shi->translucency!=0.0f) { @@ -626,7 +600,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) { - color_manage_linearize(shi->vcol, shi->vcol); + srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol); } } @@ -1291,7 +1265,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) */ if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) { - color_manage_linearize(shi->vcol, shi->vcol); + srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol); } } diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 25cfc0f1253..e551cf0f3d2 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -926,20 +926,17 @@ static void sss_create_tree_mat(Render *re, Material *mat) if(!re->test_break(re->tbh)) { SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData"); float ior= mat->sss_ior, cfac= mat->sss_colfac; - float col[3], *radius= mat->sss_radius; + float *radius= mat->sss_radius; float fw= mat->sss_front, bw= mat->sss_back; float error = mat->sss_error; error= get_render_aosss_error(&re->r, error); if((re->r.scemode & R_PREVIEWBUTS) && error < 0.5f) error= 0.5f; - - if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) color_manage_linearize(col, mat->sss_col); - else VECCOPY(col, mat->sss_col); - sss->ss[0]= scatter_settings_new(col[0], radius[0], ior, cfac, fw, bw); - sss->ss[1]= scatter_settings_new(col[1], radius[1], ior, cfac, fw, bw); - sss->ss[2]= scatter_settings_new(col[2], radius[2], ior, cfac, fw, bw); + sss->ss[0]= scatter_settings_new(mat->sss_col[0], radius[0], ior, cfac, fw, bw); + sss->ss[1]= scatter_settings_new(mat->sss_col[1], radius[1], ior, cfac, fw, bw); + sss->ss[2]= scatter_settings_new(mat->sss_col[2], radius[2], ior, cfac, fw, bw); sss->tree= scatter_tree_new(sss->ss, mat->sss_scale, error, co, color, area, totpoint); diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index a9f6e7a53fd..16372d7a15d 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -2051,8 +2051,13 @@ void do_material_tex(ShadeInput *shi) else texres.tin= texres.ta; /* inverse gamma correction */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(tcol, tcol); + if (tex->type==TEX_IMAGE) { + Image *ima = tex->ima; + ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + + /* don't linearize float buffers, assumed to be linear */ + if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) + srgb_to_linearrgb_v3_v3(tcol, tcol); } if(mtex->mapto & MAP_COL) { @@ -2404,11 +2409,6 @@ void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, floa texres.tin= texres.ta; } - /* inverse gamma correction */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(tcol, tcol); - } - /* used for emit */ if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) { float colemitfac= mtex->colemitfac*stencilTin; @@ -2556,8 +2556,13 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) else texres.tin= texres.ta; /* inverse gamma correction */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(&texres.tr, &texres.tr); + if (mtex->tex->type==TEX_IMAGE) { + Image *ima = mtex->tex->ima; + ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); + + /* don't linearize float buffers, assumed to be linear */ + if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) + srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr); } fact= texres.tin*mtex->colfac; @@ -2605,6 +2610,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread) { MTex *mtex; + Tex *tex; TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; float *co, fact, stencilTin=1.0; float tempvec[3], texvec[3], dxt[3], dyt[3]; @@ -2618,7 +2624,8 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f if(R.wrld.mtex[tex_nr]) { mtex= R.wrld.mtex[tex_nr]; - if(mtex->tex==0) continue; + tex= mtex->tex; + if(tex==0) continue; /* if(mtex->mapto==0) continue; */ /* which coords */ @@ -2700,7 +2707,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f else texvec[2]= mtex->size[2]*(mtex->ofs[2]); /* texture */ - if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); + if(tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output); @@ -2748,8 +2755,13 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb; /* inverse gamma correction */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(tcol, tcol); + if (tex->type==TEX_IMAGE) { + Image *ima = tex->ima; + ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + + /* don't linearize float buffers, assumed to be linear */ + if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) + srgb_to_linearrgb_v3_v3(tcol, tcol); } if(mtex->mapto & WOMAP_HORIZ) { @@ -2947,8 +2959,13 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef else texres.tin= texres.ta; /* inverse gamma correction */ - if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) { - color_manage_linearize(&texres.tr, &texres.tr); + if (tex->type==TEX_IMAGE) { + Image *ima = tex->ima; + ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); + + /* don't linearize float buffers, assumed to be linear */ + if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) + srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr); } /* lamp colors were premultiplied with this */ |