diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-19 15:00:34 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-19 15:04:51 +0300 |
commit | de748bbedfb81238d15da2db13b94f276038b9f0 (patch) | |
tree | 97e9242a2b83161c49091b243911ebed2527750b /source/blender | |
parent | c564d847efa6b933066c4fc02558d627bca401a4 (diff) |
Studiolight: Background Generation of icons
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_studiolight.h | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/studiolight.c | 119 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 42 |
3 files changed, 110 insertions, 70 deletions
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index 135f926df15..7ffb75820df 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -34,6 +34,8 @@ * Studio lighting for the 3dview */ +#include "BKE_context.h" + #include "BLI_sys_types.h" #include "DNA_space_types.h" @@ -52,13 +54,16 @@ #define STUDIOLIGHT_Z_POS 4 #define STUDIOLIGHT_Z_NEG 5 -#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE 0 -#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE 1 -#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP 2 -#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP_FLIPPED 3 +#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE (1 << 0) +#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE (1 << 1) +#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP (1 << 2) +#define STUDIOLIGHT_ICON_ID_TYPE_MATCAP_FLIPPED (1 << 3) + +#define STUDIOLIGHT_ICON_SIZE 96 struct GPUTexture; +/* StudioLight.flag */ enum StudioLightFlag { STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED = (1 << 0), STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED = (1 << 1), @@ -75,6 +80,7 @@ enum StudioLightFlag { STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11), STUDIOLIGHT_UI_EXPANDED = (1 << 13), } StudioLightFlag; + #define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE) #define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL) #define STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_ORIENTATION_WORLD) @@ -82,6 +88,8 @@ enum StudioLightFlag { typedef struct StudioLight { struct StudioLight *next, *prev; + + int index; int flag; char name[FILE_MAXFILE]; char path[FILE_MAX]; @@ -91,7 +99,6 @@ typedef struct StudioLight { int icon_id_radiance; int icon_id_matcap; int icon_id_matcap_flipped; - int index; float spherical_harmonics_coefs[9][3]; float light_direction[3]; ImBuf *equirectangular_radiance_buffer; @@ -107,7 +114,7 @@ void BKE_studiolight_free(void); struct StudioLight *BKE_studiolight_find(const char *name, int flag); struct StudioLight *BKE_studiolight_findindex(int index, int flag); struct StudioLight *BKE_studiolight_find_first(int flag); -unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type); +void BKE_studiolight_preview(uint* icon_buffer, StudioLight *sl, int icon_id_type); struct ListBase *BKE_studiolight_listbase(void); void BKE_studiolight_ensure_flag(StudioLight *sl, int flag); void BKE_studiolight_refresh(void); diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 6e4bfddcd8b..3cdb8da75b5 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -65,35 +65,33 @@ static const char *STUDIOLIGHT_WORLD_FOLDER = "studiolights/world/"; static const char *STUDIOLIGHT_MATCAP_FOLDER = "studiolights/matcap/"; /* FUNCTIONS */ -#define SAFE_MEM_FREEN(p) \ -if (p) { \ - MEM_freeN(p); \ - p = NULL; \ -} -#define SAFE_IMB_FREE(p) \ -if (p) { \ - IMB_freeImBuf(p); \ - p = NULL; \ -} -#define SAFE_GPU_TEXTURE_FREE(p) \ -if (p) { \ - GPU_texture_free(p); \ - p = NULL; \ -} +#define IMB_SAFE_FREE(p) do { \ +if (p) { \ + IMB_freeImBuf(p); \ + p = NULL; \ +} \ +} while (0) + +#define GPU_TEXTURE_SAFE_FREE(p) do { \ +if (p) { \ + GPU_texture_free(p); \ + p = NULL; \ +} \ +} while (0) static void studiolight_free(struct StudioLight *sl) { for (int index = 0 ; index < 6 ; index ++) { - SAFE_IMB_FREE(sl->radiance_cubemap_buffers[index]) + IMB_SAFE_FREE(sl->radiance_cubemap_buffers[index]); } - SAFE_GPU_TEXTURE_FREE(sl->equirectangular_radiance_gputexture); - SAFE_GPU_TEXTURE_FREE(sl->equirectangular_irradiance_gputexture); - SAFE_IMB_FREE(sl->equirectangular_radiance_buffer) - SAFE_IMB_FREE(sl->equirectangular_irradiance_buffer) - SAFE_MEM_FREEN(sl->path_irr_cache); - SAFE_MEM_FREEN(sl->path_sh2_cache); - SAFE_MEM_FREEN(sl->gpu_matcap_3components); - SAFE_MEM_FREEN(sl); + GPU_TEXTURE_SAFE_FREE(sl->equirectangular_radiance_gputexture); + GPU_TEXTURE_SAFE_FREE(sl->equirectangular_irradiance_gputexture); + IMB_SAFE_FREE(sl->equirectangular_radiance_buffer); + IMB_SAFE_FREE(sl->equirectangular_irradiance_buffer); + MEM_SAFE_FREE(sl->path_irr_cache); + MEM_SAFE_FREE(sl->path_sh2_cache); + MEM_SAFE_FREE(sl->gpu_matcap_3components); + MEM_SAFE_FREE(sl); } static struct StudioLight *studiolight_create(int flag) @@ -722,19 +720,18 @@ static uint alpha_circle_mask(float u, float v, float inner_edge, float outer_ed #define STUDIOLIGHT_DIAMETER 0.95f -static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size) +static void studiolight_radiance_preview(uint* icon_buffer, StudioLight *sl) { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED); - uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); - float pixel_size = 1.0f / (float)icon_size; + float pixel_size = 1.0f / (float)STUDIOLIGHT_ICON_SIZE; int offset = 0; - for (int y = 0; y < icon_size; y++) { - float dy = (y + 0.5f) / (float)icon_size; + for (int y = 0; y < STUDIOLIGHT_ICON_SIZE; y++) { + float dy = (y + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; dy = dy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; - for (int x = 0; x < icon_size; x++) { - float dx = (x + 0.5f) / (float)icon_size; + for (int x = 0; x < STUDIOLIGHT_ICON_SIZE; x++) { + float dx = (x + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; dx = dx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; uint pixelresult = 0x0; @@ -763,28 +760,26 @@ static uint *studiolight_radiance_preview(StudioLight *sl, int icon_size) linearrgb_to_srgb(color[1]), linearrgb_to_srgb(color[2])) | alphamask; } - rect[offset++] = pixelresult; + icon_buffer[offset++] = pixelresult; } } - return rect; } -static uint *studiolight_matcap_preview(StudioLight *sl, int icon_size, bool flipped) +static void studiolight_matcap_preview(uint* icon_buffer, StudioLight *sl, bool flipped) { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EXTERNAL_IMAGE_LOADED); - uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); float color[4]; float fx, fy; - float pixel_size = 1.0f / (float)icon_size; + float pixel_size = 1.0f / (float)STUDIOLIGHT_ICON_SIZE; int offset = 0; ImBuf *ibuf = sl->equirectangular_radiance_buffer; - for (int y = 0; y < icon_size; y++) { - fy = (y + 0.5f) / (float)icon_size; + for (int y = 0; y < STUDIOLIGHT_ICON_SIZE; y++) { + fy = (y + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; fy = fy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; - for (int x = 0; x < icon_size; x++) { - fx = (x + 0.5f) / (float)icon_size; + for (int x = 0; x < STUDIOLIGHT_ICON_SIZE; x++) { + fx = (x + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; fx = fx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; if (flipped) { fx = 1.0f - fx; @@ -793,28 +788,26 @@ static uint *studiolight_matcap_preview(StudioLight *sl, int icon_size, bool fli uint alphamask = alpha_circle_mask(fx, fy, 0.5f - pixel_size, 0.5f); - rect[offset++] = rgb_to_cpack( + icon_buffer[offset++] = rgb_to_cpack( linearrgb_to_srgb(color[0]), linearrgb_to_srgb(color[1]), linearrgb_to_srgb(color[2])) | alphamask; } } - return rect; } -static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size) +static void studiolight_irradiance_preview(uint* icon_buffer, StudioLight *sl) { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED); - uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__); - float pixel_size = 1.0f / (float)icon_size; + float pixel_size = 1.0f / (float)STUDIOLIGHT_ICON_SIZE; int offset = 0; - for (int y = 0; y < icon_size; y++) { - float dy = (y + 0.5f) / (float)icon_size; + for (int y = 0; y < STUDIOLIGHT_ICON_SIZE; y++) { + float dy = (y + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; dy = dy / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; - for (int x = 0; x < icon_size; x++) { - float dx = (x + 0.5f) / (float)icon_size; + for (int x = 0; x < STUDIOLIGHT_ICON_SIZE; x++) { + float dx = (x + 0.5f) / (float)STUDIOLIGHT_ICON_SIZE; dx = dx / STUDIOLIGHT_DIAMETER - (1.0f - STUDIOLIGHT_DIAMETER) / 2.0f; uint pixelresult = 0x0; @@ -848,10 +841,9 @@ static uint *studiolight_irradiance_preview(StudioLight *sl, int icon_size) linearrgb_to_srgb(color[1]), linearrgb_to_srgb(color[2])) | alphamask; } - rect[offset++] = pixelresult; + icon_buffer[offset++] = pixelresult; } } - return rect; } /* API */ @@ -863,7 +855,7 @@ void BKE_studiolight_init(void) /* Also reserve icon space for it. */ /* Add default studio light */ sl = studiolight_create(STUDIOLIGHT_INTERNAL | STUDIOLIGHT_SPHERICAL_HARMONICS_COEFFICIENTS_CALCULATED | STUDIOLIGHT_ORIENTATION_CAMERA); - BLI_strncpy(sl->name, "INTERNAL_01", FILE_MAXFILE); + BLI_strncpy(sl->name, "Default", FILE_MAXFILE); copy_v3_fl3(sl->spherical_harmonics_coefs[0], 1.03271556f, 1.07163882f, 1.11193657f); copy_v3_fl3(sl->spherical_harmonics_coefs[1], -0.00480952f, 0.05290511f, 0.16394117f); @@ -939,21 +931,34 @@ struct ListBase *BKE_studiolight_listbase(void) return &studiolights; } -uint *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type) +void BKE_studiolight_preview(uint* icon_buffer, StudioLight *sl, int icon_id_type) { switch (icon_id_type) { case STUDIOLIGHT_ICON_ID_TYPE_RADIANCE: default: - return studiolight_radiance_preview(sl, icon_size); + { + studiolight_radiance_preview(icon_buffer, sl); + break; + } case STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE: - return studiolight_irradiance_preview(sl, icon_size); + { + studiolight_irradiance_preview(icon_buffer, sl); + break; + } case STUDIOLIGHT_ICON_ID_TYPE_MATCAP: - return studiolight_matcap_preview(sl, icon_size, false); + { + studiolight_matcap_preview(icon_buffer, sl, false); + break; + } case STUDIOLIGHT_ICON_ID_TYPE_MATCAP_FLIPPED: - return studiolight_matcap_preview(sl, icon_size, true); + { + studiolight_matcap_preview(icon_buffer, sl, true); + break; + } } } +/* Ensure state of Studiolights */ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag) { if ((sl->flag & flag) == flag) { diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 91ace3e69a2..6602c4d442e 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -77,6 +77,9 @@ #include "UI_interface.h" #include "UI_interface_icons.h" +#include "WM_api.h" +#include "WM_types.h" + #include "interface_intern.h" #ifndef WITH_HEADLESS @@ -734,14 +737,7 @@ static DrawInfo *icon_create_drawinfo(Icon *icon) di->type = ICON_TYPE_GEOM; } else if (icon_data_type == ICON_DATA_STUDIOLIGHT) { - const int STUDIOLIGHT_SIZE = 96; - StudioLight *sl = icon->obj; di->type = ICON_TYPE_BUFFER; - IconImage *img = MEM_mallocN(sizeof(IconImage), __func__); - img->w = STUDIOLIGHT_SIZE; - img->h = STUDIOLIGHT_SIZE; - img->rect = BKE_studiolight_preview(sl, STUDIOLIGHT_SIZE, icon->id_type); - di->data.buffer.image = img; } else { BLI_assert(0); @@ -846,6 +842,15 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size) static void ui_id_preview_image_render_size( const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job); +static void ui_studiolight_icon_job_exec(void *customdata, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress)) +{ + Icon **tmp = (Icon **)customdata; + Icon *icon = *tmp; + DrawInfo *di = icon_ensure_drawinfo(icon); + StudioLight *sl = icon->obj; + BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type); +} + void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big) { Icon *icon = BKE_icon_get(icon_id); @@ -872,6 +877,29 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi } break; } + case ICON_TYPE_BUFFER: + { + if (icon->obj_type == ICON_DATA_STUDIOLIGHT) { + if (di->data.buffer.image == NULL) { + IconImage *img = MEM_mallocN(sizeof(IconImage), __func__); + img->w = STUDIOLIGHT_ICON_SIZE; + img->h = STUDIOLIGHT_ICON_SIZE; + size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint); + img->rect = MEM_mallocN(size, __func__); + memset(img->rect, 0, size); + di->data.buffer.image = img; + + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_ANY); + Icon** tmp = MEM_callocN(sizeof(Icon*), __func__); + *tmp = icon; + WM_jobs_customdata_set(wm_job, tmp, MEM_freeN); + WM_jobs_timer(wm_job, 0.01, 0, NC_WINDOW); + WM_jobs_callbacks(wm_job, ui_studiolight_icon_job_exec, NULL, NULL, NULL); + WM_jobs_start(CTX_wm_manager(C), wm_job); + } + } + break; + } } } } |