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>2017-03-09 03:29:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-03-09 03:30:26 +0300
commit49ef1a25b8d361a75211c29baa131d6958072685 (patch)
tree0cc20b85a96cd2549ee5c9c8699ec2fa78c69f85 /source/blender/draw/modes
parent4b31f1e5911e32cab3c2971572fae604d2e86808 (diff)
Edit Mesh overlay: Ported Display Normals option
Diffstat (limited to 'source/blender/draw/modes')
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c131
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_face_vert.glsl18
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_geom.glsl15
-rw-r--r--source/blender/draw/modes/shaders/edit_normals_vert.glsl24
4 files changed, 158 insertions, 30 deletions
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index e671e9f059b..1d5b064ebbd 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -35,11 +35,12 @@
/* keep it under MAX_PASSES */
typedef struct EDIT_MESH_PassList {
- struct DRWPass *depth_pass_hidden_wire;
- struct DRWPass *edit_face_overlay_pass;
- struct DRWPass *edit_face_occluded_pass;
- struct DRWPass *mix_occlude_pass;
- struct DRWPass *facefill_occlude_pass;
+ struct DRWPass *depth_hidden_wire;
+ struct DRWPass *edit_face_overlay;
+ struct DRWPass *edit_face_occluded;
+ struct DRWPass *mix_occlude;
+ struct DRWPass *facefill_occlude;
+ struct DRWPass *normals;
} EDIT_MESH_PassList;
/* keep it under MAX_BUFFERS */
@@ -63,6 +64,10 @@ typedef struct EDIT_MESH_Data {
static DRWShadingGroup *depth_shgrp_hidden_wire;
+static DRWShadingGroup *fnormals_shgrp;
+static DRWShadingGroup *vnormals_shgrp;
+static DRWShadingGroup *lnormals_shgrp;
+
static DRWShadingGroup *face_overlay_shgrp;
static DRWShadingGroup *ledges_overlay_shgrp;
static DRWShadingGroup *lverts_overlay_shgrp;
@@ -75,6 +80,7 @@ static DRWShadingGroup *facedot_occluded_shgrp;
static DRWShadingGroup *facefill_occluded_shgrp;
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
+extern struct GlobalsUboStorage ts; /* draw_common.c */
static struct GPUShader *overlay_tri_sh = NULL;
static struct GPUShader *overlay_tri_fast_sh = NULL;
@@ -86,6 +92,9 @@ static struct GPUShader *overlay_vert_sh = NULL;
static struct GPUShader *overlay_facedot_sh = NULL;
static struct GPUShader *overlay_mix_sh = NULL;
static struct GPUShader *overlay_facefill_sh = NULL;
+static struct GPUShader *normals_face_sh = NULL;
+static struct GPUShader *normals_sh = NULL;
+static struct GPUShader *depth_sh = NULL;
extern char datatoc_edit_overlay_frag_glsl[];
extern char datatoc_edit_overlay_vert_glsl[];
@@ -98,6 +107,10 @@ extern char datatoc_edit_overlay_mix_vert_glsl[];
extern char datatoc_edit_overlay_mix_frag_glsl[];
extern char datatoc_edit_overlay_facefill_vert_glsl[];
extern char datatoc_edit_overlay_facefill_frag_glsl[];
+extern char datatoc_edit_normals_vert_glsl[];
+extern char datatoc_edit_normals_geom_glsl[];
+
+extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
static void EDIT_MESH_engine_init(void)
{
@@ -160,6 +173,17 @@ static void EDIT_MESH_engine_init(void)
overlay_facefill_sh = DRW_shader_create(datatoc_edit_overlay_facefill_vert_glsl, NULL,
datatoc_edit_overlay_facefill_frag_glsl, NULL);
}
+ if (!normals_face_sh) {
+ normals_face_sh = DRW_shader_create(datatoc_edit_normals_vert_glsl, datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl, "#define FACE_NORMALS\n");
+ }
+ if (!normals_sh) {
+ normals_sh = DRW_shader_create(datatoc_edit_normals_vert_glsl, datatoc_edit_normals_geom_glsl,
+ datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
+ }
+ if (!depth_sh) {
+ depth_sh = DRW_shader_create_3D_depth_only();
+ }
}
static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWShadingGroup **ledges_shgrp,
@@ -170,9 +194,9 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
const struct bContext *C = DRW_get_context();
RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
+ ToolSettings *tsettings = scene->toolsettings;
- if ((ts->selectmode & SCE_SELECT_VERTEX) != 0) {
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) {
ledge_sh = overlay_edge_vcol_sh;
if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
@@ -199,12 +223,12 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
*ledges_shgrp = DRW_shgroup_create(ledge_sh, pass);
DRW_shgroup_uniform_vec2(*ledges_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
- if ((ts->selectmode & (SCE_SELECT_VERTEX)) != 0) {
+ if ((tsettings->selectmode & (SCE_SELECT_VERTEX)) != 0) {
*lverts_shgrp = DRW_shgroup_create(overlay_vert_sh, pass);
DRW_shgroup_uniform_vec2(*lverts_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
}
- if ((ts->selectmode & (SCE_SELECT_FACE)) != 0) {
+ if ((tsettings->selectmode & (SCE_SELECT_FACE)) != 0) {
*facedot_shgrp = DRW_shgroup_create(overlay_facedot_sh, pass);
}
@@ -213,6 +237,7 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
static float backwire_opacity;
static float face_mod;
+static float size_normal;
static void EDIT_MESH_cache_init(void)
{
@@ -227,35 +252,51 @@ static void EDIT_MESH_cache_init(void)
bool do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0);
static float zero = 0.0f;
- static struct GPUShader *depth_sh;
+
+ {
+ /* Complementary Depth Pass */
+ psl->depth_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_hidden_wire);
+ }
- if (!depth_sh)
- depth_sh = DRW_shader_create_3D_depth_only();
+ {
+ /* Normals */
+ psl->normals = DRW_pass_create("Edit Mesh Normals Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS);
+
+ fnormals_shgrp = DRW_shgroup_create(normals_face_sh, psl->normals);
+ DRW_shgroup_uniform_float(fnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(fnormals_shgrp, "color", ts.colorNormal, 1);
- psl->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
- depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_pass_hidden_wire);
+ vnormals_shgrp = DRW_shgroup_create(normals_sh, psl->normals);
+ DRW_shgroup_uniform_float(vnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(vnormals_shgrp, "color", ts.colorVNormal, 1);
+
+ lnormals_shgrp = DRW_shgroup_create(normals_sh, psl->normals);
+ DRW_shgroup_uniform_float(lnormals_shgrp, "normalSize", &size_normal, 1);
+ DRW_shgroup_uniform_vec4(lnormals_shgrp, "color", ts.colorLNormal, 1);
+ }
if (!do_zbufclip) {
- psl->edit_face_overlay_pass = edit_mesh_create_overlay_pass(&face_overlay_shgrp, &ledges_overlay_shgrp, &lverts_overlay_shgrp,
+ psl->edit_face_overlay = edit_mesh_create_overlay_pass(&face_overlay_shgrp, &ledges_overlay_shgrp, &lverts_overlay_shgrp,
&facedot_overlay_shgrp, &face_mod, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND);
}
else {
/* We render all wires with depth and opaque to a new fbo and blend the result based on depth values */
- psl->edit_face_occluded_pass = edit_mesh_create_overlay_pass(&face_occluded_shgrp, &ledges_occluded_shgrp, &lverts_occluded_shgrp,
+ psl->edit_face_occluded = edit_mesh_create_overlay_pass(&face_occluded_shgrp, &ledges_occluded_shgrp, &lverts_occluded_shgrp,
&facedot_occluded_shgrp, &zero, DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH);
/* 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. */
- psl->facefill_occlude_pass = DRW_pass_create("Front Face Color", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
- facefill_occluded_shgrp = DRW_shgroup_create(overlay_facefill_sh, psl->facefill_occlude_pass);
+ psl->facefill_occlude = DRW_pass_create("Front Face Color", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+ facefill_occluded_shgrp = DRW_shgroup_create(overlay_facefill_sh, psl->facefill_occlude);
DRW_shgroup_uniform_block(facefill_occluded_shgrp, "globalsBlock", globals_ubo, 0);
/* we need a full screen pass to combine the result */
struct Batch *quad = DRW_cache_fullscreen_quad_get();
static float mat[4][4]; /* not even used but avoid crash */
- psl->mix_occlude_pass = DRW_pass_create("Mix Occluded Wires", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
- DRWShadingGroup *mix_shgrp = DRW_shgroup_create(overlay_mix_sh, psl->mix_occlude_pass);
+ psl->mix_occlude = DRW_pass_create("Mix Occluded Wires", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+ DRWShadingGroup *mix_shgrp = DRW_shgroup_create(overlay_mix_sh, psl->mix_occlude);
DRW_shgroup_call_add(mix_shgrp, quad, mat);
DRW_shgroup_uniform_float(mix_shgrp, "alpha", &backwire_opacity, 1);
DRW_shgroup_uniform_buffer(mix_shgrp, "wireColor", &txl->occlude_wire_color_tx, 0);
@@ -268,7 +309,7 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *
DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp)
{
struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
- ToolSettings *ts = scene->toolsettings;
+ ToolSettings *tsettings = scene->toolsettings;
DRW_cache_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
DRW_shgroup_call_add(face_shgrp, geo_ovl_tris, ob->obmat);
@@ -277,10 +318,10 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *
if (facefill_shgrp)
DRW_shgroup_call_add(facefill_shgrp, geo_ovl_tris, ob->obmat);
- if ((ts->selectmode & SCE_SELECT_VERTEX) != 0)
+ if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0)
DRW_shgroup_call_add(lverts_shgrp, geo_ovl_lverts, ob->obmat);
- if ((ts->selectmode & SCE_SELECT_FACE) != 0) {
+ if ((tsettings->selectmode & SCE_SELECT_FACE) != 0) {
geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
DRW_shgroup_call_add(facedot_shgrp, geo_ovl_fcenter, ob->obmat);
}
@@ -298,7 +339,12 @@ static void EDIT_MESH_cache_populate(Object *ob)
if (ob == obedit) {
CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
- backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* should be done only once */
+ backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* Updating uniform */
+
+ bool fnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "face_normals_show");
+ bool vnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "vert_normals_show");
+ bool lnormals_do = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "loop_normals_show");
+ size_normal = BKE_collection_engine_property_value_get_float(ces_mode_ed, "normals_length"); /* Updating uniform */
face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
@@ -307,6 +353,21 @@ static void EDIT_MESH_cache_populate(Object *ob)
DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
}
+ if (fnormals_do) {
+ geom = DRW_cache_face_centers_get(ob);
+ DRW_shgroup_call_add(fnormals_shgrp, geom, ob->obmat);
+ }
+
+ if (vnormals_do) {
+ geom = DRW_cache_verts_get(ob);
+ DRW_shgroup_call_add(vnormals_shgrp, geom, ob->obmat);
+ }
+
+ if (lnormals_do) {
+ geom = DRW_cache_surface_verts_get(ob);
+ DRW_shgroup_call_add(lnormals_shgrp, geom, ob->obmat);
+ }
+
if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
edit_mesh_add_ob_to_pass(scene, ob, face_occluded_shgrp, ledges_occluded_shgrp,
lverts_occluded_shgrp, facedot_occluded_shgrp, facefill_occluded_shgrp);
@@ -327,30 +388,32 @@ static void EDIT_MESH_draw_scene(void)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- DRW_draw_pass(psl->depth_pass_hidden_wire);
+ DRW_draw_pass(psl->depth_hidden_wire);
- if (psl->edit_face_occluded_pass) {
+ if (psl->edit_face_occluded) {
float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* render facefill */
- DRW_draw_pass(psl->facefill_occlude_pass);
+ DRW_draw_pass(psl->facefill_occlude);
/* Render wires on a separate framebuffer */
DRW_framebuffer_bind(fbl->occlude_wire_fb);
DRW_framebuffer_clear(true, true, clearcol, 1.0f);
- DRW_draw_pass(psl->edit_face_occluded_pass);
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_occluded);
/* detach textures */
DRW_framebuffer_texture_detach(dtxl->depth);
/* Combine with scene buffer */
DRW_framebuffer_bind(dfbl->default_fb);
- DRW_draw_pass(psl->mix_occlude_pass);
+ DRW_draw_pass(psl->mix_occlude);
/* reattach */
DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0);
}
else {
- DRW_draw_pass(psl->edit_face_overlay_pass);
+ DRW_draw_pass(psl->normals);
+ DRW_draw_pass(psl->edit_face_overlay);
}
}
@@ -358,6 +421,10 @@ void EDIT_MESH_collection_settings_create(CollectionEngineSettings *ces)
{
BLI_assert(ces);
BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false);
+ BKE_collection_engine_property_add_int(ces, "face_normals_show", false);
+ BKE_collection_engine_property_add_int(ces, "vert_normals_show", false);
+ BKE_collection_engine_property_add_int(ces, "loop_normals_show", false);
+ BKE_collection_engine_property_add_float(ces, "normals_length", 0.1);
BKE_collection_engine_property_add_float(ces, "backwire_opacity", 0.5);
}
@@ -383,6 +450,10 @@ static void EDIT_MESH_engine_free(void)
DRW_shader_free(overlay_mix_sh);
if (overlay_facefill_sh)
DRW_shader_free(overlay_facefill_sh);
+ if (normals_face_sh)
+ DRW_shader_free(normals_face_sh);
+ if (normals_sh)
+ DRW_shader_free(normals_sh);
}
DrawEngineType draw_engine_edit_mesh_type = {
diff --git a/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl
new file mode 100644
index 00000000000..9c70eabc056
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_face_vert.glsl
@@ -0,0 +1,18 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ProjectionMatrix;
+uniform float normalSize;
+
+in vec3 pos;
+in vec4 norAndFlag;
+
+flat out vec4 v1;
+flat out vec4 v2;
+
+void main()
+{
+ v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 n = normalize(NormalMatrix * norAndFlag.xyz); /* viewspace */
+ v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_geom.glsl b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
new file mode 100644
index 00000000000..d17823f2f5a
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_geom.glsl
@@ -0,0 +1,15 @@
+
+layout(points) in;
+layout(line_strip, max_vertices=2) out;
+
+flat in vec4 v1[1];
+flat in vec4 v2[1];
+
+void main()
+{
+ gl_Position = v1[0];
+ EmitVertex();
+ gl_Position = v2[0];
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_normals_vert.glsl b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
new file mode 100644
index 00000000000..3e00181c8dd
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_normals_vert.glsl
@@ -0,0 +1,24 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat3 NormalMatrix;
+uniform mat4 ProjectionMatrix;
+uniform float normalSize;
+
+in vec3 pos;
+
+#ifdef FACE_NORMALS
+in vec4 norAndFlag;
+#define nor norAndFlag.xyz
+#else
+in vec3 nor;
+#endif
+
+flat out vec4 v1;
+flat out vec4 v2;
+
+void main()
+{
+ v1 = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 n = normalize(NormalMatrix * nor); /* viewspace */
+ v2 = v1 + ProjectionMatrix * vec4(n * normalSize, 0.0);
+}