Blender  V3.3
workbench_data.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. */
3 
7 #include "DRW_render.h"
8 
9 #include "workbench_private.h"
10 
11 #include "BLI_memblock.h"
12 
13 #include "DNA_userdef_types.h"
14 
15 #include "ED_screen.h"
16 #include "ED_view3d.h"
17 
18 #include "UI_resources.h"
19 
20 #include "GPU_uniform_buffer.h"
21 
22 /* -------------------------------------------------------------------- */
27 {
28  struct GPUUniformBuf **ubo = BLI_memblock_alloc(wpd->material_ubo);
29  if (*ubo == NULL) {
31  }
32  return *ubo;
33 }
34 
35 static void workbench_ubo_free(void *elem)
36 {
37  GPUUniformBuf **ubo = elem;
38  DRW_UBO_FREE_SAFE(*ubo);
39 }
40 
41 static void workbench_view_layer_data_free(void *storage)
42 {
44 
49 
52 }
53 
55 {
60 
61  if (*vldata == NULL) {
62  *vldata = MEM_callocN(sizeof(**vldata), "WORKBENCH_ViewLayerData");
63  size_t matbuf_size = sizeof(WORKBENCH_UBO_Material) * MAX_MATERIAL;
64  (*vldata)->material_ubo_data = BLI_memblock_create_ex(matbuf_size, matbuf_size * 2);
65  (*vldata)->material_ubo = BLI_memblock_create_ex(sizeof(void *), sizeof(void *) * 8);
66  (*vldata)->world_ubo = GPU_uniformbuf_create_ex(sizeof(WORKBENCH_UBO_World), NULL, "wb_World");
67  }
68 
69  return *vldata;
70 }
71 
75 {
76  StudioLight *studiolight = wpd->studio_light;
77  float view_matrix[4][4], rot_matrix[4][4];
78  DRW_view_viewmat_get(NULL, view_matrix, false);
79 
80  if (USE_WORLD_ORIENTATION(wpd)) {
81  axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
82  mul_m4_m4m4(rot_matrix, view_matrix, rot_matrix);
83  swap_v3_v3(rot_matrix[2], rot_matrix[1]);
84  negate_v3(rot_matrix[2]);
85  }
86  else {
87  unit_m4(rot_matrix);
88  }
89 
90  if (U.edit_studio_light) {
91  studiolight = BKE_studiolight_studio_edit_get();
92  }
93 
94  /* Studio Lights. */
95  for (int i = 0; i < 4; i++) {
96  WORKBENCH_UBO_Light *light = &wd->lights[i];
97 
98  SolidLight *sl = (studiolight) ? &studiolight->light[i] : NULL;
99  if (sl && sl->flag) {
100  copy_v3_v3(light->light_direction, sl->vec);
101  mul_mat3_m4_v3(rot_matrix, light->light_direction);
102  /* We should pre-divide the power by PI but that makes the lights really dim. */
103  copy_v3_v3(light->specular_color, sl->spec);
104  copy_v3_v3(light->diffuse_color, sl->col);
105  light->wrapped = sl->smooth;
106  }
107  else {
108  copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
109  copy_v3_fl(light->specular_color, 0.0f);
110  copy_v3_fl(light->diffuse_color, 0.0f);
111  light->wrapped = 0.0f;
112  }
113  }
114 
115  if (studiolight) {
116  copy_v3_v3(wd->ambient_color, studiolight->light_ambient);
117  }
118  else {
119  copy_v3_fl(wd->ambient_color, 1.0f);
120  }
121 
123 }
124 
126 {
127  if (!stl->wpd) {
128  stl->wpd = MEM_callocN(sizeof(*stl->wpd), __func__);
129  stl->wpd->taa_sample_len_previous = -1;
130  stl->wpd->view_updated = true;
131  }
132 }
133 
135 {
136  const DRWContextState *draw_ctx = DRW_context_state_get();
137  RegionView3D *rv3d = draw_ctx->rv3d;
138  View3D *v3d = draw_ctx->v3d;
139  Scene *scene = draw_ctx->scene;
141 
144 
146  draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
147 
148  wpd->preferences = &U;
149  wpd->scene = scene;
150  wpd->sh_cfg = draw_ctx->sh_cfg;
151 
152  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
153  * But this is a workaround for a missing update tagging. */
154  DRWState clip_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : 0;
155  if (clip_state != wpd->clip_state) {
156  wpd->view_updated = true;
157  }
158  wpd->clip_state = clip_state;
159 
160  wpd->vldata = vldata;
161  wpd->world_ubo = vldata->world_ubo;
162 
164 
165  wpd->volumes_do = false;
166 
167  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
168  * But this is a workaround for a missing update tagging. */
169  if ((rv3d != NULL) && (rv3d->rflag & RV3D_GPULIGHT_UPDATE)) {
170  wpd->view_updated = true;
171  rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
172  }
173 
174  if (!v3d || (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_workbench(scene))) {
175  short shading_flag = scene->display.shading.flag;
176  if (XRAY_FLAG_ENABLED((&scene->display))) {
177  /* Disable shading options that aren't supported in transparency mode. */
179  }
180 
181  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
182  * But this is a workaround for a missing update tagging from operators. */
183  if ((XRAY_ENABLED(wpd) != XRAY_ENABLED(&scene->display)) ||
184  (shading_flag != wpd->shading.flag)) {
185  wpd->view_updated = true;
186  }
187 
188  wpd->shading = scene->display.shading;
189  wpd->shading.flag = shading_flag;
190  if (XRAY_FLAG_ENABLED((&scene->display))) {
192  }
193  else {
194  wpd->shading.xray_alpha = 1.0f;
195  }
196 
197  if (scene->r.alphamode == R_ALPHAPREMUL) {
198  copy_v4_fl(wpd->background_color, 0.0f);
199  }
200  else if (scene->world) {
201  World *wo = scene->world;
202  copy_v4_fl4(wpd->background_color, wo->horr, wo->horg, wo->horb, 1.0f);
203  }
204  else {
205  copy_v4_fl4(wpd->background_color, 0.0f, 0.0f, 0.0f, 1.0f);
206  }
207  }
208  else {
209  short shading_flag = v3d->shading.flag;
210  if (XRAY_ENABLED(v3d)) {
211  /* Disable shading options that aren't supported in transparency mode. */
213  }
214 
215  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
216  * But this is a workaround for a missing update tagging from operators. */
217  if (XRAY_ENABLED(v3d) != XRAY_ENABLED(wpd) || shading_flag != wpd->shading.flag) {
218  wpd->view_updated = true;
219  }
220 
221  wpd->shading = v3d->shading;
222  wpd->shading.flag = shading_flag;
223  if (wpd->shading.type < OB_SOLID) {
226  wpd->shading.xray_alpha = 0.0f;
227  }
228  else if (XRAY_ENABLED(v3d)) {
229  wpd->shading.xray_alpha = XRAY_ALPHA(v3d);
230  }
231  else {
232  wpd->shading.xray_alpha = 1.0f;
233  }
234 
235  /* No background. The overlays will draw the correct one. */
236  copy_v4_fl(wpd->background_color, 0.0f);
237  }
238 
240 
241  if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
243  }
244  else {
246  }
247 
248  /* If matcaps are missing, use this as fallback. */
249  if (UNLIKELY(wpd->studio_light == NULL)) {
251  }
252 
253  {
254  /* Material UBOs. */
255  wpd->material_ubo_data = vldata->material_ubo_data;
256  wpd->material_ubo = vldata->material_ubo;
257  wpd->material_chunk_count = 1;
258  wpd->material_chunk_curr = 0;
259  wpd->material_index = 1;
260  /* Create default material ubo. */
263  /* Init default material used by vertex color & texture. */
266  }
267 }
268 
270 {
272 
276  wd.object_outline_color[3] = 1.0f;
279 
283 
284  GPU_uniformbuf_update(wpd->world_ubo, &wd);
285 }
286 
288 {
289  const DRWContextState *draw_ctx = DRW_context_state_get();
291 
292  BLI_memblock_iter iter, iter_data;
293  BLI_memblock_iternew(vldata->material_ubo, &iter);
294  BLI_memblock_iternew(vldata->material_ubo_data, &iter_data);
295  WORKBENCH_UBO_Material *matchunk;
296  while ((matchunk = BLI_memblock_iterstep(&iter_data))) {
297  GPUUniformBuf **ubo = BLI_memblock_iterstep(&iter);
298  BLI_assert(*ubo != NULL);
299  GPU_uniformbuf_update(*ubo, matchunk);
300  }
301 
304 }
enum eContextObjectMode CTX_data_mode_enum_ex(const struct Object *obedit, const struct Object *ob, eObjectMode object_mode)
bool BKE_scene_uses_blender_workbench(const struct Scene *scene)
@ STUDIOLIGHT_TYPE_MATCAP
@ STUDIOLIGHT_TYPE_STUDIO
struct StudioLight * BKE_studiolight_find(const char *name, int flag)
Definition: studiolight.c:1462
StudioLight * BKE_studiolight_studio_edit_get(void)
Definition: studiolight.c:1593
#define BLI_assert(a)
Definition: BLI_assert.h:46
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void unit_m4(float m[4][4])
Definition: rct.c:1090
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
void axis_angle_to_mat4_single(float R[4][4], char axis, float angle)
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void negate_v3(float r[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void copy_v4_fl(float r[4], float f)
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:66
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL()
Definition: BLI_memblock.c:145
BLI_memblock * BLI_memblock_create_ex(uint elem_size, uint chunk_size) ATTR_WARN_UNUSED_RESULT
Definition: BLI_memblock.c:47
void * BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_memblock.c:157
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_memblock.c:115
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:86
#define UNUSED(x)
#define UNLIKELY(x)
@ OB_SOLID
@ OB_RENDER
@ R_ALPHAPREMUL
@ V3D_SHADING_MATERIAL_COLOR
@ V3D_SHADING_OBJECT_COLOR
@ V3D_LIGHTING_FLAT
@ V3D_LIGHTING_MATCAP
#define RV3D_GPULIGHT_UPDATE
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ V3D_SHADING_SHADOW
@ V3D_SHADING_DEPTH_OF_FIELD
@ V3D_SHADING_CAVITY
@ V3D_SHADING_MATCAP_FLIP_X
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:342
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:316
#define DRW_UBO_FREE_SAFE(ubo)
Definition: DRW_render.h:191
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:183
#define XRAY_ENABLED(v3d)
Definition: ED_view3d.h:1299
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:1298
#define XRAY_ALPHA(v3d)
Definition: ED_view3d.h:1294
struct GPUUniformBuf GPUUniformBuf
#define GPU_uniformbuf_create(size)
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define U
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
struct DRW_Global G_draw
Definition: draw_common.c:32
bool DRW_state_is_playback(void)
bool DRW_state_is_navigating(void)
void ** DRW_view_layer_engine_data_ensure_ex(ViewLayer *view_layer, DrawEngineType *engine_type, void(*callback)(void *storage))
Definition: draw_manager.c:767
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
bool DRW_state_is_image_render(void)
const float * DRW_viewport_invert_size_get(void)
Definition: draw_manager.c:293
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
struct Object * obact
Definition: DRW_render.h:983
struct Scene * scene
Definition: DRW_render.h:979
eGPUShaderConfig sh_cfg
Definition: DRW_render.h:993
struct ViewLayer * view_layer
Definition: DRW_render.h:980
eObjectMode object_mode
Definition: DRW_render.h:991
struct View3D * v3d
Definition: DRW_render.h:976
struct Object * object_edit
Definition: DRW_render.h:1003
struct RegionView3D * rv3d
Definition: DRW_render.h:975
GlobalsUboStorage block
Definition: draw_common.h:127
View3DShading shading
struct SceneDisplay display
struct RenderData r
struct World * world
SolidLight light[STUDIOLIGHT_MAX_LIGHT]
float light_ambient[3]
float object_outline_color[3]
char studio_light[256]
View3DShading shading
struct GPUUniformBuf * world_ubo
const UserDef * preferences
struct GPUUniformBuf * material_ubo_curr
struct BLI_memblock * material_ubo_data
struct BLI_memblock * material_ubo
eGPUShaderConfig sh_cfg
eContextObjectMode ctx_mode
struct WORKBENCH_ViewLayerData * vldata
WORKBENCH_UBO_Material * material_ubo_data_curr
struct WORKBENCH_PrivateData * wpd
WORKBENCH_UBO_Light lights[4]
struct GPUUniformBuf * world_ubo
struct GPUUniformBuf * cavity_sample_ubo
struct BLI_memblock * material_ubo
struct BLI_memblock * material_ubo_data
struct GPUUniformBuf * dof_sample_ubo
struct GPUTexture * cavity_jitter_tx
float horg
float horb
float horr
GPUUniformBuf * workbench_material_ubo_alloc(WORKBENCH_PrivateData *wpd)
static void workbench_view_layer_data_free(void *storage)
void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
static WORKBENCH_ViewLayerData * workbench_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
void workbench_private_data_alloc(WORKBENCH_StorageList *stl)
void workbench_update_world_ubo(WORKBENCH_PrivateData *wpd)
static void workbench_studiolight_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_World *wd)
static void workbench_ubo_free(void *elem)
void workbench_update_material_ubos(WORKBENCH_PrivateData *UNUSED(wpd))
int workbench_antialiasing_sample_count_get(WORKBENCH_PrivateData *wpd)
void workbench_cavity_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_World *wd)
void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_UBO_Material *data, eV3DShadingColorType color_type)
void workbench_shadow_data_update(WORKBENCH_PrivateData *wpd, WORKBENCH_UBO_World *wd)
#define USE_WORLD_ORIENTATION(wpd)
struct WORKBENCH_UBO_Material WORKBENCH_UBO_Material
#define MAX_MATERIAL
#define CULL_BACKFACE_ENABLED(wpd)
BLI_INLINE bool workbench_is_specular_highlight_enabled(WORKBENCH_PrivateData *wpd)