Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-09-04 18:14:46 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-09-04 18:15:00 +0300
commit30ae0ce0e14666d327a9c2cc5d5e0c9633da1e30 (patch)
tree01d239d4e2ef75a3c6da58fc796c157abd57e4cd
parent950dcaea109fa93c3cca1fdb2f2c2b344f903104 (diff)
Xray: Add possibility to select wires in priority before surfaces
If no wires were found, try to select surfaces in a second loop.
-rw-r--r--source/blender/draw/DRW_engine.h2
-rw-r--r--source/blender/draw/intern/draw_manager.c6
-rw-r--r--source/blender/draw/modes/overlay_mode.c47
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl18
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_geom.glsl41
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl6
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c52
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: