diff options
Diffstat (limited to 'source/blender/draw/modes')
10 files changed, 236 insertions, 458 deletions
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index f76e0f4a18c..e981b305dfb 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -62,6 +62,7 @@ extern char datatoc_edit_normals_geom_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; +extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_flat_color_frag_glsl[]; extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; extern char datatoc_gpu_shader_depth_only_frag_glsl[]; @@ -103,12 +104,12 @@ typedef struct EDIT_MESH_Shaders { GPUShader *weight_face; /* Geometry */ - GPUShader *overlay_tri_cache[MAX_SHADERS]; - GPUShader *overlay_loose_edge_cache[MAX_SHADERS]; - GPUShader *overlay_vert; - GPUShader *overlay_lvert; + GPUShader *overlay_edge; + GPUShader *overlay_edge_flat; + GPUShader *overlay_face; GPUShader *overlay_facedot; + GPUShader *overlay_mix; GPUShader *overlay_facefill; GPUShader *normals_face; @@ -136,12 +137,10 @@ typedef struct EDIT_MESH_PrivateData { DRWShadingGroup *vnormals_shgrp; DRWShadingGroup *lnormals_shgrp; + DRWShadingGroup *vert_shgrp; + DRWShadingGroup *edge_shgrp; DRWShadingGroup *face_shgrp; DRWShadingGroup *face_cage_shgrp; - - DRWShadingGroup *verts_shgrp; - DRWShadingGroup *ledges_shgrp; - DRWShadingGroup *lverts_shgrp; DRWShadingGroup *facedot_shgrp; DRWShadingGroup *facefill_occluded_shgrp; @@ -157,91 +156,6 @@ typedef struct EDIT_MESH_PrivateData { /* *********** FUNCTIONS *********** */ -static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode) -{ - int result = tsettings->selectmode << 1; - if (supports_fast_mode) { - SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0); - } - return result; -} - -static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias, bool looseedge) -{ - const int selectmode = tsettings->selectmode; - const int fast_mode = rv3d->rflag & RV3D_NAVIGATING; - - char *str = NULL; - DynStr *ds = BLI_dynstr_new(); - - if (selectmode & SCE_SELECT_VERTEX) { - BLI_dynstr_append(ds, "#define VERTEX_SELECTION\n"); - } - - if (selectmode & SCE_SELECT_EDGE) { - BLI_dynstr_append(ds, "#define EDGE_SELECTION\n"); - } - - if (selectmode & SCE_SELECT_FACE) { - BLI_dynstr_append(ds, "#define FACE_SELECTION\n"); - } - - if (!fast_mode || looseedge) { - BLI_dynstr_append(ds, "#define EDGE_FIX\n"); - } - - if (anti_alias) { - BLI_dynstr_append(ds, "#define ANTI_ALIASING\n"); - } - - if (!looseedge) { - BLI_dynstr_append(ds, "#define VERTEX_FACING\n"); - } - str = BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - return str; -} -static GPUShader *EDIT_MESH_ensure_shader( - EDIT_MESH_Shaders *sh_data, - ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode, bool looseedge) -{ - const int index = EDIT_MESH_sh_index(tsettings, rv3d, supports_fast_mode); - const bool fast_mode = (rv3d->rflag & RV3D_NAVIGATING) != 0; - const bool is_clip = (rv3d->rflag & RV3D_CLIPPING) != 0; - const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : ""; - const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : ""; - - if (looseedge) { - if (!sh_data->overlay_loose_edge_cache[index]) { - char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); - char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, true); - sh_data->overlay_loose_edge_cache[index] = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, - .geom = (const char *[]){lib, datatoc_edit_mesh_overlay_geom_edge_glsl, NULL}, - .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, defines, NULL}, - }); - MEM_freeN(lib); - MEM_freeN(defines); - } - return sh_data->overlay_loose_edge_cache[index]; - } - else { - if (!sh_data->overlay_tri_cache[index]) { - char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); - char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true, false); - sh_data->overlay_tri_cache[index] = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, - .geom = fast_mode ? NULL : (const char *[]){lib, datatoc_edit_mesh_overlay_geom_tri_glsl, NULL}, - .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, defines, NULL}, - }); - MEM_freeN(lib); - MEM_freeN(defines); - } - return sh_data->overlay_tri_cache[index]; - } -} static void EDIT_MESH_engine_init(void *vedata) { @@ -277,90 +191,83 @@ static void EDIT_MESH_engine_init(void *vedata) .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->overlay_vert) { char *lib = BLI_string_joinN(world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_common_lib_glsl); + sh_data->overlay_face = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_gpu_shader_3D_smooth_color_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define FACE\n", NULL}, + }); + sh_data->overlay_edge = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", NULL}, + }); + sh_data->overlay_edge_flat = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_edit_mesh_overlay_frag_glsl, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define EDGE\n", "#define FLAT\n", NULL}, + }); sh_data->overlay_vert = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL}, + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define VERT\n", NULL}, }); - - sh_data->overlay_lvert = DRW_shader_create_from_arrays({ - .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_points_vert_glsl, NULL}, + sh_data->overlay_facedot = DRW_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_overlay_vert_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_point_varying_color_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, NULL}, + .defs = (const char *[]){world_clip_def_or_empty, "#define FACEDOT\n", NULL}, }); MEM_freeN(lib); - } - if (!sh_data->overlay_facedot) { - sh_data->overlay_facedot = DRW_shader_create_from_arrays({ - .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_vert_glsl, NULL}, - .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facedot_frag_glsl, NULL}, - .defs = (const char *[]){world_clip_def_or_empty, "#define VERTEX_FACING\n", NULL}, - }); - } - if (!sh_data->overlay_mix) { + sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, NULL); - } - if (!sh_data->overlay_facefill) { + sh_data->overlay_facefill = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_vert_glsl, NULL}, .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->normals_face) { + sh_data->normals_face = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, "#define FACE_NORMALS\n", NULL}, }); - } - if (!sh_data->normals_loop) { + sh_data->normals_loop = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, "#define LOOP_NORMALS\n", NULL}, }); - } - if (!sh_data->normals) { + sh_data->normals = DRW_shader_create_from_arrays({ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_vert_glsl, NULL}, .geom = (const char *[]){world_clip_lib_or_empty, datatoc_edit_normals_geom_glsl, NULL}, .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, .defs = (const char *[]){world_clip_def_or_empty, NULL}, }); - } - if (!sh_data->depth) { + sh_data->depth = DRW_shader_create_3D_depth_only(draw_ctx->shader_slot); - } - if (!sh_data->ghost_clear_depth) { + sh_data->ghost_clear_depth = DRW_shader_create_fullscreen(datatoc_gpu_shader_depth_only_frag_glsl, NULL); } - } static DRWPass *edit_mesh_create_overlay_pass( - float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool xray, + float *face_alpha, float *edge_width_scale, int *data_mask, bool do_edges, bool UNUSED(xray), DRWState statemod, - DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, - DRWShadingGroup **r_verts_shgrp, DRWShadingGroup **r_ledges_shgrp, - DRWShadingGroup **r_lverts_shgrp, DRWShadingGroup **r_facedot_shgrp) + DRWShadingGroup **r_face_shgrp, DRWShadingGroup **r_face_cage_shgrp, DRWShadingGroup **r_facedot_shgrp, + DRWShadingGroup **r_edge_shgrp, DRWShadingGroup **r_vert_shgrp) { - GPUShader *tri_sh, *ledge_sh; const DRWContextState *draw_ctx = DRW_context_state_get(); RegionView3D *rv3d = draw_ctx->rv3d; Scene *scene = draw_ctx->scene; ToolSettings *tsettings = scene->toolsettings; - const int fast_mode = rv3d->rflag & RV3D_NAVIGATING; EDIT_MESH_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_slot]; - - ledge_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, false, true); - tri_sh = EDIT_MESH_ensure_shader(sh_data, tsettings, rv3d, true, false); + const bool select_vert = (tsettings->selectmode & SCE_SELECT_VERTEX) != 0; + const bool select_face = (tsettings->selectmode & SCE_SELECT_FACE) != 0; DRWPass *pass = DRW_pass_create( "Edit Mesh Face Overlay Pass", @@ -368,30 +275,14 @@ static DRWPass *edit_mesh_create_overlay_pass( DRWShadingGroup *grp; - if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { - grp = *r_lverts_shgrp = DRW_shgroup_create(sh_data->overlay_lvert, pass); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); - DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); - DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); - if (rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); - } - - grp = *r_verts_shgrp = DRW_shgroup_create(sh_data->overlay_vert, pass); - DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); - DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); - DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); - DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); - if (rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); - } - } - - if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) { - grp = *r_facedot_shgrp = DRW_shgroup_create(sh_data->overlay_facedot, pass); + /* TEST */ + GPUShader *vert_sh = sh_data->overlay_vert; + GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat; + GPUShader *face_sh = sh_data->overlay_face; + GPUShader *facedot_sh = sh_data->overlay_facedot; + /* Faces */ + if (select_face) { + grp = *r_facedot_shgrp = DRW_shgroup_create(facedot_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_state_enable(grp, DRW_STATE_WRITE_DEPTH); @@ -400,20 +291,13 @@ static DRWPass *edit_mesh_create_overlay_pass( } } - grp = *r_face_shgrp = DRW_shgroup_create(tri_sh, pass); + grp = *r_face_shgrp = DRW_shgroup_create(face_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); DRW_shgroup_uniform_float(grp, "faceAlphaMod", face_alpha, 1); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1); DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges); - if (!fast_mode) { - DRW_shgroup_uniform_bool_copy(grp, "isXray", xray); - } - else { - /* To be able to use triple load. */ - DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION); - } if (rv3d->rflag & RV3D_CLIPPING) { DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); } @@ -422,16 +306,32 @@ static DRWPass *edit_mesh_create_overlay_pass( grp = *r_face_cage_shgrp = DRW_shgroup_create_sub(*r_face_shgrp); DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE); - grp = *r_ledges_shgrp = DRW_shgroup_create(ledge_sh, pass); + /* Edges */ + grp = *r_edge_shgrp = DRW_shgroup_create(edge_sh, pass); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); DRW_shgroup_uniform_ivec4(grp, "dataMask", data_mask, 1); DRW_shgroup_uniform_bool_copy(grp, "doEdges", do_edges); + DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE); + /* To match blender loop structure. */ + DRW_shgroup_state_enable(grp, DRW_STATE_FIRST_VERTEX_CONVENTION); if (rv3d->rflag & RV3D_CLIPPING) { DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); } + /* Verts */ + if (select_vert) { + grp = *r_vert_shgrp = DRW_shgroup_create(vert_sh, pass); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); + DRW_shgroup_uniform_float(grp, "edgeScale", edge_width_scale, 1); + DRW_shgroup_state_enable(grp, DRW_STATE_OFFSET_NEGATIVE | DRW_STATE_WRITE_DEPTH); + DRW_shgroup_state_disable(grp, DRW_STATE_BLEND); + if (rv3d->rflag & RV3D_CLIPPING) { + DRW_shgroup_world_clip_planes_from_rv3d(grp, rv3d); + } + } return pass; } @@ -577,10 +477,9 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND, &stl->g_data->face_shgrp, &stl->g_data->face_cage_shgrp, - &stl->g_data->verts_shgrp, - &stl->g_data->ledges_shgrp, - &stl->g_data->lverts_shgrp, - &stl->g_data->facedot_shgrp); + &stl->g_data->facedot_shgrp, + &stl->g_data->edge_shgrp, + &stl->g_data->vert_shgrp); } else { /* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */ @@ -589,10 +488,9 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH, &stl->g_data->face_shgrp, &stl->g_data->face_cage_shgrp, - &stl->g_data->verts_shgrp, - &stl->g_data->ledges_shgrp, - &stl->g_data->lverts_shgrp, - &stl->g_data->facedot_shgrp); + &stl->g_data->facedot_shgrp, + &stl->g_data->edge_shgrp, + &stl->g_data->vert_shgrp); /* however we loose the front faces value (because we need the depth of occluded wires and * faces are alpha blended ) so we recover them in a new pass. */ @@ -627,7 +525,7 @@ static void edit_mesh_add_ob_to_pass( DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp) { - struct GPUBatch *geom_tris, *geom_verts, *geom_ledges, *geom_ledges_nor, *geom_lverts, *geom_fcenter; + struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter; ToolSettings *tsettings = scene->toolsettings; bool has_edit_mesh_cage = false; @@ -639,30 +537,24 @@ static void edit_mesh_add_ob_to_pass( } DRWShadingGroup *face_shgrp = (has_edit_mesh_cage) ? g_data->face_cage_shgrp : g_data->face_shgrp; - DRWShadingGroup *verts_shgrp = g_data->verts_shgrp; - DRWShadingGroup *ledges_shgrp = g_data->ledges_shgrp; - DRWShadingGroup *lverts_shgrp = g_data->lverts_shgrp; + DRWShadingGroup *vert_shgrp = g_data->vert_shgrp; + DRWShadingGroup *edge_shgrp = g_data->edge_shgrp; geom_tris = DRW_mesh_batch_cache_get_edit_triangles(ob->data); - geom_ledges = DRW_mesh_batch_cache_get_edit_loose_edges(ob->data); + geom_edges = DRW_mesh_batch_cache_get_edit_edges(ob->data); DRW_shgroup_call_add(face_shgrp, geom_tris, ob->obmat); - DRW_shgroup_call_add(ledges_shgrp, geom_ledges, ob->obmat); + DRW_shgroup_call_add(edge_shgrp, geom_edges, ob->obmat); if (facefill_shgrp) { DRW_shgroup_call_add(facefill_shgrp, geom_tris, ob->obmat); } if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { - /* Thoses are point batches. */ geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data); - geom_ledges_nor = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data); - geom_lverts = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data); - DRW_shgroup_call_add(verts_shgrp, geom_verts, ob->obmat); - DRW_shgroup_call_add(lverts_shgrp, geom_ledges_nor, ob->obmat); - DRW_shgroup_call_add(lverts_shgrp, geom_lverts, ob->obmat); + DRW_shgroup_call_add(vert_shgrp, geom_verts, ob->obmat); } - if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0 ) { + if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) { geom_fcenter = DRW_mesh_batch_cache_get_edit_facedots(ob->data); DRW_shgroup_call_add(facedot_shgrp, geom_fcenter, ob->obmat); } @@ -717,15 +609,11 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) } if (vnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_triangles_nor(ob->data); - DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); - geom = DRW_mesh_batch_cache_get_edit_loose_verts(ob->data); - DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); - geom = DRW_mesh_batch_cache_get_edit_loose_edges_nor(ob->data); + geom = DRW_mesh_batch_cache_get_edit_vertices(ob->data); DRW_shgroup_call_add(stl->g_data->vnormals_shgrp, geom, ob->obmat); } if (lnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_triangles_lnor(ob->data); + geom = DRW_mesh_batch_cache_get_edit_lnors(ob->data); DRW_shgroup_call_add(stl->g_data->lnormals_shgrp, geom, ob->obmat); } if (fnormals_do) { diff --git a/source/blender/draw/modes/shaders/common_globals_lib.glsl b/source/blender/draw/modes/shaders/common_globals_lib.glsl index 7b0c48a76e5..1cb8a440469 100644 --- a/source/blender/draw/modes/shaders/common_globals_lib.glsl +++ b/source/blender/draw/modes/shaders/common_globals_lib.glsl @@ -81,3 +81,21 @@ layout(std140) uniform globalsBlock { float pad_globalsBlock; }; + +/* data[0] (1nd byte flags) */ +#define FACE_ACTIVE (1 << 0) +#define FACE_SELECTED (1 << 1) +#define FACE_FREESTYLE (1 << 2) +#define VERT_UV_SELECT (1 << 3) +#define VERT_UV_PINNED (1 << 4) +#define EDGE_UV_SELECT (1 << 5) +#define FACE_UV_ACTIVE (1 << 6) +#define FACE_UV_SELECT (1 << 7) +/* data[1] (2st byte flags) */ +#define VERT_ACTIVE (1 << 0) +#define VERT_SELECTED (1 << 1) +#define EDGE_ACTIVE (1 << 2) +#define EDGE_SELECTED (1 << 3) +#define EDGE_SEAM (1 << 4) +#define EDGE_SHARP (1 << 5) +#define EDGE_FREESTYLE (1 << 6) diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl index 24df1923a66..9000fd7247b 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_handle_geom.glsl @@ -1,6 +1,4 @@ -#define VERTEX_ACTIVE 1 << 0 -#define VERTEX_SELECTED 1 << 1 /* Keep the same value of `ACTIVE_NURB` in `draw_cache_imp_curve.c` */ #define ACTIVE_NURB 1 << 2 #define EVEN_U_BIT 1 << 3 @@ -41,7 +39,7 @@ void main() return; } - bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERTEX_SELECTED) != 0); + bool edge_selected = (((vertFlag[1] | vertFlag[0]) & VERT_SELECTED) != 0); vec4 inner_color; if (color_id == 0) inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree; @@ -50,7 +48,7 @@ void main() else if (color_id == 3) inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign; else if (color_id == 4) inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp; else { - bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERTEX_SELECTED) != 0); + bool is_selected = (((vertFlag[1] & vertFlag[0]) & VERT_SELECTED) != 0); bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0); if (is_u_segment) { inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline; diff --git a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl index 85e38ba3b43..eb0de41a320 100644 --- a/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_curve_overlay_loosevert_vert.glsl @@ -9,13 +9,10 @@ in int data; out vec4 finalColor; -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) - void main() { - if ((data & VERTEX_SELECTED) != 0) { - if ((data & VERTEX_ACTIVE) != 0) { + if ((data & VERT_SELECTED) != 0) { + if ((data & VERT_ACTIVE) != 0) { finalColor = colorEditMeshActive; } else { diff --git a/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl index b2720704dcc..92caa4620d7 100644 --- a/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_lattice_overlay_frag.glsl @@ -1,19 +1,16 @@ flat in int vertFlag; -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) - out vec4 FragColor; void main() { /* TODO: vertex size */ - if ((vertFlag & VERTEX_SELECTED) != 0) { + if ((vertFlag & VERT_SELECTED) != 0) { FragColor = colorVertexSelect; } - else if ((vertFlag & VERTEX_ACTIVE) != 0) { + else if ((vertFlag & VERT_ACTIVE) != 0) { FragColor = colorEditMeshActive; } else { diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl index b37862f2037..59dcf602d43 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_common_lib.glsl @@ -1,24 +1,7 @@ -#define EDGE_EXISTS (1 << 0) -#define EDGE_ACTIVE (1 << 1) -#define EDGE_SELECTED (1 << 2) -#define EDGE_SEAM (1 << 3) -#define EDGE_SHARP (1 << 4) -#define EDGE_FREESTYLE (1 << 5) -#define EDGE_VERTEX_ACTIVE (1 << (0 + 8)) -#define EDGE_VERTEX_SELECTED (1 << (1 + 8)) -#define EDGE_VERTEX_EXISTS (1 << (2 + 8)) - -#define VERTEX_ACTIVE (1 << 0) -#define VERTEX_SELECTED (1 << 1) -#define VERTEX_EXISTS (1 << 2) - -#define FACE_ACTIVE (1 << 3) -#define FACE_SELECTED (1 << 4) -#define FACE_FREESTYLE (1 << 5) uniform bool doEdges = true; -vec4 EDIT_MESH_edge_color_outer(int edge_flag, bool face_active, float crease, float bweight) +vec4 EDIT_MESH_edge_color_outer(int edge_flag, int face_flag, float crease, float bweight) { vec4 color = vec4(0.0); color = ((edge_flag & EDGE_FREESTYLE) != 0) ? colorEdgeFreestyle : color; @@ -27,13 +10,13 @@ vec4 EDIT_MESH_edge_color_outer(int edge_flag, bool face_active, float crease, f color = (bweight > 0.0) ? vec4(colorEdgeBWeight.rgb, bweight) : color; color = ((edge_flag & EDGE_SEAM) != 0) ? colorEdgeSeam : color; - if (face_active) { + if ((face_flag & FACE_ACTIVE) != 0) { color = colorEditMeshActive; } return color; } -vec4 EDIT_MESH_edge_color_inner(int edge_flag, bool face_active) +vec4 EDIT_MESH_edge_color_inner(int edge_flag) { vec4 color = colorWireEdit; #ifdef EDGE_SELECTION @@ -45,9 +28,48 @@ vec4 EDIT_MESH_edge_color_inner(int edge_flag, bool face_active) return color; } -vec4 EDIT_MESH_vertex_color(int vertex_flag) +vec4 EDIT_MESH_edge_vertex_color(int vertex_flag) { vec4 color = colorWireEdit; - color = (doEdges && (vertex_flag & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0) ? colorEdgeSelect : color; + color = (doEdges && (vertex_flag & (VERT_ACTIVE | VERT_SELECTED)) != 0) ? colorEdgeSelect : color; return color; } + +vec4 EDIT_MESH_vertex_color(int vertex_flag) +{ + if ((vertex_flag & VERT_ACTIVE) != 0) { + return vec4(colorEditMeshActive.xyz, 1.0); + } + else if ((vertex_flag & VERT_SELECTED) != 0) { + return colorVertexSelect; + } + else { + return colorVertex; + } +} + +vec4 EDIT_MESH_face_color(int face_flag) +{ + if ((face_flag & FACE_ACTIVE) != 0) { + return colorFaceSelect; + } + else if ((face_flag & FACE_SELECTED) != 0) { + return colorFaceSelect; + } + else if ((face_flag & FACE_FREESTYLE) != 0) { + return colorFaceFreestyle; + } + else { + return colorFace; + } +} + +vec4 EDIT_MESH_facedot_color(float facedot_flag) +{ + if (facedot_flag != 0.0) { + return colorFaceDot; + } + else { + return colorVertex; + } +} diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl index bc46b3fe0f4..d6e1943980a 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_facefill_vert.glsl @@ -8,10 +8,6 @@ in ivec4 data; flat out vec4 faceColor; -#define FACE_ACTIVE (1 << 3) -#define FACE_SELECTED (1 << 4) -#define FACE_FREESTYLE (1 << 5) - void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl index c6cbd712d40..248d9de7aee 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_frag.glsl @@ -1,154 +1,36 @@ -/* Solid Wirefram implementation - * Mike Erwin, Clément Foucault */ - -uniform float faceAlphaMod; uniform float edgeScale; uniform bool isXray = false; -flat in vec3 edgesCrease; -flat in vec3 edgesBweight; -flat in vec4 faceColor; -flat in ivec3 flag; -#ifdef VERTEX_SELECTION -in vec3 vertexColor; -#endif +flat in vec4 finalColorStipple; +in float dist; +flat in float base_dist; -#ifdef EDGE_FIX -flat in vec2 ssPos[3]; +#ifdef FLAT +flat in vec4 finalColor; #else -in vec3 barycentric; -#endif - -#ifdef VERTEX_FACING -in float facing; +in vec4 finalColor; +# ifdef EDGE +flat in int selectOveride; +# endif #endif out vec4 FragColor; -/* Vertex flag is shifted and combined with the edge flag */ -#define FACE_ACTIVE_ (FACE_ACTIVE << 8) - -#define LARGE_EDGE_SIZE 2.15 - -/* Enough to visually fill gaps and not enough to mess the AA gradient too much. */ -#define EDGE_FIX_ALPHA 0.67 - -void distToEdgesAndPoints(out vec3 edges, out vec3 points) -{ -#ifdef EDGE_FIX - vec2 e0 = normalize(ssPos[1] - ssPos[0] + 1e-8); - vec2 e1 = normalize(ssPos[2] - ssPos[1] + 1e-8); - vec2 e2 = normalize(ssPos[0] - ssPos[2] + 1e-8); - e0 = vec2(-e0.y, e0.x); - e1 = vec2(-e1.y, e1.x); - e2 = vec2(-e2.y, e2.x); - vec2 p0 = gl_FragCoord.xy - ssPos[0]; - vec2 p1 = gl_FragCoord.xy - ssPos[1]; - vec2 p2 = gl_FragCoord.xy - ssPos[2]; - edges.z = abs(dot(e0, p0)); - edges.x = abs(dot(e1, p1)); - edges.y = abs(dot(e2, p2)); -#else - vec3 dx = dFdx(barycentric); - vec3 dy = dFdy(barycentric); - /* per component derivative */ - vec2 d0 = vec2(dx.x, dy.x); - vec2 d1 = vec2(dx.y, dy.y); - vec2 d2 = vec2(dx.z, dy.z); - vec3 d = vec3(length(d0), length(d1), length(d2)); - - edges = abs(vec3(barycentric / d)); -#endif - -#if defined(VERTEX_SELECTION) && defined(EDGE_FIX) - points.x = dot(p0, p0); - points.y = dot(p1, p1); - points.z = dot(p2, p2); - points = sqrt(points); -#else - points = vec3(1e10); -#endif -} - -void colorDist(vec4 color, float dist) -{ - FragColor = (dist < 0) ? color : FragColor; -} - -#ifdef ANTI_ALIASING -void colorDistEdge(vec4 color, float dist) -{ - FragColor.rgb *= FragColor.a; - FragColor = mix(color, FragColor, clamp(dist, 0.0, 1.0)); - FragColor.rgb /= max(1e-8, FragColor.a); -} -#else -#define colorDistEdge colorDist -#endif - void main() { - vec3 e, p; - distToEdgesAndPoints(e, p); - - /* Face */ - FragColor = faceColor; - FragColor.a *= faceAlphaMod; - - /* Edges */ - float sizeEdgeFinal = sizeEdge * edgeScale; - - for (int v = 0; v < 3; ++v) { - if ((flag[v] & EDGE_EXISTS) != 0) { - /* Outer large edge */ - float largeEdge = e[v] - sizeEdgeFinal * LARGE_EDGE_SIZE; - - vec4 large_edge_color = EDIT_MESH_edge_color_outer(flag[v], (flag[0] & FACE_ACTIVE_) != 0, edgesCrease[v], edgesBweight[v]); -#ifdef EDGE_FIX - large_edge_color *= isXray ? 1.0 : EDGE_FIX_ALPHA; -#endif - if (large_edge_color.a != 0.0) { - colorDistEdge(large_edge_color, largeEdge); - } - - /* Inner thin edge */ - float innerEdge = e[v] - sizeEdgeFinal; -#ifdef ANTI_ALIASING - innerEdge += 0.4; -#endif - -#ifdef VERTEX_SELECTION - vec4 inner_edge_color = vec4(vertexColor, 1.0); -#else - vec4 inner_edge_color = EDIT_MESH_edge_color_inner(flag[v], (flag[0] & FACE_ACTIVE_) != 0); -#endif -#ifdef EDGE_FIX - inner_edge_color *= isXray ? 1.0 : EDGE_FIX_ALPHA; -#endif - colorDistEdge(inner_edge_color, innerEdge); - } - } - -#if defined(VERTEX_SELECTION) && defined(EDGE_FIX) - /* Points */ - for (int v = 0; v < 3; ++v) { - if ((flag[v] & EDGE_VERTEX_EXISTS) != 0) { - float size = p[v] - sizeVertex; - vec4 point_color = colorVertex; - point_color = ((flag[v] & EDGE_VERTEX_SELECTED) != 0) ? colorVertexSelect : point_color; - point_color = ((flag[v] & EDGE_VERTEX_ACTIVE) != 0) ? vec4(colorEditMeshActive.xyz, 1.0) : point_color; - colorDist(point_color, size); - } + float dist_px = dist - base_dist; + dist_px /= fwidth(dist_px); + float mix_fac = step(0.5, fract(abs(dist_px) * (1.0 / 20.0))); + if (finalColorStipple.a == 0.0) { + mix_fac = 1.0; } +#if defined(EDGE) && !defined(FLAT) + vec4 prim_col = mix(colorEditMeshMiddle, colorEdgeSelect, finalColor.a); + prim_col = (selectOveride != 0) ? prim_col : finalColor; + prim_col.a = 1.0; +#else +# define prim_col finalColor #endif - -#ifdef VERTEX_FACING - FragColor.rgb = mix(colorEditMeshMiddle.rgb, FragColor.rgb, 1.0 - abs(facing) * 0.4); -#endif - - /* don't write depth if not opaque */ - if (FragColor.a == 0.0) { - discard; - } + FragColor = mix(finalColorStipple, prim_col, mix_fac); } diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl index 8b9bcb33fae..2c906412ed2 100644 --- a/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_vert.glsl @@ -1,115 +1,99 @@ -/* Solid Wirefram implementation - * Mike Erwin, Clément Foucault */ - uniform mat3 NormalMatrix; uniform mat4 ProjectionMatrix; uniform mat4 ModelViewMatrix; uniform mat4 ModelViewProjectionMatrix; uniform mat4 ModelMatrix; +uniform float faceAlphaMod; uniform ivec4 dataMask = ivec4(0xFF); +in ivec4 data; in vec3 pos; -#ifdef VERTEX_FACING +#ifndef FACEDOT in vec3 vnor; +#else +in vec4 norAndFlag; +# define vnor norAndFlag.xyz #endif -#ifdef EDGE_FIX -in ivec4 data; +#ifdef EDGE +flat out vec4 finalColorStipple; +flat out float base_dist; +out float dist; +#endif -out vec4 pPos; -out ivec4 vData; -# ifdef VERTEX_FACING -out float vFacing; +#ifdef FLAT +flat out vec4 finalColor; +#else +out vec4 finalColor; +# ifdef EDGE +flat out int selectOveride; # endif +#endif void main() { - pPos = ModelViewProjectionMatrix * vec4(pos, 1.0); - vData = data & dataMask; -# ifdef VERTEX_FACING - vec4 vpos = ModelViewMatrix * vec4(pos, 1.0); - vec3 view_normal = normalize(NormalMatrix * vnor); - vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) - ? normalize(vpos.xyz) - : vec3(0.0, 0.0, 1.0); - vFacing = dot(view_vec, view_normal); -# endif + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); -# ifdef USE_WORLD_CLIP_PLANES - world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); -# endif -} + ivec4 m_data = data & dataMask; -#else /* EDGE_FIX */ - -/* Consecutive data of the nth vertex. - * Only valid for first vertex in the triangle. - * Assuming GL_FRIST_VERTEX_CONVENTION. */ -in ivec4 data0; -in ivec4 data1; -in ivec4 data2; - -flat out vec3 edgesCrease; -flat out vec3 edgesBweight; -flat out vec4 faceColor; -flat out ivec3 flag; -# ifdef VERTEX_SELECTION -out vec3 vertexColor; -# endif -# ifdef VERTEX_FACING -out float facing; +#if defined(VERT) + finalColor = EDIT_MESH_vertex_color(m_data.y); + gl_PointSize = sizeVertex * 2.0; + gl_Position.z -= 3e-5 * ((ProjectionMatrix[3][3] == 0.0) ? 1.0 : 0.0); + /* Make selected and active vertex always on top. */ + if ((data.x & VERT_SELECTED) != 0) { + gl_Position.z -= 1e-7; + } + if ((data.x & VERT_ACTIVE) != 0) { + gl_Position.z -= 1e-7; + } + +#elif defined(EDGE) +# ifdef FLAT + finalColor = EDIT_MESH_edge_color_inner(m_data.y); +# else + finalColor = EDIT_MESH_edge_vertex_color(m_data.y); + selectOveride = (m_data.y & EDGE_SELECTED); # endif -out vec3 barycentric; + float crease = float(m_data.z) / 255.0; + float bweight = float(m_data.w) / 255.0; + finalColorStipple = EDIT_MESH_edge_color_outer(m_data.y, m_data.x, crease, bweight); + base_dist = dist = float(gl_VertexID % 128); -void main() -{ - gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +#elif defined(FACE) + finalColor = EDIT_MESH_face_color(m_data.x); + finalColor.a *= faceAlphaMod; - int v_0 = (gl_VertexID / 3) * 3; - int vidx = gl_VertexID % 3; - barycentric = vec3(equal(ivec3(0, 1, 2), ivec3(vidx))); - - /* Edge */ - ivec4 vData[3] = ivec4[3](data0, data1, data2); - ivec3 eflag; - for (int v = 0; v < 3; ++v) { - vData[v] = vData[v] & dataMask; - flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8); - edgesCrease[v] = vData[v].z / 255.0; - edgesBweight[v] = vData[v].w / 255.0; - } +#elif defined(FACEDOT) + finalColor = EDIT_MESH_facedot_color(norAndFlag.w); + /* Bias Facedot Z position in clipspace. */ + gl_Position.z -= 0.00035; + gl_PointSize = sizeFaceDot; - /* Face */ - if ((vData[0].x & FACE_ACTIVE) != 0) { - faceColor = colorFaceSelect; - } - else if ((vData[0].x & FACE_SELECTED) != 0) { - faceColor = colorFaceSelect; - } - else if ((vData[0].x & FACE_FREESTYLE) != 0) { - faceColor = colorFaceFreestyle; - } - else { - faceColor = colorFace; - } +#endif -# ifdef VERTEX_SELECTION - vertexColor = EDIT_MESH_vertex_color(data0.x).rgb; -# endif -# ifdef VERTEX_FACING - vec4 vPos = ModelViewMatrix * vec4(pos, 1.0); +#ifndef FACE + vec4 vpos = ModelViewMatrix * vec4(pos, 1.0); vec3 view_normal = normalize(NormalMatrix * vnor); vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) - ? normalize(vPos.xyz) + ? normalize(vpos.xyz) : vec3(0.0, 0.0, 1.0); - facing = dot(view_vec, view_normal); -# endif + float facing = dot(view_vec, view_normal); + facing = 1.0 - abs(facing) * 0.3; -# ifdef USE_WORLD_CLIP_PLANES - world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); + finalColor = mix(colorEditMeshMiddle, finalColor, facing); + finalColor.a = 1.0; + +# if defined(EDGE) && !defined(FLAT) + /* Hack to blend color in pixel shader in case of overide. */ + finalColor.a = facing; # endif -} #endif + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz); +#endif +} diff --git a/source/blender/draw/modes/shaders/paint_vert_frag.glsl b/source/blender/draw/modes/shaders/paint_vert_frag.glsl index 2e83362b90f..3042ddf9770 100644 --- a/source/blender/draw/modes/shaders/paint_vert_frag.glsl +++ b/source/blender/draw/modes/shaders/paint_vert_frag.glsl @@ -2,15 +2,11 @@ flat in vec4 finalColor; out vec4 fragColor; -#define VERTEX_SELECTED (1 << 0) - void main() { vec2 centered = gl_PointCoord - vec2(0.5); float dist_squared = dot(centered, centered); const float rad_squared = 0.25; - const vec4 colSel = vec4(1.0, 1.0, 1.0, 1.0); - const vec4 colUnsel = vec4(0.0, 0.0, 0.0, 1.0); // round point with jaggy edges if (dist_squared > rad_squared) { |