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-05-31 20:01:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-31 20:09:20 +0300
commitbf4ce5755f3699105a1e97793db63f9fc8f7ad9a (patch)
treee9c6855b3305e26dd4def29cea78253e7b7fa507
parent712885c30ef2a8dbde91b7d8b4ffb9784a70fca5 (diff)
Overlay: Add Wireframe overlay.
This overlay is showing mesh topology. It is usable with transparency even if the mesh order can mess up with the expected result (some object more prominent than others). Edge thickness and alpha values are hardcoded for now but can easily be added to theme or object settings.
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py1
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/modes/overlay_mode.c60
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl36
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl106
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_space.c6
7 files changed, 206 insertions, 6 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index fbbb169a64a..f9d9c77bc25 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3593,6 +3593,7 @@ class VIEW3D_PT_overlay(Panel):
col.prop(overlay, "show_all_objects_origin")
col.prop(overlay, "show_relationship_lines")
col.prop(overlay, "show_face_orientation")
+ col.prop(overlay, "show_wireframes")
col.prop(overlay, "show_backface_culling")
col = layout.column()
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 96dd9356109..0eeb6bae09e 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -274,6 +274,8 @@ 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_frag.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)
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index c4b64e03c48..505472460a1 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -25,6 +25,8 @@
#include "DNA_view3d_types.h"
+#include "BKE_object.h"
+
#include "GPU_shader.h"
#include "DRW_render.h"
@@ -37,6 +39,7 @@ typedef struct OVERLAY_StorageList {
typedef struct OVERLAY_PassList {
struct DRWPass *face_orientation_pass;
+ struct DRWPass *face_wireframe_pass;
} OVERLAY_PassList;
typedef struct OVERLAY_Data {
@@ -56,12 +59,18 @@ typedef struct OVERLAY_PrivateData {
static struct {
/* Face orientation shader */
struct GPUShader *face_orientation_sh;
+ /* Wireframe shader */
+ struct GPUShader *face_wireframe_sh;
} e_data = {NULL};
/* Shaders */
extern char datatoc_overlay_face_orientation_frag_glsl[];
extern char datatoc_overlay_face_orientation_vert_glsl[];
+extern char datatoc_overlay_face_wireframe_vert_glsl[];
+extern char datatoc_overlay_face_wireframe_frag_glsl[];
+
+extern struct GlobalsUboStorage ts; /* draw_common.c */
/* Functions */
static void overlay_engine_init(void *vedata)
@@ -77,7 +86,14 @@ static void overlay_engine_init(void *vedata)
if (!e_data.face_orientation_sh) {
/* Face orientation */
e_data.face_orientation_sh = DRW_shader_create(
- datatoc_overlay_face_orientation_vert_glsl, NULL, datatoc_overlay_face_orientation_frag_glsl, "\n");
+ datatoc_overlay_face_orientation_vert_glsl, NULL,
+ datatoc_overlay_face_orientation_frag_glsl, NULL);
+ }
+
+ if (!e_data.face_wireframe_sh) {
+ e_data.face_wireframe_sh = DRW_shader_create(
+ datatoc_overlay_face_wireframe_vert_glsl, NULL,
+ datatoc_overlay_face_wireframe_frag_glsl, NULL);
}
}
@@ -99,11 +115,15 @@ static void overlay_cache_init(void *vedata)
/* Face Orientation Pass */
if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
- int state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
psl->face_orientation_pass = DRW_pass_create("Face Orientation", state);
stl->g_data->face_orientation_shgrp = DRW_shgroup_create(
e_data.face_orientation_sh, psl->face_orientation_pass);
}
+ if (stl->g_data->overlay.flag & V3D_OVERLAY_WIREFRAMES) {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
+ psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
+ }
}
static void overlay_cache_populate(void *vedata, Object *ob)
@@ -111,17 +131,41 @@ static void overlay_cache_populate(void *vedata, Object *ob)
OVERLAY_Data * data = (OVERLAY_Data *)vedata;
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->g_data;
+ OVERLAY_PassList *psl = data->psl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
if (!DRW_object_is_renderable(ob))
return;
- struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- /* Face Orientation */
- if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
+ if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
+ struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat);
}
}
+
+ if (stl->g_data->overlay.flag & V3D_OVERLAY_WIREFRAMES) {
+ /* Don't do that in edit mode. */
+ if ((ob != draw_ctx->object_edit) && !BKE_object_is_in_editmode(ob)) {
+ int tri_count;
+ GPUTexture *verts = NULL, *faceids;
+ DRW_cache_object_face_wireframe_get(ob, &verts, &faceids, &tri_count);
+ if (verts) {
+ float *rim_col = ts.colorWire;
+ if ((ob->base_flag & BASE_SELECTED) != 0) {
+ rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect;
+ }
+ /* TODO(fclem): Compare performance with a geom shader based approach. */
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.face_wireframe_sh, psl->face_wireframe_pass);
+ 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_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, ob->obmat);
+ }
+ }
+ }
}
static void overlay_cache_finish(void *UNUSED(vedata))
@@ -138,11 +182,15 @@ static void overlay_draw_scene(void *vedata)
if (pd->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
DRW_draw_pass(psl->face_orientation_pass);
}
+ if (pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) {
+ DRW_draw_pass(psl->face_wireframe_pass);
+ }
}
static void overlay_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh);
+ DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh);
}
static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data);
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
new file mode 100644
index 00000000000..86e3bb959e9
--- /dev/null
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_frag.glsl
@@ -0,0 +1,36 @@
+uniform vec3 wireColor;
+uniform vec3 rimColor;
+
+flat in vec3 ssVec0;
+flat in vec3 ssVec1;
+flat in vec3 ssVec2;
+in float facing;
+
+out vec4 fragColor;
+
+float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
+
+/* In pixels */
+const float wire_size = 0.0; /* Expands the core of the wire (part that is 100% wire color) */
+const float wire_smooth = 1.4; /* Smoothing distance after the 100% core. */
+
+/* Alpha constants could be exposed in the future. */
+const float front_alpha = 0.55;
+const float rim_alpha = 0.75;
+
+void main()
+{
+ vec3 ss_pos = vec3(gl_FragCoord.xy, 1.0);
+ vec3 dist_to_edge = vec3(
+ dot(ss_pos, ssVec0),
+ dot(ss_pos, ssVec1),
+ dot(ss_pos, ssVec2)
+ );
+
+ float fac = smoothstep(wire_size, wire_size + wire_smooth, min_v3(abs(dist_to_edge)));
+ float facing_clamped = clamp((gl_FrontFacing) ? facing : -facing, 0.0, 1.0);
+
+ vec3 final_front_col = rimColor * 0.5 + wireColor * 0.5;
+ fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
+ fragColor.a *= (1.0 - fac);
+}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
new file mode 100644
index 00000000000..67f4a5c7668
--- /dev/null
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -0,0 +1,106 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat4 ProjectionMatrix;
+uniform mat3 NormalMatrix;
+
+uniform vec2 viewportSize;
+uniform float nearDist;
+
+uniform samplerBuffer vertData;
+uniform isamplerBuffer faceIds;
+
+flat out vec3 ssVec0;
+flat out vec3 ssVec1;
+flat out vec3 ssVec2;
+out float facing;
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+vec3 compute_vec(vec2 v0, vec2 v1)
+{
+ vec2 v = normalize(v1 - v0);
+ v = vec2(-v.y, v.x);
+ return vec3(v, -dot(v, v0));
+}
+
+float short_to_unit_float(uint s)
+{
+ int value = int(s) & 0x7FFF;
+ if ((s & 0x8000u) != 0u) {
+ value |= ~0x7FFF;
+ }
+ return float(value) / float(0x7FFF);
+}
+
+vec3 get_vertex_nor(int v_id)
+{
+ v_id *= 5; /* See vertex format for explanation. */
+ /* Fetch compressed normal as float and unpack them. */
+ vec2 data;
+ data.x = texelFetch(vertData, v_id + 3).r;
+ data.y = texelFetch(vertData, v_id + 4).r;
+
+ uvec2 udata = floatBitsToUint(data);
+
+ vec3 nor;
+ nor.x = short_to_unit_float(udata.x & 0xFFFFu);
+ nor.y = short_to_unit_float(udata.x >> 16u);
+ nor.z = short_to_unit_float(udata.y & 0xFFFFu);
+ return nor;
+}
+
+vec3 get_vertex_pos(int v_id)
+{
+ v_id *= 5; /* See vertex format for explanation. */
+ vec3 pos;
+ pos.x = texelFetch(vertData, v_id).r;
+ pos.y = texelFetch(vertData, v_id + 1).r;
+ pos.z = texelFetch(vertData, v_id + 2).r;
+ return pos;
+}
+
+#define NO_EDGE vec3(10000.0);
+
+void main()
+{
+
+ int v_0 = (gl_VertexID / 3) * 3;
+ int v_n = gl_VertexID % 3;
+ /* Getting the same positions for each of the 3 verts. */
+ ivec3 v_id;
+ v_id.x = texelFetch(faceIds, v_0).r;
+ v_id.y = texelFetch(faceIds, v_0 + 1).r;
+ v_id.z = texelFetch(faceIds, v_0 + 2).r;
+
+ bvec3 do_edge = lessThan(v_id, ivec3(0));
+ v_id = abs(v_id) - 1;
+
+ vec3 pos[3];
+ pos[0] = get_vertex_pos(v_id.x);
+ pos[1] = get_vertex_pos(v_id.y);
+ pos[2] = get_vertex_pos(v_id.z);
+
+ vec4 p_pos[3];
+ p_pos[0] = ModelViewProjectionMatrix * vec4(pos[0], 1.0);
+ p_pos[1] = ModelViewProjectionMatrix * vec4(pos[1], 1.0);
+ p_pos[2] = ModelViewProjectionMatrix * vec4(pos[2], 1.0);
+
+ vec2 ss_pos[3];
+ ss_pos[0] = proj(p_pos[0]);
+ ss_pos[1] = proj(p_pos[1]);
+ ss_pos[2] = proj(p_pos[2]);
+
+ /* Compute the edges screen vectors */
+ ssVec0 = do_edge.x ? compute_vec(ss_pos[0], ss_pos[1]) : NO_EDGE;
+ ssVec1 = do_edge.y ? compute_vec(ss_pos[1], ss_pos[2]) : NO_EDGE;
+ ssVec2 = do_edge.z ? compute_vec(ss_pos[2], ss_pos[0]) : NO_EDGE;
+
+ gl_Position = p_pos[v_n];
+
+ vec3 nor = get_vertex_nor(v_id[v_n]);
+ facing = (NormalMatrix * nor).z;
+}
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 533ea2dbd84..d0a68a9343c 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -357,6 +357,7 @@ enum {
V3D_OVERLAY_HIDE_CURSOR = (1 << 1),
V3D_OVERLAY_BONE_SELECTION = (1 << 2),
V3D_OVERLAY_LOOK_DEV = (1 << 3),
+ V3D_OVERLAY_WIREFRAMES = (1 << 4),
};
/* View3DOverlay->edit_flag */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 4c7b5b3f0a6..19fd87c0735 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2484,6 +2484,12 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Look Dev", "Show Look Development Balls and Palette");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_wireframes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_WIREFRAMES);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Wireframes", "Show face edges wires");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "show_paint_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.paint_flag", V3D_OVERLAY_PAINT_WIRE);
RNA_def_property_ui_text(prop, "Show Wire", "Use wireframe display in painting modes");