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