Compare commits
90 Commits
node-edito
...
tmp-overla
Author | SHA1 | Date | |
---|---|---|---|
a35c635edb | |||
7164e63fef | |||
915e54ee9d | |||
4926e7413d | |||
2c5cd812f7 | |||
2367fd9e1f | |||
4e298108a3 | |||
1a44c77bb4 | |||
120a7e1b44 | |||
626e291d1c | |||
4b7cdfe6f9 | |||
d33477d1a4 | |||
5daca04d4e | |||
8b48b5a11d | |||
da13ddb65a | |||
c980f9e652 | |||
443effa45f | |||
4baf738540 | |||
dfad332740 | |||
ded3fc0725 | |||
7330b347d7 | |||
d4420d7070 | |||
41dbaa4aee | |||
9a207356ca | |||
1b32f27b13 | |||
6183d49ad8 | |||
bd09bd2ffa | |||
03cc35013c | |||
c7a13de09a | |||
98360afb33 | |||
2723032ca7 | |||
1552dd3f16 | |||
7c17e76e0e | |||
d027db16e3 | |||
cfcbb1daee | |||
fa009ca0bd | |||
06bbcb8ffa | |||
e0a0f1cbe0 | |||
79beba2005 | |||
3cd95fc46f | |||
0a9ff3d25a | |||
ed12703bd1 | |||
4bf0c9793a | |||
b695343c6c | |||
ae3687ac48 | |||
00ba7b314e | |||
a527a3e159 | |||
f21f35b68d | |||
52e69ce747 | |||
b5d3d4e41f | |||
872cbbf84f | |||
75c39c8d23 | |||
a9c8eab4b6 | |||
122b04aec5 | |||
d78bd78c14 | |||
5ea8bed6f2 | |||
0417033bf3 | |||
e06882633a | |||
89b3a9c147 | |||
7282ecc672 | |||
380a702172 | |||
0a12d49392 | |||
53bce31c95 | |||
995a96e630 | |||
2a02329cb2 | |||
99fcb0a2ca | |||
864ec2cb54 | |||
5cae096d13 | |||
73162d80c2 | |||
9364ae3984 | |||
0389895f25 | |||
632b00aead | |||
1bf797be98 | |||
ecd57e8184 | |||
5e9dd6d2b4 | |||
551c10f8ce | |||
08466bebdf | |||
d16c0501bd | |||
8e49022d93 | |||
32fb5f7a6b | |||
38ef4c02e1 | |||
d2a1d222c0 | |||
fb7d446e37 | |||
3f651fb979 | |||
6f260d96a4 | |||
8ccff665fc | |||
bca4edeb14 | |||
0c28626de6 | |||
029587583b | |||
f3a6fe1c73 |
@@ -168,6 +168,7 @@ class DATA_PT_lightprobe_display(DataButtonsPanel, Panel):
|
||||
|
||||
if probe.type == 'PLANAR':
|
||||
col.prop(ob, "empty_display_size", text="Arrow Size")
|
||||
col.prop(probe, "show_influence")
|
||||
col.prop(probe, "show_data")
|
||||
|
||||
if probe.type in {'GRID', 'CUBEMAP'}:
|
||||
|
@@ -96,7 +96,13 @@ static void blf_batch_draw_init(void)
|
||||
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
|
||||
g_batch.glyph_len = 0;
|
||||
|
||||
g_batch.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, g_batch.verts, NULL, GPU_BATCH_OWNS_VBO);
|
||||
/* A dummy vbo containing 4 points, attribs are not used. */
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, 4);
|
||||
|
||||
/* We render a quad as a triangle strip and instance it for each glyph. */
|
||||
g_batch.batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
GPU_batch_instbuf_set(g_batch.batch, g_batch.verts, true);
|
||||
}
|
||||
|
||||
static void blf_batch_draw_exit(void)
|
||||
@@ -188,8 +194,7 @@ void blf_batch_draw(void)
|
||||
GPU_vertbuf_data_len_set(g_batch.verts, g_batch.glyph_len);
|
||||
GPU_vertbuf_use(g_batch.verts); /* send data */
|
||||
|
||||
eGPUBuiltinShader shader = (g_batch.simple_shader) ? GPU_SHADER_TEXT_SIMPLE : GPU_SHADER_TEXT;
|
||||
GPU_batch_program_set_builtin(g_batch.batch, shader);
|
||||
GPU_batch_program_set_builtin(g_batch.batch, GPU_SHADER_TEXT);
|
||||
GPU_batch_uniform_1i(g_batch.batch, "glyph", 0);
|
||||
GPU_batch_draw(g_batch.batch);
|
||||
|
||||
|
@@ -21,7 +21,6 @@
|
||||
set(INC
|
||||
.
|
||||
intern
|
||||
modes
|
||||
|
||||
../blenfont
|
||||
../blenkernel
|
||||
@@ -49,8 +48,6 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/draw_anim_viz.c
|
||||
intern/draw_armature.c
|
||||
intern/draw_cache.c
|
||||
intern/draw_cache_extract_mesh.c
|
||||
intern/draw_cache_impl_curve.c
|
||||
@@ -72,20 +69,6 @@ set(SRC
|
||||
intern/draw_manager_texture.c
|
||||
intern/draw_select_buffer.c
|
||||
intern/draw_view.c
|
||||
modes/edit_armature_mode.c
|
||||
modes/edit_curve_mode.c
|
||||
modes/edit_lattice_mode.c
|
||||
modes/edit_mesh_mode.c
|
||||
modes/edit_mesh_mode_text.c
|
||||
modes/edit_metaball_mode.c
|
||||
modes/edit_text_mode.c
|
||||
modes/object_mode.c
|
||||
modes/overlay_mode.c
|
||||
modes/paint_texture_mode.c
|
||||
modes/paint_vertex_mode.c
|
||||
modes/particle_mode.c
|
||||
modes/pose_mode.c
|
||||
modes/sculpt_mode.c
|
||||
engines/basic/basic_engine.c
|
||||
engines/eevee/eevee_bloom.c
|
||||
engines/eevee/eevee_data.c
|
||||
@@ -136,6 +119,25 @@ set(SRC
|
||||
engines/gpencil/gpencil_shader_fx.c
|
||||
engines/select/select_draw_utils.c
|
||||
engines/select/select_engine.c
|
||||
engines/overlay/overlay_antialiasing.c
|
||||
engines/overlay/overlay_armature.c
|
||||
engines/overlay/overlay_engine.c
|
||||
engines/overlay/overlay_edit_curve.c
|
||||
engines/overlay/overlay_edit_text.c
|
||||
engines/overlay/overlay_edit_mesh.c
|
||||
engines/overlay/overlay_extra.c
|
||||
engines/overlay/overlay_facing.c
|
||||
engines/overlay/overlay_grid.c
|
||||
engines/overlay/overlay_image.c
|
||||
engines/overlay/overlay_lattice.c
|
||||
engines/overlay/overlay_metaball.c
|
||||
engines/overlay/overlay_motion_path.c
|
||||
engines/overlay/overlay_outline.c
|
||||
engines/overlay/overlay_paint.c
|
||||
engines/overlay/overlay_particle.c
|
||||
engines/overlay/overlay_shader.c
|
||||
engines/overlay/overlay_sculpt.c
|
||||
engines/overlay/overlay_wireframe.c
|
||||
|
||||
DRW_engine.h
|
||||
DRW_select_buffer.h
|
||||
@@ -152,8 +154,7 @@ set(SRC
|
||||
intern/draw_manager_profiling.h
|
||||
intern/draw_manager_text.h
|
||||
intern/draw_view.h
|
||||
modes/draw_mode_engines.h
|
||||
modes/edit_mesh_mode_intern.h
|
||||
intern/smaa_textures.h
|
||||
engines/basic/basic_engine.h
|
||||
engines/eevee/eevee_engine.h
|
||||
engines/eevee/eevee_lightcache.h
|
||||
@@ -164,6 +165,8 @@ set(SRC
|
||||
engines/workbench/workbench_private.h
|
||||
engines/select/select_engine.h
|
||||
engines/select/select_private.h
|
||||
engines/overlay/overlay_engine.h
|
||||
engines/overlay/overlay_private.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
@@ -261,90 +264,14 @@ data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
|
||||
|
||||
data_to_c_simple(modes/shaders/common_colormanagement_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_hair_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_hair_refine_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_view_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_fxaa_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_fullscreen_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_lines_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_lines_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/animviz_mpath_points_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_axes_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_sphere_solid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_sphere_solid_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_sphere_outline_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_envelope_solid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_envelope_solid_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_envelope_outline_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_envelope_distance_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_shape_solid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_shape_solid_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_shape_outline_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_shape_outline_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_stick_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_stick_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/armature_dof_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_common_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_mix_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_mesh_skin_root_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_curve_overlay_normals_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/overlay_face_orientation_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/overlay_face_wireframe_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/overlay_face_wireframe_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/overlay_face_wireframe_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_camera_image_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_camera_image_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_color_axes_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_empty_axes_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_prepass_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_prepass_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_prepass_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_lightprobe_grid_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_mball_handles_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_particle_prim_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_particle_dot_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_particle_dot_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_loose_points_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_texture_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_texture_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_vertex_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_vertex_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_weight_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_weight_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_face_selection_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_face_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/pose_selection_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/sculpt_mask_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_colormanagement_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_fullscreen_vert.glsl SRC)
|
||||
|
||||
data_to_c_simple(engines/gpencil/shaders/gpencil_fill_vert.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/gpencil_fill_frag.glsl SRC)
|
||||
@@ -380,6 +307,81 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC)
|
||||
data_to_c_simple(engines/select/shaders/selection_id_3D_vert.glsl SRC)
|
||||
data_to_c_simple(engines/select/shaders/selection_id_frag.glsl SRC)
|
||||
|
||||
data_to_c_simple(engines/overlay/shaders/antialiasing_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/antialiasing_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_dof_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_outline_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_solid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_solid_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_shape_outline_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_shape_outline_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_shape_solid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_shape_solid_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_sphere_outline_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_sphere_solid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_sphere_solid_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_stick_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_stick_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_wire_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/depth_only_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_curve_handle_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_curve_handle_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_curve_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_curve_wire_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_lattice_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_lattice_wire_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_common_lib.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_facefill_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_facefill_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_normal_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_analysis_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_analysis_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_skin_root_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_mesh_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_particle_strand_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/edit_particle_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_groundline_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_loose_point_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_loose_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_wire_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/extra_wire_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/facing_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/facing_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/grid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/grid_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/image_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/image_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/motion_path_line_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/motion_path_line_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/motion_path_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_detect_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_expand_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_prepass_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_prepass_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_prepass_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_lightprobe_grid_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/outline_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_face_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_point_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_texture_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_texture_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_vertcol_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_vertcol_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_weight_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_weight_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/paint_wire_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/particle_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/particle_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/sculpt_mask_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/volume_velocity_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/wireframe_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/wireframe_geom.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/wireframe_frag.glsl SRC)
|
||||
|
||||
list(APPEND INC
|
||||
)
|
||||
|
@@ -52,6 +52,7 @@ struct rcti;
|
||||
/* Buffer and textures used by the viewport by default */
|
||||
typedef struct DefaultFramebufferList {
|
||||
struct GPUFrameBuffer *default_fb;
|
||||
struct GPUFrameBuffer *in_front_fb;
|
||||
struct GPUFrameBuffer *color_only_fb;
|
||||
struct GPUFrameBuffer *depth_only_fb;
|
||||
struct GPUFrameBuffer *multisample_fb;
|
||||
@@ -60,6 +61,7 @@ typedef struct DefaultFramebufferList {
|
||||
typedef struct DefaultTextureList {
|
||||
struct GPUTexture *color;
|
||||
struct GPUTexture *depth;
|
||||
struct GPUTexture *depth_in_front;
|
||||
struct GPUTexture *multisample_color;
|
||||
struct GPUTexture *multisample_depth;
|
||||
} DefaultTextureList;
|
||||
|
@@ -46,8 +46,8 @@ typedef struct BASIC_StorageList {
|
||||
} BASIC_StorageList;
|
||||
|
||||
typedef struct BASIC_PassList {
|
||||
struct DRWPass *depth_pass;
|
||||
struct DRWPass *depth_pass_cull;
|
||||
struct DRWPass *depth_pass[2];
|
||||
struct DRWPass *depth_pass_cull[2];
|
||||
} BASIC_PassList;
|
||||
|
||||
typedef struct BASIC_Data {
|
||||
@@ -70,8 +70,8 @@ static struct {
|
||||
} e_data = {{{NULL}}}; /* Engine data */
|
||||
|
||||
typedef struct BASIC_PrivateData {
|
||||
DRWShadingGroup *depth_shgrp;
|
||||
DRWShadingGroup *depth_shgrp_cull;
|
||||
DRWShadingGroup *depth_shgrp[2];
|
||||
DRWShadingGroup *depth_shgrp_cull[2];
|
||||
} BASIC_PrivateData; /* Transient data */
|
||||
|
||||
/* Functions */
|
||||
@@ -97,24 +97,21 @@ static void basic_cache_init(void *vedata)
|
||||
|
||||
if (!stl->g_data) {
|
||||
/* Alloc transient pointers */
|
||||
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
|
||||
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
|
||||
{
|
||||
psl->depth_pass = DRW_pass_create("Depth Pass",
|
||||
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
|
||||
stl->g_data->depth_shgrp = DRW_shgroup_create(sh_data->depth, psl->depth_pass);
|
||||
if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
|
||||
DRW_shgroup_state_enable(stl->g_data->depth_shgrp, DRW_STATE_CLIP_PLANES);
|
||||
}
|
||||
/* Twice for normal and infront objects. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
DRWState clip_state = (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? DRW_STATE_CLIP_PLANES : 0;
|
||||
DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
|
||||
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
|
||||
psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull",
|
||||
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
DRW_STATE_CULL_BACK);
|
||||
stl->g_data->depth_shgrp_cull = DRW_shgroup_create(sh_data->depth, psl->depth_pass_cull);
|
||||
if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
|
||||
DRW_shgroup_state_enable(stl->g_data->depth_shgrp_cull, DRW_STATE_CLIP_PLANES);
|
||||
}
|
||||
DRW_PASS_CREATE(psl->depth_pass[i], state | clip_state | infront_state);
|
||||
stl->g_data->depth_shgrp[i] = DRW_shgroup_create(sh_data->depth, psl->depth_pass[i]);
|
||||
|
||||
state |= DRW_STATE_CULL_BACK;
|
||||
DRW_PASS_CREATE(psl->depth_pass_cull[i], state | clip_state | infront_state);
|
||||
stl->g_data->depth_shgrp_cull[i] = DRW_shgroup_create(sh_data->depth, psl->depth_pass_cull[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +125,8 @@ static void basic_cache_populate(void *vedata, Object *ob)
|
||||
return;
|
||||
}
|
||||
|
||||
bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
if (ob != draw_ctx->object_edit) {
|
||||
for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
|
||||
@@ -138,7 +137,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
|
||||
const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
|
||||
if (draw_as == PART_DRAW_PATH) {
|
||||
struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
|
||||
DRW_shgroup_call(stl->g_data->depth_shgrp, hairs, NULL);
|
||||
DRW_shgroup_call(stl->g_data->depth_shgrp[do_in_front], hairs, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +154,7 @@ static void basic_cache_populate(void *vedata, Object *ob)
|
||||
/* Avoid losing flat objects when in ortho views (see T56549) */
|
||||
struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call(stl->g_data->depth_shgrp, geom, ob);
|
||||
DRW_shgroup_call(stl->g_data->depth_shgrp[do_in_front], geom, ob);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -165,7 +164,8 @@ static void basic_cache_populate(void *vedata, Object *ob)
|
||||
!DRW_state_is_image_render();
|
||||
const bool do_cull = (draw_ctx->v3d &&
|
||||
(draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
|
||||
DRWShadingGroup *shgrp = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
|
||||
DRWShadingGroup *shgrp = (do_cull) ? stl->g_data->depth_shgrp_cull[do_in_front] :
|
||||
stl->g_data->depth_shgrp[do_in_front];
|
||||
|
||||
if (use_sculpt_pbvh) {
|
||||
DRW_shgroup_call_sculpt(shgrp, ob, false, false, false);
|
||||
@@ -189,8 +189,10 @@ static void basic_draw_scene(void *vedata)
|
||||
{
|
||||
BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
|
||||
|
||||
DRW_draw_pass(psl->depth_pass);
|
||||
DRW_draw_pass(psl->depth_pass_cull);
|
||||
DRW_draw_pass(psl->depth_pass[0]);
|
||||
DRW_draw_pass(psl->depth_pass_cull[0]);
|
||||
DRW_draw_pass(psl->depth_pass[1]);
|
||||
DRW_draw_pass(psl->depth_pass_cull[1]);
|
||||
}
|
||||
|
||||
static void basic_engine_free(void)
|
||||
|
@@ -33,8 +33,6 @@
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "draw_mode_engines.h"
|
||||
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "gpencil_engine.h"
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
extern DrawEngineType draw_engine_gpencil_type;
|
||||
|
||||
struct GPENCIL_Data;
|
||||
struct GPENCIL_StorageList;
|
||||
struct MaterialGPencilStyle;
|
||||
|
@@ -29,8 +29,6 @@
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "draw_mode_engines.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
#include "gpencil_engine.h"
|
||||
|
184
source/blender/draw/engines/overlay/overlay_antialiasing.c
Normal file
184
source/blender/draw/engines/overlay/overlay_antialiasing.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Overlay antialiasing:
|
||||
*
|
||||
* Most of the overlays are wires which causes a lot of flickering in motions
|
||||
* due to aliasing problems.
|
||||
*
|
||||
* Our goal is to have a technique that works with single sample per pixel
|
||||
* to avoid extra cost of managing MSAA or additional texture buffers and jitters.
|
||||
*
|
||||
* To solve this we use a simple and effective post-process AA. The technique
|
||||
* goes like this:
|
||||
*
|
||||
* - During wireframe rendering, we output the line color, the line direction
|
||||
* and the distance from the line for the pixel center.
|
||||
*
|
||||
* - Then, in a post process pass, for each pixels we gather all lines in a search area
|
||||
* that could cover (even partially) the center pixel.
|
||||
* We compute the coverage of each line and do a sorted alpha compositing of them.
|
||||
*
|
||||
* This technique has one major shortcoming compared to MSAA:
|
||||
* - It handles (initial) partial visibility poorly (because of single sample). This makes
|
||||
* overlaping / crossing wires a bit too thin at their intersection.
|
||||
* Wireframe meshes overlaid over solid meshes can have half of the edge missing due to
|
||||
* z-fighting (this has workaround).
|
||||
* Another manifestation of this, is fickering of really dense wireframe if using small
|
||||
* line thickness (also has workaround).
|
||||
*
|
||||
* The pros of this approach are many:
|
||||
* - Works without geometry shader.
|
||||
* - Can inflate line thickness.
|
||||
* - Coverage is very close to perfect and can even be filtered (Blackman-Harris, gaussian).
|
||||
* - Wires can "bleed" / overlap non-line objects since the filter is in screenspace.
|
||||
* - Only uses one additional lightweight fullscreen buffer (compared to MSAA/SMAA).
|
||||
* - No convergence time (compared to TAA).
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_antialiasing_reset(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
pd->antialiasing.sample = 0;
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
if (!DRW_state_is_fbo()) {
|
||||
/* Use default view */
|
||||
pd->view_default = (DRWView *)DRW_view_default_get();
|
||||
pd->antialiasing.enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO Get real userpref option and remove MSAA buffer. */
|
||||
pd->antialiasing.enabled = dtxl->multisample_color != NULL;
|
||||
|
||||
/* Use default view */
|
||||
pd->view_default = (DRWView *)DRW_view_default_get();
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_RGBA8, DRW_TEX_FILTER);
|
||||
DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0);
|
||||
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->overlay_color_only_fb,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->overlay_default_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
|
||||
GPU_framebuffer_ensure_config(&fbl->overlay_line_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->overlay_line_tx)});
|
||||
}
|
||||
else {
|
||||
/* Just a copy of the defaults framebuffers. */
|
||||
GPU_framebuffer_ensure_config(&fbl->overlay_color_only_fb,
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->overlay_default_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->overlay_line_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
struct GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
DRW_PASS_CREATE(psl->antialiasing_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||
|
||||
sh = OVERLAY_shader_antialiasing();
|
||||
grp = DRW_shgroup_create(sh, psl->antialiasing_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthTex", &dtxl->depth);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "colorTex", &txl->overlay_color_tx);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "lineTex", &txl->overlay_line_tx);
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
GPU_framebuffer_ensure_config(&fbl->overlay_in_front_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->overlay_color_tx)});
|
||||
}
|
||||
else {
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->overlay_in_front_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
GPU_framebuffer_bind(fbl->overlay_line_fb);
|
||||
GPU_framebuffer_clear_color(fbl->overlay_line_fb, clear_col);
|
||||
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_end(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
GPU_framebuffer_bind(dfbl->color_only_fb);
|
||||
DRW_draw_pass(psl->antialiasing_ps);
|
||||
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
}
|
||||
}
|
2338
source/blender/draw/engines/overlay/overlay_armature.c
Normal file
2338
source/blender/draw/engines/overlay/overlay_armature.c
Normal file
File diff suppressed because it is too large
Load Diff
127
source/blender/draw/engines/overlay/overlay_edit_curve.c
Normal file
127
source/blender/draw/engines/overlay/overlay_edit_curve.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_edit_curve_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
DRWShadingGroup *grp;
|
||||
GPUShader *sh;
|
||||
DRWState state;
|
||||
|
||||
pd->edit_curve.show_handles = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) != 0;
|
||||
pd->shdata.edit_curve_normal_length = v3d->overlay.normals_length;
|
||||
|
||||
/* Run Twice for in-front passes. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH;
|
||||
state |= ((i == 0) ? DRW_STATE_DEPTH_LESS_EQUAL : DRW_STATE_DEPTH_ALWAYS);
|
||||
DRW_PASS_CREATE(psl->edit_curve_wire_ps[i], state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_curve_wire();
|
||||
pd->edit_curve_normal_grp[i] = grp = DRW_shgroup_create(sh, psl->edit_curve_wire_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "normalSize", pd->shdata.edit_curve_normal_length);
|
||||
|
||||
pd->edit_curve_wire_grp[i] = grp = DRW_shgroup_create(sh, psl->edit_curve_wire_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "normalSize", 0.0f);
|
||||
}
|
||||
{
|
||||
state = DRW_STATE_WRITE_COLOR;
|
||||
DRW_PASS_CREATE(psl->edit_curve_handle_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_curve_handle();
|
||||
pd->edit_curve_handle_grp = grp = DRW_shgroup_create(sh, psl->edit_curve_handle_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "showCurveHandles", pd->edit_curve.show_handles);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
|
||||
|
||||
sh = OVERLAY_shader_edit_curve_point();
|
||||
pd->edit_curve_points_grp = grp = DRW_shgroup_create(sh, psl->edit_curve_handle_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
bool draw_normals = (pd->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_NORMALS) != 0;
|
||||
bool do_xray = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
|
||||
Curve *cu = ob->data;
|
||||
struct GPUBatch *geom;
|
||||
|
||||
geom = DRW_cache_curve_edge_wire_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_curve_wire_grp[do_xray], geom, ob);
|
||||
}
|
||||
|
||||
if ((cu->flag & CU_3D) && draw_normals) {
|
||||
geom = DRW_cache_curve_edge_normal_get(ob);
|
||||
DRW_shgroup_call_instances(pd->edit_curve_normal_grp[do_xray], ob, geom, 3);
|
||||
}
|
||||
|
||||
geom = DRW_cache_curve_edge_overlay_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_curve_handle_grp, geom, ob);
|
||||
}
|
||||
|
||||
geom = DRW_cache_curve_vert_overlay_get(ob, pd->edit_curve.show_handles);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_curve_points_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_surf_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUBatch *geom;
|
||||
|
||||
geom = DRW_cache_curve_edge_overlay_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_curve_handle_grp, geom, ob);
|
||||
}
|
||||
|
||||
geom = DRW_cache_curve_vert_overlay_get(ob, false);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_curve_points_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_curve_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->edit_curve_wire_ps[0]);
|
||||
DRW_draw_pass(psl->edit_curve_wire_ps[1]);
|
||||
|
||||
DRW_draw_pass(psl->edit_curve_handle_ps);
|
||||
}
|
419
source/blender/draw/engines/overlay/overlay_edit_mesh.c
Normal file
419
source/blender/draw/engines/overlay/overlay_edit_mesh.c
Normal file
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BKE_editmesh.h"
|
||||
|
||||
#include "draw_cache_impl.h"
|
||||
#include "draw_manager_text.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
#define OVERLAY_EDIT_TEXT \
|
||||
(V3D_OVERLAY_EDIT_EDGE_LEN | V3D_OVERLAY_EDIT_FACE_AREA | V3D_OVERLAY_EDIT_FACE_ANG | \
|
||||
V3D_OVERLAY_EDIT_EDGE_ANG | V3D_OVERLAY_EDIT_INDICES)
|
||||
|
||||
void OVERLAY_edit_mesh_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
pd->edit_mesh.do_zbufclip = XRAY_FLAG_ENABLED(draw_ctx->v3d);
|
||||
|
||||
if (!pd->edit_mesh.do_zbufclip) {
|
||||
/* Small texture which will have very small impact on rendertime. */
|
||||
DRW_texture_ensure_2d(&txl->dummy_depth_tx, 1, 1, GPU_DEPTH_COMPONENT24, 0);
|
||||
}
|
||||
|
||||
/* Create view with depth offset */
|
||||
DRWView *default_view = (DRWView *)DRW_view_default_get();
|
||||
/* Don't use AA view (pd->view_default) because edit mode already has anti-aliasing. */
|
||||
pd->view_edit_faces = default_view;
|
||||
pd->view_edit_faces_cage = DRW_view_create_with_zoffset(default_view, draw_ctx->rv3d, 0.5f);
|
||||
pd->view_edit_edges = DRW_view_create_with_zoffset(default_view, draw_ctx->rv3d, 1.0f);
|
||||
pd->view_edit_verts = DRW_view_create_with_zoffset(default_view, draw_ctx->rv3d, 1.5f);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_ShadingData *shdata = &pd->shdata;
|
||||
DRWShadingGroup *grp = NULL;
|
||||
GPUShader *sh = NULL;
|
||||
DRWState state = 0;
|
||||
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
ToolSettings *tsettings = draw_ctx->scene->toolsettings;
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
bool select_vert = pd->edit_mesh.select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0;
|
||||
bool select_face = pd->edit_mesh.select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0;
|
||||
bool select_edge = pd->edit_mesh.select_edge = (tsettings->selectmode & SCE_SELECT_EDGE) != 0;
|
||||
|
||||
bool do_occlude_wire = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
|
||||
bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0 ||
|
||||
pd->edit_mesh.do_zbufclip;
|
||||
|
||||
pd->edit_mesh.ghost_ob = 0;
|
||||
pd->edit_mesh.edit_ob = 0;
|
||||
pd->edit_mesh.do_faces = true;
|
||||
pd->edit_mesh.do_edges = true;
|
||||
|
||||
int *mask = shdata->data_mask;
|
||||
mask[0] = 0xFF; /* Face Flag */
|
||||
mask[1] = 0xFF; /* Edge Flag */
|
||||
|
||||
const int flag = pd->edit_mesh.flag = v3d->overlay.edit_flag;
|
||||
|
||||
SET_FLAG_FROM_TEST(mask[0], flag & V3D_OVERLAY_EDIT_FACES, VFLAG_FACE_SELECTED);
|
||||
SET_FLAG_FROM_TEST(mask[0], flag & V3D_OVERLAY_EDIT_FREESTYLE_FACE, VFLAG_FACE_FREESTYLE);
|
||||
SET_FLAG_FROM_TEST(mask[1], flag & V3D_OVERLAY_EDIT_FREESTYLE_EDGE, VFLAG_EDGE_FREESTYLE);
|
||||
SET_FLAG_FROM_TEST(mask[1], flag & V3D_OVERLAY_EDIT_SEAMS, VFLAG_EDGE_SEAM);
|
||||
SET_FLAG_FROM_TEST(mask[1], flag & V3D_OVERLAY_EDIT_SHARP, VFLAG_EDGE_SHARP);
|
||||
SET_FLAG_FROM_TEST(mask[2], flag & V3D_OVERLAY_EDIT_CREASES, 0xFF);
|
||||
SET_FLAG_FROM_TEST(mask[3], flag & V3D_OVERLAY_EDIT_BWEIGHTS, 0xFF);
|
||||
|
||||
if ((flag & V3D_OVERLAY_EDIT_FACES) == 0) {
|
||||
pd->edit_mesh.do_faces = false;
|
||||
pd->edit_mesh.do_zbufclip = false;
|
||||
}
|
||||
if ((flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
|
||||
if ((tsettings->selectmode & SCE_SELECT_EDGE) == 0) {
|
||||
if ((v3d->shading.type < OB_SOLID) || (v3d->shading.flag & V3D_SHADING_XRAY)) {
|
||||
/* Special case, when drawing wire, draw edges, see: T67637. */
|
||||
}
|
||||
else {
|
||||
pd->edit_mesh.do_edges = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float backwire_opacity = (pd->edit_mesh.do_zbufclip) ? v3d->overlay.backwire_opacity : 1.0f;
|
||||
float face_alpha = (do_occlude_wire || !pd->edit_mesh.do_faces) ? 0.0f : 1.0f;
|
||||
GPUTexture **depth_tex = (pd->edit_mesh.do_zbufclip) ? &dtxl->depth : &txl->dummy_depth_tx;
|
||||
|
||||
if (select_face && !pd->edit_mesh.do_faces && pd->edit_mesh.do_edges) {
|
||||
/* Force display of face centers in this case because that's
|
||||
* the only way to see if a face is selected. */
|
||||
show_face_dots = true;
|
||||
}
|
||||
|
||||
{
|
||||
/* TODO(fclem) Shouldn't this be going into the paint overlay? */
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->edit_mesh_weight_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_paint_weight();
|
||||
pd->edit_mesh_weight_grp = grp = DRW_shgroup_create(sh, psl->edit_mesh_weight_ps);
|
||||
DRW_shgroup_uniform_float_copy(grp, "opacity", 1.0);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "drawContours", false);
|
||||
DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
/* Run Twice for in-front passes. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
/* Complementary Depth Pass */
|
||||
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
|
||||
DRW_PASS_CREATE(psl->edit_mesh_depth_ps[i], state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_depth_only();
|
||||
pd->edit_mesh_depth_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_depth_ps[i]);
|
||||
}
|
||||
{
|
||||
/* Normals */
|
||||
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
(pd->edit_mesh.do_zbufclip ? DRW_STATE_BLEND_ALPHA : 0);
|
||||
DRW_PASS_CREATE(psl->edit_mesh_normals_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_mesh_normal();
|
||||
pd->edit_mesh_normals_grp = grp = DRW_shgroup_create(sh, psl->edit_mesh_normals_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "normalSize", v3d->overlay.normals_length);
|
||||
DRW_shgroup_uniform_float_copy(grp, "alpha", backwire_opacity);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
|
||||
}
|
||||
{
|
||||
/* Mesh Analysis Pass */
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->edit_mesh_analysis_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_mesh_analysis();
|
||||
pd->edit_mesh_analysis_grp = grp = DRW_shgroup_create(sh, psl->edit_mesh_analysis_ps);
|
||||
DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
|
||||
}
|
||||
/* Run Twice for in-front passes. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
GPUShader *edge_sh = OVERLAY_shader_edit_mesh_edge(!select_vert);
|
||||
GPUShader *face_sh = OVERLAY_shader_edit_mesh_face();
|
||||
const bool do_zbufclip = (i == 0 && pd->edit_mesh.do_zbufclip);
|
||||
DRWState state_common = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
DRW_STATE_BLEND_ALPHA;
|
||||
/* Faces */
|
||||
/* Cage geom needs to be offsetted to avoid Z-fighting. */
|
||||
for (int j = 0; j < 2; j++) {
|
||||
DRWPass **edit_face_ps = (j == 0) ? &psl->edit_mesh_faces_ps[i] :
|
||||
&psl->edit_mesh_faces_cage_ps[i];
|
||||
DRWShadingGroup **shgrp = (j == 0) ? &pd->edit_mesh_faces_grp[i] :
|
||||
&pd->edit_mesh_faces_cage_grp[i];
|
||||
state = state_common;
|
||||
DRW_PASS_CREATE(*edit_face_ps, state | pd->clipping_state);
|
||||
|
||||
grp = *shgrp = DRW_shgroup_create(face_sh, *edit_face_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_ivec4(grp, "dataMask", mask, 1);
|
||||
DRW_shgroup_uniform_float_copy(grp, "alpha", face_alpha);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "selectFaces", select_face);
|
||||
}
|
||||
|
||||
if (do_zbufclip) {
|
||||
state_common |= DRW_STATE_WRITE_DEPTH;
|
||||
// state_common &= ~DRW_STATE_BLEND_ALPHA;
|
||||
}
|
||||
|
||||
/* Edges */
|
||||
/* Change first vertex convention to match blender loop structure. */
|
||||
state = state_common | DRW_STATE_FIRST_VERTEX_CONVENTION;
|
||||
DRW_PASS_CREATE(psl->edit_mesh_edges_ps[i], state | pd->clipping_state);
|
||||
|
||||
grp = pd->edit_mesh_edges_grp[i] = DRW_shgroup_create(edge_sh, psl->edit_mesh_edges_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_ivec4(grp, "dataMask", mask, 1);
|
||||
DRW_shgroup_uniform_float_copy(grp, "alpha", backwire_opacity);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "selectEdges", pd->edit_mesh.do_edges || select_edge);
|
||||
|
||||
/* Verts */
|
||||
DRW_PASS_CREATE(psl->edit_mesh_verts_ps[i], state | pd->clipping_state);
|
||||
|
||||
if (select_vert) {
|
||||
sh = OVERLAY_shader_edit_mesh_vert();
|
||||
grp = pd->edit_mesh_verts_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_verts_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "alpha", backwire_opacity);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
|
||||
|
||||
sh = OVERLAY_shader_edit_mesh_skin_root();
|
||||
grp = pd->edit_mesh_skin_roots_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_verts_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
/* Facedots */
|
||||
if (select_face && show_face_dots) {
|
||||
sh = OVERLAY_shader_edit_mesh_facedot();
|
||||
grp = pd->edit_mesh_facedots_grp[i] = DRW_shgroup_create(sh, psl->edit_mesh_verts_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "alpha", backwire_opacity);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH);
|
||||
}
|
||||
else {
|
||||
pd->edit_mesh_facedots_grp[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob, bool in_front)
|
||||
{
|
||||
struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter, *skin_roots, *circle;
|
||||
DRWShadingGroup *vert_shgrp, *edge_shgrp, *fdot_shgrp, *face_shgrp, *skin_roots_shgrp;
|
||||
|
||||
bool has_edit_mesh_cage = false;
|
||||
bool has_skin_roots = false;
|
||||
/* TODO: Should be its own function. */
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
BMEditMesh *embm = me->edit_mesh;
|
||||
if (embm) {
|
||||
has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
|
||||
has_skin_roots = CustomData_get_offset(&embm->bm->vdata, CD_MVERT_SKIN) != -1;
|
||||
}
|
||||
|
||||
vert_shgrp = pd->edit_mesh_verts_grp[in_front];
|
||||
edge_shgrp = pd->edit_mesh_edges_grp[in_front];
|
||||
fdot_shgrp = pd->edit_mesh_facedots_grp[in_front];
|
||||
face_shgrp = (has_edit_mesh_cage) ? pd->edit_mesh_faces_cage_grp[in_front] :
|
||||
pd->edit_mesh_faces_grp[in_front];
|
||||
skin_roots_shgrp = pd->edit_mesh_skin_roots_grp[in_front];
|
||||
|
||||
geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data);
|
||||
geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data);
|
||||
DRW_shgroup_call_no_cull(edge_shgrp, geom_edges, ob);
|
||||
DRW_shgroup_call_no_cull(face_shgrp, geom_tris, ob);
|
||||
|
||||
if (pd->edit_mesh.select_vert) {
|
||||
geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data);
|
||||
DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob);
|
||||
|
||||
if (has_skin_roots) {
|
||||
circle = DRW_cache_circle_get();
|
||||
skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(ob->data);
|
||||
DRW_shgroup_call_instances_with_attribs(skin_roots_shgrp, ob, circle, skin_roots);
|
||||
}
|
||||
}
|
||||
|
||||
if (fdot_shgrp) {
|
||||
geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
|
||||
DRW_shgroup_call_no_cull(fdot_shgrp, geom_fcenter, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUBatch *geom = NULL;
|
||||
|
||||
bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
bool do_occlude_wire = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_OCCLUDE_WIRE) != 0;
|
||||
bool do_show_weight = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_WEIGHT) != 0;
|
||||
bool do_show_mesh_analysis = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_STATVIS) != 0;
|
||||
bool fnormals_do = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_FACE_NORMALS) != 0;
|
||||
bool vnormals_do = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_VERT_NORMALS) != 0;
|
||||
bool lnormals_do = (pd->edit_mesh.flag & V3D_OVERLAY_EDIT_LOOP_NORMALS) != 0;
|
||||
|
||||
if (do_show_weight) {
|
||||
geom = DRW_cache_mesh_surface_weights_get(ob);
|
||||
DRW_shgroup_call_no_cull(pd->edit_mesh_weight_grp, geom, ob);
|
||||
}
|
||||
else if (do_show_mesh_analysis && !pd->xray_enabled) {
|
||||
geom = DRW_cache_mesh_surface_mesh_analysis_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_no_cull(pd->edit_mesh_analysis_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_occlude_wire || do_in_front) {
|
||||
geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call_no_cull(pd->edit_mesh_depth_grp[do_in_front], geom, ob);
|
||||
}
|
||||
|
||||
if (vnormals_do || lnormals_do || fnormals_do) {
|
||||
struct GPUBatch *normal_geom = DRW_cache_normal_arrow_get();
|
||||
if (vnormals_do) {
|
||||
geom = DRW_mesh_batch_cache_get_edit_vnors(ob->data);
|
||||
DRW_shgroup_call_instances_with_attribs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
|
||||
}
|
||||
if (lnormals_do) {
|
||||
geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data);
|
||||
DRW_shgroup_call_instances_with_attribs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
|
||||
}
|
||||
if (fnormals_do) {
|
||||
geom = DRW_mesh_batch_cache_get_edit_facedots(ob->data);
|
||||
DRW_shgroup_call_instances_with_attribs(pd->edit_mesh_normals_grp, ob, normal_geom, geom);
|
||||
}
|
||||
}
|
||||
|
||||
if (pd->edit_mesh.do_zbufclip) {
|
||||
overlay_edit_mesh_add_ob_to_pass(pd, ob, false);
|
||||
}
|
||||
else {
|
||||
overlay_edit_mesh_add_ob_to_pass(pd, ob, do_in_front);
|
||||
}
|
||||
|
||||
pd->edit_mesh.ghost_ob += (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
|
||||
pd->edit_mesh.edit_ob += 1;
|
||||
|
||||
if (DRW_state_show_text() && (pd->edit_mesh.flag & OVERLAY_EDIT_TEXT)) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
DRW_text_edit_mesh_measure_stats(draw_ctx->ar, draw_ctx->v3d, ob, &draw_ctx->scene->unit);
|
||||
}
|
||||
}
|
||||
|
||||
static void overlay_edit_mesh_draw_components(OVERLAY_PassList *psl,
|
||||
OVERLAY_PrivateData *pd,
|
||||
bool in_front)
|
||||
{
|
||||
DRW_view_set_active(pd->view_edit_faces);
|
||||
DRW_draw_pass(psl->edit_mesh_faces_ps[in_front]);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_faces_cage);
|
||||
DRW_draw_pass(psl->edit_mesh_faces_cage_ps[in_front]);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_edges);
|
||||
DRW_draw_pass(psl->edit_mesh_edges_ps[in_front]);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_verts);
|
||||
DRW_draw_pass(psl->edit_mesh_verts_ps[in_front]);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
|
||||
DRW_draw_pass(psl->edit_mesh_weight_ps);
|
||||
DRW_draw_pass(psl->edit_mesh_analysis_ps);
|
||||
|
||||
DRW_draw_pass(psl->edit_mesh_depth_ps[NOT_IN_FRONT]);
|
||||
|
||||
if (pd->edit_mesh.do_zbufclip) {
|
||||
DRW_draw_pass(psl->edit_mesh_depth_ps[IN_FRONT]);
|
||||
|
||||
/* render facefill */
|
||||
DRW_view_set_active(pd->view_edit_faces);
|
||||
DRW_draw_pass(psl->edit_mesh_faces_ps[NOT_IN_FRONT]);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_faces_cage);
|
||||
DRW_draw_pass(psl->edit_mesh_faces_cage_ps[NOT_IN_FRONT]);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
|
||||
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
|
||||
GPU_framebuffer_clear_depth(fbl->overlay_in_front_fb, 1.0f);
|
||||
DRW_draw_pass(psl->edit_mesh_normals_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_edges);
|
||||
DRW_draw_pass(psl->edit_mesh_edges_ps[NOT_IN_FRONT]);
|
||||
|
||||
DRW_view_set_active(pd->view_edit_verts);
|
||||
DRW_draw_pass(psl->edit_mesh_verts_ps[NOT_IN_FRONT]);
|
||||
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
}
|
||||
else {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
|
||||
DRW_draw_pass(psl->edit_mesh_normals_ps);
|
||||
overlay_edit_mesh_draw_components(psl, pd, false);
|
||||
|
||||
if (v3d->shading.type == OB_SOLID && pd->edit_mesh.ghost_ob == 1 &&
|
||||
pd->edit_mesh.edit_ob == 1) {
|
||||
/* In the case of single ghost object edit (common case for retopology):
|
||||
* we clear the depth buffer so that only the depth of the retopo mesh
|
||||
* is occluding the edit cage. */
|
||||
GPU_framebuffer_clear_depth(fbl->overlay_default_fb, 1.0f);
|
||||
}
|
||||
|
||||
DRW_draw_pass(psl->edit_mesh_depth_ps[IN_FRONT]);
|
||||
overlay_edit_mesh_draw_components(psl, pd, true);
|
||||
}
|
||||
}
|
201
source/blender/draw/engines/overlay/overlay_edit_text.c
Normal file
201
source/blender/draw/engines/overlay/overlay_edit_text.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BKE_font.h"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
DRWShadingGroup *grp;
|
||||
GPUShader *sh;
|
||||
DRWState state;
|
||||
|
||||
pd->edit_curve.show_handles = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) != 0;
|
||||
pd->shdata.edit_curve_normal_length = v3d->overlay.normals_length;
|
||||
|
||||
/* Run Twice for in-front passes. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH;
|
||||
state |= ((i == 0) ? DRW_STATE_DEPTH_LESS_EQUAL : DRW_STATE_DEPTH_ALWAYS);
|
||||
DRW_PASS_CREATE(psl->edit_text_wire_ps[i], state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_uniform_color();
|
||||
pd->edit_text_wire_grp[i] = grp = DRW_shgroup_create(sh, psl->edit_text_wire_ps[i]);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.colorWire);
|
||||
}
|
||||
{
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_LOGIC_INVERT;
|
||||
DRW_PASS_CREATE(psl->edit_text_overlay_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_uniform_color();
|
||||
pd->edit_text_overlay_grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps);
|
||||
}
|
||||
}
|
||||
|
||||
/* Use 2D quad corners to create a matrix that set
|
||||
* a [-1..1] quad at the right position. */
|
||||
static void v2_quad_corners_to_mat4(float corners[4][2], float r_mat[4][4])
|
||||
{
|
||||
unit_m4(r_mat);
|
||||
sub_v2_v2v2(r_mat[0], corners[1], corners[0]);
|
||||
sub_v2_v2v2(r_mat[1], corners[3], corners[0]);
|
||||
mul_v2_fl(r_mat[0], 0.5f);
|
||||
mul_v2_fl(r_mat[1], 0.5f);
|
||||
copy_v2_v2(r_mat[3], corners[0]);
|
||||
add_v2_v2(r_mat[3], r_mat[0]);
|
||||
add_v2_v2(r_mat[3], r_mat[1]);
|
||||
}
|
||||
|
||||
static void edit_text_cache_populate_select(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const Curve *cu = ob->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
float final_mat[4][4], box[4][2];
|
||||
struct GPUBatch *geom = DRW_cache_quad_get();
|
||||
|
||||
for (int i = 0; i < ef->selboxes_len; i++) {
|
||||
EditFontSelBox *sb = &ef->selboxes[i];
|
||||
|
||||
float selboxw;
|
||||
if (i + 1 != ef->selboxes_len) {
|
||||
if (ef->selboxes[i + 1].y == sb->y) {
|
||||
selboxw = ef->selboxes[i + 1].x - sb->x;
|
||||
}
|
||||
else {
|
||||
selboxw = sb->w;
|
||||
}
|
||||
}
|
||||
else {
|
||||
selboxw = sb->w;
|
||||
}
|
||||
/* NOTE: v2_quad_corners_to_mat4 don't need the 3rd corner. */
|
||||
if (sb->rot == 0.0f) {
|
||||
copy_v2_fl2(box[0], sb->x, sb->y);
|
||||
copy_v2_fl2(box[1], sb->x + selboxw, sb->y);
|
||||
copy_v2_fl2(box[3], sb->x, sb->y + sb->h);
|
||||
}
|
||||
else {
|
||||
float mat[2][2];
|
||||
angle_to_mat2(mat, sb->rot);
|
||||
copy_v2_fl2(box[0], sb->x, sb->y);
|
||||
mul_v2_v2fl(box[1], mat[0], selboxw);
|
||||
add_v2_v2(box[1], &sb->x);
|
||||
mul_v2_v2fl(box[3], mat[1], sb->h);
|
||||
add_v2_v2(box[3], &sb->x);
|
||||
}
|
||||
v2_quad_corners_to_mat4(box, final_mat);
|
||||
mul_m4_m4m4(final_mat, ob->obmat, final_mat);
|
||||
|
||||
DRW_shgroup_call_obmat(pd->edit_text_overlay_grp, geom, final_mat);
|
||||
}
|
||||
}
|
||||
|
||||
static void edit_text_cache_populate_cursor(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const Curve *cu = ob->data;
|
||||
EditFont *edit_font = cu->editfont;
|
||||
float(*cursor)[2] = edit_font->textcurs;
|
||||
float mat[4][4];
|
||||
|
||||
v2_quad_corners_to_mat4(cursor, mat);
|
||||
mul_m4_m4m4(mat, ob->obmat, mat);
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_quad_get();
|
||||
DRW_shgroup_call_obmat(pd->edit_text_overlay_grp, geom, mat);
|
||||
}
|
||||
|
||||
static void edit_text_cache_populate_boxes(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||
const Curve *cu = ob->data;
|
||||
|
||||
for (int i = 0; i < cu->totbox; i++) {
|
||||
TextBox *tb = &cu->tb[i];
|
||||
const bool is_active = (i == (cu->actbox - 1));
|
||||
float *color = is_active ? G_draw.block.colorActive : G_draw.block.colorWire;
|
||||
|
||||
if ((tb->w != 0.0f) || (tb->h != 0.0f)) {
|
||||
float vecs[4][3];
|
||||
vecs[0][0] = vecs[1][0] = vecs[2][0] = vecs[3][0] = cu->xof + tb->x;
|
||||
vecs[0][1] = vecs[1][1] = vecs[2][1] = vecs[3][1] = cu->yof + tb->y + cu->fsize_realtime;
|
||||
vecs[0][2] = vecs[1][2] = vecs[2][2] = vecs[3][2] = 0.001;
|
||||
|
||||
vecs[1][0] += tb->w;
|
||||
vecs[2][0] += tb->w;
|
||||
vecs[2][1] -= tb->h;
|
||||
vecs[3][1] -= tb->h;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
mul_v3_m4v3(vecs[j], ob->obmat, vecs[j]);
|
||||
}
|
||||
for (int j = 0; j < 4; j++) {
|
||||
OVERLAY_extra_line_dashed(cb, vecs[j], vecs[(j + 1) % 4], color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_text_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
Curve *cu = ob->data;
|
||||
struct GPUBatch *geom;
|
||||
bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
|
||||
bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f || cu->ext2 != 0.0f;
|
||||
if ((cu->flag & CU_FAST) || !has_surface) {
|
||||
geom = DRW_cache_text_edge_wire_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call(pd->edit_text_wire_grp[do_in_front], geom, ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* object mode draws */
|
||||
}
|
||||
|
||||
edit_text_cache_populate_select(vedata, ob);
|
||||
edit_text_cache_populate_cursor(vedata, ob);
|
||||
edit_text_cache_populate_boxes(vedata, ob);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_text_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_view_set_active(NULL);
|
||||
|
||||
DRW_draw_pass(psl->edit_text_wire_ps[0]);
|
||||
DRW_draw_pass(psl->edit_text_wire_ps[1]);
|
||||
|
||||
DRW_draw_pass(psl->edit_text_overlay_ps);
|
||||
}
|
491
source/blender/draw/engines/overlay/overlay_engine.c
Normal file
491
source/blender/draw/engines/overlay/overlay_engine.c
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*
|
||||
* Engine for drawing a selection map where the pixels indicate the selection indices.
|
||||
*/
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "overlay_engine.h"
|
||||
#include "overlay_private.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Engine Callbacks
|
||||
* \{ */
|
||||
|
||||
static void OVERLAY_engine_init(void *vedata)
|
||||
{
|
||||
OVERLAY_Data *data = vedata;
|
||||
OVERLAY_StorageList *stl = data->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
const View3D *v3d = draw_ctx->v3d;
|
||||
|
||||
if (!stl->pd) {
|
||||
/* Alloc transient pointers */
|
||||
stl->pd = MEM_callocN(sizeof(*stl->pd), __func__);
|
||||
}
|
||||
|
||||
OVERLAY_PrivateData *pd = stl->pd;
|
||||
View3DOverlay overlay;
|
||||
short v3d_flag, v3d_gridflag;
|
||||
|
||||
pd->hide_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) != 0;
|
||||
pd->ctx_mode = CTX_data_mode_enum_ex(
|
||||
draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
|
||||
|
||||
if (!pd->hide_overlays) {
|
||||
overlay = v3d->overlay;
|
||||
v3d_flag = v3d->flag;
|
||||
v3d_gridflag = v3d->gridflag;
|
||||
}
|
||||
else {
|
||||
memset(&overlay, 0, sizeof(overlay));
|
||||
v3d_flag = 0;
|
||||
v3d_gridflag = 0;
|
||||
overlay.flag = V3D_OVERLAY_HIDE_TEXT | V3D_OVERLAY_HIDE_MOTION_PATHS | V3D_OVERLAY_HIDE_BONES |
|
||||
V3D_OVERLAY_HIDE_OBJECT_XTRAS | V3D_OVERLAY_HIDE_OBJECT_ORIGINS;
|
||||
}
|
||||
|
||||
if (v3d->shading.type == OB_WIRE) {
|
||||
overlay.flag |= V3D_OVERLAY_WIREFRAMES;
|
||||
}
|
||||
|
||||
/* Check if anything changed, and if so, reset AA. */
|
||||
if (v3d_flag != pd->v3d_flag || pd->v3d_gridflag != v3d_gridflag ||
|
||||
memcmp(&pd->overlay, &overlay, sizeof(overlay))) {
|
||||
pd->overlay = overlay;
|
||||
pd->v3d_flag = v3d_flag;
|
||||
pd->v3d_gridflag = v3d_gridflag;
|
||||
OVERLAY_antialiasing_reset(vedata);
|
||||
}
|
||||
|
||||
pd->wireframe_mode = (v3d->shading.type == OB_WIRE);
|
||||
pd->clipping_state = (rv3d->rflag & RV3D_CLIPPING) ? DRW_STATE_CLIP_PLANES : 0;
|
||||
pd->xray_enabled = XRAY_ACTIVE(v3d);
|
||||
pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
|
||||
pd->clear_in_front = (v3d->shading.type != OB_SOLID);
|
||||
|
||||
OVERLAY_antialiasing_init(vedata);
|
||||
|
||||
switch (stl->pd->ctx_mode) {
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
OVERLAY_edit_mesh_init(vedata);
|
||||
break;
|
||||
default:
|
||||
/* Nothing to do. */
|
||||
break;
|
||||
}
|
||||
OVERLAY_facing_init(vedata);
|
||||
OVERLAY_grid_init(vedata);
|
||||
OVERLAY_image_init(vedata);
|
||||
OVERLAY_outline_init(vedata);
|
||||
OVERLAY_wireframe_init(vedata);
|
||||
}
|
||||
|
||||
static void OVERLAY_cache_init(void *vedata)
|
||||
{
|
||||
OVERLAY_Data *data = vedata;
|
||||
OVERLAY_StorageList *stl = data->stl;
|
||||
OVERLAY_PrivateData *pd = stl->pd;
|
||||
|
||||
switch (pd->ctx_mode) {
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
OVERLAY_edit_mesh_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_EDIT_SURFACE:
|
||||
case CTX_MODE_EDIT_CURVE:
|
||||
OVERLAY_edit_curve_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_EDIT_TEXT:
|
||||
OVERLAY_edit_text_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_EDIT_ARMATURE:
|
||||
break;
|
||||
case CTX_MODE_EDIT_METABALL:
|
||||
break;
|
||||
case CTX_MODE_EDIT_LATTICE:
|
||||
OVERLAY_edit_lattice_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_PARTICLE:
|
||||
OVERLAY_edit_particle_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_POSE:
|
||||
case CTX_MODE_PAINT_WEIGHT:
|
||||
case CTX_MODE_PAINT_VERTEX:
|
||||
case CTX_MODE_PAINT_TEXTURE:
|
||||
OVERLAY_paint_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_SCULPT:
|
||||
OVERLAY_sculpt_cache_init(vedata);
|
||||
break;
|
||||
case CTX_MODE_OBJECT:
|
||||
case CTX_MODE_PAINT_GPENCIL:
|
||||
case CTX_MODE_EDIT_GPENCIL:
|
||||
case CTX_MODE_SCULPT_GPENCIL:
|
||||
case CTX_MODE_WEIGHT_GPENCIL:
|
||||
break;
|
||||
default:
|
||||
BLI_assert(!"Draw mode invalid");
|
||||
break;
|
||||
}
|
||||
OVERLAY_antialiasing_cache_init(vedata);
|
||||
OVERLAY_armature_cache_init(vedata);
|
||||
OVERLAY_extra_cache_init(vedata);
|
||||
OVERLAY_facing_cache_init(vedata);
|
||||
OVERLAY_grid_cache_init(vedata);
|
||||
OVERLAY_image_cache_init(vedata);
|
||||
OVERLAY_metaball_cache_init(vedata);
|
||||
OVERLAY_motion_path_cache_init(vedata);
|
||||
OVERLAY_outline_cache_init(vedata);
|
||||
OVERLAY_particle_cache_init(vedata);
|
||||
OVERLAY_wireframe_cache_init(vedata);
|
||||
}
|
||||
|
||||
BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init)
|
||||
{
|
||||
OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata);
|
||||
*do_init = false;
|
||||
if (!ELEM(ob->type, OB_MESH, OB_SURF, OB_LATTICE, OB_CURVE, OB_FONT)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dupli_data) {
|
||||
if (*dupli_data == NULL) {
|
||||
*dupli_data = MEM_callocN(sizeof(OVERLAY_DupliData), __func__);
|
||||
*do_init = true;
|
||||
}
|
||||
else if ((*dupli_data)->base_flag != ob->base_flag) {
|
||||
/* Select state might have change, reinit. */
|
||||
*do_init = true;
|
||||
}
|
||||
return *dupli_data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void OVERLAY_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_Data *data = vedata;
|
||||
OVERLAY_PrivateData *pd = data->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const bool is_select = DRW_state_is_select();
|
||||
const bool renderable = DRW_object_is_renderable(ob);
|
||||
const bool in_pose_mode = ob->type == OB_ARMATURE && OVERLAY_armature_is_pose_mode(ob, draw_ctx);
|
||||
const bool in_edit_mode = BKE_object_is_in_editmode(ob);
|
||||
const bool in_particle_edit_mode = ob->mode == OB_MODE_PARTICLE_EDIT;
|
||||
const bool in_paint_mode = (ob == draw_ctx->obact) &&
|
||||
(draw_ctx->object_mode & OB_MODE_ALL_PAINT);
|
||||
const bool in_sculpt_mode = (ob == draw_ctx->obact) && (ob->sculpt != NULL);
|
||||
const bool has_surface = ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL, OB_FONT);
|
||||
const bool draw_surface = !((ob->dt < OB_WIRE) || (!renderable && (ob->dt != OB_WIRE)));
|
||||
const bool draw_facing = draw_surface && (pd->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION);
|
||||
const bool draw_bones = (pd->overlay.flag & V3D_OVERLAY_HIDE_BONES) == 0;
|
||||
const bool draw_wires = draw_surface && has_surface &&
|
||||
(pd->wireframe_mode || !pd->hide_overlays);
|
||||
const bool draw_outlines = !in_edit_mode && !in_paint_mode && renderable &&
|
||||
(pd->v3d_flag & V3D_SELECT_OUTLINE) &&
|
||||
((ob->base_flag & BASE_SELECTED) ||
|
||||
(is_select && ob->type == OB_LIGHTPROBE));
|
||||
const bool draw_bone_selection = (ob->type == OB_MESH) && pd->armature.do_pose_fade_geom &&
|
||||
!is_select;
|
||||
const bool draw_extras =
|
||||
((pd->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) == 0) ||
|
||||
/* Show if this is the camera we're looking through since it's useful for selecting. */
|
||||
((draw_ctx->rv3d->persp == RV3D_CAMOB) && ((ID *)draw_ctx->v3d->camera == ob->id.orig_id));
|
||||
|
||||
const bool draw_motion_paths = (pd->overlay.flag & V3D_OVERLAY_HIDE_MOTION_PATHS) == 0;
|
||||
|
||||
bool do_init;
|
||||
OVERLAY_DupliData *dupli = OVERLAY_duplidata_get(ob, vedata, &do_init);
|
||||
|
||||
if (draw_facing) {
|
||||
OVERLAY_facing_cache_populate(vedata, ob);
|
||||
}
|
||||
if (draw_wires) {
|
||||
OVERLAY_wireframe_cache_populate(vedata, ob, dupli, do_init);
|
||||
}
|
||||
if (draw_outlines) {
|
||||
OVERLAY_outline_cache_populate(vedata, ob, dupli, do_init);
|
||||
}
|
||||
if (draw_bone_selection) {
|
||||
OVERLAY_pose_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
if (in_edit_mode) {
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
OVERLAY_edit_mesh_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
if (draw_bones) {
|
||||
OVERLAY_edit_armature_cache_populate(vedata, ob);
|
||||
}
|
||||
break;
|
||||
case OB_CURVE:
|
||||
OVERLAY_edit_curve_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_SURF:
|
||||
OVERLAY_edit_surf_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
OVERLAY_edit_lattice_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_MBALL:
|
||||
OVERLAY_edit_metaball_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_FONT:
|
||||
OVERLAY_edit_text_cache_populate(vedata, ob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (in_pose_mode && draw_bones) {
|
||||
OVERLAY_pose_armature_cache_populate(vedata, ob);
|
||||
}
|
||||
else if (in_paint_mode) {
|
||||
switch (draw_ctx->object_mode) {
|
||||
case OB_MODE_VERTEX_PAINT:
|
||||
OVERLAY_paint_vertex_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_MODE_WEIGHT_PAINT:
|
||||
OVERLAY_paint_weight_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_MODE_TEXTURE_PAINT:
|
||||
OVERLAY_paint_texture_cache_populate(vedata, ob);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (in_particle_edit_mode) {
|
||||
OVERLAY_edit_particle_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
if (in_sculpt_mode) {
|
||||
OVERLAY_sculpt_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
if (draw_motion_paths) {
|
||||
OVERLAY_motion_path_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
switch (ob->type) {
|
||||
case OB_ARMATURE:
|
||||
if (draw_bones && (is_select || (!in_edit_mode && !in_pose_mode))) {
|
||||
OVERLAY_armature_cache_populate(vedata, ob);
|
||||
}
|
||||
break;
|
||||
case OB_MBALL:
|
||||
if (!in_edit_mode) {
|
||||
OVERLAY_metaball_cache_populate(vedata, ob);
|
||||
}
|
||||
break;
|
||||
case OB_GPENCIL:
|
||||
OVERLAY_gpencil_cache_populate(vedata, ob);
|
||||
break;
|
||||
}
|
||||
/* Non-Meshes */
|
||||
if (draw_extras) {
|
||||
switch (ob->type) {
|
||||
case OB_EMPTY:
|
||||
OVERLAY_empty_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_LAMP:
|
||||
OVERLAY_light_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_CAMERA:
|
||||
OVERLAY_camera_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_SPEAKER:
|
||||
OVERLAY_speaker_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_LIGHTPROBE:
|
||||
OVERLAY_lightprobe_cache_populate(vedata, ob);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
OVERLAY_lattice_cache_populate(vedata, ob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BLI_listbase_is_empty(&ob->particlesystem)) {
|
||||
OVERLAY_particle_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
/* Relationship, object center, bounbox ... */
|
||||
OVERLAY_extra_cache_populate(vedata, ob);
|
||||
|
||||
if (dupli) {
|
||||
dupli->base_flag = ob->base_flag;
|
||||
}
|
||||
}
|
||||
|
||||
static void OVERLAY_cache_finish(void *vedata)
|
||||
{
|
||||
/* TODO(fclem) Only do this when really needed. */
|
||||
{
|
||||
/* HACK we allocate the infront depth here to avoid the overhead when if is not needed. */
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
DRW_texture_ensure_fullscreen_2d(&dtxl->depth_in_front, GPU_DEPTH24_STENCIL8, 0);
|
||||
|
||||
GPU_framebuffer_ensure_config(
|
||||
&dfbl->default_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
GPU_framebuffer_ensure_config(
|
||||
&dfbl->in_front_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth_in_front), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
}
|
||||
|
||||
OVERLAY_antialiasing_cache_finish(vedata);
|
||||
OVERLAY_armature_cache_finish(vedata);
|
||||
OVERLAY_image_cache_finish(vedata);
|
||||
}
|
||||
|
||||
static void OVERLAY_draw_scene(void *vedata)
|
||||
{
|
||||
OVERLAY_Data *data = vedata;
|
||||
OVERLAY_PrivateData *pd = data->stl->pd;
|
||||
OVERLAY_FramebufferList *fbl = data->fbl;
|
||||
|
||||
OVERLAY_antialiasing_start(vedata);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
|
||||
OVERLAY_image_draw(vedata);
|
||||
OVERLAY_facing_draw(vedata);
|
||||
OVERLAY_wireframe_draw(vedata);
|
||||
OVERLAY_armature_draw(vedata);
|
||||
OVERLAY_particle_draw(vedata);
|
||||
OVERLAY_metaball_draw(vedata);
|
||||
OVERLAY_extra_draw(vedata);
|
||||
|
||||
DRW_view_set_active(NULL);
|
||||
|
||||
OVERLAY_grid_draw(vedata);
|
||||
OVERLAY_outline_draw(vedata);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(fbl->overlay_in_front_fb);
|
||||
|
||||
/* If we are not in solid shading mode, we clear the depth. */
|
||||
if (pd->clear_in_front) {
|
||||
/* TODO(fclem) This clear should be done in a global place. */
|
||||
GPU_framebuffer_clear_depth(fbl->overlay_in_front_fb, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
OVERLAY_wireframe_in_front_draw(vedata);
|
||||
OVERLAY_armature_in_front_draw(vedata);
|
||||
OVERLAY_extra_in_front_draw(vedata);
|
||||
OVERLAY_metaball_in_front_draw(vedata);
|
||||
OVERLAY_image_in_front_draw(vedata);
|
||||
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
}
|
||||
|
||||
OVERLAY_motion_path_draw(vedata);
|
||||
OVERLAY_extra_centers_draw(vedata);
|
||||
|
||||
switch (pd->ctx_mode) {
|
||||
case CTX_MODE_EDIT_MESH:
|
||||
OVERLAY_edit_mesh_draw(vedata);
|
||||
break;
|
||||
case CTX_MODE_EDIT_SURFACE:
|
||||
case CTX_MODE_EDIT_CURVE:
|
||||
OVERLAY_edit_curve_draw(vedata);
|
||||
break;
|
||||
case CTX_MODE_EDIT_TEXT:
|
||||
/* Text overlay need final color for color inversion. */
|
||||
OVERLAY_antialiasing_end(vedata);
|
||||
OVERLAY_edit_text_draw(vedata);
|
||||
return; /* WATCH! dont do AA twice. */
|
||||
case CTX_MODE_EDIT_LATTICE:
|
||||
OVERLAY_edit_lattice_draw(vedata);
|
||||
break;
|
||||
case CTX_MODE_POSE:
|
||||
/* Pain overlay needs final color because of multiply blend mode. */
|
||||
OVERLAY_antialiasing_end(vedata);
|
||||
OVERLAY_paint_draw(vedata);
|
||||
OVERLAY_pose_draw(vedata);
|
||||
return; /* WATCH! dont do AA twice. */
|
||||
case CTX_MODE_PAINT_WEIGHT:
|
||||
case CTX_MODE_PAINT_VERTEX:
|
||||
case CTX_MODE_PAINT_TEXTURE:
|
||||
/* Pain overlay need final color because of multiply blend mode. */
|
||||
OVERLAY_antialiasing_end(vedata);
|
||||
OVERLAY_paint_draw(vedata);
|
||||
return; /* WATCH! dont do AA twice. */
|
||||
case CTX_MODE_PARTICLE:
|
||||
OVERLAY_edit_particle_draw(vedata);
|
||||
break;
|
||||
case CTX_MODE_SCULPT:
|
||||
OVERLAY_sculpt_draw(vedata);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
OVERLAY_antialiasing_end(vedata);
|
||||
}
|
||||
|
||||
static void OVERLAY_engine_free(void)
|
||||
{
|
||||
OVERLAY_shader_free();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Engine Type
|
||||
* \{ */
|
||||
|
||||
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
|
||||
|
||||
DrawEngineType draw_engine_overlay_type = {
|
||||
NULL,
|
||||
NULL,
|
||||
N_("Overlay"),
|
||||
&overlay_data_size,
|
||||
&OVERLAY_engine_init,
|
||||
&OVERLAY_engine_free,
|
||||
&OVERLAY_cache_init,
|
||||
&OVERLAY_cache_populate,
|
||||
&OVERLAY_cache_finish,
|
||||
NULL,
|
||||
&OVERLAY_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
#undef SELECT_ENGINE
|
@@ -12,24 +12,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#ifndef __EDIT_MESH_MODE_INTERN_H__
|
||||
#define __EDIT_MESH_MODE_INTERN_H__
|
||||
#ifndef __OVERLAY_ENGINE_H__
|
||||
#define __OVERLAY_ENGINE_H__
|
||||
|
||||
struct ARegion;
|
||||
struct Object;
|
||||
struct UnitSettings;
|
||||
struct View3D;
|
||||
extern DrawEngineType draw_engine_overlay_type;
|
||||
|
||||
/* edit_mesh_mode_text.c */
|
||||
void DRW_edit_mesh_mode_text_measure_stats(struct ARegion *ar,
|
||||
struct View3D *v3d,
|
||||
struct Object *ob,
|
||||
const UnitSettings *unit);
|
||||
|
||||
#endif /* __EDIT_MESH_MODE_INTERN_H__ */
|
||||
#endif /* __OVERLAY_ENGINE_H__ */
|
1586
source/blender/draw/engines/overlay/overlay_extra.c
Normal file
1586
source/blender/draw/engines/overlay/overlay_extra.c
Normal file
File diff suppressed because it is too large
Load Diff
64
source/blender/draw/engines/overlay/overlay_facing.c
Normal file
64
source/blender/draw/engines/overlay/overlay_facing.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_facing_init(OVERLAY_Data *UNUSED(vedata))
|
||||
{
|
||||
}
|
||||
|
||||
void OVERLAY_facing_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->facing_ps, state | pd->clipping_state);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_facing();
|
||||
pd->facing_grp = DRW_shgroup_create(sh, psl->facing_ps);
|
||||
}
|
||||
|
||||
void OVERLAY_facing_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call(pd->facing_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_facing_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
/* We need to match underlying geometry pass, at the cost of bypassing TAA. */
|
||||
DRW_view_set_active(NULL);
|
||||
|
||||
DRW_draw_pass(psl->facing_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
}
|
220
source/blender/draw/engines/overlay/overlay_grid.c
Normal file
220
source/blender/draw/engines/overlay/overlay_grid.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
enum {
|
||||
SHOW_AXIS_X = (1 << 0),
|
||||
SHOW_AXIS_Y = (1 << 1),
|
||||
SHOW_AXIS_Z = (1 << 2),
|
||||
SHOW_GRID = (1 << 3),
|
||||
PLANE_XY = (1 << 4),
|
||||
PLANE_XZ = (1 << 5),
|
||||
PLANE_YZ = (1 << 6),
|
||||
CLIP_ZPOS = (1 << 7),
|
||||
CLIP_ZNEG = (1 << 8),
|
||||
GRID_BACK = (1 << 9),
|
||||
};
|
||||
|
||||
void OVERLAY_grid_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_ShadingData *shd = &pd->shdata;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
Scene *scene = draw_ctx->scene;
|
||||
RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
|
||||
const bool show_axis_x = (pd->v3d_gridflag & V3D_SHOW_X) != 0;
|
||||
const bool show_axis_y = (pd->v3d_gridflag & V3D_SHOW_Y) != 0;
|
||||
const bool show_axis_z = (pd->v3d_gridflag & V3D_SHOW_Z) != 0;
|
||||
const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0;
|
||||
const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
|
||||
|
||||
shd->grid_flag = 0;
|
||||
|
||||
if (pd->hide_overlays || !(show_axis_y || show_axis_z || show_floor || show_ortho_grid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float viewinv[4][4], wininv[4][4];
|
||||
float viewmat[4][4], winmat[4][4];
|
||||
DRW_view_winmat_get(NULL, winmat, false);
|
||||
DRW_view_winmat_get(NULL, wininv, true);
|
||||
DRW_view_viewmat_get(NULL, viewmat, false);
|
||||
DRW_view_viewmat_get(NULL, viewinv, true);
|
||||
|
||||
/* if perps */
|
||||
if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
|
||||
if (show_axis_x) {
|
||||
shd->grid_flag |= PLANE_XY | SHOW_AXIS_X;
|
||||
}
|
||||
if (show_axis_y) {
|
||||
shd->grid_flag |= PLANE_XY | SHOW_AXIS_Y;
|
||||
}
|
||||
if (show_floor) {
|
||||
shd->grid_flag |= PLANE_XY | SHOW_GRID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
|
||||
shd->grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
|
||||
}
|
||||
else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
|
||||
shd->grid_flag = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK;
|
||||
}
|
||||
else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
|
||||
shd->grid_flag = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
shd->grid_axes[0] = (float)((shd->grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
|
||||
shd->grid_axes[1] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
|
||||
shd->grid_axes[2] = (float)((shd->grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
|
||||
|
||||
/* Z axis if needed */
|
||||
if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
|
||||
shd->zpos_flag = SHOW_AXIS_Z;
|
||||
|
||||
float zvec[3], campos[3];
|
||||
negate_v3_v3(zvec, viewinv[2]);
|
||||
copy_v3_v3(campos, viewinv[3]);
|
||||
|
||||
/* z axis : chose the most facing plane */
|
||||
if (fabsf(zvec[0]) < fabsf(zvec[1])) {
|
||||
shd->zpos_flag |= PLANE_XZ;
|
||||
}
|
||||
else {
|
||||
shd->zpos_flag |= PLANE_YZ;
|
||||
}
|
||||
|
||||
shd->zneg_flag = shd->zpos_flag;
|
||||
|
||||
/* Persp : If camera is below floor plane, we switch clipping
|
||||
* Ortho : If eye vector is looking up, we switch clipping */
|
||||
if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
|
||||
((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
|
||||
shd->zpos_flag |= CLIP_ZPOS;
|
||||
shd->zneg_flag |= CLIP_ZNEG;
|
||||
}
|
||||
else {
|
||||
shd->zpos_flag |= CLIP_ZNEG;
|
||||
shd->zneg_flag |= CLIP_ZPOS;
|
||||
}
|
||||
|
||||
shd->zplane_axes[0] = (float)((shd->zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
|
||||
shd->zplane_axes[1] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
|
||||
shd->zplane_axes[2] = (float)((shd->zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
|
||||
}
|
||||
else {
|
||||
shd->zneg_flag = shd->zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
|
||||
}
|
||||
|
||||
float dist;
|
||||
if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) {
|
||||
Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
|
||||
dist = ((Camera *)(camera_object->data))->clip_end;
|
||||
}
|
||||
else {
|
||||
dist = v3d->clip_end;
|
||||
}
|
||||
|
||||
if (winmat[3][3] == 0.0f) {
|
||||
shd->grid_mesh_size = dist;
|
||||
}
|
||||
else {
|
||||
float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
|
||||
shd->grid_mesh_size = viewdist * dist;
|
||||
}
|
||||
|
||||
shd->grid_distance = dist / 2.0f;
|
||||
shd->grid_line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
|
||||
|
||||
ED_view3d_grid_steps(scene, v3d, rv3d, shd->grid_steps);
|
||||
}
|
||||
|
||||
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_ShadingData *shd = &vedata->stl->pd->shdata;
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
psl->grid_ps = NULL;
|
||||
|
||||
if (shd->grid_flag == 0 || !DRW_state_is_fbo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->grid_ps, state);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_grid();
|
||||
struct GPUBatch *geom = DRW_cache_grid_get();
|
||||
|
||||
/* Create 3 quads to render ordered transparency Z axis */
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps);
|
||||
DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zneg_flag, 1);
|
||||
DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1);
|
||||
DRW_shgroup_uniform_float(grp, "gridDistance", &shd->grid_distance, 1);
|
||||
DRW_shgroup_uniform_float_copy(grp, "lineKernel", shd->grid_line_size);
|
||||
DRW_shgroup_uniform_float_copy(grp, "meshSize", shd->grid_mesh_size);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_call(grp, geom, NULL);
|
||||
|
||||
grp = DRW_shgroup_create(sh, psl->grid_ps);
|
||||
DRW_shgroup_uniform_int(grp, "gridFlag", &shd->grid_flag, 1);
|
||||
DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->grid_axes, 1);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_uniform_float(grp, "gridSteps", shd->grid_steps, ARRAY_SIZE(shd->grid_steps));
|
||||
DRW_shgroup_call(grp, geom, NULL);
|
||||
|
||||
grp = DRW_shgroup_create(sh, psl->grid_ps);
|
||||
DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zpos_flag, 1);
|
||||
DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_call(grp, geom, NULL);
|
||||
}
|
||||
|
||||
void OVERLAY_grid_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
|
||||
if (psl->grid_ps) {
|
||||
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
|
||||
DRW_draw_pass(psl->grid_ps);
|
||||
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
}
|
||||
}
|
470
source/blender/draw/engines/overlay/overlay_image.c
Normal file
470
source/blender/draw/engines/overlay/overlay_image.c
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_image_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
pd->view_reference_images = DRW_view_create_with_zoffset(
|
||||
pd->view_default, draw_ctx->rv3d, -1.0f);
|
||||
}
|
||||
|
||||
void OVERLAY_image_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DRWState state;
|
||||
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL;
|
||||
DRW_PASS_CREATE(psl->image_background_under_ps, state);
|
||||
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->image_background_over_ps, state);
|
||||
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
|
||||
DRW_PASS_CREATE(psl->image_empties_ps, state | pd->clipping_state);
|
||||
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->image_empties_back_ps, state | pd->clipping_state);
|
||||
DRW_PASS_CREATE(psl->image_empties_blend_ps, state | pd->clipping_state);
|
||||
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->image_empties_front_ps, state);
|
||||
DRW_PASS_CREATE(psl->image_foreground_ps, state);
|
||||
}
|
||||
|
||||
static void overlay_image_calc_aspect(Image *ima, const int size[2], float r_image_aspect[2])
|
||||
{
|
||||
float ima_x, ima_y;
|
||||
if (ima) {
|
||||
ima_x = size[0];
|
||||
ima_y = size[1];
|
||||
}
|
||||
else {
|
||||
/* if no image, make it a 1x1 empty square, honor scale & offset */
|
||||
ima_x = ima_y = 1.0f;
|
||||
}
|
||||
/* Get the image aspect even if the buffer is invalid */
|
||||
float sca_x = 1.0f, sca_y = 1.0f;
|
||||
if (ima) {
|
||||
if (ima->aspx > ima->aspy) {
|
||||
sca_y = ima->aspy / ima->aspx;
|
||||
}
|
||||
else if (ima->aspx < ima->aspy) {
|
||||
sca_x = ima->aspx / ima->aspy;
|
||||
}
|
||||
}
|
||||
|
||||
const float scale_x_inv = ima_x * sca_x;
|
||||
const float scale_y_inv = ima_y * sca_y;
|
||||
if (scale_x_inv > scale_y_inv) {
|
||||
r_image_aspect[0] = 1.0f;
|
||||
r_image_aspect[1] = scale_y_inv / scale_x_inv;
|
||||
}
|
||||
else {
|
||||
r_image_aspect[0] = scale_x_inv / scale_y_inv;
|
||||
r_image_aspect[1] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void camera_background_images_stereo_setup(Scene *scene,
|
||||
View3D *v3d,
|
||||
Image *ima,
|
||||
ImageUser *iuser)
|
||||
{
|
||||
if (BKE_image_is_stereo(ima)) {
|
||||
iuser->flag |= IMA_SHOW_STEREO;
|
||||
|
||||
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
|
||||
iuser->multiview_eye = STEREO_LEFT_ID;
|
||||
}
|
||||
else if (v3d->stereo3d_camera != STEREO_3D_ID) {
|
||||
/* show only left or right camera */
|
||||
iuser->multiview_eye = v3d->stereo3d_camera;
|
||||
}
|
||||
|
||||
BKE_image_multiview_index(ima, iuser);
|
||||
}
|
||||
else {
|
||||
iuser->flag &= ~IMA_SHOW_STEREO;
|
||||
}
|
||||
}
|
||||
|
||||
static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgpic,
|
||||
const DRWContextState *draw_ctx,
|
||||
OVERLAY_PrivateData *pd,
|
||||
float *r_aspect,
|
||||
bool *r_use_alpha_premult)
|
||||
{
|
||||
Image *image = bgpic->ima;
|
||||
ImageUser *iuser = &bgpic->iuser;
|
||||
MovieClip *clip = NULL;
|
||||
GPUTexture *tex = NULL;
|
||||
Scene *scene = draw_ctx->scene;
|
||||
float aspect_x, aspect_y;
|
||||
int width, height;
|
||||
int ctime = (int)DEG_get_ctime(draw_ctx->depsgraph);
|
||||
*r_use_alpha_premult = false;
|
||||
|
||||
switch (bgpic->source) {
|
||||
case CAM_BGIMG_SOURCE_IMAGE:
|
||||
if (image == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
*r_use_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
|
||||
|
||||
BKE_image_user_frame_calc(image, iuser, ctime);
|
||||
if (image->source == IMA_SRC_SEQUENCE && !(iuser->flag & IMA_USER_FRAME_IN_RANGE)) {
|
||||
/* Frame is out of range, dont show. */
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
|
||||
}
|
||||
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, NULL);
|
||||
if (ibuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = GPU_texture_from_blender(image, iuser, GL_TEXTURE_2D);
|
||||
if (tex == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aspect_x = bgpic->ima->aspx;
|
||||
aspect_y = bgpic->ima->aspy;
|
||||
|
||||
width = ibuf->x;
|
||||
height = ibuf->y;
|
||||
|
||||
BKE_image_release_ibuf(image, ibuf, NULL);
|
||||
break;
|
||||
|
||||
case CAM_BGIMG_SOURCE_MOVIE:
|
||||
if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) {
|
||||
if (scene->camera) {
|
||||
clip = BKE_object_movieclip_get(scene, scene->camera, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
clip = bgpic->clip;
|
||||
}
|
||||
|
||||
if (clip == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
|
||||
tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D);
|
||||
if (tex == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aspect_x = clip->aspx;
|
||||
aspect_y = clip->aspy;
|
||||
|
||||
BKE_movieclip_get_size(clip, &bgpic->cuser, &width, &height);
|
||||
|
||||
/* Save for freeing. */
|
||||
BLI_addtail(&pd->bg_movie_clips, BLI_genericNodeN(clip));
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unsupported type. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*r_aspect = (width * aspect_x) / (height * aspect_y);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
|
||||
{
|
||||
/* Free Movie clip textures after rendering */
|
||||
LinkData *link;
|
||||
while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
|
||||
MovieClip *clip = (MovieClip *)link->data;
|
||||
GPU_free_texture_movieclip(clip);
|
||||
MEM_freeN(link);
|
||||
}
|
||||
}
|
||||
|
||||
static void image_camera_background_matrix_get(const Camera *cam,
|
||||
const CameraBGImage *bgpic,
|
||||
const DRWContextState *draw_ctx,
|
||||
const float image_aspect,
|
||||
float rmat[4][4])
|
||||
{
|
||||
float rotate[4][4], scale[4][4], translate[4][4];
|
||||
|
||||
axis_angle_to_mat4_single(rotate, 'Z', -bgpic->rotation);
|
||||
unit_m4(scale);
|
||||
unit_m4(translate);
|
||||
|
||||
/* Normalized Object space camera frame corners. */
|
||||
float cam_corners[4][3];
|
||||
BKE_camera_view_frame(draw_ctx->scene, cam, cam_corners);
|
||||
float cam_width = fabsf(cam_corners[0][0] - cam_corners[3][0]);
|
||||
float cam_height = fabsf(cam_corners[0][1] - cam_corners[1][1]);
|
||||
float cam_aspect = cam_width / cam_height;
|
||||
|
||||
if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) {
|
||||
/* Crop. */
|
||||
if (image_aspect > cam_aspect) {
|
||||
scale[0][0] *= cam_height * image_aspect;
|
||||
scale[1][1] *= cam_height;
|
||||
}
|
||||
else {
|
||||
scale[0][0] *= cam_width;
|
||||
scale[1][1] *= cam_width / image_aspect;
|
||||
}
|
||||
}
|
||||
else if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) {
|
||||
/* Fit. */
|
||||
if (image_aspect > cam_aspect) {
|
||||
scale[0][0] *= cam_width;
|
||||
scale[1][1] *= cam_width / image_aspect;
|
||||
}
|
||||
else {
|
||||
scale[0][0] *= cam_height * image_aspect;
|
||||
scale[1][1] *= cam_height;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Stretch. */
|
||||
scale[0][0] *= cam_width;
|
||||
scale[1][1] *= cam_height;
|
||||
}
|
||||
|
||||
translate[3][0] = bgpic->offset[0];
|
||||
translate[3][1] = bgpic->offset[1];
|
||||
translate[3][2] = cam_corners[0][2];
|
||||
/* These lines are for keeping 2.80 behavior and could be removed to keep 2.79 behavior. */
|
||||
translate[3][0] *= min_ff(1.0f, cam_aspect);
|
||||
translate[3][1] /= max_ff(1.0f, cam_aspect) * (image_aspect / cam_aspect);
|
||||
/* quad is -1..1 so divide by 2. */
|
||||
scale[0][0] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0);
|
||||
scale[1][1] *= 0.5f * bgpic->scale * ((bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0);
|
||||
/* Camera shift. (middle of cam_corners) */
|
||||
translate[3][0] += (cam_corners[0][0] + cam_corners[2][0]) * 0.5f;
|
||||
translate[3][1] += (cam_corners[0][1] + cam_corners[2][1]) * 0.5f;
|
||||
|
||||
mul_m4_series(rmat, translate, rotate, scale);
|
||||
}
|
||||
|
||||
void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Camera *cam = ob->data;
|
||||
|
||||
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, draw_ctx->rv3d);
|
||||
|
||||
if (!show_frame || DRW_state_is_select()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float norm_obmat[4][4];
|
||||
normalize_m4_m4(norm_obmat, ob->obmat);
|
||||
|
||||
for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
|
||||
if (bgpic->flag & CAM_BGIMG_FLAG_DISABLED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float aspect = 1.0;
|
||||
bool use_alpha_premult;
|
||||
float mat[4][4];
|
||||
|
||||
/* retrieve the image we want to show, continue to next when no image could be found */
|
||||
GPUTexture *tex = image_camera_background_texture_get(
|
||||
bgpic, draw_ctx, pd, &aspect, &use_alpha_premult);
|
||||
|
||||
if (tex) {
|
||||
image_camera_background_matrix_get(cam, bgpic, draw_ctx, aspect, mat);
|
||||
|
||||
mul_m4_m4m4(mat, norm_obmat, mat);
|
||||
const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0;
|
||||
|
||||
/* When drawing background we do 2 passes.
|
||||
* - One alpha over, which works where background is visible.
|
||||
* - One alpha under, works under partially visible objects. (only in cycles)
|
||||
* This approach is not ideal and should be revisited.
|
||||
**/
|
||||
for (int i = 0; i < (is_foreground ? 1 : 2); i++) {
|
||||
DRWPass *pass = is_foreground ? psl->image_foreground_ps :
|
||||
((i == 0) ? psl->image_background_under_ps :
|
||||
psl->image_background_over_ps);
|
||||
GPUShader *sh = OVERLAY_shader_image();
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
float color[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
|
||||
DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgLinear", !DRW_state_do_color_management());
|
||||
DRW_shgroup_uniform_bool_copy(grp, "depthSet", true);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
|
||||
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
GPUTexture *tex = NULL;
|
||||
Image *ima = ob->data;
|
||||
float mat[4][4];
|
||||
|
||||
const bool show_frame = BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d);
|
||||
const bool show_image = show_frame && BKE_object_empty_image_data_is_visible_in_view3d(ob, rv3d);
|
||||
const bool use_alpha_blend = (ob->empty_image_flag & OB_EMPTY_IMAGE_USE_ALPHA_BLEND) != 0;
|
||||
const bool use_alpha_premult = ima && (ima->alpha_mode == IMA_ALPHA_PREMUL);
|
||||
|
||||
if (!show_frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
/* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead,
|
||||
* see: T59347 */
|
||||
int size[2] = {0};
|
||||
if (ima != NULL) {
|
||||
tex = GPU_texture_from_blender(ima, ob->iuser, GL_TEXTURE_2D);
|
||||
if (tex) {
|
||||
size[0] = GPU_texture_orig_width(tex);
|
||||
size[1] = GPU_texture_orig_height(tex);
|
||||
}
|
||||
}
|
||||
CLAMP_MIN(size[0], 1);
|
||||
CLAMP_MIN(size[1], 1);
|
||||
|
||||
float image_aspect[2];
|
||||
overlay_image_calc_aspect(ob->data, size, image_aspect);
|
||||
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
mul_v3_fl(mat[0], image_aspect[0] * 0.5f * ob->empty_drawsize);
|
||||
mul_v3_fl(mat[1], image_aspect[1] * 0.5f * ob->empty_drawsize);
|
||||
madd_v3_v3fl(mat[3], mat[0], ob->ima_ofs[0] * 2.0f + 1.0f);
|
||||
madd_v3_v3fl(mat[3], mat[1], ob->ima_ofs[1] * 2.0f + 1.0f);
|
||||
}
|
||||
|
||||
/* Use the actual depth if we are doing depth tests to determine the distance to the object */
|
||||
char depth_mode = DRW_state_is_depth() ? OB_EMPTY_IMAGE_DEPTH_DEFAULT : ob->empty_image_depth;
|
||||
DRWPass *pass = NULL;
|
||||
switch (depth_mode) {
|
||||
case OB_EMPTY_IMAGE_DEPTH_DEFAULT:
|
||||
pass = (use_alpha_blend) ? psl->image_empties_blend_ps : psl->image_empties_ps;
|
||||
break;
|
||||
case OB_EMPTY_IMAGE_DEPTH_BACK:
|
||||
pass = psl->image_empties_back_ps;
|
||||
break;
|
||||
case OB_EMPTY_IMAGE_DEPTH_FRONT:
|
||||
pass = psl->image_empties_front_ps;
|
||||
break;
|
||||
}
|
||||
|
||||
if (show_frame) {
|
||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||
OVERLAY_empty_shape(cb, mat, 1.0f, OB_EMPTY_IMAGE, color);
|
||||
}
|
||||
|
||||
if (show_image && tex && ((ob->color[3] > 0.0f) || !use_alpha_blend)) {
|
||||
GPUShader *sh = OVERLAY_shader_image();
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_texture(grp, "imgTexture", tex);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "imgLinear", false);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", ob->color);
|
||||
DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_image_cache_finish(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_pass_sort_shgroup_reverse(psl->image_background_under_ps);
|
||||
DRW_pass_sort_shgroup_z(psl->image_empties_blend_ps);
|
||||
DRW_pass_sort_shgroup_z(psl->image_empties_front_ps);
|
||||
DRW_pass_sort_shgroup_z(psl->image_empties_back_ps);
|
||||
}
|
||||
|
||||
void OVERLAY_image_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
DRW_view_set_active(pd->view_reference_images);
|
||||
|
||||
DRW_draw_pass(psl->image_background_over_ps);
|
||||
DRW_draw_pass(psl->image_background_under_ps);
|
||||
DRW_draw_pass(psl->image_empties_back_ps);
|
||||
|
||||
DRW_draw_pass(psl->image_empties_ps);
|
||||
DRW_draw_pass(psl->image_empties_blend_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
}
|
||||
|
||||
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
DRW_view_set_active(pd->view_reference_images);
|
||||
|
||||
DRW_draw_pass(psl->image_empties_front_ps);
|
||||
DRW_draw_pass(psl->image_foreground_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
|
||||
OVERLAY_image_free_movieclips_textures(vedata);
|
||||
}
|
78
source/blender/draw/engines/overlay/overlay_lattice.c
Normal file
78
source/blender/draw/engines/overlay/overlay_lattice.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_edit_lattice_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->edit_lattice_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_lattice_wire();
|
||||
pd->edit_lattice_wires_grp = grp = DRW_shgroup_create(sh, psl->edit_lattice_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
|
||||
|
||||
sh = OVERLAY_shader_edit_lattice_point();
|
||||
pd->edit_lattice_points_grp = grp = DRW_shgroup_create(sh, psl->edit_lattice_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUBatch *geom;
|
||||
|
||||
geom = DRW_cache_lattice_wire_get(ob, true);
|
||||
DRW_shgroup_call(pd->edit_lattice_wires_grp, geom, ob);
|
||||
|
||||
geom = DRW_cache_lattice_vert_overlay_get(ob);
|
||||
DRW_shgroup_call(pd->edit_lattice_points_grp, geom, ob);
|
||||
}
|
||||
|
||||
void OVERLAY_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false);
|
||||
OVERLAY_extra_wire(cb, geom, ob->obmat, color);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_lattice_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->edit_lattice_ps);
|
||||
}
|
143
source/blender/draw/engines/overlay/overlay_metaball.c
Normal file
143
source/blender/draw/engines/overlay/overlay_metaball.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_meta_types.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "ED_mball.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
OVERLAY_InstanceFormats *formats = OVERLAY_shader_instance_formats_get();
|
||||
|
||||
#define BUF_INSTANCE DRW_shgroup_call_buffer_instance
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->metaball_ps[i], state | pd->clipping_state | infront_state);
|
||||
|
||||
/* Reuse armature shader as it's perfect to outline ellipsoids. */
|
||||
struct GPUVertFormat *format = formats->instance_bone;
|
||||
struct GPUShader *sh = OVERLAY_shader_armature_sphere(true);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->metaball_ps[i]);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
pd->mball.handle[i] = BUF_INSTANCE(grp, format, DRW_cache_bone_point_wire_outline_get());
|
||||
}
|
||||
}
|
||||
|
||||
static void metaball_instance_data_set(
|
||||
BoneInstanceData *data, Object *ob, const float *pos, const float radius, const float color[4])
|
||||
{
|
||||
/* Bone point radius is 0.05. Compensate for that. */
|
||||
mul_v3_v3fl(data->mat[0], ob->obmat[0], radius / 0.05f);
|
||||
mul_v3_v3fl(data->mat[1], ob->obmat[1], radius / 0.05f);
|
||||
mul_v3_v3fl(data->mat[2], ob->obmat[2], radius / 0.05f);
|
||||
mul_v3_m4v3(data->mat[3], ob->obmat, pos);
|
||||
/* WATCH: Reminder, alpha is wiresize. */
|
||||
OVERLAY_bone_instance_data_set_color(data, color);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
const bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
const bool is_select = DRW_state_is_select();
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
MetaBall *mb = ob->data;
|
||||
|
||||
const float *color;
|
||||
const float col_radius[4] = {0.63f, 0.19f, 0.19f, 1.0f}; /* 0x3030A0 */
|
||||
const float col_radius_select[4] = {0.94f, 0.63f, 0.63f, 1.0f}; /* 0xA0A0F0 */
|
||||
const float col_stiffness[4] = {0.19f, 0.63f, 0.19f, 1.0f}; /* 0x30A030 */
|
||||
const float col_stiffness_select[4] = {0.63f, 0.94f, 0.63f, 1.0f}; /* 0xA0F0A0 */
|
||||
|
||||
int select_id = 0;
|
||||
if (is_select) {
|
||||
const Object *orig_object = DEG_get_original_object(ob);
|
||||
select_id = orig_object->runtime.select_id;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
|
||||
const bool is_selected = (ml->flag & SELECT) != 0;
|
||||
const bool is_scale_radius = (ml->flag & MB_SCALE_RAD) != 0;
|
||||
float stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2;
|
||||
BoneInstanceData instdata;
|
||||
|
||||
if (is_select) {
|
||||
DRW_select_load_id(select_id | MBALLSEL_RADIUS);
|
||||
}
|
||||
color = (is_selected && is_scale_radius) ? col_radius_select : col_radius;
|
||||
metaball_instance_data_set(&instdata, ob, &ml->x, ml->rad, color);
|
||||
DRW_buffer_add_entry_struct(pd->mball.handle[do_in_front], &instdata);
|
||||
|
||||
if (is_select) {
|
||||
DRW_select_load_id(select_id | MBALLSEL_STIFF);
|
||||
}
|
||||
color = (is_selected && !is_scale_radius) ? col_stiffness_select : col_stiffness;
|
||||
metaball_instance_data_set(&instdata, ob, &ml->x, stiffness_radius, color);
|
||||
DRW_buffer_add_entry_struct(pd->mball.handle[do_in_front], &instdata);
|
||||
|
||||
select_id += 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
const bool do_in_front = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
MetaBall *mb = ob->data;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||
|
||||
LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
|
||||
/* Draw radius only. */
|
||||
BoneInstanceData instdata;
|
||||
metaball_instance_data_set(&instdata, ob, &ml->x, ml->rad, color);
|
||||
DRW_buffer_add_entry_struct(pd->mball.handle[do_in_front], &instdata);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_metaball_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->metaball_ps[0]);
|
||||
}
|
||||
|
||||
void OVERLAY_metaball_in_front_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->metaball_ps[1]);
|
||||
}
|
231
source/blender/draw/engines/overlay/overlay_motion_path.c
Normal file
231
source/blender/draw/engines/overlay/overlay_motion_path.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "draw_manager_text.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DRWShadingGroup *grp;
|
||||
GPUShader *sh;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR;
|
||||
DRW_PASS_CREATE(psl->motion_paths_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_motion_path_line();
|
||||
pd->motion_path_lines_grp = grp = DRW_shgroup_create(sh, psl->motion_paths_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
|
||||
sh = OVERLAY_shader_motion_path_vert();
|
||||
pd->motion_path_points_grp = grp = DRW_shgroup_create(sh, psl->motion_paths_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
|
||||
/* Just convert the CPU cache to GPU cache. */
|
||||
/* T0D0(fclem) This should go into a draw_cache_impl_motionpath. */
|
||||
static GPUVertBuf *mpath_vbo_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->points_vbo) {
|
||||
GPUVertFormat format = {0};
|
||||
/* Match structure of bMotionPathVert. */
|
||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
GPU_vertformat_attr_add(&format, "flag", GPU_COMP_I32, 1, GPU_FETCH_INT);
|
||||
mpath->points_vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(mpath->points_vbo, mpath->length);
|
||||
/* meh... a useless memcpy. */
|
||||
memcpy(mpath->points_vbo->data, mpath->points, sizeof(bMotionPathVert) * mpath->length);
|
||||
}
|
||||
return mpath->points_vbo;
|
||||
}
|
||||
|
||||
static GPUBatch *mpath_batch_line_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->batch_line) {
|
||||
mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL);
|
||||
}
|
||||
return mpath->batch_line;
|
||||
}
|
||||
|
||||
static GPUBatch *mpath_batch_points_get(bMotionPath *mpath)
|
||||
{
|
||||
if (!mpath->batch_points) {
|
||||
mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), NULL);
|
||||
}
|
||||
return mpath->batch_points;
|
||||
}
|
||||
|
||||
static void motion_path_get_frame_range_to_draw(bAnimVizSettings *avs,
|
||||
bMotionPath *mpath,
|
||||
int current_frame,
|
||||
int *r_start,
|
||||
int *r_end,
|
||||
int *r_step)
|
||||
{
|
||||
int start, end;
|
||||
|
||||
if (avs->path_type == MOTIONPATH_TYPE_ACFRA) {
|
||||
start = current_frame - avs->path_bc;
|
||||
end = current_frame + avs->path_ac + 1;
|
||||
}
|
||||
else {
|
||||
start = avs->path_sf;
|
||||
end = avs->path_ef;
|
||||
}
|
||||
|
||||
if (start > end) {
|
||||
SWAP(int, start, end);
|
||||
}
|
||||
|
||||
CLAMP(start, mpath->start_frame, mpath->end_frame);
|
||||
CLAMP(end, mpath->start_frame, mpath->end_frame);
|
||||
|
||||
*r_start = start;
|
||||
*r_end = end;
|
||||
*r_step = max_ii(avs->path_step, 1);
|
||||
}
|
||||
|
||||
static void motion_path_cache(OVERLAY_Data *vedata,
|
||||
Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
bAnimVizSettings *avs,
|
||||
bMotionPath *mpath)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
struct DRWTextStore *dt = DRW_text_cache_ensure();
|
||||
int txt_flag = DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII;
|
||||
int cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
|
||||
bool selected = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->base_flag & BASE_SELECTED);
|
||||
bool show_keyframes = (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) != 0;
|
||||
bool show_keyframes_no = (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) != 0;
|
||||
bool show_frame_no = (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) != 0;
|
||||
bool show_lines = (mpath->flag & MOTIONPATH_FLAG_LINES) != 0;
|
||||
float no_custom_col[3] = {-1.0f, -1.0f, -1.0f};
|
||||
float *color = (mpath->flag & MOTIONPATH_FLAG_CUSTOM) ? mpath->color : no_custom_col;
|
||||
|
||||
int sfra, efra, stepsize;
|
||||
motion_path_get_frame_range_to_draw(avs, mpath, cfra, &sfra, &efra, &stepsize);
|
||||
|
||||
int len = efra - sfra;
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int start_index = sfra - mpath->start_frame;
|
||||
|
||||
/* Draw curve-line of path. */
|
||||
if (show_lines) {
|
||||
int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame};
|
||||
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_lines_grp);
|
||||
DRW_shgroup_uniform_ivec4_copy(grp, "mpathLineSettings", motion_path_settings);
|
||||
DRW_shgroup_uniform_int_copy(grp, "lineThickness", mpath->line_thickness);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "selected", selected);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range(grp, mpath_batch_line_get(mpath), start_index, len);
|
||||
}
|
||||
|
||||
/* Draw points. */
|
||||
{
|
||||
int pt_size = max_ii(mpath->line_thickness - 1, 1);
|
||||
int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize};
|
||||
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_points_grp);
|
||||
DRW_shgroup_uniform_ivec4_copy(grp, "mpathPointSettings", motion_path_settings);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "customColor", color);
|
||||
/* Only draw the required range. */
|
||||
DRW_shgroup_call_range(grp, mpath_batch_points_get(mpath), start_index, len);
|
||||
}
|
||||
|
||||
/* Draw frame numbers at each framestep value */
|
||||
if (show_frame_no || (show_keyframes_no && show_keyframes)) {
|
||||
int i;
|
||||
uchar col[4], col_kf[4];
|
||||
UI_GetThemeColor3ubv(TH_TEXT_HI, col);
|
||||
UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col_kf);
|
||||
col[3] = col_kf[3] = 255;
|
||||
|
||||
bMotionPathVert *mpv = mpath->points + start_index;
|
||||
for (i = 0; i < len; i += stepsize, mpv += stepsize) {
|
||||
int frame = sfra + i;
|
||||
char numstr[32];
|
||||
size_t numstr_len;
|
||||
bool is_keyframe = (mpv->flag & MOTIONPATH_VERT_KEY) != 0;
|
||||
|
||||
if ((show_keyframes && show_keyframes_no && is_keyframe) || (show_frame_no && (i == 0))) {
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), " %d", frame);
|
||||
DRW_text_cache_add(
|
||||
dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, (is_keyframe) ? col_kf : col);
|
||||
}
|
||||
else if (show_frame_no) {
|
||||
bMotionPathVert *mpvP = (mpv - stepsize);
|
||||
bMotionPathVert *mpvN = (mpv + stepsize);
|
||||
/* Only draw framenum if several consecutive highlighted points don't occur on same point.
|
||||
*/
|
||||
if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) {
|
||||
numstr_len = BLI_snprintf(numstr, sizeof(numstr), " %d", frame);
|
||||
DRW_text_cache_add(dt, mpv->co, numstr, numstr_len, 0, 0, txt_flag, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
if (OVERLAY_armature_is_pose_mode(ob, draw_ctx)) {
|
||||
for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->mpath) {
|
||||
motion_path_cache(vedata, ob, pchan, &ob->pose->avs, pchan->mpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ob->mpath) {
|
||||
motion_path_cache(vedata, ob, NULL, &ob->avs, ob->mpath);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_motion_path_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->motion_paths_ps);
|
||||
}
|
353
source/blender/draw/engines/overlay/overlay_outline.c
Normal file
353
source/blender/draw/engines/overlay/overlay_outline.c
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_lightprobe_types.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_outline_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
|
||||
if (DRW_state_is_fbo()) {
|
||||
/* TODO only alloc if needed. */
|
||||
/* XXX TODO GPU_R16UI can overflow, it would cause no harm
|
||||
* (only bad colored or missing outlines) but we should
|
||||
* use 32bits only if the scene have that many objects */
|
||||
DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
|
||||
DRW_texture_ensure_fullscreen_2d(&txl->outlines_id_tx, GPU_R16UI, 0);
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->outlines_prepass_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx), GPU_ATTACHMENT_TEXTURE(txl->outlines_id_tx)});
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
DRW_texture_ensure_fullscreen_2d(&txl->outlines_color_tx[i], GPU_RGBA8, DRW_TEX_FILTER);
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->outlines_process_fb[i],
|
||||
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->outlines_color_tx[i])});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int shgroup_theme_id_to_outline_id(int theme_id, const int base_flag)
|
||||
{
|
||||
if (UNLIKELY(base_flag & BASE_FROM_DUPLI)) {
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
case TH_SELECT:
|
||||
return 2;
|
||||
case TH_TRANSFORM:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch (theme_id) {
|
||||
case TH_ACTIVE:
|
||||
return 3;
|
||||
case TH_SELECT:
|
||||
return 1;
|
||||
case TH_TRANSFORM:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_theme_id_to_outline_or_null(OVERLAY_PrivateData *pd,
|
||||
int theme_id,
|
||||
const int base_flag)
|
||||
{
|
||||
int outline_id = shgroup_theme_id_to_outline_id(theme_id, base_flag);
|
||||
switch (outline_id) {
|
||||
case 3: /* TH_ACTIVE */
|
||||
return pd->outlines_active_grp;
|
||||
case 2: /* Duplis */
|
||||
return pd->outlines_select_dupli_grp;
|
||||
case 1: /* TH_SELECT */
|
||||
return pd->outlines_select_grp;
|
||||
case 0: /* TH_TRANSFORM */
|
||||
return pd->outlines_transform_grp;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *shgroup_theme_id_to_probe_outline_or_null(OVERLAY_PrivateData *pd,
|
||||
int theme_id,
|
||||
const int base_flag)
|
||||
{
|
||||
int outline_id = shgroup_theme_id_to_outline_id(theme_id, base_flag);
|
||||
switch (outline_id) {
|
||||
case 3: /* TH_ACTIVE */
|
||||
return pd->outlines_probe_active_grp;
|
||||
case 2: /* Duplis */
|
||||
return pd->outlines_probe_select_dupli_grp;
|
||||
case 1: /* TH_SELECT */
|
||||
return pd->outlines_probe_select_grp;
|
||||
case 0: /* TH_TRANSFORM */
|
||||
return pd->outlines_probe_transform_grp;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *outline_shgroup(DRWPass *pass, int outline_id, GPUShader *sh)
|
||||
{
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_int_copy(grp, "outlineId", outline_id);
|
||||
return grp;
|
||||
}
|
||||
|
||||
void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_TextureList *txl = vedata->txl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
DRWShadingGroup *grp = NULL;
|
||||
|
||||
const float outline_width = UI_GetThemeValuef(TH_OUTLINE_WIDTH);
|
||||
const bool do_outline_expand = (U.pixelsize > 1.0) || (outline_width > 2.0f);
|
||||
const bool do_large_expand = ((U.pixelsize > 1.0) && (outline_width > 2.0f)) ||
|
||||
(outline_width > 4.0f);
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->outlines_prepass_ps, state | pd->clipping_state);
|
||||
|
||||
GPUShader *sh_grid = OVERLAY_shader_outline_prepass_grid();
|
||||
GPUShader *sh_geom = OVERLAY_shader_outline_prepass(pd->xray_enabled_and_not_wire);
|
||||
GPUShader *sh = OVERLAY_shader_outline_prepass(false);
|
||||
|
||||
pd->outlines_transform_grp = outline_shgroup(psl->outlines_prepass_ps, 0, sh_geom);
|
||||
pd->outlines_select_grp = outline_shgroup(psl->outlines_prepass_ps, 1, sh_geom);
|
||||
pd->outlines_select_dupli_grp = outline_shgroup(psl->outlines_prepass_ps, 2, sh_geom);
|
||||
pd->outlines_active_grp = outline_shgroup(psl->outlines_prepass_ps, 3, sh_geom);
|
||||
|
||||
pd->outlines_probe_transform_grp = outline_shgroup(psl->outlines_prepass_ps, 0, sh);
|
||||
pd->outlines_probe_select_grp = outline_shgroup(psl->outlines_prepass_ps, 1, sh);
|
||||
pd->outlines_probe_select_dupli_grp = outline_shgroup(psl->outlines_prepass_ps, 2, sh);
|
||||
pd->outlines_probe_active_grp = outline_shgroup(psl->outlines_prepass_ps, 3, sh);
|
||||
|
||||
pd->outlines_probe_grid_grp = grp = DRW_shgroup_create(sh_grid, psl->outlines_prepass_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
|
||||
/* outlines_prepass_ps is still needed for selection of probes. */
|
||||
if (!(pd->v3d_flag & V3D_SELECT_OUTLINE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
DRW_PASS_CREATE(psl->outlines_detect_ps, DRW_STATE_WRITE_COLOR);
|
||||
DRW_PASS_CREATE(psl->outlines_expand_ps, DRW_STATE_WRITE_COLOR);
|
||||
DRW_PASS_CREATE(psl->outlines_bleed_ps, DRW_STATE_WRITE_COLOR);
|
||||
DRW_PASS_CREATE(psl->outlines_resolve_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_outline_detect(pd->xray_enabled_and_not_wire);
|
||||
|
||||
grp = DRW_shgroup_create(sh, psl->outlines_detect_ps);
|
||||
/* Don't occlude the "outline" detection pass if in xray mode (too much flickering). */
|
||||
DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", (pd->xray_enabled) ? 1.0f : 0.35f);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineId", &txl->outlines_id_tx);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &txl->temp_depth_tx);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
|
||||
if (do_outline_expand) {
|
||||
sh = OVERLAY_shader_outline_expand(do_large_expand);
|
||||
grp = DRW_shgroup_create(sh, psl->outlines_expand_ps);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &txl->outlines_color_tx[0]);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "doExpand", true);
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
|
||||
sh = OVERLAY_shader_outline_expand(false);
|
||||
grp = DRW_shgroup_create(sh, psl->outlines_bleed_ps);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &txl->outlines_color_tx[1]);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "doExpand", false);
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
}
|
||||
else {
|
||||
sh = OVERLAY_shader_outline_expand(false);
|
||||
grp = DRW_shgroup_create(sh, psl->outlines_expand_ps);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &txl->outlines_color_tx[0]);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "doExpand", false);
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
}
|
||||
|
||||
GPUTexture **outline_tx = &txl->outlines_color_tx[do_outline_expand ? 0 : 1];
|
||||
sh = OVERLAY_shader_outline_resolve();
|
||||
|
||||
grp = DRW_shgroup_create(sh, psl->outlines_resolve_ps);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "outlineBluredColor", outline_tx);
|
||||
DRW_shgroup_uniform_vec2_copy(grp, "rcpDimensions", DRW_viewport_invert_size_get());
|
||||
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void outline_lightprobe(OVERLAY_PrivateData *pd, Object *ob, ViewLayer *view_layer)
|
||||
{
|
||||
DRWShadingGroup *grp;
|
||||
LightProbe *prb = (LightProbe *)ob->data;
|
||||
int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
|
||||
|
||||
if (prb->type == LIGHTPROBE_TYPE_GRID) {
|
||||
float corner[3];
|
||||
float increment[3][3];
|
||||
/* Update transforms */
|
||||
float cell_dim[3], half_cell_dim[3];
|
||||
cell_dim[0] = 2.0f / (float)(prb->grid_resolution_x);
|
||||
cell_dim[1] = 2.0f / (float)(prb->grid_resolution_y);
|
||||
cell_dim[2] = 2.0f / (float)(prb->grid_resolution_z);
|
||||
|
||||
mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
|
||||
|
||||
/* First cell. */
|
||||
copy_v3_fl(corner, -1.0f);
|
||||
add_v3_v3(corner, half_cell_dim);
|
||||
mul_m4_v3(ob->obmat, corner);
|
||||
|
||||
/* Opposite neighbor cell. */
|
||||
copy_v3_fl3(increment[0], cell_dim[0], 0.0f, 0.0f);
|
||||
copy_v3_fl3(increment[1], 0.0f, cell_dim[1], 0.0f);
|
||||
copy_v3_fl3(increment[2], 0.0f, 0.0f, cell_dim[2]);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
add_v3_v3(increment[i], half_cell_dim);
|
||||
add_v3_fl(increment[i], -1.0f);
|
||||
mul_m4_v3(ob->obmat, increment[i]);
|
||||
sub_v3_v3(increment[i], corner);
|
||||
}
|
||||
|
||||
int outline_id = shgroup_theme_id_to_outline_id(theme_id, ob->base_flag);
|
||||
uint cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
|
||||
grp = DRW_shgroup_create_sub(pd->outlines_probe_grid_grp);
|
||||
DRW_shgroup_uniform_int_copy(grp, "outlineId", outline_id);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "corner", corner);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "increment_x", increment[0]);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "increment_y", increment[1]);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "increment_z", increment[2]);
|
||||
DRW_shgroup_uniform_ivec3_copy(grp, "grid_resolution", &prb->grid_resolution_x);
|
||||
DRW_shgroup_call_procedural_points(grp, NULL, cell_count);
|
||||
}
|
||||
else if (prb->type == LIGHTPROBE_TYPE_PLANAR && (prb->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
|
||||
grp = shgroup_theme_id_to_probe_outline_or_null(pd, theme_id, ob->base_flag);
|
||||
DRW_shgroup_call_no_cull(grp, DRW_cache_quad_get(), ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
||||
Object *ob,
|
||||
OVERLAY_DupliData *dupli,
|
||||
bool init_dupli)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
struct GPUBatch *geom;
|
||||
DRWShadingGroup *shgroup = NULL;
|
||||
|
||||
if (ob->type == OB_LIGHTPROBE) {
|
||||
outline_lightprobe(pd, ob, draw_ctx->view_layer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dupli && !init_dupli) {
|
||||
geom = dupli->outline_geom;
|
||||
shgroup = dupli->outline_shgrp;
|
||||
}
|
||||
else {
|
||||
/* This fixes only the biggest case which is a plane in ortho view. */
|
||||
int flat_axis = 0;
|
||||
bool is_flat_object_viewed_from_side = ((draw_ctx->rv3d->persp == RV3D_ORTHO) &&
|
||||
DRW_object_is_flat(ob, &flat_axis) &&
|
||||
DRW_object_axis_orthogonal_to_view(ob, flat_axis));
|
||||
|
||||
if (pd->xray_enabled_and_not_wire || is_flat_object_viewed_from_side) {
|
||||
geom = DRW_cache_object_edge_detection_get(ob, NULL);
|
||||
}
|
||||
else {
|
||||
geom = DRW_cache_object_surface_get(ob);
|
||||
}
|
||||
|
||||
if (geom) {
|
||||
int theme_id = DRW_object_wire_theme_get(ob, draw_ctx->view_layer, NULL);
|
||||
shgroup = shgroup_theme_id_to_outline_or_null(pd, theme_id, ob->base_flag);
|
||||
}
|
||||
}
|
||||
|
||||
if (shgroup && geom) {
|
||||
DRW_shgroup_call(shgroup, geom, ob);
|
||||
}
|
||||
|
||||
if (init_dupli) {
|
||||
dupli->outline_shgrp = shgroup;
|
||||
dupli->outline_geom = geom;
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_outline_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = vedata->fbl;
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
bool do_outlines = psl->outlines_prepass_ps != NULL &&
|
||||
!DRW_pass_is_empty(psl->outlines_prepass_ps);
|
||||
|
||||
if (DRW_state_is_fbo() && do_outlines) {
|
||||
DRW_stats_group_start("Outlines");
|
||||
|
||||
/* Render filled polygon on a separate framebuffer */
|
||||
GPU_framebuffer_bind(fbl->outlines_prepass_fb);
|
||||
GPU_framebuffer_clear_color_depth(fbl->outlines_prepass_fb, clearcol, 1.0f);
|
||||
DRW_draw_pass(psl->outlines_prepass_ps);
|
||||
|
||||
/* Search outline pixels */
|
||||
GPU_framebuffer_bind(fbl->outlines_process_fb[0]);
|
||||
DRW_draw_pass(psl->outlines_detect_ps);
|
||||
|
||||
/* Expand outline to form a 3px wide line */
|
||||
GPU_framebuffer_bind(fbl->outlines_process_fb[1]);
|
||||
DRW_draw_pass(psl->outlines_expand_ps);
|
||||
|
||||
/* Bleed color so the AA can do it's stuff */
|
||||
GPU_framebuffer_bind(fbl->outlines_process_fb[0]);
|
||||
DRW_draw_pass(psl->outlines_bleed_ps);
|
||||
|
||||
/* restore main framebuffer */
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
DRW_draw_pass(psl->outlines_resolve_ps);
|
||||
|
||||
DRW_stats_group_end();
|
||||
}
|
||||
else if (DRW_state_is_select()) {
|
||||
/* Render probes spheres/planes so we can select them. */
|
||||
DRW_draw_pass(psl->outlines_prepass_ps);
|
||||
}
|
||||
}
|
211
source/blender/draw/engines/overlay/overlay_paint.c
Normal file
211
source/blender/draw/engines/overlay/overlay_paint.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
DRWState state;
|
||||
|
||||
const bool use_alpha_blending = (draw_ctx->v3d->shading.type == OB_WIRE);
|
||||
const bool draw_contours = (pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0;
|
||||
float opacity = 0.0f;
|
||||
|
||||
switch (pd->ctx_mode) {
|
||||
case CTX_MODE_POSE:
|
||||
case CTX_MODE_PAINT_WEIGHT: {
|
||||
opacity = pd->overlay.weight_paint_mode_opacity;
|
||||
if (opacity > 0.0f) {
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
|
||||
state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
|
||||
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_paint_weight();
|
||||
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending);
|
||||
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
|
||||
DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTX_MODE_PAINT_VERTEX: {
|
||||
opacity = pd->overlay.vertex_paint_mode_opacity;
|
||||
if (opacity > 0.0f) {
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL;
|
||||
state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL;
|
||||
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_paint_vertcol();
|
||||
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending);
|
||||
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTX_MODE_PAINT_TEXTURE: {
|
||||
const ImagePaintSettings *imapaint = &draw_ctx->scene->toolsettings->imapaint;
|
||||
const bool mask_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL &&
|
||||
imapaint->stencil != NULL;
|
||||
|
||||
opacity = mask_enabled ? pd->overlay.texture_paint_mode_opacity : 0.0f;
|
||||
if (opacity > 0.0f) {
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
|
||||
|
||||
GPUTexture *tex = GPU_texture_from_blender(imapaint->stencil, NULL, GL_TEXTURE_2D);
|
||||
|
||||
const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL);
|
||||
const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0;
|
||||
sh = OVERLAY_shader_paint_texture();
|
||||
pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "opacity", opacity);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "maskPremult", mask_premult);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "maskColor", imapaint->stencil_col);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "maskInvertStencil", mask_inverted);
|
||||
DRW_shgroup_uniform_texture(grp, "maskImage", tex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (opacity <= 0.0f) {
|
||||
psl->paint_color_ps = NULL;
|
||||
pd->paint_surf_grp = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->paint_overlay_ps, state | pd->clipping_state);
|
||||
sh = OVERLAY_shader_paint_face();
|
||||
pd->paint_face_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 0.2f});
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
|
||||
|
||||
sh = OVERLAY_shader_paint_wire();
|
||||
pd->paint_wire_selected_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useSelect", true);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
|
||||
|
||||
pd->paint_wire_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useSelect", false);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ALPHA);
|
||||
|
||||
sh = OVERLAY_shader_paint_point();
|
||||
pd->paint_point_grp = grp = DRW_shgroup_create(sh, psl->paint_overlay_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUBatch *geom = NULL;
|
||||
|
||||
const Mesh *me_orig = DEG_get_original_object(ob)->data;
|
||||
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
|
||||
if (pd->paint_surf_grp) {
|
||||
geom = DRW_cache_mesh_surface_texpaint_single_get(ob);
|
||||
DRW_shgroup_call(pd->paint_surf_grp, geom, ob);
|
||||
}
|
||||
|
||||
if (use_face_sel) {
|
||||
geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call(pd->paint_face_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
struct GPUBatch *geom = NULL;
|
||||
|
||||
const Mesh *me = ob->data;
|
||||
const Mesh *me_orig = DEG_get_original_object(ob)->data;
|
||||
const bool use_wire = (pd->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0;
|
||||
const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
const bool use_vert_sel = (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
|
||||
|
||||
if (pd->paint_surf_grp) {
|
||||
if (ob->mode == OB_MODE_VERTEX_PAINT) {
|
||||
if (me->mloopcol == NULL) {
|
||||
return;
|
||||
}
|
||||
geom = DRW_cache_mesh_surface_vertpaint_get(ob);
|
||||
}
|
||||
else {
|
||||
geom = DRW_cache_mesh_surface_weights_get(ob);
|
||||
}
|
||||
DRW_shgroup_call(pd->paint_surf_grp, geom, ob);
|
||||
}
|
||||
|
||||
if (use_face_sel || use_wire) {
|
||||
geom = DRW_cache_mesh_surface_edges_get(ob);
|
||||
DRW_shgroup_call(use_face_sel ? pd->paint_wire_selected_grp : pd->paint_wire_grp, geom, ob);
|
||||
}
|
||||
|
||||
if (use_face_sel) {
|
||||
geom = DRW_cache_mesh_surface_get(ob);
|
||||
DRW_shgroup_call(pd->paint_face_grp, geom, ob);
|
||||
}
|
||||
|
||||
if (use_vert_sel) {
|
||||
geom = DRW_cache_mesh_all_verts_get(ob);
|
||||
DRW_shgroup_call(pd->paint_point_grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_paint_weight_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_paint_vertex_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
void OVERLAY_paint_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
if (psl->paint_color_ps) {
|
||||
DRW_view_set_active(NULL);
|
||||
DRW_draw_pass(psl->paint_color_ps);
|
||||
}
|
||||
DRW_draw_pass(psl->paint_overlay_ps);
|
||||
}
|
217
source/blender/draw/engines/overlay/overlay_particle.c
Normal file
217
source/blender/draw/engines/overlay/overlay_particle.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_particle_types.h"
|
||||
|
||||
#include "BKE_pointcache.h"
|
||||
|
||||
#include "ED_particle.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Edit Particles
|
||||
* \{ */
|
||||
|
||||
void OVERLAY_edit_particle_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
ParticleEditSettings *pset = PE_settings(draw_ctx->scene);
|
||||
GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
pd->edit_particle.use_weight = (pset->brushtype == PE_BRUSH_WEIGHT);
|
||||
pd->edit_particle.select_mode = pset->selectmode;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->edit_particle_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_edit_particle_strand();
|
||||
pd->edit_particle_strand_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useWeight", pd->edit_particle.use_weight);
|
||||
DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
|
||||
|
||||
sh = OVERLAY_shader_edit_particle_point();
|
||||
pd->edit_particle_point_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
|
||||
void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene_orig = (Scene *)DEG_get_original_id(&draw_ctx->scene->id);
|
||||
|
||||
/* Usually the edit structure is created by Particle Edit Mode Toggle
|
||||
* operator, but sometimes it's invoked after tagging hair as outdated
|
||||
* (for example, when toggling edit mode). That makes it impossible to
|
||||
* create edit structure for until after next dependency graph evaluation.
|
||||
*
|
||||
* Ideally, the edit structure will be created here already via some
|
||||
* dependency graph callback or so, but currently trying to make it nicer
|
||||
* only causes bad level calls and breaks design from the past.
|
||||
*/
|
||||
Object *ob_orig = DEG_get_original_object(ob);
|
||||
PTCacheEdit *edit = PE_create_current(draw_ctx->depsgraph, scene_orig, ob_orig);
|
||||
if (edit == NULL) {
|
||||
/* Happens when trying to edit particles in EMITTER mode without
|
||||
* having them cached.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/* NOTE: We need to pass evaluated particle system, which we need
|
||||
* to find first.
|
||||
*/
|
||||
ParticleSystem *psys = ob->particlesystem.first;
|
||||
LISTBASE_FOREACH (ParticleSystem *, psys_orig, &ob_orig->particlesystem) {
|
||||
if (PE_get_current_from_psys(psys_orig) == edit) {
|
||||
break;
|
||||
}
|
||||
psys = psys->next;
|
||||
}
|
||||
if (psys == NULL) {
|
||||
printf("Error getting evaluated particle system for edit.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct GPUBatch *geom;
|
||||
{
|
||||
geom = DRW_cache_particles_get_edit_strands(ob, psys, edit, pd->edit_particle.use_weight);
|
||||
DRW_shgroup_call(pd->edit_particle_strand_grp, geom, NULL);
|
||||
}
|
||||
|
||||
if (pd->edit_particle.select_mode == SCE_SELECT_POINT) {
|
||||
geom = DRW_cache_particles_get_edit_inner_points(ob, psys, edit);
|
||||
DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
|
||||
}
|
||||
|
||||
if (ELEM(pd->edit_particle.select_mode, SCE_SELECT_POINT, SCE_SELECT_END)) {
|
||||
geom = DRW_cache_particles_get_edit_tip_points(ob, psys, edit);
|
||||
DRW_shgroup_call(pd->edit_particle_point_grp, geom, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_edit_particle_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->edit_particle_ps);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Particles
|
||||
* \{ */
|
||||
|
||||
void OVERLAY_particle_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
ParticleEditSettings *pset = PE_settings(draw_ctx->scene);
|
||||
GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
pd->edit_particle.use_weight = (pset->brushtype == PE_BRUSH_WEIGHT);
|
||||
pd->edit_particle.select_mode = pset->selectmode;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->particle_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_particle_dot();
|
||||
pd->particle_dots_grp = grp = DRW_shgroup_create(sh, psl->particle_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_persistent(grp, "weightTex", G_draw.ramp);
|
||||
|
||||
sh = OVERLAY_shader_particle_shape();
|
||||
pd->particle_shapes_grp = grp = DRW_shgroup_create(sh, psl->particle_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_texture_persistent(grp, "weightTex", G_draw.ramp);
|
||||
}
|
||||
|
||||
void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
|
||||
if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ParticleSettings *part = psys->part;
|
||||
int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
|
||||
|
||||
if (part->type == PART_HAIR) {
|
||||
/* Hairs should have been rendered by the render engine.*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ELEM(draw_as, PART_DRAW_NOT, PART_DRAW_OB, PART_DRAW_GR)) {
|
||||
struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys);
|
||||
struct GPUBatch *shape = NULL;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
/* TODO(fclem) Here would be a good place for preemptive culling. */
|
||||
|
||||
/* fclem: Is color even usefull in our modern context? */
|
||||
Material *ma = give_current_material(ob, part->omat);
|
||||
float color[4] = {0.6f, 0.6f, 0.6f, part->draw_size};
|
||||
if (ma != NULL) {
|
||||
copy_v3_v3(color, &ma->r);
|
||||
}
|
||||
|
||||
switch (draw_as) {
|
||||
default:
|
||||
case PART_DRAW_DOT:
|
||||
grp = DRW_shgroup_create_sub(pd->particle_dots_grp);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
|
||||
DRW_shgroup_call(grp, geom, NULL);
|
||||
break;
|
||||
case PART_DRAW_AXIS:
|
||||
case PART_DRAW_CIRC:
|
||||
case PART_DRAW_CROSS:
|
||||
grp = DRW_shgroup_create_sub(pd->particle_shapes_grp);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
|
||||
shape = DRW_cache_particles_get_prim(draw_as);
|
||||
DRW_shgroup_call_instances_with_attribs(grp, NULL, shape, geom);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_particle_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->particle_ps);
|
||||
}
|
||||
|
||||
/** \} */
|
585
source/blender/draw/engines/overlay/overlay_private.h
Normal file
585
source/blender/draw/engines/overlay/overlay_private.h
Normal file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup DNA
|
||||
*/
|
||||
|
||||
#ifndef __OVERLAY_PRIVATE_H__
|
||||
#define __OVERLAY_PRIVATE_H__
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define USE_GEOM_SHADER_WORKAROUND 1
|
||||
#else
|
||||
# define USE_GEOM_SHADER_WORKAROUND 0
|
||||
#endif
|
||||
|
||||
typedef struct OVERLAY_FramebufferList {
|
||||
struct GPUFrameBuffer *overlay_default_fb;
|
||||
struct GPUFrameBuffer *overlay_line_fb;
|
||||
struct GPUFrameBuffer *overlay_color_only_fb;
|
||||
struct GPUFrameBuffer *overlay_in_front_fb;
|
||||
struct GPUFrameBuffer *outlines_prepass_fb;
|
||||
struct GPUFrameBuffer *outlines_process_fb[2];
|
||||
} OVERLAY_FramebufferList;
|
||||
|
||||
typedef struct OVERLAY_TextureList {
|
||||
struct GPUTexture *temp_depth_tx;
|
||||
struct GPUTexture *dummy_depth_tx;
|
||||
struct GPUTexture *outlines_id_tx;
|
||||
struct GPUTexture *outlines_color_tx[2];
|
||||
struct GPUTexture *overlay_color_tx;
|
||||
struct GPUTexture *overlay_color_history_tx;
|
||||
struct GPUTexture *overlay_line_tx;
|
||||
struct GPUTexture *edit_mesh_occlude_wire_tx;
|
||||
} OVERLAY_TextureList;
|
||||
|
||||
#define NOT_IN_FRONT 0
|
||||
#define IN_FRONT 1
|
||||
|
||||
typedef struct OVERLAY_PassList {
|
||||
DRWPass *antialiasing_ps;
|
||||
DRWPass *armature_ps[2];
|
||||
DRWPass *armature_bone_select_ps;
|
||||
DRWPass *armature_transp_ps;
|
||||
DRWPass *edit_curve_wire_ps[2];
|
||||
DRWPass *edit_curve_handle_ps;
|
||||
DRWPass *edit_lattice_ps;
|
||||
DRWPass *edit_mesh_depth_ps[2];
|
||||
DRWPass *edit_mesh_verts_ps[2];
|
||||
DRWPass *edit_mesh_edges_ps[2];
|
||||
DRWPass *edit_mesh_faces_ps[2];
|
||||
DRWPass *edit_mesh_faces_cage_ps[2];
|
||||
DRWPass *edit_mesh_analysis_ps;
|
||||
DRWPass *edit_mesh_normals_ps;
|
||||
DRWPass *edit_mesh_weight_ps;
|
||||
DRWPass *edit_particle_ps;
|
||||
DRWPass *edit_text_overlay_ps;
|
||||
DRWPass *edit_text_wire_ps[2];
|
||||
DRWPass *extra_ps[2];
|
||||
DRWPass *extra_blend_ps;
|
||||
DRWPass *extra_centers_ps;
|
||||
DRWPass *facing_ps;
|
||||
DRWPass *grid_ps;
|
||||
DRWPass *image_background_under_ps;
|
||||
DRWPass *image_background_over_ps;
|
||||
DRWPass *image_empties_ps;
|
||||
DRWPass *image_empties_back_ps;
|
||||
DRWPass *image_empties_blend_ps;
|
||||
DRWPass *image_empties_front_ps;
|
||||
DRWPass *image_foreground_ps;
|
||||
DRWPass *metaball_ps[2];
|
||||
DRWPass *motion_paths_ps;
|
||||
DRWPass *outlines_prepass_ps;
|
||||
DRWPass *outlines_detect_ps;
|
||||
DRWPass *outlines_expand_ps;
|
||||
DRWPass *outlines_bleed_ps;
|
||||
DRWPass *outlines_resolve_ps;
|
||||
DRWPass *paint_color_ps;
|
||||
DRWPass *paint_overlay_ps;
|
||||
DRWPass *particle_ps;
|
||||
DRWPass *sculpt_mask_ps;
|
||||
DRWPass *wireframe_ps;
|
||||
DRWPass *wireframe_xray_ps;
|
||||
} OVERLAY_PassList;
|
||||
|
||||
/* Data used by GLSL shader. To be used as UBO. */
|
||||
typedef struct OVERLAY_ShadingData {
|
||||
/** Grid */
|
||||
float grid_axes[3], grid_distance;
|
||||
float zplane_axes[3], grid_mesh_size;
|
||||
float grid_steps[8];
|
||||
float inv_viewport_size[2];
|
||||
float grid_line_size;
|
||||
int grid_flag;
|
||||
int zpos_flag;
|
||||
int zneg_flag;
|
||||
/** Wireframe */
|
||||
float wire_step_param;
|
||||
/** Edit Curve */
|
||||
float edit_curve_normal_length;
|
||||
/** Edit Mesh */
|
||||
int data_mask[4];
|
||||
} OVERLAY_ShadingData;
|
||||
|
||||
typedef struct OVERLAY_ExtraCallBuffers {
|
||||
DRWCallBuffer *camera_frame;
|
||||
DRWCallBuffer *camera_tria[2];
|
||||
DRWCallBuffer *camera_distances;
|
||||
DRWCallBuffer *camera_volume;
|
||||
DRWCallBuffer *camera_volume_frame;
|
||||
|
||||
DRWCallBuffer *center_active;
|
||||
DRWCallBuffer *center_selected;
|
||||
DRWCallBuffer *center_deselected;
|
||||
DRWCallBuffer *center_selected_lib;
|
||||
DRWCallBuffer *center_deselected_lib;
|
||||
|
||||
DRWCallBuffer *empty_axes;
|
||||
DRWCallBuffer *empty_capsule_body;
|
||||
DRWCallBuffer *empty_capsule_cap;
|
||||
DRWCallBuffer *empty_circle;
|
||||
DRWCallBuffer *empty_cone;
|
||||
DRWCallBuffer *empty_cube;
|
||||
DRWCallBuffer *empty_cylinder;
|
||||
DRWCallBuffer *empty_image_frame;
|
||||
DRWCallBuffer *empty_plain_axes;
|
||||
DRWCallBuffer *empty_single_arrow;
|
||||
DRWCallBuffer *empty_sphere;
|
||||
DRWCallBuffer *empty_sphere_solid;
|
||||
|
||||
DRWCallBuffer *extra_dashed_lines;
|
||||
DRWCallBuffer *extra_lines;
|
||||
|
||||
DRWCallBuffer *field_curve;
|
||||
DRWCallBuffer *field_force;
|
||||
DRWCallBuffer *field_vortex;
|
||||
DRWCallBuffer *field_wind;
|
||||
DRWCallBuffer *field_cone_limit;
|
||||
DRWCallBuffer *field_sphere_limit;
|
||||
DRWCallBuffer *field_tube_limit;
|
||||
|
||||
DRWCallBuffer *groundline;
|
||||
|
||||
DRWCallBuffer *light_point;
|
||||
DRWCallBuffer *light_sun;
|
||||
DRWCallBuffer *light_spot;
|
||||
DRWCallBuffer *light_spot_cone_back;
|
||||
DRWCallBuffer *light_spot_cone_front;
|
||||
DRWCallBuffer *light_area[2];
|
||||
|
||||
DRWCallBuffer *origin_xform;
|
||||
|
||||
DRWCallBuffer *probe_planar;
|
||||
DRWCallBuffer *probe_cube;
|
||||
DRWCallBuffer *probe_grid;
|
||||
|
||||
DRWCallBuffer *speaker;
|
||||
|
||||
DRWShadingGroup *extra_wire;
|
||||
DRWShadingGroup *extra_loose_points;
|
||||
} OVERLAY_ExtraCallBuffers;
|
||||
|
||||
typedef struct OVERLAY_ArmatureCallBuffers {
|
||||
DRWCallBuffer *box_outline;
|
||||
DRWCallBuffer *box_solid;
|
||||
|
||||
DRWCallBuffer *dof_lines;
|
||||
DRWCallBuffer *dof_sphere;
|
||||
|
||||
DRWCallBuffer *envelope_distance;
|
||||
DRWCallBuffer *envelope_outline;
|
||||
DRWCallBuffer *envelope_solid;
|
||||
|
||||
DRWCallBuffer *octa_outline;
|
||||
DRWCallBuffer *octa_solid;
|
||||
|
||||
DRWCallBuffer *point_outline;
|
||||
DRWCallBuffer *point_solid;
|
||||
|
||||
DRWCallBuffer *stick;
|
||||
|
||||
DRWCallBuffer *wire;
|
||||
|
||||
DRWShadingGroup *custom_solid;
|
||||
DRWShadingGroup *custom_outline;
|
||||
GHash *custom_shapes_ghash;
|
||||
} OVERLAY_ArmatureCallBuffers;
|
||||
|
||||
typedef struct OVERLAY_PrivateData {
|
||||
DRWShadingGroup *armature_bone_select_act_grp;
|
||||
DRWShadingGroup *armature_bone_select_grp;
|
||||
DRWShadingGroup *edit_curve_normal_grp[2];
|
||||
DRWShadingGroup *edit_curve_wire_grp[2];
|
||||
DRWShadingGroup *edit_curve_handle_grp;
|
||||
DRWShadingGroup *edit_curve_points_grp;
|
||||
DRWShadingGroup *edit_lattice_points_grp;
|
||||
DRWShadingGroup *edit_lattice_wires_grp;
|
||||
DRWShadingGroup *edit_mesh_depth_grp[2];
|
||||
DRWShadingGroup *edit_mesh_faces_grp[2];
|
||||
DRWShadingGroup *edit_mesh_faces_cage_grp[2];
|
||||
DRWShadingGroup *edit_mesh_verts_grp[2];
|
||||
DRWShadingGroup *edit_mesh_edges_grp[2];
|
||||
DRWShadingGroup *edit_mesh_facedots_grp[2];
|
||||
DRWShadingGroup *edit_mesh_skin_roots_grp[2];
|
||||
DRWShadingGroup *edit_mesh_normals_grp;
|
||||
DRWShadingGroup *edit_mesh_analysis_grp;
|
||||
DRWShadingGroup *edit_mesh_weight_grp;
|
||||
DRWShadingGroup *edit_particle_strand_grp;
|
||||
DRWShadingGroup *edit_particle_point_grp;
|
||||
DRWShadingGroup *edit_text_overlay_grp;
|
||||
DRWShadingGroup *edit_text_wire_grp[2];
|
||||
DRWShadingGroup *facing_grp;
|
||||
DRWShadingGroup *motion_path_lines_grp;
|
||||
DRWShadingGroup *motion_path_points_grp;
|
||||
DRWShadingGroup *outlines_active_grp;
|
||||
DRWShadingGroup *outlines_select_grp;
|
||||
DRWShadingGroup *outlines_select_dupli_grp;
|
||||
DRWShadingGroup *outlines_transform_grp;
|
||||
DRWShadingGroup *outlines_probe_transform_grp;
|
||||
DRWShadingGroup *outlines_probe_select_grp;
|
||||
DRWShadingGroup *outlines_probe_select_dupli_grp;
|
||||
DRWShadingGroup *outlines_probe_active_grp;
|
||||
DRWShadingGroup *outlines_probe_grid_grp;
|
||||
DRWShadingGroup *paint_surf_grp;
|
||||
DRWShadingGroup *paint_wire_grp;
|
||||
DRWShadingGroup *paint_wire_selected_grp;
|
||||
DRWShadingGroup *paint_point_grp;
|
||||
DRWShadingGroup *paint_face_grp;
|
||||
DRWShadingGroup *particle_dots_grp;
|
||||
DRWShadingGroup *particle_shapes_grp;
|
||||
DRWShadingGroup *sculpt_mask_grp;
|
||||
DRWShadingGroup *wires_grp[2][2]; /* With and without coloring. */
|
||||
DRWShadingGroup *wires_all_grp[2][2]; /* With and without coloring. */
|
||||
DRWShadingGroup *wires_sculpt_grp[2];
|
||||
|
||||
DRWView *view_default;
|
||||
DRWView *view_wires;
|
||||
DRWView *view_edit_faces;
|
||||
DRWView *view_edit_faces_cage;
|
||||
DRWView *view_edit_edges;
|
||||
DRWView *view_edit_verts;
|
||||
DRWView *view_reference_images;
|
||||
|
||||
/** TODO get rid of this. */
|
||||
ListBase smoke_domains;
|
||||
ListBase bg_movie_clips;
|
||||
|
||||
/** Two instances for in_front option and without. */
|
||||
OVERLAY_ExtraCallBuffers extra_call_buffers[2];
|
||||
|
||||
OVERLAY_ArmatureCallBuffers armature_call_buffers[2];
|
||||
|
||||
View3DOverlay overlay;
|
||||
enum eContextObjectMode ctx_mode;
|
||||
bool clear_in_front;
|
||||
bool wireframe_mode;
|
||||
bool hide_overlays;
|
||||
bool xray_enabled;
|
||||
bool xray_enabled_and_not_wire;
|
||||
short v3d_flag; /* TODO move to View3DOverlay */
|
||||
short v3d_gridflag; /* TODO move to View3DOverlay */
|
||||
DRWState clipping_state;
|
||||
OVERLAY_ShadingData shdata;
|
||||
|
||||
struct {
|
||||
short sample;
|
||||
short target_sample;
|
||||
float prev_persmat[4][4];
|
||||
bool enabled;
|
||||
} antialiasing;
|
||||
struct {
|
||||
bool show_handles;
|
||||
} edit_curve;
|
||||
struct {
|
||||
int ghost_ob;
|
||||
int edit_ob;
|
||||
bool do_zbufclip;
|
||||
bool do_faces;
|
||||
bool do_edges;
|
||||
bool select_vert;
|
||||
bool select_face;
|
||||
bool select_edge;
|
||||
int flag; /** Copy of v3d->overlay.edit_flag. */
|
||||
} edit_mesh;
|
||||
struct {
|
||||
bool use_weight;
|
||||
int select_mode;
|
||||
} edit_particle;
|
||||
struct {
|
||||
bool transparent;
|
||||
bool show_relations;
|
||||
bool do_pose_fade_geom;
|
||||
} armature;
|
||||
struct {
|
||||
DRWCallBuffer *handle[2];
|
||||
} mball;
|
||||
} OVERLAY_PrivateData; /* Transient data */
|
||||
|
||||
typedef struct OVERLAY_StorageList {
|
||||
struct OVERLAY_PrivateData *pd;
|
||||
} OVERLAY_StorageList;
|
||||
|
||||
typedef struct OVERLAY_Data {
|
||||
void *engine_type;
|
||||
OVERLAY_FramebufferList *fbl;
|
||||
OVERLAY_TextureList *txl;
|
||||
OVERLAY_PassList *psl;
|
||||
OVERLAY_StorageList *stl;
|
||||
} OVERLAY_Data;
|
||||
|
||||
typedef struct OVERLAY_DupliData {
|
||||
DRWShadingGroup *wire_shgrp;
|
||||
DRWShadingGroup *outline_shgrp;
|
||||
DRWShadingGroup *extra_shgrp;
|
||||
struct GPUBatch *wire_geom;
|
||||
struct GPUBatch *outline_geom;
|
||||
struct GPUBatch *extra_geom;
|
||||
short base_flag;
|
||||
} OVERLAY_DupliData;
|
||||
|
||||
typedef struct BoneInstanceData {
|
||||
/* Keep sync with bone instance vertex format (OVERLAY_InstanceFormats) */
|
||||
union {
|
||||
float mat[4][4];
|
||||
struct {
|
||||
float _pad0[3], color_hint_a;
|
||||
float _pad1[3], color_hint_b;
|
||||
float _pad2[3], color_a;
|
||||
float _pad3[3], color_b;
|
||||
};
|
||||
struct {
|
||||
float _pad00[3], amin_a;
|
||||
float _pad01[3], amin_b;
|
||||
float _pad02[3], amax_a;
|
||||
float _pad03[3], amax_b;
|
||||
};
|
||||
};
|
||||
} BoneInstanceData;
|
||||
|
||||
typedef struct OVERLAY_InstanceFormats {
|
||||
struct GPUVertFormat *instance_pos;
|
||||
struct GPUVertFormat *instance_extra;
|
||||
struct GPUVertFormat *instance_bone;
|
||||
struct GPUVertFormat *instance_bone_outline;
|
||||
struct GPUVertFormat *instance_bone_envelope;
|
||||
struct GPUVertFormat *instance_bone_envelope_distance;
|
||||
struct GPUVertFormat *instance_bone_envelope_outline;
|
||||
struct GPUVertFormat *instance_bone_stick;
|
||||
struct GPUVertFormat *pos;
|
||||
struct GPUVertFormat *pos_color;
|
||||
struct GPUVertFormat *wire_extra;
|
||||
} OVERLAY_InstanceFormats;
|
||||
|
||||
/* Pack data into the last row of the 4x4 matrix. It will be decoded by the vertex shader. */
|
||||
BLI_INLINE void pack_data_in_mat4(
|
||||
float rmat[4][4], const float mat[4][4], float a, float b, float c, float d)
|
||||
{
|
||||
copy_m4_m4(rmat, mat);
|
||||
rmat[0][3] = a;
|
||||
rmat[1][3] = b;
|
||||
rmat[2][3] = c;
|
||||
rmat[3][3] = d;
|
||||
}
|
||||
|
||||
BLI_INLINE void pack_v4_in_mat4(float rmat[4][4], const float mat[4][4], const float v[4])
|
||||
{
|
||||
pack_data_in_mat4(rmat, mat, v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
|
||||
BLI_INLINE void pack_fl_in_mat4(float rmat[4][4], const float mat[4][4], float a)
|
||||
{
|
||||
copy_m4_m4(rmat, mat);
|
||||
rmat[3][3] = a;
|
||||
}
|
||||
|
||||
void OVERLAY_antialiasing_reset(OVERLAY_Data *vedata);
|
||||
void OVERLAY_antialiasing_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata);
|
||||
void OVERLAY_antialiasing_start(OVERLAY_Data *vedata);
|
||||
void OVERLAY_antialiasing_end(OVERLAY_Data *vedata);
|
||||
|
||||
bool OVERLAY_armature_is_pose_mode(Object *ob, const struct DRWContextState *draw_ctx);
|
||||
void OVERLAY_armature_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_armature_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_pose_armature_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_armature_cache_finish(OVERLAY_Data *vedata);
|
||||
void OVERLAY_armature_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_pose_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_pose_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_bone_instance_data_set_color_hint(BoneInstanceData *data, const float hint_color[4]);
|
||||
void OVERLAY_bone_instance_data_set_color(BoneInstanceData *data, const float bone_color[4]);
|
||||
|
||||
void OVERLAY_edit_curve_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_curve_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_curve_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_surf_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_curve_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_edit_lattice_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_lattice_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_text_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_text_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_edit_mesh_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_mesh_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_edit_particle_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_edit_particle_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_extra_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_extra_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_extra_in_front_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_extra_centers_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_camera_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_empty_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_lightprobe_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_speaker_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
|
||||
OVERLAY_ExtraCallBuffers *OVERLAY_extra_call_buffer_get(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_extra_line_dashed(OVERLAY_ExtraCallBuffers *cb,
|
||||
const float start[3],
|
||||
const float end[3],
|
||||
const float color[4]);
|
||||
void OVERLAY_extra_line(OVERLAY_ExtraCallBuffers *cb,
|
||||
const float start[3],
|
||||
const float end[3],
|
||||
const int color_id);
|
||||
void OVERLAY_empty_shape(OVERLAY_ExtraCallBuffers *cb,
|
||||
const float mat[4][4],
|
||||
const float draw_size,
|
||||
const char draw_type,
|
||||
const float color[4]);
|
||||
void OVERLAY_extra_loose_points(OVERLAY_ExtraCallBuffers *cb,
|
||||
struct GPUBatch *geom,
|
||||
const float mat[4][4],
|
||||
const float color[4]);
|
||||
void OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers *cb,
|
||||
struct GPUBatch *geom,
|
||||
const float mat[4][4],
|
||||
const float color[4]);
|
||||
|
||||
void OVERLAY_facing_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_facing_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_facing_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_facing_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_grid_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_grid_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_image_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_image_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_image_cache_finish(OVERLAY_Data *vedata);
|
||||
void OVERLAY_image_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_metaball_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_metaball_in_front_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_motion_path_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_outline_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_outline_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
||||
Object *ob,
|
||||
OVERLAY_DupliData *dupli,
|
||||
bool init_dupli);
|
||||
void OVERLAY_outline_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_paint_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_paint_texture_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_paint_weight_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_paint_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_particle_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_particle_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_sculpt_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_wireframe_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
|
||||
Object *ob,
|
||||
OVERLAY_DupliData *dupli,
|
||||
bool init_dupli);
|
||||
void OVERLAY_wireframe_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *vedata);
|
||||
|
||||
GPUShader *OVERLAY_shader_antialiasing(void);
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom(void);
|
||||
GPUShader *OVERLAY_shader_armature_envelope(bool use_outline);
|
||||
GPUShader *OVERLAY_shader_armature_shape(bool use_outline);
|
||||
GPUShader *OVERLAY_shader_armature_sphere(bool use_outline);
|
||||
GPUShader *OVERLAY_shader_armature_stick(void);
|
||||
GPUShader *OVERLAY_shader_armature_wire(void);
|
||||
GPUShader *OVERLAY_shader_depth_only(void);
|
||||
GPUShader *OVERLAY_shader_edit_curve_handle(void);
|
||||
GPUShader *OVERLAY_shader_edit_curve_point(void);
|
||||
GPUShader *OVERLAY_shader_edit_curve_wire(void);
|
||||
GPUShader *OVERLAY_shader_edit_lattice_point(void);
|
||||
GPUShader *OVERLAY_shader_edit_lattice_wire(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_analysis(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_edge(bool use_flat_interp);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_face(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_facedot(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_normal(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_skin_root(void);
|
||||
GPUShader *OVERLAY_shader_edit_mesh_vert(void);
|
||||
GPUShader *OVERLAY_shader_edit_particle_strand(void);
|
||||
GPUShader *OVERLAY_shader_edit_particle_point(void);
|
||||
GPUShader *OVERLAY_shader_extra(void);
|
||||
GPUShader *OVERLAY_shader_extra_groundline(void);
|
||||
GPUShader *OVERLAY_shader_extra_wire(bool use_object);
|
||||
GPUShader *OVERLAY_shader_extra_loose_point(void);
|
||||
GPUShader *OVERLAY_shader_extra_point(void);
|
||||
GPUShader *OVERLAY_shader_facing(void);
|
||||
GPUShader *OVERLAY_shader_grid(void);
|
||||
GPUShader *OVERLAY_shader_image(void);
|
||||
GPUShader *OVERLAY_shader_motion_path_line(void);
|
||||
GPUShader *OVERLAY_shader_motion_path_vert(void);
|
||||
GPUShader *OVERLAY_shader_uniform_color(void);
|
||||
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
|
||||
GPUShader *OVERLAY_shader_outline_prepass_grid(void);
|
||||
GPUShader *OVERLAY_shader_outline_resolve(void);
|
||||
GPUShader *OVERLAY_shader_outline_expand(bool high_dpi);
|
||||
GPUShader *OVERLAY_shader_outline_detect(bool use_wire);
|
||||
GPUShader *OVERLAY_shader_paint_face(void);
|
||||
GPUShader *OVERLAY_shader_paint_point(void);
|
||||
GPUShader *OVERLAY_shader_paint_texture(void);
|
||||
GPUShader *OVERLAY_shader_paint_vertcol(void);
|
||||
GPUShader *OVERLAY_shader_paint_weight(void);
|
||||
GPUShader *OVERLAY_shader_paint_wire(void);
|
||||
GPUShader *OVERLAY_shader_particle_dot(void);
|
||||
GPUShader *OVERLAY_shader_particle_shape(void);
|
||||
GPUShader *OVERLAY_shader_sculpt_mask(void);
|
||||
GPUShader *OVERLAY_shader_volume_velocity(bool use_needle);
|
||||
GPUShader *OVERLAY_shader_wireframe(void);
|
||||
GPUShader *OVERLAY_shader_wireframe_select(void);
|
||||
|
||||
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
|
||||
|
||||
void OVERLAY_shader_free(void);
|
||||
|
||||
#endif /* __OVERLAY_PRIVATE_H__ */
|
65
source/blender/draw/engines/overlay/overlay_sculpt.c
Normal file
65
source/blender/draw/engines/overlay/overlay_sculpt.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
|
||||
void OVERLAY_sculpt_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
|
||||
DRW_PASS_CREATE(psl->sculpt_mask_ps, state | pd->clipping_state);
|
||||
|
||||
GPUShader *sh = OVERLAY_shader_sculpt_mask();
|
||||
pd->sculpt_mask_grp = grp = DRW_shgroup_create(sh, psl->sculpt_mask_ps);
|
||||
DRW_shgroup_uniform_float_copy(grp, "maskOpacity", pd->overlay.sculpt_mode_mask_opacity);
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
|
||||
const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
|
||||
|
||||
if (use_pbvh || !ob->sculpt->deform_modifiers_active || ob->sculpt->shapekey_active) {
|
||||
if (pbvh_has_mask(pbvh)) {
|
||||
DRW_shgroup_call_sculpt(pd->sculpt_mask_grp, ob, false, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->sculpt_mask_ps);
|
||||
}
|
1337
source/blender/draw/engines/overlay/overlay_shader.c
Normal file
1337
source/blender/draw/engines/overlay/overlay_shader.c
Normal file
File diff suppressed because it is too large
Load Diff
231
source/blender/draw/engines/overlay/overlay_wireframe.c
Normal file
231
source/blender/draw/engines/overlay/overlay_wireframe.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "BLI_hash.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
void OVERLAY_wireframe_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
pd->view_wires = DRW_view_create_with_zoffset(pd->view_default, draw_ctx->rv3d, 0.5f);
|
||||
}
|
||||
|
||||
void OVERLAY_wireframe_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
DRWShadingGroup *grp = NULL;
|
||||
|
||||
View3DShading *shading = &draw_ctx->v3d->shading;
|
||||
|
||||
pd->shdata.wire_step_param = pd->overlay.wireframe_threshold - 254.0f / 255.0f;
|
||||
|
||||
bool is_wire_shmode = (shading->type == OB_WIRE);
|
||||
bool is_material_shmode = (shading->type > OB_SOLID);
|
||||
bool is_object_color = is_wire_shmode && (shading->wire_color_type == V3D_SHADING_OBJECT_COLOR);
|
||||
bool is_random_color = is_wire_shmode && (shading->wire_color_type == V3D_SHADING_RANDOM_COLOR);
|
||||
|
||||
const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
|
||||
GPUShader *wires_sh = use_select ? OVERLAY_shader_wireframe_select() :
|
||||
OVERLAY_shader_wireframe();
|
||||
|
||||
for (int xray = 0; xray < 2; xray++) {
|
||||
/* Only do stencil test if stencil buffer is written by the render engine. */
|
||||
DRWState stencil_state = is_material_shmode ? 0 : DRW_STATE_STENCIL_EQUAL;
|
||||
DRWState state = DRW_STATE_FIRST_VERTEX_CONVENTION | DRW_STATE_WRITE_COLOR |
|
||||
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRWPass *pass;
|
||||
uint stencil_mask;
|
||||
|
||||
if (xray == 0) {
|
||||
DRW_PASS_CREATE(psl->wireframe_ps, state | stencil_state | pd->clipping_state);
|
||||
pass = psl->wireframe_ps;
|
||||
stencil_mask = 0xFF;
|
||||
}
|
||||
else {
|
||||
DRW_PASS_CREATE(psl->wireframe_xray_ps, state | pd->clipping_state);
|
||||
pass = psl->wireframe_xray_ps;
|
||||
stencil_mask = 0x00;
|
||||
}
|
||||
|
||||
for (int use_coloring = 0; use_coloring < 2; use_coloring++) {
|
||||
pd->wires_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", pd->shdata.wire_step_param);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useColoring", use_coloring);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "isObjectColor", is_object_color);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "isRandomColor", is_random_color);
|
||||
DRW_shgroup_stencil_mask(grp, stencil_mask);
|
||||
|
||||
pd->wires_all_grp[xray][use_coloring] = grp = DRW_shgroup_create(wires_sh, pass);
|
||||
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 1.0f);
|
||||
DRW_shgroup_stencil_mask(grp, stencil_mask);
|
||||
}
|
||||
|
||||
pd->wires_sculpt_grp[xray] = grp = DRW_shgroup_create(wires_sh, pass);
|
||||
DRW_shgroup_uniform_float_copy(grp, "wireStepParam", 10.0f);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useColoring", false);
|
||||
DRW_shgroup_stencil_mask(grp, stencil_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
|
||||
Object *ob,
|
||||
OVERLAY_DupliData *dupli,
|
||||
bool init_dupli)
|
||||
{
|
||||
OVERLAY_Data *data = vedata;
|
||||
OVERLAY_PrivateData *pd = data->stl->pd;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES) != 0;
|
||||
const bool is_xray = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
const bool is_mesh = ob->type == OB_MESH;
|
||||
const bool use_wire = (pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) || (ob->dtx & OB_DRAWWIRE) ||
|
||||
(ob->dt == OB_WIRE);
|
||||
|
||||
/* Fast path for duplis. */
|
||||
if (dupli && !init_dupli) {
|
||||
if (dupli->wire_shgrp && dupli->wire_geom) {
|
||||
if (dupli->base_flag == ob->base_flag) {
|
||||
DRW_shgroup_call(dupli->wire_shgrp, dupli->wire_geom, ob);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Nothing to draw for this dupli. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_edit_mode = BKE_object_is_in_editmode(ob);
|
||||
bool has_edit_mesh_cage = false;
|
||||
if (is_mesh && is_edit_mode) {
|
||||
/* TODO: Should be its own function. */
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
BMEditMesh *embm = me->edit_mesh;
|
||||
if (embm) {
|
||||
has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't do that in edit Mesh mode, unless there is a modifier preview. */
|
||||
if (use_wire && (!is_mesh || (!is_edit_mode || has_edit_mesh_cage))) {
|
||||
const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
|
||||
!DRW_state_is_image_render();
|
||||
const bool use_coloring = (use_wire && !is_edit_mode && !use_sculpt_pbvh &&
|
||||
!has_edit_mesh_cage);
|
||||
DRWShadingGroup *shgrp = NULL;
|
||||
struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
|
||||
|
||||
if (geom || use_sculpt_pbvh) {
|
||||
if (use_sculpt_pbvh) {
|
||||
shgrp = pd->wires_sculpt_grp[is_xray];
|
||||
}
|
||||
else if (all_wires) {
|
||||
shgrp = pd->wires_all_grp[is_xray][use_coloring];
|
||||
}
|
||||
else {
|
||||
shgrp = pd->wires_grp[is_xray][use_coloring];
|
||||
}
|
||||
|
||||
if (use_sculpt_pbvh) {
|
||||
DRW_shgroup_call_sculpt(shgrp, ob, true, false, false);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_call(shgrp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
if (dupli) {
|
||||
dupli->wire_shgrp = shgrp;
|
||||
dupli->wire_geom = geom;
|
||||
}
|
||||
}
|
||||
else if (is_mesh && (!is_edit_mode || has_edit_mesh_cage)) {
|
||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||
Mesh *me = ob->data;
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||
|
||||
/* Draw loose geometry. */
|
||||
if ((me->totpoly == 0 && me->totedge > 0) || has_edit_mesh_cage) {
|
||||
struct GPUBatch *geom = DRW_cache_mesh_loose_edges_get(ob);
|
||||
if (geom) {
|
||||
OVERLAY_extra_wire(cb, geom, ob->obmat, color);
|
||||
}
|
||||
}
|
||||
else if (me->totedge == 0 && me->totvert > 0) {
|
||||
struct GPUBatch *geom = DRW_cache_mesh_all_verts_get(ob);
|
||||
if (geom) {
|
||||
OVERLAY_extra_loose_points(cb, geom, ob->obmat, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_wireframe_draw(OVERLAY_Data *data)
|
||||
{
|
||||
OVERLAY_FramebufferList *fbl = data->fbl;
|
||||
OVERLAY_PassList *psl = data->psl;
|
||||
OVERLAY_PrivateData *pd = data->stl->pd;
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
GPU_framebuffer_bind(fbl->overlay_line_fb);
|
||||
}
|
||||
|
||||
DRW_view_set_active(pd->view_wires);
|
||||
DRW_draw_pass(psl->wireframe_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
|
||||
if (pd->antialiasing.enabled) {
|
||||
GPU_framebuffer_bind(fbl->overlay_default_fb);
|
||||
}
|
||||
}
|
||||
|
||||
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *data)
|
||||
{
|
||||
OVERLAY_PassList *psl = data->psl;
|
||||
OVERLAY_PrivateData *pd = data->stl->pd;
|
||||
|
||||
DRW_view_set_active(pd->view_wires);
|
||||
DRW_draw_pass(psl->wireframe_xray_ps);
|
||||
|
||||
DRW_view_set_active(pd->view_default);
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
|
||||
uniform sampler2D colorTex;
|
||||
uniform sampler2D depthTex;
|
||||
uniform sampler2D lineTex;
|
||||
|
||||
in vec2 uvs;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
|
||||
|
||||
/**
|
||||
* We want to know how much a pixel is covered by a line.
|
||||
* We replace the square pixel with acircle of the same area and try to find the intersection area.
|
||||
* The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
|
||||
* The formula for the area uses inverse trig function and is quite complexe. Instead,
|
||||
* we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
|
||||
*/
|
||||
#define DISC_RADIUS (M_1_SQRTPI * 1.05)
|
||||
#define LINE_SMOOTH_START (0.5 - DISC_RADIUS)
|
||||
#define LINE_SMOOTH_END (0.5 + DISC_RADIUS)
|
||||
|
||||
/**
|
||||
* Returns coverage of a line onto a sample that is distance_to_line (in pixels) far from the line.
|
||||
* line_kernel_size is the inner size of the line with 100% coverage.
|
||||
*/
|
||||
float line_coverage(float distance_to_line, float line_kernel_size)
|
||||
{
|
||||
return smoothstep(LINE_SMOOTH_END, LINE_SMOOTH_START, abs(distance_to_line) - line_kernel_size);
|
||||
}
|
||||
vec4 line_coverage(vec4 distance_to_line, float line_kernel_size)
|
||||
{
|
||||
return smoothstep(LINE_SMOOTH_END, LINE_SMOOTH_START, abs(distance_to_line) - line_kernel_size);
|
||||
}
|
||||
|
||||
vec2 decode_line_dir(vec2 dir)
|
||||
{
|
||||
return dir * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
float decode_line_dist(float dist)
|
||||
{
|
||||
return (dist - 0.1) * 4.0 - 2.0;
|
||||
}
|
||||
|
||||
float neighbor_dist(vec3 line_dir_and_dist, vec2 ofs)
|
||||
{
|
||||
float dist = decode_line_dist(line_dir_and_dist.z);
|
||||
vec2 dir = decode_line_dir(line_dir_and_dist.xy);
|
||||
|
||||
bool is_line = line_dir_and_dist.z != 0.0;
|
||||
bool dir_horiz = abs(dir.x) > abs(dir.y);
|
||||
bool ofs_horiz = (ofs.x != 0);
|
||||
|
||||
if (!is_line || (ofs_horiz != dir_horiz)) {
|
||||
dist += 1e10; /* No line. */
|
||||
}
|
||||
else {
|
||||
dist += dot(ofs, -dir);
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
void neighbor_blend(
|
||||
float line_coverage, float line_depth, vec4 line_color, inout float frag_depth, inout vec4 col)
|
||||
{
|
||||
line_color *= line_coverage;
|
||||
if (line_coverage > 0.0 && line_depth < frag_depth) {
|
||||
/* Alpha over. */
|
||||
col = col * (1.0 - line_color.a) + line_color;
|
||||
frag_depth = line_depth;
|
||||
}
|
||||
else {
|
||||
/* Alpha under. */
|
||||
col = col + line_color * (1.0 - col.a);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 center_texel = ivec2(gl_FragCoord.xy);
|
||||
const float line_kernel = 0.0;
|
||||
|
||||
fragColor = texelFetch(colorTex, center_texel, 0);
|
||||
|
||||
float depth = texelFetch(depthTex, center_texel, 0).r;
|
||||
|
||||
float dist_raw = texelFetch(lineTex, center_texel, 0).b;
|
||||
float dist = decode_line_dist(dist_raw);
|
||||
|
||||
/* TODO Opti: use textureGather */
|
||||
vec4 neightbor_col0 = texelFetchOffset(colorTex, center_texel, 0, ivec2(1, 0));
|
||||
vec4 neightbor_col1 = texelFetchOffset(colorTex, center_texel, 0, ivec2(-1, 0));
|
||||
vec4 neightbor_col2 = texelFetchOffset(colorTex, center_texel, 0, ivec2(0, 1));
|
||||
vec4 neightbor_col3 = texelFetchOffset(colorTex, center_texel, 0, ivec2(0, -1));
|
||||
|
||||
vec3 neightbor_line0 = texelFetchOffset(lineTex, center_texel, 0, ivec2(1, 0)).rgb;
|
||||
vec3 neightbor_line1 = texelFetchOffset(lineTex, center_texel, 0, ivec2(-1, 0)).rgb;
|
||||
vec3 neightbor_line2 = texelFetchOffset(lineTex, center_texel, 0, ivec2(0, 1)).rgb;
|
||||
vec3 neightbor_line3 = texelFetchOffset(lineTex, center_texel, 0, ivec2(0, -1)).rgb;
|
||||
|
||||
vec4 depths;
|
||||
depths.x = texelFetchOffset(depthTex, center_texel, 0, ivec2(1, 0)).r;
|
||||
depths.y = texelFetchOffset(depthTex, center_texel, 0, ivec2(-1, 0)).r;
|
||||
depths.z = texelFetchOffset(depthTex, center_texel, 0, ivec2(0, 1)).r;
|
||||
depths.w = texelFetchOffset(depthTex, center_texel, 0, ivec2(0, -1)).r;
|
||||
|
||||
vec4 line_dists;
|
||||
line_dists.x = neighbor_dist(neightbor_line0, vec2(1, 0));
|
||||
line_dists.y = neighbor_dist(neightbor_line1, vec2(-1, 0));
|
||||
line_dists.z = neighbor_dist(neightbor_line2, vec2(0, 1));
|
||||
line_dists.w = neighbor_dist(neightbor_line3, vec2(0, -1));
|
||||
|
||||
vec4 coverage = line_coverage(line_dists, line_kernel);
|
||||
|
||||
if (dist_raw > 0.0) {
|
||||
fragColor *= line_coverage(dist, line_kernel);
|
||||
}
|
||||
|
||||
/* We dont order fragments but use alpha over/alpha under based on current minimum frag depth. */
|
||||
neighbor_blend(coverage.x, depths.x, neightbor_col0, depth, fragColor);
|
||||
neighbor_blend(coverage.y, depths.y, neightbor_col1, depth, fragColor);
|
||||
neighbor_blend(coverage.z, depths.z, neightbor_col2, depth, fragColor);
|
||||
neighbor_blend(coverage.w, depths.w, neightbor_col3, depth, fragColor);
|
||||
|
||||
#if 1
|
||||
/* Fix aliasing issue with really dense meshes and 1 pixel sized lines. */
|
||||
if (dist_raw > 0.0 && line_kernel < 0.45) {
|
||||
vec4 lines = vec4(neightbor_line0.z, neightbor_line1.z, neightbor_line2.z, neightbor_line3.z);
|
||||
/* Count number of line neighbors. */
|
||||
float blend = dot(vec4(0.25), step(0.001, lines));
|
||||
fragColor = mix(fragColor, fragColor / fragColor.a, blend);
|
||||
}
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
|
||||
out vec2 uvs;
|
||||
|
||||
void main()
|
||||
{
|
||||
int v = gl_VertexID % 3;
|
||||
float x = float((v & 1) << 2);
|
||||
float y = float((v & 2) << 1);
|
||||
gl_Position = vec4(x - 1.0, y - 1.0, 1.0, 1.0);
|
||||
uvs = vec2(x, y) * 0.5;
|
||||
}
|
@@ -1,15 +1,11 @@
|
||||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
/* Assumed to be in world coordinate already. */
|
||||
in mat4 InstanceModelMatrix;
|
||||
in vec4 color;
|
||||
in vec2 amin;
|
||||
in vec2 amax;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
@@ -23,8 +19,15 @@ vec3 sphere_project(float ax, float az)
|
||||
|
||||
void main()
|
||||
{
|
||||
mat4 model_mat = inst_obmat;
|
||||
model_mat[0][3] = model_mat[1][3] = model_mat[2][3] = 0.0;
|
||||
model_mat[3][3] = 1.0;
|
||||
|
||||
vec2 amin = vec2(inst_obmat[0][3], inst_obmat[1][3]);
|
||||
vec2 amax = vec2(inst_obmat[2][3], inst_obmat[3][3]);
|
||||
|
||||
vec3 final_pos = sphere_project(pos.x * abs((pos.x > 0.0) ? amax.x : amin.x),
|
||||
pos.y * abs((pos.y > 0.0) ? amax.y : amin.y));
|
||||
gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(final_pos, 1.0));
|
||||
gl_Position = ViewProjectionMatrix * (model_mat * vec4(final_pos, 1.0));
|
||||
finalColor = color;
|
||||
}
|
@@ -1,12 +1,4 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
|
||||
uniform vec2 viewportSize;
|
||||
uniform float lineThickness = 2.0;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos0;
|
||||
in vec2 pos1;
|
||||
@@ -24,7 +16,7 @@ flat out vec4 finalColor;
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
vec2 compute_dir(vec2 v0, vec2 v1, vec2 v2)
|
||||
@@ -159,8 +151,9 @@ void main()
|
||||
vec2 ss2 = proj(p2);
|
||||
vec2 edge_dir = compute_dir(ss0, ss1, ss2);
|
||||
|
||||
float line_thickness = 2.0 * sizePixel;
|
||||
bool outer = ((gl_VertexID & 1) == 1);
|
||||
vec2 t = outlineColorSize.w * (lineThickness / viewportSize);
|
||||
vec2 t = outlineColorSize.w * line_thickness * sizeViewportInv.xy;
|
||||
t *= pres_fac;
|
||||
t = (outer) ? t : vec2(0.0);
|
||||
|
@@ -0,0 +1,25 @@
|
||||
|
||||
uniform float alpha = 0.6;
|
||||
uniform bool isDistance;
|
||||
|
||||
flat in vec3 finalStateColor;
|
||||
flat in vec3 finalBoneColor;
|
||||
in vec3 normalView;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float n = normalize(normalView).z;
|
||||
if (isDistance) {
|
||||
n = 1.0 - clamp(-n, 0.0, 1.0);
|
||||
fragColor = vec4(1.0, 1.0, 1.0, 0.2) * n;
|
||||
}
|
||||
else {
|
||||
/* Smooth lighting factor. */
|
||||
const float s = 0.2; /* [0.0-0.5] range */
|
||||
float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0);
|
||||
fragColor.rgb = mix(finalStateColor, finalBoneColor, fac);
|
||||
fragColor.a = alpha;
|
||||
}
|
||||
}
|
@@ -1,8 +1,4 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec3 pos;
|
||||
|
@@ -9,8 +9,6 @@ in vec2 ssNor[];
|
||||
in vec4 vColSize[];
|
||||
|
||||
flat out vec4 finalColor;
|
||||
uniform vec2 viewportSize;
|
||||
uniform float lineThickness = 2.0;
|
||||
|
||||
vec2 compute_dir(vec2 v0, vec2 v1)
|
||||
{
|
||||
@@ -93,7 +91,8 @@ void main(void)
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
|
||||
float line_thickness = 2.0 * sizePixel;
|
||||
vec2 thick = vColSize[0].w * (line_thickness * sizeViewportInv.xy);
|
||||
vec2 edge_dir = compute_dir(ssPos[1], ssPos[2]);
|
||||
|
||||
vec2 hidden_point;
|
@@ -1,13 +1,11 @@
|
||||
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec3 pos;
|
||||
in vec3 snor;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in mat4 InstanceModelMatrix;
|
||||
in vec4 outlineColorSize;
|
||||
in vec4 color;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
out vec4 pPos;
|
||||
out vec3 vPos;
|
||||
@@ -18,12 +16,15 @@ out vec4 vColSize;
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 worldPosition = InstanceModelMatrix * vec4(pos, 1.0);
|
||||
vec4 bone_color, state_color;
|
||||
mat4 model_mat = extract_matrix_packed_data(inst_obmat, state_color, bone_color);
|
||||
|
||||
vec4 worldPosition = model_mat * vec4(pos, 1.0);
|
||||
vec4 viewpos = ViewMatrix * worldPosition;
|
||||
|
||||
vPos = viewpos.xyz;
|
||||
@@ -31,7 +32,7 @@ void main()
|
||||
|
||||
/* This is slow and run per vertex, but it's still faster than
|
||||
* doing it per instance on CPU and sending it on via instance attribute. */
|
||||
mat3 normal_mat = transpose(inverse(mat3(InstanceModelMatrix)));
|
||||
mat3 normal_mat = transpose(inverse(mat3(model_mat)));
|
||||
/* TODO FIX: there is still a problem with this vector
|
||||
* when the bone is scaled or in persp mode. But it's
|
||||
* barelly visible at the outline corners. */
|
||||
@@ -39,7 +40,7 @@ void main()
|
||||
|
||||
ssPos = proj(pPos);
|
||||
|
||||
vColSize = outlineColorSize;
|
||||
vColSize = bone_color;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(worldPosition.xyz);
|
@@ -4,17 +4,18 @@ in vec3 pos;
|
||||
in vec3 nor;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in mat4 InstanceModelMatrix;
|
||||
in vec3 boneColor;
|
||||
in vec3 stateColor;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 bone_color, state_color;
|
||||
mat4 model_mat = extract_matrix_packed_data(inst_obmat, state_color, bone_color);
|
||||
|
||||
/* This is slow and run per vertex, but it's still faster than
|
||||
* doing it per instance on CPU and sending it on via instance attribute. */
|
||||
mat3 normal_mat = transpose(inverse(mat3(InstanceModelMatrix)));
|
||||
mat3 normal_mat = transpose(inverse(mat3(model_mat)));
|
||||
vec3 normal = normalize(normal_world_to_view(normal_mat * nor));
|
||||
|
||||
/* Do lighting at an angle to avoid flat shading on front facing bone. */
|
||||
@@ -24,10 +25,10 @@ void main()
|
||||
/* Smooth lighting factor. */
|
||||
const float s = 0.2; /* [0.0-0.5] range */
|
||||
float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0);
|
||||
finalColor.rgb = mix(stateColor, boneColor, fac);
|
||||
finalColor.rgb = mix(state_color.rgb, bone_color.rgb, fac);
|
||||
finalColor.a = 1.0;
|
||||
|
||||
vec4 worldPosition = InstanceModelMatrix * vec4(pos, 1.0);
|
||||
vec4 worldPosition = model_mat * vec4(pos, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * worldPosition;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
@@ -1,23 +1,17 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
uniform float lineThickness = 2.0;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos0;
|
||||
in vec2 pos1;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in mat4 InstanceModelMatrix;
|
||||
in vec4 outlineColorSize;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
vec2 compute_dir(vec2 v0, vec2 v1, vec2 c)
|
||||
@@ -34,7 +28,10 @@ vec2 compute_dir(vec2 v0, vec2 v1, vec2 c)
|
||||
|
||||
void main()
|
||||
{
|
||||
mat4 model_view_matrix = ViewMatrix * InstanceModelMatrix;
|
||||
vec4 bone_color, state_color;
|
||||
mat4 model_mat = extract_matrix_packed_data(inst_obmat, state_color, bone_color);
|
||||
|
||||
mat4 model_view_matrix = ViewMatrix * model_mat;
|
||||
mat4 sphereMatrix = inverse(model_view_matrix);
|
||||
|
||||
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
|
||||
@@ -91,17 +88,17 @@ void main()
|
||||
|
||||
bool outer = ((gl_VertexID & 1) == 1);
|
||||
|
||||
vec2 t = outlineColorSize.w * (lineThickness / viewportSize);
|
||||
vec2 t = bone_color.w * (2.0 * sizeViewportInv.xy);
|
||||
t *= (is_persp) ? abs(V.z) : 1.0;
|
||||
t = (outer) ? t : vec2(0.0);
|
||||
|
||||
gl_Position = p0;
|
||||
gl_Position.xy += t * edge_dir;
|
||||
|
||||
finalColor = vec4(outlineColorSize.rgb, 1.0);
|
||||
finalColor = vec4(bone_color.rgb, 1.0);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
vec4 worldPosition = InstanceModelMatrix * vec4(cam_pos0, 1.0);
|
||||
vec4 worldPosition = model_mat * vec4(cam_pos0, 1.0);
|
||||
world_clip_planes_calc_clip_distance(worldPosition.xyz);
|
||||
#endif
|
||||
}
|
@@ -1,8 +1,4 @@
|
||||
|
||||
#extension GL_ARB_conservative_depth : enable
|
||||
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform float alpha = 0.4;
|
||||
|
||||
flat in vec3 finalStateColor;
|
@@ -1,14 +1,10 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in mat4 InstanceModelMatrix;
|
||||
in vec3 stateColor;
|
||||
in vec3 boneColor;
|
||||
in vec4 color;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
flat out vec3 finalStateColor;
|
||||
flat out vec3 finalBoneColor;
|
||||
@@ -20,7 +16,10 @@ const float rad = 0.05;
|
||||
|
||||
void main()
|
||||
{
|
||||
mat4 model_view_matrix = ViewMatrix * InstanceModelMatrix;
|
||||
vec4 bone_color, state_color;
|
||||
mat4 model_mat = extract_matrix_packed_data(inst_obmat, state_color, bone_color);
|
||||
|
||||
mat4 model_view_matrix = ViewMatrix * model_mat;
|
||||
sphereMatrix = inverse(model_view_matrix);
|
||||
|
||||
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
|
||||
@@ -78,11 +77,11 @@ void main()
|
||||
gl_Position = ProjectionMatrix * V;
|
||||
viewPosition = V.xyz;
|
||||
|
||||
finalStateColor = stateColor;
|
||||
finalBoneColor = boneColor;
|
||||
finalStateColor = state_color.xyz;
|
||||
finalBoneColor = bone_color.xyz;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
vec4 worldPosition = InstanceModelMatrix * pos_4d;
|
||||
vec4 worldPosition = model_mat * pos_4d;
|
||||
world_clip_planes_calc_clip_distance(worldPosition.xyz);
|
||||
#endif
|
||||
}
|
@@ -1,10 +1,4 @@
|
||||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec2 pos; /* bone aligned screen space */
|
||||
in uint flag;
|
||||
@@ -34,12 +28,10 @@ noperspective out float colorFac;
|
||||
flat out vec4 finalWireColor;
|
||||
flat out vec4 finalInnerColor;
|
||||
|
||||
uniform float stickSize = 5.0; /* might be dependent on DPI setting in the future. */
|
||||
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -83,8 +75,9 @@ void main()
|
||||
vpos *= (do_wire) ? 1.0 : 0.5;
|
||||
|
||||
if (finalInnerColor.a > 0.0) {
|
||||
float stick_size = sizePixel * 5.0;
|
||||
gl_Position = (is_head) ? p0 : p1;
|
||||
gl_Position.xy += stickSize * (vpos / viewportSize);
|
||||
gl_Position.xy += stick_size * (vpos * sizeViewportInv.xy);
|
||||
gl_Position.z += (is_bone) ? 0.0 : 1e-6; /* Avoid Z fighting of head/tails. */
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
@@ -0,0 +1,18 @@
|
||||
|
||||
in vec3 color;
|
||||
in vec3 pos;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
finalColor.rgb = color;
|
||||
finalColor.a = 1.0;
|
||||
|
||||
vec3 worldPosition = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(worldPosition);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(worldPosition);
|
||||
#endif
|
||||
}
|
@@ -3,6 +3,8 @@ in vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
@@ -6,7 +6,6 @@
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 10) out;
|
||||
|
||||
uniform vec2 viewportSize;
|
||||
uniform bool showCurveHandles;
|
||||
|
||||
flat in int vertFlag[];
|
||||
@@ -82,9 +81,9 @@ void main()
|
||||
vec4(inner_color.rgb, 0.0);
|
||||
|
||||
vec2 v1_2 = (v2.xy / v2.w - v1.xy / v1.w);
|
||||
vec2 offset = sizeEdge * 4.0 / viewportSize; /* 4.0 is eyeballed */
|
||||
vec2 offset = sizeEdge * 4.0 * sizeViewportInv.xy; /* 4.0 is eyeballed */
|
||||
|
||||
if (abs(v1_2.x * viewportSize.x) < abs(v1_2.y * viewportSize.y)) {
|
||||
if (abs(v1_2.x * sizeViewport.x) < abs(v1_2.y * sizeViewport.y)) {
|
||||
offset.y = 0.0;
|
||||
}
|
||||
else {
|
@@ -1,4 +1,3 @@
|
||||
/* Draw Curve Handles */
|
||||
|
||||
in vec3 pos;
|
||||
in int data;
|
@@ -1,6 +1,3 @@
|
||||
/* Draw Curve Vertices */
|
||||
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
in vec3 pos;
|
||||
in int data;
|
@@ -1,4 +1,3 @@
|
||||
/* Draw Curve Normals */
|
||||
|
||||
uniform float normalSize;
|
||||
|
||||
@@ -7,6 +6,8 @@ in vec3 nor;
|
||||
in vec3 tan;
|
||||
in float rad;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
@@ -22,6 +23,8 @@ void main()
|
||||
vec3 world_pos = point_object_to_world(final_pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor = colorWireEdit;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
@@ -0,0 +1,32 @@
|
||||
|
||||
in vec3 pos;
|
||||
in int data;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
if ((data & VERT_SELECTED) != 0) {
|
||||
finalColor = colorVertexSelect;
|
||||
}
|
||||
else if ((data & VERT_ACTIVE) != 0) {
|
||||
finalColor = colorEditMeshActive;
|
||||
}
|
||||
else {
|
||||
finalColor = colorVertex;
|
||||
}
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
/* Small offset in Z */
|
||||
gl_Position.z -= 3e-4;
|
||||
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
|
||||
uniform sampler1D weightTex;
|
||||
|
||||
in vec3 pos;
|
||||
in float weight;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
#define no_active_weight 666.0
|
||||
|
||||
vec3 weight_to_rgb(float t)
|
||||
{
|
||||
if (t == no_active_weight) {
|
||||
/* No weight. */
|
||||
return colorWire.rgb;
|
||||
}
|
||||
if (t > 1.0 || t < 0.0) {
|
||||
/* Error color */
|
||||
return vec3(1.0, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
return texture(weightTex, t).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
finalColor = vec4(weight_to_rgb(weight), 1.0);
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -12,12 +12,20 @@
|
||||
#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
|
||||
#define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS)
|
||||
|
||||
uniform sampler2D depthTex;
|
||||
uniform float alpha = 1.0;
|
||||
|
||||
flat in vec4 finalColorOuter_f;
|
||||
in vec4 finalColor_f;
|
||||
noperspective in float edgeCoord_f;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
bool test_occlusion()
|
||||
{
|
||||
return gl_FragCoord.z > texelFetch(depthTex, ivec2(gl_FragCoord.xy), 0).r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float dist = abs(edgeCoord_f) - max(sizeEdge - 0.5, 0.0);
|
||||
@@ -33,4 +41,6 @@ void main()
|
||||
FragColor = mix(finalColorOuter_f, finalColor_f, 1.0 - mix_w * finalColorOuter_f.a);
|
||||
/* Line edges shape. */
|
||||
FragColor.a *= 1.0 - (finalColorOuter_f.a > 0.0 ? mix_w_outer : mix_w);
|
||||
|
||||
FragColor.a *= test_occlusion() ? alpha : 1.0;
|
||||
}
|
@@ -2,9 +2,6 @@
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform vec2 viewportSize;
|
||||
uniform vec2 viewportSizeInv;
|
||||
|
||||
in vec4 finalColor[2];
|
||||
in vec4 finalColorOuter[2];
|
||||
in int selectOveride[2];
|
||||
@@ -55,7 +52,7 @@ void main()
|
||||
ss_pos[1] = pos1.xy / pos1.w;
|
||||
|
||||
vec2 line = ss_pos[0] - ss_pos[1];
|
||||
line = abs(line) * viewportSize;
|
||||
line = abs(line) * sizeViewport.xy;
|
||||
|
||||
finalColorOuter_f = finalColorOuter[0];
|
||||
float half_size = sizeEdge;
|
||||
@@ -67,7 +64,7 @@ void main()
|
||||
half_size += 0.5;
|
||||
#endif
|
||||
|
||||
vec3 edge_ofs = half_size * viewportSizeInv.xyy * vec3(1.0, 1.0, 0.0);
|
||||
vec3 edge_ofs = vec3(half_size * sizeViewportInv.xy, 0.0);
|
||||
|
||||
bool horizontal = line.x > line.y;
|
||||
edge_ofs = (horizontal) ? edge_ofs.zyz : edge_ofs.xzz;
|
@@ -0,0 +1,53 @@
|
||||
|
||||
uniform float normalSize;
|
||||
uniform sampler2D depthTex;
|
||||
uniform float alpha = 1.0;
|
||||
|
||||
in vec3 pos;
|
||||
in vec3 lnor;
|
||||
in vec3 vnor;
|
||||
in vec4 norAndFlag;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
bool test_occlusion()
|
||||
{
|
||||
vec3 ndc = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
|
||||
return (ndc.z - 0.00035) > texture(depthTex, ndc.xy).r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 nor;
|
||||
/* Select the right normal by cheking if the generic attrib is used. */
|
||||
if (!all(equal(lnor, vec3(0)))) {
|
||||
nor = lnor;
|
||||
finalColor = colorLNormal;
|
||||
}
|
||||
else if (!all(equal(vnor, vec3(0)))) {
|
||||
nor = vnor;
|
||||
finalColor = colorVNormal;
|
||||
}
|
||||
else {
|
||||
nor = norAndFlag.xyz;
|
||||
finalColor = colorNormal;
|
||||
}
|
||||
|
||||
vec3 n = normalize(normal_object_to_world(nor));
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
|
||||
if (gl_VertexID == 0) {
|
||||
world_pos += n * normalSize;
|
||||
}
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor.a *= (test_occlusion()) ? alpha : 1.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec3 pos;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in float size;
|
||||
in vec3 local_pos;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
mat3 imat = mat3(ModelMatrixInverse);
|
||||
vec3 right = normalize(imat * screenVecs[0].xyz);
|
||||
vec3 up = normalize(imat * screenVecs[1].xyz);
|
||||
vec3 screen_pos = (right * pos.x + up * pos.z) * size;
|
||||
vec4 pos_4d = ModelMatrix * vec4(local_pos + screen_pos, 1.0);
|
||||
gl_Position = ViewProjectionMatrix * pos_4d;
|
||||
/* Manual stipple: one segment out of 2 is transparent. */
|
||||
finalColor = ((gl_VertexID & 1) == 0) ? colorSkinRoot : vec4(0.0);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(pos_4d.xyz);
|
||||
#endif
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
|
||||
uniform float faceAlphaMod;
|
||||
uniform sampler2D depthTex;
|
||||
uniform float alpha = 1.0;
|
||||
uniform ivec4 dataMask = ivec4(0xFF);
|
||||
|
||||
in ivec4 data;
|
||||
@@ -12,11 +13,19 @@ in vec4 norAndFlag;
|
||||
#endif
|
||||
|
||||
out vec4 finalColor;
|
||||
#ifdef EDGE
|
||||
out vec4 finalColorOuter;
|
||||
#endif
|
||||
#ifdef USE_GEOM_SHADER
|
||||
out int selectOveride;
|
||||
#endif
|
||||
|
||||
bool test_occlusion()
|
||||
{
|
||||
vec3 ndc = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
|
||||
return ndc.z > texture(depthTex, ndc.xy).r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
@@ -37,6 +46,8 @@ void main()
|
||||
gl_Position.z -= 1e-7;
|
||||
}
|
||||
|
||||
bool occluded = test_occlusion();
|
||||
|
||||
#elif defined(EDGE)
|
||||
# ifdef FLAT
|
||||
finalColor = EDIT_MESH_edge_color_inner(m_data.y);
|
||||
@@ -50,18 +61,25 @@ void main()
|
||||
float bweight = float(m_data.w) / 255.0;
|
||||
finalColorOuter = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight);
|
||||
|
||||
bool occluded = false; /* Done in fragment shader */
|
||||
|
||||
#elif defined(FACE)
|
||||
finalColor = EDIT_MESH_face_color(m_data.x);
|
||||
finalColor.a *= faceAlphaMod;
|
||||
bool occluded = true;
|
||||
|
||||
#elif defined(FACEDOT)
|
||||
finalColor = EDIT_MESH_facedot_color(norAndFlag.w);
|
||||
|
||||
/* Bias Facedot Z position in clipspace. */
|
||||
gl_Position.z -= 0.00035;
|
||||
gl_PointSize = sizeFaceDot;
|
||||
|
||||
bool occluded = test_occlusion();
|
||||
|
||||
#endif
|
||||
|
||||
finalColor.a *= (occluded) ? alpha : 1.0;
|
||||
|
||||
#if !defined(FACE)
|
||||
/* Facing based color blend */
|
||||
vec3 vpos = point_world_to_view(world_pos);
|
@@ -1,10 +1,18 @@
|
||||
|
||||
in vec3 pos;
|
||||
in float color;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
finalColor = mix(colorWire, colorEdgeSelect, color);
|
||||
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
@@ -0,0 +1,42 @@
|
||||
|
||||
uniform sampler1D weightTex;
|
||||
uniform bool useWeight;
|
||||
|
||||
in vec3 pos;
|
||||
in float color;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
#define no_active_weight 666.0
|
||||
|
||||
vec3 weight_to_rgb(float t)
|
||||
{
|
||||
if (t == no_active_weight) {
|
||||
/* No weight. */
|
||||
return colorWire.rgb;
|
||||
}
|
||||
if (t > 1.0 || t < 0.0) {
|
||||
/* Error color */
|
||||
return vec3(1.0, 0.0, 1.0);
|
||||
}
|
||||
else {
|
||||
return texture(weightTex, t).rgb;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
if (useWeight) {
|
||||
finalColor = vec4(weight_to_rgb(color), 1.0);
|
||||
}
|
||||
else {
|
||||
finalColor = mix(colorWire, colorEdgeSelect, color);
|
||||
}
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
13
source/blender/draw/engines/overlay/shaders/extra_frag.glsl
Normal file
13
source/blender/draw/engines/overlay/shaders/extra_frag.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
noperspective in vec2 edgePos;
|
||||
flat in vec2 edgeStart;
|
||||
flat in vec4 finalColor;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec4 lineOutput;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
lineOutput = pack_line_data(gl_FragCoord.xy, edgeStart, edgePos);
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
/* Instance */
|
||||
in vec3 inst_pos;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
flat out vec2 edgeStart;
|
||||
noperspective out vec2 edgePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
finalColor = colorLight;
|
||||
|
||||
/* Relative to DPI scalling. Have constant screen size. */
|
||||
vec3 screen_pos = screenVecs[0].xyz * pos.x + screenVecs[1].xyz * pos.y;
|
||||
vec3 p = inst_pos;
|
||||
p.z *= (pos.z == 0.0) ? 0.0 : 1.0;
|
||||
float screen_size = mul_project_m4_v3_zfac(p) * sizePixel;
|
||||
vec3 world_pos = p + screen_pos * screen_size;
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
/* Convert to screen position [0..sizeVp]. */
|
||||
edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
|
||||
uniform vec4 color;
|
||||
uniform vec4 innerColor;
|
||||
in vec4 finalColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
@@ -10,10 +9,10 @@ void main()
|
||||
float dist = max(centered.x, centered.y);
|
||||
|
||||
float fac = dist * dist * 4.0;
|
||||
fragColor = mix(innerColor, color, 0.45 + fac * 0.65);
|
||||
fragColor = mix(colorEditMeshMiddle, finalColor, 0.45 + fac * 0.65);
|
||||
|
||||
/* Make the effect more like a fresnel by offsetting
|
||||
* the depth and creating mini-spheres.
|
||||
* Disabled as it has performance impact. */
|
||||
// gl_FragDepth = gl_FragCoord.z + 1e-6 * fac;
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Extract data packed inside the unused mat4 members. */
|
||||
mat4 obmat = ModelMatrix;
|
||||
finalColor = vec4(obmat[0][3], obmat[1][3], obmat[2][3], obmat[3][3]);
|
||||
|
||||
vec3 world_pos = (ModelMatrix * vec4(pos, 1.0)).xyz;
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
|
||||
uniform vec4 color;
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec4 radii;
|
||||
out vec4 fillColor;
|
||||
out vec4 outlineColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
gl_PointSize = sizeObjectCenter;
|
||||
float radius = 0.5 * sizeObjectCenter;
|
||||
float outline_width = sizePixel;
|
||||
radii[0] = radius;
|
||||
radii[1] = radius - 1.0;
|
||||
radii[2] = radius - outline_width;
|
||||
radii[3] = radius - outline_width - 1.0;
|
||||
radii /= sizeObjectCenter;
|
||||
|
||||
fillColor = color;
|
||||
outlineColor = colorOutline;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
227
source/blender/draw/engines/overlay/shaders/extra_vert.glsl
Normal file
227
source/blender/draw/engines/overlay/shaders/extra_vert.glsl
Normal file
@@ -0,0 +1,227 @@
|
||||
|
||||
in vec3 pos;
|
||||
in int vclass;
|
||||
|
||||
/* Instance */
|
||||
in mat4 inst_obmat;
|
||||
in vec4 color;
|
||||
|
||||
#define lamp_area_size inst_data.xy
|
||||
#define lamp_clip_sta inst_data.z
|
||||
#define lamp_clip_end inst_data.w
|
||||
|
||||
#define lamp_spot_cosine inst_data.x
|
||||
#define lamp_spot_blend inst_data.y
|
||||
|
||||
#define camera_corner inst_data.xy
|
||||
#define camera_center inst_data.zw
|
||||
#define camera_dist inst_color_data
|
||||
#define camera_dist_sta inst_data.z
|
||||
#define camera_dist_end inst_data.w
|
||||
#define camera_distance_color inst_data.x
|
||||
|
||||
#define empty_size inst_data.xyz
|
||||
#define empty_scale inst_data.w
|
||||
|
||||
#define VCLASS_LIGHT_AREA_SHAPE (1 << 0)
|
||||
#define VCLASS_LIGHT_SPOT_SHAPE (1 << 1)
|
||||
#define VCLASS_LIGHT_SPOT_BLEND (1 << 2)
|
||||
#define VCLASS_LIGHT_SPOT_CONE (1 << 3)
|
||||
#define VCLASS_LIGHT_DIST (1 << 4)
|
||||
|
||||
#define VCLASS_CAMERA_FRAME (1 << 5)
|
||||
#define VCLASS_CAMERA_DIST (1 << 6)
|
||||
#define VCLASS_CAMERA_VOLUME (1 << 7)
|
||||
|
||||
#define VCLASS_SCREENSPACE (1 << 8)
|
||||
#define VCLASS_SCREENALIGNED (1 << 9)
|
||||
|
||||
#define VCLASS_EMPTY_SCALED (1 << 10)
|
||||
#define VCLASS_EMPTY_AXES (1 << 11)
|
||||
#define VCLASS_EMPTY_AXES_NAME (1 << 12)
|
||||
#define VCLASS_EMPTY_AXES_SHADOW (1 << 13)
|
||||
#define VCLASS_EMPTY_SIZE (1 << 14)
|
||||
|
||||
flat out vec4 finalColor;
|
||||
flat out vec2 edgeStart;
|
||||
noperspective out vec2 edgePos;
|
||||
|
||||
void main()
|
||||
{
|
||||
/* Extract data packed inside the unused mat4 members. */
|
||||
vec4 inst_data = vec4(inst_obmat[0][3], inst_obmat[1][3], inst_obmat[2][3], inst_obmat[3][3]);
|
||||
float inst_color_data = color.a;
|
||||
mat4 obmat = inst_obmat;
|
||||
obmat[0][3] = obmat[1][3] = obmat[2][3] = 0.0;
|
||||
obmat[3][3] = 1.0;
|
||||
|
||||
finalColor = color;
|
||||
if (color.a < 0.0) {
|
||||
finalColor.a = 1.0;
|
||||
}
|
||||
|
||||
float lamp_spot_sine;
|
||||
vec3 vpos = pos;
|
||||
vec3 vofs = vec3(0.0);
|
||||
/* Lights */
|
||||
if ((vclass & VCLASS_LIGHT_AREA_SHAPE) != 0) {
|
||||
/* HACK: use alpha color for spots to pass the area_size. */
|
||||
if (inst_color_data < 0.0) {
|
||||
lamp_area_size.xy = vec2(-inst_color_data);
|
||||
}
|
||||
vpos.xy *= lamp_area_size.xy;
|
||||
}
|
||||
else if ((vclass & VCLASS_LIGHT_SPOT_SHAPE) != 0) {
|
||||
lamp_spot_sine = sqrt(1.0 - lamp_spot_cosine * lamp_spot_cosine);
|
||||
lamp_spot_sine *= ((vclass & VCLASS_LIGHT_SPOT_BLEND) != 0) ? lamp_spot_blend : 1.0;
|
||||
vpos = vec3(pos.xy * lamp_spot_sine, -lamp_spot_cosine);
|
||||
}
|
||||
else if ((vclass & VCLASS_LIGHT_DIST) != 0) {
|
||||
/* Meh nasty mess. Select one of the 6 axes to display on. (see light_distance_z_get()) */
|
||||
int dist_axis = int(pos.z);
|
||||
float dist = pos.z - floor(pos.z) - 0.5;
|
||||
float inv = sign(dist);
|
||||
dist = (abs(dist) > 0.15) ? lamp_clip_end : lamp_clip_sta;
|
||||
vofs[dist_axis] = inv * dist / length(obmat[dist_axis].xyz);
|
||||
vpos.z = 0.0;
|
||||
if (lamp_clip_end < 0.0) {
|
||||
vpos = vofs = vec3(0.0);
|
||||
}
|
||||
}
|
||||
/* Camera */
|
||||
else if ((vclass & VCLASS_CAMERA_FRAME) != 0) {
|
||||
if ((vclass & VCLASS_CAMERA_VOLUME) != 0) {
|
||||
vpos.z = mix(color.b, color.a, pos.z);
|
||||
}
|
||||
else if (camera_dist > 0.0) {
|
||||
vpos.z = -abs(camera_dist);
|
||||
}
|
||||
else {
|
||||
vpos.z *= -abs(camera_dist);
|
||||
}
|
||||
vpos.xy = (camera_center + camera_corner * vpos.xy) * abs(vpos.z);
|
||||
}
|
||||
else if ((vclass & VCLASS_CAMERA_DIST) != 0) {
|
||||
vofs.xy = vec2(0.0);
|
||||
vofs.z = -mix(camera_dist_sta, camera_dist_end, pos.z);
|
||||
vpos.z = 0.0;
|
||||
/* Distance line endpoints color */
|
||||
if (any(notEqual(pos.xy, vec2(0.0)))) {
|
||||
/* Override color. */
|
||||
switch (int(camera_distance_color)) {
|
||||
case 0: /* Mist */
|
||||
finalColor = vec4(0.5, 0.5, 0.5, 1.0);
|
||||
break;
|
||||
case 1: /* Mist Active */
|
||||
finalColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
break;
|
||||
case 2: /* Clip */
|
||||
finalColor = vec4(0.5, 0.5, 0.25, 1.0);
|
||||
break;
|
||||
case 3: /* Clip Active */
|
||||
finalColor = vec4(1.0, 1.0, 0.5, 1.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Focus cross */
|
||||
if (pos.z == 2.0) {
|
||||
vofs.z = 0.0;
|
||||
if (camera_dist < 0.0) {
|
||||
vpos.z = -abs(camera_dist);
|
||||
}
|
||||
else {
|
||||
/* Disabled */
|
||||
vpos = vec3(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Empties */
|
||||
else if ((vclass & VCLASS_EMPTY_SCALED) != 0) {
|
||||
/* This is a bit silly but we avoid scalling the object matrix on CPU (saving a mat4 mul) */
|
||||
vpos *= empty_scale;
|
||||
}
|
||||
else if ((vclass & VCLASS_EMPTY_SIZE) != 0) {
|
||||
/* This is a bit silly but we avoid scalling the object matrix on CPU (saving a mat4 mul) */
|
||||
vpos *= empty_size;
|
||||
}
|
||||
else if ((vclass & VCLASS_EMPTY_AXES) != 0) {
|
||||
float axis = vpos.z;
|
||||
vofs[int(axis)] = (1.0 + fract(axis)) * empty_scale;
|
||||
/* Scale uniformly by axis length */
|
||||
vpos *= length(obmat[int(axis)].xyz) * empty_scale;
|
||||
|
||||
vec3 axis_color = vec3(0.0);
|
||||
axis_color[int(axis)] = 1.0;
|
||||
finalColor.rgb = mix(axis_color + fract(axis), color.rgb, color.a);
|
||||
finalColor.a = 1.0;
|
||||
}
|
||||
|
||||
/* Not exclusive with previous flags. */
|
||||
if ((vclass & VCLASS_CAMERA_VOLUME) != 0) {
|
||||
/* Unpack final color. */
|
||||
int color_class = int(floor(color.r));
|
||||
float color_intensity = fract(color.r);
|
||||
switch (color_class) {
|
||||
case 0: /* No eye (convergence plane) */
|
||||
finalColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
break;
|
||||
case 1: /* Left eye */
|
||||
finalColor = vec4(0.0, 1.0, 1.0, 1.0);
|
||||
break;
|
||||
case 2: /* Right eye */
|
||||
finalColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
break;
|
||||
}
|
||||
finalColor *= vec4(vec3(color_intensity), color.g);
|
||||
}
|
||||
|
||||
vec3 world_pos;
|
||||
if ((vclass & VCLASS_SCREENSPACE) != 0) {
|
||||
/* Relative to DPI scalling. Have constant screen size. */
|
||||
vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
|
||||
vec3 p = (obmat * vec4(vofs, 1.0)).xyz;
|
||||
float screen_size = mul_project_m4_v3_zfac(p) * sizePixel;
|
||||
world_pos = p + screen_pos * screen_size;
|
||||
}
|
||||
else if ((vclass & VCLASS_SCREENALIGNED) != 0) {
|
||||
/* World sized, camera facing geometry. */
|
||||
vec3 screen_pos = screenVecs[0].xyz * vpos.x + screenVecs[1].xyz * vpos.y;
|
||||
world_pos = (obmat * vec4(vofs, 1.0)).xyz + screen_pos;
|
||||
}
|
||||
else {
|
||||
world_pos = (obmat * vec4(vofs + vpos, 1.0)).xyz;
|
||||
}
|
||||
|
||||
if ((vclass & VCLASS_LIGHT_SPOT_CONE) != 0) {
|
||||
/* Compute point on the cone before and after this one. */
|
||||
vec2 perp = vec2(pos.y, -pos.x);
|
||||
const float incr_angle = 2.0 * 3.1415 / 32.0;
|
||||
const vec2 slope = vec2(cos(incr_angle), sin(incr_angle));
|
||||
vec3 p0 = vec3((pos.xy * slope.x + perp * slope.y) * lamp_spot_sine, -lamp_spot_cosine);
|
||||
vec3 p1 = vec3((pos.xy * slope.x - perp * slope.y) * lamp_spot_sine, -lamp_spot_cosine);
|
||||
p0 = (obmat * vec4(p0, 1.0)).xyz;
|
||||
p1 = (obmat * vec4(p1, 1.0)).xyz;
|
||||
/* Compute normals of each side. */
|
||||
vec3 edge = obmat[3].xyz - world_pos;
|
||||
vec3 n0 = normalize(cross(edge, p0 - world_pos));
|
||||
vec3 n1 = normalize(cross(edge, world_pos - p1));
|
||||
bool persp = (ProjectionMatrix[3][3] == 0.0);
|
||||
vec3 V = (persp) ? normalize(ViewMatrixInverse[3].xyz - world_pos) : ViewMatrixInverse[2].xyz;
|
||||
/* Discard non-silhouete edges. */
|
||||
bool facing0 = dot(n0, V) > 0.0;
|
||||
bool facing1 = dot(n1, V) > 0.0;
|
||||
if (facing0 == facing1) {
|
||||
/* Hide line by making it cover 0 pixels. */
|
||||
world_pos = obmat[3].xyz;
|
||||
}
|
||||
}
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
/* Convert to screen position [0..sizeVp]. */
|
||||
edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
|
||||
noperspective in vec2 stipple_coord;
|
||||
flat in vec2 stipple_start;
|
||||
flat in vec4 finalColor;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec4 lineOutput;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
|
||||
/* Stipple */
|
||||
const float dash_width = 6.0;
|
||||
const float dash_factor = 0.5;
|
||||
|
||||
lineOutput = pack_line_data(gl_FragCoord.xy, stipple_start, stipple_coord);
|
||||
|
||||
float dist = distance(stipple_start, stipple_coord);
|
||||
|
||||
if (fragColor.a == 0.0) {
|
||||
/* Disable stippling. */
|
||||
dist = 0.0;
|
||||
}
|
||||
|
||||
fragColor.a = 1.0;
|
||||
|
||||
if (fract(dist / dash_width) > dash_factor) {
|
||||
discard;
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 color;
|
||||
in int colorid; /* if equal 0 (i.e: Not specified) use color attrib and stippling. */
|
||||
|
||||
noperspective out vec2 stipple_coord;
|
||||
flat out vec2 stipple_start;
|
||||
flat out vec4 finalColor;
|
||||
|
||||
vec2 screen_position(vec4 p)
|
||||
{
|
||||
return ((p.xy / p.w) * 0.5 + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
stipple_coord = stipple_start = screen_position(gl_Position);
|
||||
|
||||
#ifdef OBJECT_WIRE
|
||||
/* Extract data packed inside the unused mat4 members. */
|
||||
finalColor = vec4(ModelMatrix[0][3], ModelMatrix[1][3], ModelMatrix[2][3], ModelMatrix[3][3]);
|
||||
#else
|
||||
|
||||
if (colorid == TH_CAMERA_PATH) {
|
||||
finalColor = colorCameraPath;
|
||||
finalColor.a = 0.0; /* No Stipple */
|
||||
}
|
||||
else {
|
||||
finalColor = color;
|
||||
finalColor.a = 1.0; /* Stipple */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -9,7 +9,6 @@ in vec3 local_pos;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform vec3 planeAxes;
|
||||
uniform vec3 screenVecs[2];
|
||||
uniform float gridDistance;
|
||||
uniform float meshSize;
|
||||
uniform float lineKernel = 0.0;
|
||||
@@ -120,7 +119,7 @@ void main()
|
||||
if ((gridFlag & GRID) != 0) {
|
||||
/* Using `max(dot(dFdxPos, screenVecs[0]), dot(dFdyPos, screenVecs[1]))`
|
||||
* would be more accurate, but not really necessary. */
|
||||
float grid_res = dot(dFdxPos, screenVecs[0]);
|
||||
float grid_res = dot(dFdxPos, screenVecs[0].xyz);
|
||||
|
||||
/* The gride begins to appear when it comprises 4 pixels */
|
||||
grid_res *= 4;
|
34
source/blender/draw/engines/overlay/shaders/image_frag.glsl
Normal file
34
source/blender/draw/engines/overlay/shaders/image_frag.glsl
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
uniform sampler2D imgTexture;
|
||||
uniform bool imgPremultiplied;
|
||||
uniform bool imgAlphaBlend;
|
||||
uniform bool imgLinear;
|
||||
uniform vec4 color;
|
||||
|
||||
in vec2 uvs;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uvs_clamped = clamp(uvs, 0.0, 1.0);
|
||||
vec4 tex_color;
|
||||
if (imgLinear) {
|
||||
tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped);
|
||||
}
|
||||
else {
|
||||
tex_color = texture_read_as_srgb(imgTexture, imgPremultiplied, uvs_clamped);
|
||||
}
|
||||
fragColor = tex_color * color;
|
||||
|
||||
if (!imgAlphaBlend) {
|
||||
/* Arbitrary discard anything below 5% opacity.
|
||||
* Note that this could be exposed to the User. */
|
||||
if (tex_color.a < 0.05) {
|
||||
discard;
|
||||
}
|
||||
else {
|
||||
fragColor.a = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
21
source/blender/draw/engines/overlay/shaders/image_vert.glsl
Normal file
21
source/blender/draw/engines/overlay/shaders/image_vert.glsl
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
uniform bool depthSet;
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec2 uvs;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
if (depthSet) {
|
||||
/* Result in a position at 1.0 (far plane). Small epsilon to avoid precision issue.
|
||||
* This mimics the effect of infinite projection matrix
|
||||
* (see http://www.terathon.com/gdc07_lengyel.pdf). */
|
||||
gl_Position.z = gl_Position.w - 2.4e-7;
|
||||
}
|
||||
|
||||
uvs = pos.xy * 0.5 + 0.5;
|
||||
}
|
@@ -2,8 +2,6 @@
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
uniform int lineThickness = 2;
|
||||
|
||||
in vec4 finalColor_geom[];
|
||||
@@ -21,19 +19,26 @@ vec2 compute_dir(vec2 v0, vec2 v1)
|
||||
void main(void)
|
||||
{
|
||||
vec2 t;
|
||||
vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) / viewportSize;
|
||||
vec2 edge_dir = compute_dir(ssPos[0], ssPos[1]) * sizeViewportInv.xy;
|
||||
|
||||
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
|
||||
float line_size = float(lineThickness) * sizePixel;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_set_clip_distance(gl_in[0].gl_ClipDistance);
|
||||
#endif
|
||||
finalColor = finalColor_geom[0];
|
||||
t = edge_dir * (float(lineThickness) * (is_persp ? gl_in[0].gl_Position.w : 1.0));
|
||||
t = edge_dir * (line_size * (is_persp ? gl_in[0].gl_Position.w : 1.0));
|
||||
gl_Position = gl_in[0].gl_Position + vec4(t, 0.0, 0.0);
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[0].gl_Position - vec4(t, 0.0, 0.0);
|
||||
EmitVertex();
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_set_clip_distance(gl_in[1].gl_ClipDistance);
|
||||
#endif
|
||||
finalColor = finalColor_geom[1];
|
||||
t = edge_dir * (float(lineThickness) * (is_persp ? gl_in[1].gl_Position.w : 1.0));
|
||||
t = edge_dir * (line_size * (is_persp ? gl_in[1].gl_Position.w : 1.0));
|
||||
gl_Position = gl_in[1].gl_Position + vec4(t, 0.0, 0.0);
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[1].gl_Position - vec4(t, 0.0, 0.0);
|
@@ -1,16 +1,13 @@
|
||||
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
uniform int frameCurrent;
|
||||
uniform int frameStart;
|
||||
uniform int frameEnd;
|
||||
uniform int cacheStart;
|
||||
uniform ivec4 mpathLineSettings;
|
||||
uniform bool selected;
|
||||
uniform bool useCustomColor;
|
||||
uniform vec3 customColor;
|
||||
|
||||
#define frameCurrent mpathLineSettings.x
|
||||
#define frameStart mpathLineSettings.y
|
||||
#define frameEnd mpathLineSettings.z
|
||||
#define cacheStart mpathLineSettings.w
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
out vec2 ssPos;
|
||||
@@ -19,7 +16,7 @@ out vec4 finalColor_geom;
|
||||
/* project to screen space */
|
||||
vec2 proj(vec4 pos)
|
||||
{
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
||||
return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy;
|
||||
}
|
||||
|
||||
#define SET_INTENSITY(A, B, C, min, max) \
|
||||
@@ -38,10 +35,10 @@ void main()
|
||||
vec3 blend_base = (abs(frame - frameCurrent) == 1) ?
|
||||
colorCurrentFrame.rgb :
|
||||
colorBackground.rgb; /* "bleed" cframe color to ease color blending */
|
||||
|
||||
bool use_custom_color = customColor.x >= 0.0;
|
||||
/* TODO: We might want something more consistent with custom color and standard colors. */
|
||||
if (frame < frameCurrent) {
|
||||
if (useCustomColor) {
|
||||
if (use_custom_color) {
|
||||
/* Custom color: previous frames color is darker than current frame */
|
||||
finalColor_geom.rgb = customColor * 0.25;
|
||||
}
|
||||
@@ -57,7 +54,7 @@ void main()
|
||||
}
|
||||
}
|
||||
else if (frame > frameCurrent) {
|
||||
if (useCustomColor) {
|
||||
if (use_custom_color) {
|
||||
/* Custom color: next frames color is equal to user selected color */
|
||||
finalColor_geom.rgb = customColor;
|
||||
}
|
||||
@@ -74,7 +71,7 @@ void main()
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (useCustomColor) {
|
||||
if (use_custom_color) {
|
||||
/* Custom color: current frame color is slightly darker than user selected color */
|
||||
finalColor_geom.rgb = customColor * 0.5;
|
||||
}
|
||||
@@ -92,4 +89,8 @@ void main()
|
||||
}
|
||||
|
||||
finalColor_geom.a = 1.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(pos);
|
||||
#endif
|
||||
}
|
@@ -1,13 +1,12 @@
|
||||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
uniform int pointSize = 2;
|
||||
uniform int frameCurrent;
|
||||
uniform int cacheStart;
|
||||
uniform ivec4 mpathPointSettings;
|
||||
uniform bool showKeyFrames = true;
|
||||
uniform bool useCustomColor;
|
||||
uniform vec3 customColor;
|
||||
uniform int stepSize;
|
||||
|
||||
#define pointSize mpathPointSettings.x
|
||||
#define frameCurrent mpathPointSettings.y
|
||||
#define cacheStart mpathPointSettings.z
|
||||
#define stepSize mpathPointSettings.w
|
||||
|
||||
in vec3 pos;
|
||||
in int flag;
|
||||
@@ -23,7 +22,8 @@ void main()
|
||||
gl_PointSize = float(pointSize + 2);
|
||||
|
||||
int frame = gl_VertexID + cacheStart;
|
||||
finalColor = (useCustomColor) ? vec4(customColor, 1.0) : vec4(1.0);
|
||||
bool use_custom_color = customColor.x >= 0.0;
|
||||
finalColor = (use_custom_color) ? vec4(customColor, 1.0) : vec4(1.0);
|
||||
|
||||
/* Bias to reduce z fighting with the path */
|
||||
gl_Position.z -= 1e-4;
|
||||
@@ -49,4 +49,10 @@ void main()
|
||||
gl_Position.z -= 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
gl_PointSize *= sizePixel;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(pos);
|
||||
#endif
|
||||
}
|
@@ -8,7 +8,6 @@ uniform sampler2D outlineDepth;
|
||||
uniform sampler2D sceneDepth;
|
||||
|
||||
uniform float alphaOcclu;
|
||||
uniform vec2 viewportSize;
|
||||
|
||||
void main()
|
||||
{
|
@@ -4,12 +4,17 @@ in vec4 nor; /* select flag on the 4th component */
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
bool is_select = (nor.w > 0.0);
|
||||
bool is_hidden = (nor.w < 0.0);
|
||||
|
||||
/* Don't draw faces that are selected. */
|
||||
if (nor.w > 0.0) {
|
||||
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
if (is_hidden || is_select) {
|
||||
gl_Position = vec4(-2.0, -2.0, -2.0, 1.0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
@@ -0,0 +1,32 @@
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 nor; /* select flag on the 4th component */
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
bool is_select = (nor.w > 0.0);
|
||||
bool is_hidden = (nor.w < 0.0);
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
/* Add offset in Z to avoid zfighting and render selected wires on top. */
|
||||
/* TODO scale this bias using znear and zfar range. */
|
||||
gl_Position.z -= (is_select ? 2e-4 : 1e-4);
|
||||
|
||||
if (is_hidden) {
|
||||
gl_Position = vec4(-2.0, -2.0, -2.0, 1.0);
|
||||
}
|
||||
|
||||
finalColor = (is_select) ? vec4(1.0) : colorWire;
|
||||
finalColor.a = nor.w;
|
||||
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
in vec2 uv_interp;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform float opacity = 1.0;
|
||||
|
||||
uniform sampler2D maskImage;
|
||||
uniform bool maskImagePremultiplied;
|
||||
uniform vec3 maskColor;
|
||||
uniform bool maskInvertStencil;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 mask = vec4(texture_read_as_srgb(maskImage, maskImagePremultiplied, uv_interp).rgb, 1.0);
|
||||
if (maskInvertStencil) {
|
||||
mask.rgb = 1.0 - mask.rgb;
|
||||
}
|
||||
float mask_step = smoothstep(0, 3.0, mask.r + mask.g + mask.b);
|
||||
mask.rgb *= maskColor;
|
||||
mask.a = mask_step * opacity;
|
||||
|
||||
fragColor = mask;
|
||||
}
|
@@ -2,14 +2,16 @@
|
||||
in vec3 pos;
|
||||
in vec2 mu; /* masking uv map */
|
||||
|
||||
out vec2 masking_uv_interp;
|
||||
out vec2 uv_interp;
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
masking_uv_interp = mu;
|
||||
uv_interp = mu;
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
@@ -2,7 +2,9 @@
|
||||
in vec3 finalColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform float opacity = 1.0;
|
||||
uniform bool useAlphaBlend = false;
|
||||
|
||||
vec3 linear_to_srgb_attr(vec3 c)
|
||||
{
|
||||
@@ -15,10 +17,12 @@ vec3 linear_to_srgb_attr(vec3 c)
|
||||
void main()
|
||||
{
|
||||
vec3 color = linear_to_srgb_attr(finalColor);
|
||||
#ifdef DRW_STATE_BLEND_ALPHA
|
||||
fragColor = vec4(color, opacity);
|
||||
#else
|
||||
fragColor.rgb = mix(vec3(1.0), color, opacity);
|
||||
fragColor.a = 1.0;
|
||||
#endif
|
||||
|
||||
if (useAlphaBlend) {
|
||||
fragColor = vec4(color, opacity);
|
||||
}
|
||||
else {
|
||||
/* mix with 1.0 -> is like opacity when using multiply blend mode */
|
||||
fragColor = vec4(mix(vec3(1.0), color, opacity), 1.0);
|
||||
}
|
||||
}
|
@@ -14,6 +14,8 @@ vec3 srgb_to_linear_attr(vec3 c)
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
@@ -6,6 +6,7 @@ out vec4 fragColor;
|
||||
uniform float opacity = 1.0;
|
||||
uniform sampler1D colorramp;
|
||||
|
||||
uniform bool useAlphaBlend = false;
|
||||
uniform bool drawContours = false;
|
||||
|
||||
float contours(float value, float steps, float width_px, float max_rel_width, float gradient)
|
||||
@@ -95,11 +96,11 @@ void main()
|
||||
color = mix(weight_color, colorVertexUnreferenced, alert * alert);
|
||||
}
|
||||
|
||||
#ifdef DRW_STATE_BLEND_ALPHA
|
||||
/* alpha blending mix */
|
||||
fragColor = vec4(color.rgb, opacity);
|
||||
#else
|
||||
/* mix with 1.0 -> is like opacity when using multiply blend mode */
|
||||
fragColor = vec4(mix(vec3(1.0), color.rgb, opacity), 1.0);
|
||||
#endif
|
||||
if (useAlphaBlend) {
|
||||
fragColor = vec4(color.rgb, opacity);
|
||||
}
|
||||
else {
|
||||
/* mix with 1.0 -> is like opacity when using multiply blend mode */
|
||||
fragColor = vec4(mix(vec3(1.0), color.rgb, opacity), 1.0);
|
||||
}
|
||||
}
|
@@ -6,6 +6,8 @@ out vec2 weight_interp; /* (weight, alert) */
|
||||
|
||||
void main()
|
||||
{
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
@@ -1,4 +1,6 @@
|
||||
|
||||
uniform bool useSelect;
|
||||
|
||||
in vec3 pos;
|
||||
in vec4 nor; /* flag stored in w */
|
||||
|
||||
@@ -6,13 +8,11 @@ flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef USE_SELECT
|
||||
bool is_select = (nor.w > 0.0);
|
||||
bool is_hidden = (nor.w < 0.0);
|
||||
#else
|
||||
bool is_select = false;
|
||||
bool is_hidden = false;
|
||||
#endif
|
||||
GPU_INTEL_VERTEX_SHADER_WORKAROUND
|
||||
|
||||
bool is_select = (nor.w > 0.0) && useSelect;
|
||||
bool is_hidden = (nor.w < 0.0) && useSelect;
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
/* Add offset in Z to avoid zfighting and render selected wires on top. */
|
||||
@@ -23,30 +23,14 @@ void main()
|
||||
gl_Position = vec4(-2.0, -2.0, -2.0, 1.0);
|
||||
}
|
||||
|
||||
#ifdef VERTEX_MODE
|
||||
vec4 colSel = colorEdgeSelect;
|
||||
colSel.rgb = clamp(colSel.rgb - 0.2, 0.0, 1.0);
|
||||
#else
|
||||
const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
#endif
|
||||
const vec4 colSel = vec4(1.0);
|
||||
|
||||
#ifdef USE_SELECT
|
||||
finalColor = (is_select) ? colSel : colorWire;
|
||||
finalColor.a = nor.w;
|
||||
#else
|
||||
# ifdef VERTEX_MODE
|
||||
finalColor.xyz = colorWire.xyz;
|
||||
finalColor.a = 1.0;
|
||||
# else
|
||||
/* Weight paint needs a light color to contrasts with dark weights. */
|
||||
finalColor = vec4(1, 1, 1, 0.2);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Needed for Radeon (TM) RX 480 Graphics. */
|
||||
#if defined(GPU_ATI)
|
||||
gl_PointSize = sizeVertex * 2.0;
|
||||
#endif
|
||||
/* Weight paint needs a light color to contrasts with dark weights. */
|
||||
if (!useSelect) {
|
||||
finalColor = vec4(1.0, 1.0, 1.0, 0.3);
|
||||
}
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
@@ -0,0 +1,16 @@
|
||||
|
||||
in vec4 finalColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float dist = length(gl_PointCoord - vec2(0.5));
|
||||
|
||||
if (dist > 0.5) {
|
||||
discard;
|
||||
}
|
||||
/* Nice sphere falloff. */
|
||||
float intensity = sqrt(1.0 - dist * 2.0) * 0.5 + 0.5;
|
||||
fragColor = finalColor * vec4(intensity, intensity, intensity, 1.0);
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
|
||||
uniform sampler1D weightTex;
|
||||
uniform vec4 color; /* Drawsize packed in alpha */
|
||||
|
||||
/* ---- Instantiated Attrs ---- */
|
||||
in vec3 pos;
|
||||
in int vclass;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in vec3 part_pos;
|
||||
in vec4 part_rot;
|
||||
in float part_val;
|
||||
|
||||
#ifdef USE_DOTS
|
||||
out vec4 finalColor;
|
||||
#else
|
||||
flat out vec4 finalColor;
|
||||
#endif
|
||||
|
||||
#define VCLASS_SCREENALIGNED (1 << 9)
|
||||
|
||||
#define VCLASS_EMPTY_AXES (1 << 11)
|
||||
|
||||
vec3 rotate(vec3 vec, vec4 quat)
|
||||
{
|
||||
/* The quaternion representation here stores the w component in the first index */
|
||||
return vec + 2.0 * cross(quat.yzw, cross(quat.yzw, vec) + quat.x * vec);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float draw_size = color.a;
|
||||
|
||||
vec3 world_pos = part_pos;
|
||||
|
||||
#ifdef USE_DOTS
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
/* World sized points. */
|
||||
gl_PointSize = sizePixel * draw_size * ProjectionMatrix[1][1] * sizeViewport.y / gl_Position.w;
|
||||
#else
|
||||
|
||||
if ((vclass & VCLASS_SCREENALIGNED) != 0) {
|
||||
/* World sized, camera facing geometry. */
|
||||
world_pos += (screenVecs[0].xyz * pos.x + screenVecs[1].xyz * pos.y) * draw_size;
|
||||
}
|
||||
else {
|
||||
world_pos += rotate(pos, part_rot) * draw_size;
|
||||
}
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
#endif
|
||||
|
||||
/* Coloring */
|
||||
if ((vclass & VCLASS_EMPTY_AXES) != 0) {
|
||||
/* see VBO construction for explanation. */
|
||||
finalColor = vec4(clamp(pos * 10000.0, 0.0, 1.0), 1.0);
|
||||
}
|
||||
else if (part_val < 0.0) {
|
||||
finalColor = vec4(color.rgb, 1.0);
|
||||
}
|
||||
else {
|
||||
finalColor = vec4(texture(weightTex, part_val).rgb, 1.0);
|
||||
}
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
@@ -12,5 +12,9 @@ void main()
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
float mask = 1.0 - (msk * maskOpacity);
|
||||
finalColor = vec4(mask, mask, mask, 1.0);
|
||||
finalColor = vec4(0.0, 0.0, 0.0, mask);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user