4ee12a692f54968341c5f8a04200e0aeaf1ba433
[blender.git] / source / blender / draw / engines / workbench / workbench_data.c
1 #include "workbench_private.h"
2
3 #include "DNA_userdef_types.h"
4
5 #include "UI_resources.h"
6
7
8 void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
9 {
10         const DRWContextState *draw_ctx = DRW_context_state_get();
11         const Scene *scene = draw_ctx->scene;
12         wpd->material_hash = BLI_ghash_ptr_new(__func__);
13
14         View3D *v3d = draw_ctx->v3d;
15         if (v3d) {
16                 wpd->shading = v3d->shading;
17                 wpd->drawtype = v3d->drawtype;
18                 wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, 0);
19         }
20         else {
21                 memset(&wpd->shading, 0, sizeof(wpd->shading));
22                 wpd->shading.light = V3D_LIGHTING_STUDIO;
23                 wpd->shading.shadow_intensity = 0.5;
24                 copy_v3_fl(wpd->shading.single_color, 0.8f);
25                 wpd->drawtype = OB_SOLID;
26                 wpd->studio_light = BKE_studiolight_findindex(0);
27         }
28         wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity;
29
30         WORKBENCH_UBO_World *wd = &wpd->world_data;
31
32         if ((v3d->flag3 & V3D_SHOW_WORLD) &&
33             (scene->world != NULL))
34         {
35                 copy_v3_v3(wd->background_color_low, &scene->world->horr);
36                 copy_v3_v3(wd->background_color_high, &scene->world->horr);
37         }
38         else {
39                 UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low);
40                 UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
41
42                 /* XXX: Really quick conversion to avoid washed out background.
43                  * Needs to be adressed properly (color managed using ocio). */
44                 srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high);
45                 srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low);
46         }
47
48         studiolight_update_world(wpd->studio_light, wd);
49
50         copy_v3_v3(wd->object_outline_color, wpd->shading.object_outline_color);
51         wd->object_outline_color[3] = 1.0f;
52
53         wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), &wpd->world_data);
54 }
55
56 void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3])
57 {
58         const DRWContextState *draw_ctx = DRW_context_state_get();
59         Scene *scene = draw_ctx->scene;
60         WORKBENCH_UBO_World *wd = &wpd->world_data;
61         float view_matrix[4][4];
62         DRW_viewport_matrix_get(view_matrix, DRW_MAT_VIEW);
63
64         {
65                 WORKBENCH_UBO_Light *light = &wd->lights[0];
66                 mul_v3_mat3_m4v3(light->light_direction_vs, view_matrix, light_direction);
67                 light->light_direction_vs[3] = 0.0f;
68                 copy_v3_fl(light->specular_color, 1.0f);
69                 light->energy = 1.0f;
70                 copy_v4_v4(wd->light_direction_vs, light->light_direction_vs);
71                 wd->num_lights = 1;
72         }
73
74         if (STUDIOLIGHT_ORIENTATION_CAMERA_ENABLED(wpd)) {
75                 int light_index = 0;
76                 for (int index = 0 ; index < 3; index++) {
77                         SolidLight *sl = &U.light[index];
78                         if (sl->flag) {
79                                 WORKBENCH_UBO_Light *light = &wd->lights[light_index++];
80                                 copy_v4_v4(light->light_direction_vs, sl->vec);
81                                 negate_v3(light->light_direction_vs);
82                                 copy_v4_v4(light->specular_color, sl->spec);
83                                 light->energy = 1.0f;
84                         }
85                 }
86                 wd->num_lights = light_index;
87         }
88
89 #if 0
90         if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
91                 BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED);
92                 float rot_matrix[3][3];
93                 axis_angle_to_mat3_single(rot_matrix, 'Z', wpd->shading.studiolight_rot_z);
94                 mul_v3_m3v3(e_data.display.light_direction, rot_matrix, wpd->studio_light->light_direction);
95         }
96         else {
97 #else
98         {
99 #endif
100                 copy_v3_v3(light_direction, scene->display.light_direction);
101                 negate_v3(light_direction);
102         }
103
104         DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data);
105 }
106
107 static void workbench_private_material_free(void *data)
108 {
109         WORKBENCH_MaterialData *material_data = data;
110         DRW_UBO_FREE_SAFE(material_data->material_ubo);
111         MEM_freeN(material_data);
112 }
113
114 void workbench_private_data_free(WORKBENCH_PrivateData *wpd)
115 {
116         BLI_ghash_free(wpd->material_hash, NULL, workbench_private_material_free);
117         DRW_UBO_FREE_SAFE(wpd->world_ubo);
118 }