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:
-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");