Studiolight: Background Generation of icons
This commit is contained in:
parent
c564d847ef
commit
de748bbedf
|
@ -1617,6 +1617,8 @@ class StudioLightPanelMixin():
|
|||
op = row.operator('wm.studiolight_uninstall', text="", icon='ZOOMOUT')
|
||||
op.index = studio_light.index
|
||||
|
||||
box.label(text=studio_light.name)
|
||||
|
||||
|
||||
class USERPREF_PT_studiolight_matcaps(Panel, StudioLightPanelMixin):
|
||||
bl_label = "MatCaps"
|
||||
|
|
|
@ -3630,7 +3630,7 @@ class VIEW3D_PT_shading_lighting(Panel):
|
|||
layout.row().prop(shading, "light", expand=True)
|
||||
if shading.light == 'STUDIO':
|
||||
row = layout.row()
|
||||
row.template_icon_view(shading, "studio_light")
|
||||
row.template_icon_view(shading, "studio_light", show_labels=True)
|
||||
sub = row.column()
|
||||
sub.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES')
|
||||
if shading.selected_studio_light.orientation == 'WORLD':
|
||||
|
@ -3638,14 +3638,14 @@ class VIEW3D_PT_shading_lighting(Panel):
|
|||
|
||||
elif shading.light == 'MATCAP':
|
||||
row = layout.row()
|
||||
row.template_icon_view(shading, "studio_light")
|
||||
row.template_icon_view(shading, "studio_light", show_labels=True)
|
||||
sub = row.column()
|
||||
sub.operator('VIEW3D_OT_toggle_matcap_flip', emboss=False, text="", icon='ARROW_LEFTRIGHT')
|
||||
sub.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES')
|
||||
|
||||
elif shading.type in ('MATERIAL'):
|
||||
row = layout.row()
|
||||
row.template_icon_view(shading, "studio_light")
|
||||
row.template_icon_view(shading, "studio_light", show_labels=True)
|
||||
sub = row.column()
|
||||
sub.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES')
|
||||
if shading.selected_studio_light.orientation == 'WORLD':
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue