Blender  V2.93
workbench_data.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2018, Blender Foundation.
17  */
18 
22 #include "DRW_render.h"
23 
24 #include "workbench_private.h"
25 
26 #include "BLI_memblock.h"
27 
28 #include "DNA_userdef_types.h"
29 
30 #include "ED_screen.h"
31 #include "ED_view3d.h"
32 
33 #include "UI_resources.h"
34 
35 #include "GPU_uniform_buffer.h"
36 
37 /* -------------------------------------------------------------------- */
42 {
43  struct GPUUniformBuf **ubo = BLI_memblock_alloc(wpd->material_ubo);
44  if (*ubo == NULL) {
46  }
47  return *ubo;
48 }
49 
50 static void workbench_ubo_free(void *elem)
51 {
52  GPUUniformBuf **ubo = elem;
53  DRW_UBO_FREE_SAFE(*ubo);
54 }
55 
56 static void workbench_view_layer_data_free(void *storage)
57 {
59 
64 
67 }
68 
70 {
75 
76  if (*vldata == NULL) {
77  *vldata = MEM_callocN(sizeof(**vldata), "WORKBENCH_ViewLayerData");
78  size_t matbuf_size = sizeof(WORKBENCH_UBO_Material) * MAX_MATERIAL;
79  (*vldata)->material_ubo_data = BLI_memblock_create_ex(matbuf_size, matbuf_size * 2);
80  (*vldata)->material_ubo = BLI_memblock_create_ex(sizeof(void *), sizeof(void *) * 8);
81  (*vldata)->world_ubo = GPU_uniformbuf_create_ex(sizeof(WORKBENCH_UBO_World), NULL, "wb_World");
82  }
83 
84  return *vldata;
85 }
86 
90 {
91  StudioLight *studiolight = wpd->studio_light;
92  float view_matrix[4][4], rot_matrix[4][4];
93  DRW_view_viewmat_get(NULL, view_matrix, false);
94 
95  if (USE_WORLD_ORIENTATION(wpd)) {
96  axis_angle_to_mat4_single(rot_matrix, 'Z', -wpd->shading.studiolight_rot_z);
97  mul_m4_m4m4(rot_matrix, view_matrix, rot_matrix);
98  swap_v3_v3(rot_matrix[2], rot_matrix[1]);
99  negate_v3(rot_matrix[2]);
100  }
101  else {
102  unit_m4(rot_matrix);
103  }
104 
105  if (U.edit_studio_light) {
106  studiolight = BKE_studiolight_studio_edit_get();
107  }
108 
109  /* Studio Lights. */
110  for (int i = 0; i < 4; i++) {
111  WORKBENCH_UBO_Light *light = &wd->lights[i];
112 
113  SolidLight *sl = (studiolight) ? &studiolight->light[i] : NULL;
114  if (sl && sl->flag) {
115  copy_v3_v3(light->light_direction, sl->vec);
116  mul_mat3_m4_v3(rot_matrix, light->light_direction);
117  /* We should predivide the power by PI but that makes the lights really dim. */
118  copy_v3_v3(light->specular_color, sl->spec);
119  copy_v3_v3(light->diffuse_color, sl->col);
120  light->wrapped = sl->smooth;
121  }
122  else {
123  copy_v3_fl3(light->light_direction, 1.0f, 0.0f, 0.0f);
124  copy_v3_fl(light->specular_color, 0.0f);
125  copy_v3_fl(light->diffuse_color, 0.0f);
126  light->wrapped = 0.0f;
127  }
128  }
129 
130  if (studiolight) {
131  copy_v3_v3(wd->ambient_color, studiolight->light_ambient);
132  }
133  else {
134  copy_v3_fl(wd->ambient_color, 1.0f);
135  }
136 
138 }
139 
141 {
142  if (!stl->wpd) {
143  stl->wpd = MEM_callocN(sizeof(*stl->wpd), __func__);
144  stl->wpd->taa_sample_len_previous = -1;
145  stl->wpd->view_updated = true;
146  }
147 }
148 
150 {
151  const DRWContextState *draw_ctx = DRW_context_state_get();
152  RegionView3D *rv3d = draw_ctx->rv3d;
153  View3D *v3d = draw_ctx->v3d;
154  Scene *scene = draw_ctx->scene;
156 
159 
161  draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
162 
163  wpd->preferences = &U;
164  wpd->scene = scene;
165  wpd->sh_cfg = draw_ctx->sh_cfg;
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  DRWState clip_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : 0;
170  if (clip_state != wpd->clip_state) {
171  wpd->view_updated = true;
172  }
173  wpd->clip_state = clip_state;
174 
175  wpd->vldata = vldata;
176  wpd->world_ubo = vldata->world_ubo;
177 
179 
180  wpd->volumes_do = false;
182 
183  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
184  * But this is a workaround for a missing update tagging. */
185  if ((rv3d != NULL) && (rv3d->rflag & RV3D_GPULIGHT_UPDATE)) {
186  wpd->view_updated = true;
187  rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
188  }
189 
190  if (!v3d || (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_workbench(scene))) {
191  short shading_flag = scene->display.shading.flag;
192  if (XRAY_FLAG_ENABLED((&scene->display))) {
193  /* Disable shading options that aren't supported in transparency mode. */
195  }
196 
197  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
198  * But this is a workaround for a missing update tagging from operators. */
199  if ((XRAY_ENABLED(wpd) != XRAY_ENABLED(&scene->display)) ||
200  (shading_flag != wpd->shading.flag)) {
201  wpd->view_updated = true;
202  }
203 
204  wpd->shading = scene->display.shading;
205  wpd->shading.flag = shading_flag;
206  if (XRAY_FLAG_ENABLED((&scene->display))) {
208  }
209  else {
210  wpd->shading.xray_alpha = 1.0f;
211  }
212 
213  if (scene->r.alphamode == R_ALPHAPREMUL) {
214  copy_v4_fl(wpd->background_color, 0.0f);
215  }
216  else if (scene->world) {
217  World *wo = scene->world;
218  copy_v4_fl4(wpd->background_color, wo->horr, wo->horg, wo->horb, 1.0f);
219  }
220  else {
221  copy_v4_fl4(wpd->background_color, 0.0f, 0.0f, 0.0f, 1.0f);
222  }
223  }
224  else {
225  short shading_flag = v3d->shading.flag;
226  if (XRAY_ENABLED(v3d)) {
227  /* Disable shading options that aren't supported in transparency mode. */
229  }
230 
231  /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
232  * But this is a workaround for a missing update tagging from operators. */
233  if (XRAY_ENABLED(v3d) != XRAY_ENABLED(wpd) || shading_flag != wpd->shading.flag) {
234  wpd->view_updated = true;
235  }
236 
237  wpd->shading = v3d->shading;
238  wpd->shading.flag = shading_flag;
239  if (wpd->shading.type < OB_SOLID) {
242  wpd->shading.xray_alpha = 0.0f;
243  }
244  else if (XRAY_ENABLED(v3d)) {
245  wpd->shading.xray_alpha = XRAY_ALPHA(v3d);
246  }
247  else {
248  wpd->shading.xray_alpha = 1.0f;
249  }
250 
251  /* No background. The overlays will draw the correct one. */
252  copy_v4_fl(wpd->background_color, 0.0f);
253  }
254 
256 
257  if (wpd->shading.light == V3D_LIGHTING_MATCAP) {
259  }
260  else {
262  }
263 
264  /* If matcaps are missing, use this as fallback. */
265  if (UNLIKELY(wpd->studio_light == NULL)) {
267  }
268 
269  {
270  /* Material UBOs. */
271  wpd->material_ubo_data = vldata->material_ubo_data;
272  wpd->material_ubo = vldata->material_ubo;
273  wpd->material_chunk_count = 1;
274  wpd->material_chunk_curr = 0;
275  wpd->material_index = 1;
276  /* Create default material ubo. */
279  /* Init default material used by vertex color & texture. */
282  }
283 }
284 
286 {
288 
292  wd.object_outline_color[3] = 1.0f;
295 
299 
300  GPU_uniformbuf_update(wpd->world_ubo, &wd);
301 }
302 
304 {
305  const DRWContextState *draw_ctx = DRW_context_state_get();
307 
308  BLI_memblock_iter iter, iter_data;
309  BLI_memblock_iternew(vldata->material_ubo, &iter);
310  BLI_memblock_iternew(vldata->material_ubo_data, &iter_data);
311  WORKBENCH_UBO_Material *matchunk;
312  while ((matchunk = BLI_memblock_iterstep(&iter_data))) {
313  GPUUniformBuf **ubo = BLI_memblock_iterstep(&iter);
314  BLI_assert(*ubo != NULL);
315  GPU_uniformbuf_update(*ubo, matchunk);
316  }
317 
320 }
enum eContextObjectMode CTX_data_mode_enum_ex(const struct Object *obedit, const struct Object *ob, const 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:1483
StudioLight * BKE_studiolight_studio_edit_get(void)
Definition: studiolight.c:1615
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void unit_m4(float m[4][4])
Definition: rct.c:1140
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void axis_angle_to_mat4_single(float R[4][4], const char axis, const 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:82
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL()
Definition: BLI_memblock.c:163
BLI_memblock * BLI_memblock_create_ex(uint elem_size, uint chunk_size) ATTR_WARN_UNUSED_RESULT
Definition: BLI_memblock.c:63
void * BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_memblock.c:175
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_memblock.c:133
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:104
#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:312
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:354
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:328
#define DRW_UBO_FREE_SAFE(ubo)
Definition: DRW_render.h:188
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
#define XRAY_ENABLED(v3d)
Definition: ED_view3d.h:710
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:709
#define XRAY_ALPHA(v3d)
Definition: ED_view3d.h:705
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:45
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:797
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
bool DRW_state_is_image_render(void)
const float * DRW_viewport_invert_size_get(void)
Definition: draw_manager.c:444
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:45
struct Object * obact
Definition: DRW_render.h:749
struct Scene * scene
Definition: DRW_render.h:745
eGPUShaderConfig sh_cfg
Definition: DRW_render.h:759
struct ViewLayer * view_layer
Definition: DRW_render.h:746
eObjectMode object_mode
Definition: DRW_render.h:757
struct View3D * v3d
Definition: DRW_render.h:742
struct Object * object_edit
Definition: DRW_render.h:769
struct RegionView3D * rv3d
Definition: DRW_render.h:741
GlobalsUboStorage block
Definition: draw_common.h:208
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)