Blender V4.3
overlay_next_private.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include "BKE_movieclip.h"
12
13#include "BLI_function_ref.hh"
14
15#include "GPU_matrix.hh"
16
17#include "DRW_gpu_wrapper.hh"
18#include "DRW_render.hh"
19#include "UI_resources.hh"
20#include "draw_manager.hh"
21#include "draw_pass.hh"
23
26
27#include "draw_common.hh"
28
29/* Needed for BoneInstanceData. */
30#include "overlay_private.hh"
31
32namespace blender::draw::overlay {
33
35
41
42struct State {
43 Depsgraph *depsgraph;
45 const Scene *scene;
46 const View3D *v3d;
53 float pixelsize;
64 /* Brings the active pose armature in front of all objects. */
66 /* Add a veil on top of all surfaces to make the active pose armature pop out. */
69 short v3d_flag; /* TODO: move to #View3DOverlay. */
70 short v3d_gridflag; /* TODO: move to #View3DOverlay. */
71 int cfra;
75
76 /* Active Image properties. Only valid image space only. */
80
81 float view_dist_get(const float4x4 &winmat) const
82 {
83 float view_dist = rv3d->dist;
84 /* Special exception for orthographic camera:
85 * `view_dist` isn't used as the depth range isn't the same. */
86 if (rv3d->persp == RV3D_CAMOB && rv3d->is_persp == false) {
87 view_dist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
88 }
89 return view_dist;
90 }
91};
92
93static inline float4x4 winmat_polygon_offset(float4x4 winmat, float view_dist, float offset)
94{
95 winmat[3][2] -= GPU_polygon_offset_calc(winmat.ptr(), view_dist, offset);
96 return winmat;
97}
98
103 private:
104 struct BatchDeleter {
105 void operator()(gpu::Batch *shader)
106 {
108 }
109 };
110 using BatchPtr = std::unique_ptr<gpu::Batch, BatchDeleter>;
111
112 public:
113 BatchPtr bone_box;
119 BatchPtr bone_sphere;
121 BatchPtr bone_stick;
122
125
126 BatchPtr grid;
127
128 BatchPtr quad_wire;
129 BatchPtr quad_solid;
130 BatchPtr plain_axes;
131 BatchPtr single_arrow;
132 BatchPtr cube;
133 BatchPtr circle;
134 BatchPtr empty_sphere;
135 BatchPtr empty_cone;
136 BatchPtr cylinder;
137 BatchPtr capsule_body;
138 BatchPtr capsule_cap;
139 BatchPtr arrows;
141
142 BatchPtr speaker;
143
145 BatchPtr camera_frame;
147 BatchPtr camera_tria;
148
151
153
154 BatchPtr ground_line;
155
165
166 BatchPtr field_force;
167 BatchPtr field_wind;
168 BatchPtr field_vortex;
169 BatchPtr field_curve;
173
177
178 ShapeCache();
179};
180
185 private:
186 struct ShaderDeleter {
187 void operator()(GPUShader *shader)
188 {
189 DRW_SHADER_FREE_SAFE(shader);
190 }
191 };
192 using ShaderPtr = std::unique_ptr<GPUShader, ShaderDeleter>;
193
195 static ShaderModule *g_shader_modules[2 /* Selection Instance. */][2 /* Clipping Enabled. */];
196
197 const SelectionType selection_type_;
200 const bool clipping_enabled_;
201
202 public:
208
209 ShaderPtr anti_aliasing = shader("overlay_antialiasing");
211 ShaderPtr background_fill = shader("overlay_background");
212 ShaderPtr background_clip_bound = shader("overlay_clipbound");
215 ShaderPtr curve_edit_handles = shader("overlay_edit_curves_handle_next");
216 ShaderPtr extra_point;
217 ShaderPtr facing;
218 ShaderPtr grid = shader("overlay_grid");
220 ShaderPtr grid_grease_pencil = shader("overlay_gpencil_canvas");
221 ShaderPtr grid_image;
223 ShaderPtr legacy_curve_edit_normals = shader("overlay_edit_curve_normals");
224 ShaderPtr legacy_curve_edit_handles = shader("overlay_edit_curve_handle_next");
226 ShaderPtr motion_path_line = shader("overlay_motion_path_line_next");
227 ShaderPtr motion_path_vert = shader("overlay_motion_path_point");
228 ShaderPtr mesh_analysis;
230 ShaderPtr mesh_edit_edge = shader("overlay_edit_mesh_edge_next");
231 ShaderPtr mesh_edit_face = shader("overlay_edit_mesh_face_next");
232 ShaderPtr mesh_edit_vert = shader("overlay_edit_mesh_vert_next");
233 ShaderPtr mesh_edit_facedot = shader("overlay_edit_mesh_facedot_next");
239 ShaderPtr outline_prepass_wire = shader("overlay_outline_prepass_wire_next");
243 ShaderPtr outline_detect = shader("overlay_outline_detect");
249 ShaderPtr paint_texture;
250 ShaderPtr paint_weight;
251 ShaderPtr paint_weight_fake_shading; /* TODO(fclem): Specialization constant. */
252 ShaderPtr sculpt_mesh;
253 ShaderPtr sculpt_curves;
255 ShaderPtr uniform_color;
260 ShaderPtr uv_edit_edge = shader("overlay_edit_uv_edges_next");
261 ShaderPtr uv_edit_face;
263 ShaderPtr uv_edit_vert;
265 ShaderPtr uv_paint_mask;
266 ShaderPtr uv_wireframe = shader("overlay_wireframe_uv");
267 ShaderPtr xray_fade;
268
277 ShaderPtr armature_stick;
278 ShaderPtr armature_wire;
279 ShaderPtr depth_curves = selectable_shader("overlay_depth_curves");
280 ShaderPtr depth_grease_pencil = selectable_shader("overlay_depth_gpencil");
281 ShaderPtr depth_mesh = selectable_shader("overlay_depth_mesh");
282 ShaderPtr depth_mesh_conservative = selectable_shader("overlay_depth_mesh_conservative");
283 ShaderPtr depth_point_cloud = selectable_shader("overlay_depth_pointcloud");
284 ShaderPtr extra_grid;
285 ShaderPtr extra_shape;
287 ShaderPtr extra_wire;
296 ShaderPtr image_plane;
297 ShaderPtr lattice_points;
298 ShaderPtr lattice_wire;
299 ShaderPtr particle_dot;
300 ShaderPtr particle_shape;
301 ShaderPtr particle_hair;
302 ShaderPtr wireframe_mesh;
304 ShaderPtr wireframe_points; /* Draw objects without edges for the wireframe overlay. */
305
306 ShaderModule(const SelectionType selection_type, const bool clipping_enabled);
307
310 static ShaderModule &module_get(SelectionType selection_type, bool clipping_enabled);
311 static void module_free();
312
313 private:
314 ShaderPtr shader(const char *create_info_name)
315 {
316 return ShaderPtr(GPU_shader_create_from_info_name(create_info_name));
317 }
318 ShaderPtr shader(const char *create_info_name,
319 FunctionRef<void(gpu::shader::ShaderCreateInfo &info)> patch);
320 ShaderPtr selectable_shader(const char *create_info_name);
321 ShaderPtr selectable_shader(const char *create_info_name,
322 FunctionRef<void(gpu::shader::ShaderCreateInfo &info)> patch);
323};
324
327
328 /* Overlay Color. */
329 Framebuffer overlay_color_only_fb = {"overlay_color_only_fb"};
330 /* Overlay Color, Line Data. */
331 Framebuffer overlay_line_only_fb = {"overlay_line_only_fb"};
332 /* Depth, Overlay Color. */
333 Framebuffer overlay_fb = {"overlay_fb"};
334 /* Depth, Overlay Color, Line Data. */
335 Framebuffer overlay_line_fb = {"overlay_line_fb"};
336 /* Depth In-Front, Overlay Color. */
337 Framebuffer overlay_in_front_fb = {"overlay_in_front_fb"};
338 /* Depth In-Front, Overlay Color, Line Data. */
339 Framebuffer overlay_line_in_front_fb = {"overlay_line_in_front_fb"};
340
341 /* Output Color. */
342 Framebuffer overlay_output_fb = {"overlay_output_fb"};
343
344 /* Render Frame-buffers. Only used for multiplicative blending on top of the render. */
345 /* TODO(fclem): Remove the usage of these somehow. This is against design. */
346 GPUFrameBuffer *render_fb = nullptr;
347 GPUFrameBuffer *render_in_front_fb = nullptr;
348
349 /* Target containing line direction and data for line expansion and anti-aliasing. */
351 /* Target containing overlay color before anti-aliasing. */
352 TextureFromPool overlay_tx = {"overlay_tx"};
353 /* Target containing depth of overlays when xray is enabled. */
354 TextureFromPool xray_depth_tx = {"xray_depth_tx"};
355
356 /* Texture that are usually allocated inside. These are fallback when they aren't.
357 * They are then wrapped inside the #TextureRefs below. */
358 TextureFromPool depth_in_front_alloc_tx = {"overlay_depth_in_front_tx"};
359 TextureFromPool color_overlay_alloc_tx = {"overlay_color_overlay_alloc_tx"};
360 TextureFromPool color_render_alloc_tx = {"overlay_color_render_alloc_tx"};
361
362 Texture dummy_depth_tx = {"dummy_depth_tx"};
363
367 /* References, not owned. */
368 GPUUniformBuf *globals_buf;
370 /* Wrappers around #DefaultTextureList members. */
389
391
392 Resources(const SelectionType selection_type_, ShaderModule &shader_module)
393 : select::SelectMap(selection_type_), shaders(shader_module){};
394
399
401 {
402 SelectMap::begin_sync();
404 }
405
407 {
408 const bool is_edit = (state.object_mode & OB_MODE_EDIT) &&
409 (ob_ref.object->mode & OB_MODE_EDIT);
410 const bool active = (state.active_base != nullptr) &&
411 ((ob_ref.dupli_parent != nullptr) ?
412 (state.active_base->object == ob_ref.dupli_parent) :
413 (state.active_base->object == ob_ref.object));
414 const bool is_selected = ((ob_ref.object->base_flag & BASE_SELECTED) != 0);
415
416 /* Object in edit mode. */
417 if (is_edit) {
418 return TH_WIRE_EDIT;
419 }
420 /* Transformed object during operators. */
421 if (((G.moving & G_TRANSFORM_OBJ) != 0) && is_selected) {
422 return TH_TRANSFORM;
423 }
424 /* Sets the 'theme_id' or fallback to wire */
425 if ((ob_ref.object->base_flag & BASE_SELECTED) != 0) {
426 return (active) ? TH_ACTIVE : TH_SELECT;
427 }
428
429 switch (ob_ref.object->type) {
430 case OB_LAMP:
431 return TH_LIGHT;
432 case OB_SPEAKER:
433 return TH_SPEAKER;
434 case OB_CAMERA:
435 return TH_CAMERA;
436 case OB_LIGHTPROBE:
437 /* TODO: add light-probe color. Use empty color for now. */
438 case OB_EMPTY:
439 return TH_EMPTY;
440 default:
441 return (is_edit) ? TH_WIRE_EDIT : TH_WIRE;
442 }
443 }
444
445 const float4 &object_wire_color(const ObjectRef &ob_ref, ThemeColorID theme_id) const
446 {
447 if (UNLIKELY(ob_ref.object->base_flag & BASE_FROM_SET)) {
449 }
450 switch (theme_id) {
451 case TH_WIRE_EDIT:
453 case TH_ACTIVE:
455 case TH_SELECT:
457 case TH_TRANSFORM:
459 case TH_SPEAKER:
461 case TH_CAMERA:
463 case TH_EMPTY:
465 case TH_LIGHT:
467 default:
469 }
470 }
471
472 const float4 &object_wire_color(const ObjectRef &ob_ref, const State &state) const
473 {
474 ThemeColorID theme_id = object_wire_theme_id(ob_ref, state);
475 return object_wire_color(ob_ref, theme_id);
476 }
477
479 {
480 float4 color;
481 UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, 0, color);
482 return color;
483 }
484
486 {
487 ThemeColorID theme_id = object_wire_theme_id(ob_ref, state);
488 return background_blend_color(theme_id);
489 }
490
492 {
493 if (state.v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
494 if (state.scene->world) {
495 return float4(float3(&state.scene->world->horr));
496 }
497 }
498 else if (state.v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) {
499 return state.v3d->shading.background_color;
500 }
501 float4 color;
503 return color;
504 }
505
507 {
508 /* Free Movie clip textures after rendering */
509 for (MovieClip *clip : bg_movie_clips) {
511 }
512 }
513};
514
518template<typename InstanceDataT> struct ShapeInstanceBuf : private select::SelectBuf {
519
521
522 ShapeInstanceBuf(const SelectionType selection_type, const char *name = nullptr)
524
525 void clear()
526 {
527 this->select_clear();
528 data_buf.clear();
529 }
530
531 void append(const InstanceDataT &data, select::ID select_id)
532 {
533 this->select_append(select_id);
534 data_buf.append(data);
535 }
536
537 void end_sync(PassSimple::Sub &pass, gpu::Batch *shape)
538 {
539 if (data_buf.is_empty()) {
540 return;
541 }
542 this->select_bind(pass);
544 pass.bind_ssbo("data_buf", &data_buf);
545 pass.draw(shape, data_buf.size());
546 }
547
549 gpu::Batch *shape,
550 GPUPrimType primitive_type,
551 uint primitive_len)
552 {
553 if (data_buf.is_empty()) {
554 return;
555 }
556 this->select_bind(pass);
558 pass.bind_ssbo("data_buf", &data_buf);
559 pass.draw_expand(
560 shape, primitive_type, primitive_len, data_buf.size(), ResourceHandle(0), uint(0));
561 }
562};
563
565 protected:
568 int color_id = 0;
569
570 VertexPrimitiveBuf(const SelectionType selection_type, const char *name = nullptr)
571 : select_buf(selection_type), data_buf(name){};
572
573 void append(const float3 &position, const float4 &color)
574 {
575 data_buf.append({float4(position), color});
576 }
577
578 void end_sync(PassSimple::Sub &pass, GPUPrimType primitive)
579 {
580 if (data_buf.is_empty()) {
581 return;
582 }
585 pass.bind_ssbo("data_buf", &data_buf);
586 pass.push_constant("colorid", color_id);
587 pass.draw_procedural(primitive, 1, data_buf.size());
588 }
589
590 public:
591 void clear()
592 {
594 data_buf.clear();
595 color_id = 0;
596 }
597};
598
600
601 public:
602 PointPrimitiveBuf(const SelectionType selection_type, const char *name = nullptr)
603 : VertexPrimitiveBuf(selection_type, name)
604 {
605 }
606
607 void append(const float3 &position,
608 const float4 &color,
610 {
611 select_buf.select_append(select_id);
612 VertexPrimitiveBuf::append(position, color);
613 }
614
615 void append(const float3 &position, const int color_id, select::ID select_id)
616 {
617 this->color_id = color_id;
618 append(position, float4(), select_id);
619 }
620
625};
626
628
629 public:
630 LinePrimitiveBuf(const SelectionType selection_type, const char *name = nullptr)
631 : VertexPrimitiveBuf(selection_type, name)
632 {
633 }
634
635 void append(const float3 &start,
636 const float3 &end,
637 const float4 &color,
639 {
640 select_buf.select_append(select_id);
641 VertexPrimitiveBuf::append(start, color);
642 VertexPrimitiveBuf::append(end, color);
643 }
644
645 void append(const float3 &start,
646 const float3 &end,
647 const int color_id,
649 {
650 this->color_id = color_id;
651 append(start, end, float4(), select_id);
652 }
653
658};
659
660} // namespace blender::draw::overlay
eContextObjectMode
@ G_TRANSFORM_OBJ
void BKE_movieclip_free_gputexture(struct MovieClip *clip)
MINLINE float max_ff(float a, float b)
unsigned int uint
#define UNLIKELY(x)
@ BASE_FROM_SET
eObjectMode
@ OB_MODE_EDIT
@ OB_SPEAKER
@ OB_EMPTY
@ OB_CAMERA
@ OB_LAMP
@ OB_LIGHTPROBE
#define BASE_SELECTED(v3d, base)
eSpace_Type
@ V3D_SHADING_BACKGROUND_VIEWPORT
@ V3D_SHADING_BACKGROUND_WORLD
@ RV3D_CAMOB
#define DRW_SHADER_FREE_SAFE(shader)
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition GPU_batch.hh:205
float GPU_polygon_offset_calc(const float(*winmat)[4], float viewdist, float dist)
GPUPrimType
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
GPUShader * GPU_shader_create_from_info_name(const char *info_name)
void UI_GetThemeColor3fv(int colorid, float col[3])
ThemeColorID
@ TH_LIGHT
@ TH_BACK
@ TH_WIRE
@ TH_CAMERA
@ TH_TRANSFORM
@ TH_SPEAKER
@ TH_EMPTY
@ TH_SELECT
@ TH_WIRE_EDIT
@ TH_ACTIVE
void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
struct GPUShader GPUShader
ShaderModule(const SelectionType selection_type, const bool clipping_enabled)
static ShaderModule & module_get(SelectionType selection_type, bool clipping_enabled)
append
#define fabsf(x)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
static ulong state[N]
#define G(x, y, z)
static float4x4 winmat_polygon_offset(float4x4 winmat, float view_dist, float offset)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
short base_flag
const c_style_mat & ptr() const
void append(const float3 &start, const float3 &end, const float4 &color, select::ID select_id=select::SelectMap::select_invalid_id())
void append(const float3 &start, const float3 &end, const int color_id, select::ID select_id=select::SelectMap::select_invalid_id())
LinePrimitiveBuf(const SelectionType selection_type, const char *name=nullptr)
PointPrimitiveBuf(const SelectionType selection_type, const char *name=nullptr)
void append(const float3 &position, const int color_id, select::ID select_id)
void append(const float3 &position, const float4 &color, select::ID select_id=select::SelectMap::select_invalid_id())
float4 background_color_get(const State &state)
const float4 & object_wire_color(const ObjectRef &ob_ref, ThemeColorID theme_id) const
const float4 & object_wire_color(const ObjectRef &ob_ref, const State &state) const
float4 object_background_blend_color(const ObjectRef &ob_ref, const State &state) const
float4 background_blend_color(ThemeColorID theme_id) const
Resources(const SelectionType selection_type_, ShaderModule &shader_module)
ThemeColorID object_wire_theme_id(const ObjectRef &ob_ref, const State &state) const
ShapeInstanceBuf(const SelectionType selection_type, const char *name=nullptr)
void end_sync(PassSimple::Sub &pass, gpu::Batch *shape)
StorageVectorBuffer< InstanceDataT > data_buf
void append(const InstanceDataT &data, select::ID select_id)
void end_sync(PassSimple::Sub &pass, gpu::Batch *shape, GPUPrimType primitive_type, uint primitive_len)
float view_dist_get(const float4x4 &winmat) const
void end_sync(PassSimple::Sub &pass, GPUPrimType primitive)
void append(const float3 &position, const float4 &color)
VertexPrimitiveBuf(const SelectionType selection_type, const char *name=nullptr)
StorageVectorBuffer< VertexData > data_buf
void select_bind(PassSimple::Sub &pass)
SelectBuf(const SelectionType selection_type)
SelectMap(const SelectionType selection_type)
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...