diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-09-04 18:14:46 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-09-04 18:15:00 +0300 |
commit | 30ae0ce0e14666d327a9c2cc5d5e0c9633da1e30 (patch) | |
tree | 01d239d4e2ef75a3c6da58fc796c157abd57e4cd /source/blender | |
parent | 950dcaea109fa93c3cca1fdb2f2c2b344f903104 (diff) |
Xray: Add possibility to select wires in priority before surfaces
If no wires were found, try to select surfaces in a second loop.
Diffstat (limited to 'source/blender')
7 files changed, 127 insertions, 45 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 6d8e8a69e29..d61958931e5 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -119,7 +119,7 @@ void DRW_draw_render_loop_offscreen( void DRW_draw_select_loop( struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d, - bool use_obedit_skip, bool use_nearest, const struct rcti *rect, + bool use_obedit_skip, bool draw_surface, bool use_nearest, const struct rcti *rect, DRW_SelectPassFn select_pass_fn, void *select_pass_user_data, DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data); void DRW_draw_depth_loop( diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index cd64c080e78..73257826e07 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1987,7 +1987,7 @@ void DRW_render_instance_buffer_finish(void) void DRW_draw_select_loop( struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d, - bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect, + bool UNUSED(use_obedit_skip), bool draw_surface, bool UNUSED(use_nearest), const rcti *rect, DRW_SelectPassFn select_pass_fn, void *select_pass_user_data, DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data) { @@ -2037,6 +2037,10 @@ void DRW_draw_select_loop( drw_engines_enable_from_paint_mode(obedit_mode); drw_engines_enable_from_mode(obedit_mode); } + else if (!draw_surface) { + drw_engines_enable_from_overlays(v3d->overlay.flag); + drw_engines_enable_from_object_mode(); + } else { drw_engines_enable_basic(); drw_engines_enable_from_object_mode(); diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index 2e16ba5e847..dc6aa1daa76 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -67,6 +67,7 @@ static struct { /* Face orientation shader */ struct GPUShader *face_orientation_sh; /* Wireframe shader */ + struct GPUShader *select_wireframe_sh; struct GPUShader *face_wireframe_sh; struct GPUShader *face_wireframe_pretty_sh; struct GPUShader *face_wireframe_sculpt_sh; @@ -105,6 +106,14 @@ static void overlay_engine_init(void *vedata) if (!e_data.face_wireframe_sh) { bool use_geom = GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY); + e_data.select_wireframe_sh = DRW_shader_create( + datatoc_overlay_face_wireframe_vert_glsl, + datatoc_overlay_face_wireframe_geom_glsl, + datatoc_overlay_face_wireframe_frag_glsl, + "#define SELECT_EDGES\n" + "#define LIGHT_EDGES\n" + "#define USE_GEOM_SHADER\n"); + e_data.face_wireframe_sh = DRW_shader_create( datatoc_overlay_face_wireframe_vert_glsl, use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL, @@ -207,6 +216,7 @@ static void overlay_cache_populate(void *vedata, Object *ob) OVERLAY_PrivateData *pd = stl->g_data; OVERLAY_PassList *psl = data->psl; const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; if (!stl->g_data->show_overlays) return; @@ -250,13 +260,31 @@ static void overlay_cache_populate(void *vedata, Object *ob) DRWPass *pass = (all_wires) ? psl->face_wireframe_full_pass : psl->face_wireframe_pass; GPUShader *sh = (all_wires) ? e_data.face_wireframe_sh : e_data.face_wireframe_pretty_sh; - DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass); - DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF); - DRW_shgroup_uniform_texture(shgrp, "vertData", verts); - DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids); - DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1); - DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1); - DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob); + if ((DRW_state_is_select() || DRW_state_is_depth()) && + (v3d->shading.flag & V3D_SHADING_XRAY) != 0) + { + static float params[2] = {1.2f, 1.0f}; /* Parameters for all wires */ + + sh = e_data.select_wireframe_sh; + DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1); + DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", (all_wires) + ? params + : stl->g_data->wire_step_param, 1); + DRW_shgroup_uniform_texture(shgrp, "vertData", verts); + DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids); + DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob); + } + else { + DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass); + DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF); + DRW_shgroup_uniform_texture(shgrp, "vertData", verts); + DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids); + DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1); + DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1); + DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob); + } + } } } @@ -291,7 +319,9 @@ static void overlay_draw_scene(void *vedata) OVERLAY_PassList *psl = data->psl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - GPU_framebuffer_bind(dfbl->default_fb); + if (DRW_state_is_fbo()) { + GPU_framebuffer_bind(dfbl->default_fb); + } DRW_draw_pass(psl->face_orientation_pass); DRW_draw_pass(psl->face_wireframe_pass); DRW_draw_pass(psl->face_wireframe_full_pass); @@ -300,6 +330,7 @@ static void overlay_draw_scene(void *vedata) static void overlay_engine_free(void) { DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh); + DRW_SHADER_FREE_SAFE(e_data.select_wireframe_sh); DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh); DRW_SHADER_FREE_SAFE(e_data.face_wireframe_pretty_sh); DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sculpt_sh); diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl index 5dfbb4352e4..ca41ed1ac6c 100644 --- a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl +++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl @@ -1,3 +1,4 @@ +#ifndef SELECT_EDGES uniform vec3 wireColor; uniform vec3 rimColor; @@ -6,11 +7,12 @@ flat in vec3 ssVec1; flat in vec3 ssVec2; in float facing; -#ifdef LIGHT_EDGES +# ifdef LIGHT_EDGES flat in vec3 edgeSharpness; -#endif +# endif out vec4 fragColor; +#endif float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); } float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); } @@ -25,6 +27,7 @@ const float rim_alpha = 0.75; void main() { +#ifndef SELECT_EDGES vec3 ss_pos = vec3(gl_FragCoord.xy, 1.0); vec3 dist_to_edge = vec3( dot(ss_pos, ssVec0), @@ -32,11 +35,11 @@ void main() dot(ss_pos, ssVec2) ); -#ifdef LIGHT_EDGES +# ifdef LIGHT_EDGES vec3 fac = abs(dist_to_edge); -#else +# else float fac = min_v3(abs(dist_to_edge)); -#endif +# endif fac = smoothstep(wire_size + wire_smooth, wire_size, fac); @@ -45,9 +48,10 @@ void main() vec3 final_front_col = mix(rimColor, wireColor, 0.05); fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped); -#ifdef LIGHT_EDGES +# ifdef LIGHT_EDGES fragColor.a *= max_v3(fac * edgeSharpness); -#else +# else fragColor.a *= fac; +# endif #endif } diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl index eb69af92435..a508b59b9f0 100644 --- a/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl +++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl @@ -3,24 +3,32 @@ * than doing everything thrice in the vertex shader. */ layout(triangles) in; +#ifdef SELECT_EDGES +layout(line_strip, max_vertices = 6) out; +#else layout(triangle_strip, max_vertices = 3) out; +#endif uniform vec2 wireStepParam; in vec2 ssPos[]; in float facingOut[]; +#ifndef SELECT_EDGES flat out vec3 ssVec0; flat out vec3 ssVec1; flat out vec3 ssVec2; out float facing; +#endif #ifdef LIGHT_EDGES in vec3 obPos[]; in vec3 vNor[]; in float forceEdge[]; +# ifndef SELECT_EDGES flat out vec3 edgeSharpness; +# endif #endif #define NO_EDGE vec3(10000.0); @@ -53,9 +61,13 @@ void main(void) bvec3 do_edge = greaterThan(abs(facings), vec3(1.0)); facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0); +#ifndef SELECT_EDGES ssVec0 = do_edge.x ? compute_vec(ssPos[0], ssPos[1]) : NO_EDGE; ssVec1 = do_edge.y ? compute_vec(ssPos[1], ssPos[2]) : NO_EDGE; ssVec2 = do_edge.z ? compute_vec(ssPos[2], ssPos[0]) : NO_EDGE; +#else + vec3 edgeSharpness; +#endif #ifdef LIGHT_EDGES vec3 edges[3]; @@ -71,6 +83,34 @@ void main(void) edgeSharpness.y = (forceEdge[1] == 1.0) ? 1.0 : edgeSharpness.y; edgeSharpness.z = (forceEdge[2] == 1.0) ? 1.0 : edgeSharpness.z; #endif + +#ifdef SELECT_EDGES + const float edge_select_threshold = 0.3; + if (edgeSharpness.x > edge_select_threshold) { + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + gl_Position = gl_in[1].gl_Position; + EmitVertex(); + EndPrimitive(); + } + + if (edgeSharpness.y > edge_select_threshold) { + gl_Position = gl_in[1].gl_Position; + EmitVertex(); + gl_Position = gl_in[2].gl_Position; + EmitVertex(); + EndPrimitive(); + } + + if (edgeSharpness.z > edge_select_threshold) { + gl_Position = gl_in[2].gl_Position; + EmitVertex(); + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + EndPrimitive(); + } +#else + gl_Position = gl_in[0].gl_Position; facing = facings.x; EmitVertex(); @@ -83,4 +123,5 @@ void main(void) facing = facings.z; EmitVertex(); EndPrimitive(); +#endif } diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl index 9a34fc740db..5016ceed09e 100644 --- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl +++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl @@ -27,13 +27,13 @@ out float facing; #endif #ifdef LIGHT_EDGES -#ifdef USE_GEOM_SHADER +# ifdef USE_GEOM_SHADER out vec3 obPos; out vec3 vNor; out float forceEdge; -#else +# else flat out vec3 edgeSharpness; -#endif +# endif #endif /* project to screen space */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 8a4a0efad2a..c65c3f16d6d 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -857,7 +857,6 @@ void view3d_opengl_select_cache_end(void) GPU_select_cache_end(); } -#ifndef WITH_OPENGL_LEGACY struct DrawSelectLoopUserData { uint pass; uint hits; @@ -894,7 +893,6 @@ static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data) return continue_pass; } -#endif /* WITH_OPENGL_LEGACY */ /** Implement #VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK. */ static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data) @@ -920,7 +918,7 @@ int view3d_opengl_select( View3D *v3d = vc->v3d; ARegion *ar = vc->ar; rcti rect; - int hits; + int hits = 0; const bool use_obedit_skip = (OBEDIT_FROM_VIEW_LAYER(vc->view_layer) != NULL) && (vc->obedit == NULL); const bool is_pick_select = (U.gpu_select_pick_deph != 0); const bool do_passes = ( @@ -928,6 +926,7 @@ int view3d_opengl_select( (select_mode == VIEW3D_SELECT_PICK_NEAREST) && GPU_select_query_check_active()); const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST); + bool draw_surface = true; char gpu_select_mode; @@ -992,10 +991,8 @@ int view3d_opengl_select( goto finally; } -#ifndef WITH_OPENGL_LEGACY /* All of the queries need to be perform on the drawing context. */ DRW_opengl_context_enable(); -#endif G.f |= G_PICKSEL; @@ -1007,25 +1004,32 @@ int view3d_opengl_select( GPU_depth_test(true); } - if (vc->rv3d->rflag & RV3D_CLIPPING) + if (vc->rv3d->rflag & RV3D_CLIPPING) { ED_view3d_clipping_set(vc->rv3d); + } - -#ifdef WITH_OPENGL_LEGACY - if (IS_VIEWPORT_LEGACY(vc->v3d)) { - GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0); - ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); - hits = GPU_select_end(); - - if (do_passes && (hits > 0)) { - GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); - ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); - GPU_select_end(); - } + /* If in xray mode, we select the wires in priority. */ + if (v3d->shading.flag & V3D_SHADING_XRAY) { + /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop + * because the OpenGL context created & destroyed inside this function. */ + struct DrawSelectLoopUserData drw_select_loop_user_data = { + .pass = 0, + .hits = 0, + .buffer = buffer, + .buffer_len = bufsize, + .rect = &rect, + .gpu_select_mode = gpu_select_mode, + }; + draw_surface = false; + DRW_draw_select_loop( + depsgraph, ar, v3d, + use_obedit_skip, draw_surface, use_nearest, &rect, + drw_select_loop_pass, &drw_select_loop_user_data, + object_filter.fn, object_filter.user_data); + hits = drw_select_loop_user_data.hits; } - else -#else - { + + if (hits == 0) { /* We need to call "GPU_select_*" API's inside DRW_draw_select_loop * because the OpenGL context created & destroyed inside this function. */ struct DrawSelectLoopUserData drw_select_loop_user_data = { @@ -1036,14 +1040,14 @@ int view3d_opengl_select( .rect = &rect, .gpu_select_mode = gpu_select_mode, }; + draw_surface = true; DRW_draw_select_loop( depsgraph, ar, v3d, - use_obedit_skip, use_nearest, &rect, + use_obedit_skip, draw_surface, use_nearest, &rect, drw_select_loop_pass, &drw_select_loop_user_data, object_filter.fn, object_filter.user_data); hits = drw_select_loop_user_data.hits; } -#endif /* WITH_OPENGL_LEGACY */ G.f &= ~G_PICKSEL; ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL); @@ -1055,9 +1059,7 @@ int view3d_opengl_select( if (vc->rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); -#ifndef WITH_OPENGL_LEGACY DRW_opengl_context_disable(); -#endif finally: |