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-02 03:07:03 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-03-02 03:08:32 +0300
commitb463cd2ab8f1a48200e6b348002ac88d3a8507ca (patch)
tree0dc31f194e4ab344657651484dc2f65054ed2faa /source/blender/draw
parentaa102283daf0fd7a6a59d241c0b353f3e0ecfffc (diff)
Edit Mode overlay: Moved Shaders to draw modules and resolved some draw issue.
We don't want to clutter gpu_shader.c with engine specific code Added face's center dot Simplified loose vert shader
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt10
-rw-r--r--source/blender/draw/engines/clay/clay.c2
-rw-r--r--source/blender/draw/engines/clay/clay.h2
-rw-r--r--source/blender/draw/intern/draw_cache.c11
-rw-r--r--source/blender/draw/intern/draw_cache.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c4
-rw-r--r--source/blender/draw/intern/draw_mode_pass.c2
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c154
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.h2
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_facedot_frag.glsl55
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_facedot_vert.glsl57
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_frag.glsl223
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_geom_edge.glsl186
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_geom_tri.glsl314
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_loosevert_vert.glsl91
-rw-r--r--source/blender/draw/modes/shaders/edit_overlay_vert.glsl23
16 files changed, 1103 insertions, 34 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 12722ff23ef..ea1d179aa40 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -27,7 +27,7 @@ set(INC
.
intern
engines/clay
- modes/
+ modes
../blenkernel
../blenlib
@@ -82,6 +82,14 @@ data_to_c_simple(engines/clay/shaders/clay_vert.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_alchemy.glsl SRC)
data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_geom_tri.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_geom_edge.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_loosevert_vert.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_facedot_frag.glsl SRC)
+data_to_c_simple(modes/shaders/edit_overlay_facedot_vert.glsl SRC)
+
list(APPEND INC
)
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index 54bae5de85c..bde1ffe2fa7 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -754,7 +754,7 @@ static void CLAY_collection_settings_create(RenderEngine *UNUSED(engine), Collec
BKE_collection_engine_property_add_float(ces, "ssao_factor_edge", 1.0f);
}
-void clay_engine_free(void)
+void CLAY_engine_free(void)
{
/* data.depth_sh Is builtin so it's automaticaly freed */
if (data.clay_sh) {
diff --git a/source/blender/draw/engines/clay/clay.h b/source/blender/draw/engines/clay/clay.h
index add2a45fbd7..34dd74b9500 100644
--- a/source/blender/draw/engines/clay/clay.h
+++ b/source/blender/draw/engines/clay/clay.h
@@ -31,6 +31,6 @@ extern RenderEngineType viewport_clay_type;
struct RenderEngineSettings *CLAY_render_settings_create(void);
struct MaterialEngineSettings *CLAY_material_settings_create(void);
-void clay_engine_free(void);
+void CLAY_engine_free(void);
#endif /* __CLAY_H__ */
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index f8d81458435..c16e7c23f0d 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -868,8 +868,6 @@ Batch *DRW_cache_single_vert_get(void)
/* Meshes */
void DRW_cache_wire_overlay_get(Object *ob, Batch **tris, Batch **ledges, Batch **lverts)
{
- Batch *overlay_wire = NULL;
-
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
@@ -877,8 +875,15 @@ void DRW_cache_wire_overlay_get(Object *ob, Batch **tris, Batch **ledges, Batch
*tris = BKE_mesh_batch_cache_get_overlay_triangles(me);
*ledges = BKE_mesh_batch_cache_get_overlay_loose_edges(me);
*lverts = BKE_mesh_batch_cache_get_overlay_loose_verts(me);
+}
+
+Batch *DRW_cache_face_centers_get(Object *ob)
+{
+ BLI_assert(ob->type == OB_MESH);
+
+ Mesh *me = ob->data;
- return overlay_wire;
+ return BKE_mesh_batch_cache_get_overlay_facedots(me);
}
Batch *DRW_cache_wire_outline_get(Object *ob)
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index f34dc54729a..042bc65b17c 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -63,6 +63,7 @@ struct Batch *DRW_cache_bone_arrows_get(void);
/* Meshes */
void DRW_cache_wire_overlay_get(
struct Object *ob, struct Batch **tris, struct Batch **ledges, struct Batch **lverts);
+struct Batch *DRW_cache_face_centers_get(struct Object *ob);
struct Batch *DRW_cache_wire_outline_get(struct Object *ob);
struct Batch *DRW_cache_surface_get(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index c9e788fd8a8..d4b773f8d1b 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1372,7 +1372,9 @@ extern struct GPUUniformBuffer *globals_ubo; /* draw_mode_pass.c */
void DRW_engines_free(void)
{
#ifdef WITH_CLAY_ENGINE
- clay_engine_free();
+ CLAY_engine_free();
+
+ EDIT_MESH_engine_free();
DRW_shape_cache_free();
diff --git a/source/blender/draw/intern/draw_mode_pass.c b/source/blender/draw/intern/draw_mode_pass.c
index 1d16ef26f56..7bf34c4a9b1 100644
--- a/source/blender/draw/intern/draw_mode_pass.c
+++ b/source/blender/draw/intern/draw_mode_pass.c
@@ -113,7 +113,7 @@ void DRW_update_global_values(void)
/* M_SQRT2 to be at least the same size of the old square */
ts.sizeVertex = UI_GetThemeValuef(TH_VERTEX_SIZE) * M_SQRT2 / 2.0f;
- ts.sizeFaceDot = UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2 / 2.0f;
+ ts.sizeFaceDot = UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2;
ts.sizeEdge = 1.0f / 2.0f; /* TODO Theme */
ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * M_SQRT1_2);
ts.sizeNormal = 1.0f; /* TODO compute */
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 1f394870c40..4177e7b843f 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -46,43 +46,117 @@ static DRWShadingGroup *depth_shgrp_hidden_wire;
static DRWShadingGroup *face_overlay_shgrp;
static DRWShadingGroup *ledges_overlay_shgrp;
static DRWShadingGroup *lverts_overlay_shgrp;
+static DRWShadingGroup *facedot_overlay_shgrp;
extern struct GPUUniformBuffer *globals_ubo; /* draw_mode_pass.c */
+static struct GPUShader *overlay_tri_sh = NULL;
+static struct GPUShader *overlay_tri_fast_sh = NULL;
+static struct GPUShader *overlay_tri_vcol_sh = NULL;
+static struct GPUShader *overlay_tri_vcol_fast_sh = NULL;
+static struct GPUShader *overlay_edge_sh = NULL;
+static struct GPUShader *overlay_edge_vcol_sh = NULL;
+static struct GPUShader *overlay_vert_sh = NULL;
+static struct GPUShader *overlay_facedot_sh = NULL;
+
+extern char datatoc_edit_overlay_frag_glsl[];
+extern char datatoc_edit_overlay_vert_glsl[];
+extern char datatoc_edit_overlay_geom_tri_glsl[];
+extern char datatoc_edit_overlay_geom_edge_glsl[];
+extern char datatoc_edit_overlay_loosevert_vert_glsl[];
+extern char datatoc_edit_overlay_facedot_frag_glsl[];
+extern char datatoc_edit_overlay_facedot_vert_glsl[];
+
void EDIT_MESH_cache_init(void)
{
EDIT_MESH_PassList *psl = DRW_mode_pass_list_get();
- static struct GPUShader *depth_sh;
- static struct GPUShader *over_tri_sh, *over_vert_sh, *over_edge_sh, *over_tri_fast_sh;
+ static struct GPUShader *depth_sh, *tri_sh, *ledge_sh;
const struct bContext *C = DRW_get_context();
struct RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
if (!depth_sh)
depth_sh = DRW_shader_create_3D_depth_only();
- if (!over_tri_fast_sh)
- over_tri_fast_sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_OVERLAY_EDIT_TRI_FAST);
- if (!over_tri_sh)
- over_tri_sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_OVERLAY_EDIT_TRI);
- if (!over_edge_sh)
- over_edge_sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_OVERLAY_EDIT_EDGE);
- if (!over_vert_sh)
- over_vert_sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_OVERLAY_EDIT_VERT);
+
+ if (!overlay_tri_sh) {
+ overlay_tri_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_tri_glsl,
+ datatoc_edit_overlay_frag_glsl, "#define EDGE_FIX\n");
+ }
+ if (!overlay_tri_fast_sh) {
+ overlay_tri_fast_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_tri_glsl,
+ datatoc_edit_overlay_frag_glsl, NULL);
+ }
+ if (!overlay_tri_vcol_sh) {
+ overlay_tri_vcol_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_tri_glsl,
+ datatoc_edit_overlay_frag_glsl, "#define EDGE_FIX\n"
+ "#define VERTEX_SELECTION\n");
+ }
+ if (!overlay_tri_vcol_fast_sh) {
+ overlay_tri_vcol_fast_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_tri_glsl,
+ datatoc_edit_overlay_frag_glsl, "#define VERTEX_SELECTION\n");
+ }
+ if (!overlay_edge_sh) {
+ overlay_edge_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_edge_glsl,
+ datatoc_edit_overlay_frag_glsl, NULL);
+ }
+ if (!overlay_edge_vcol_sh) {
+ overlay_edge_vcol_sh = DRW_shader_create(datatoc_edit_overlay_vert_glsl,
+ datatoc_edit_overlay_geom_edge_glsl,
+ datatoc_edit_overlay_frag_glsl, "#define VERTEX_SELECTION\n");
+ }
+ if (!overlay_vert_sh) {
+ overlay_vert_sh = DRW_shader_create(datatoc_edit_overlay_loosevert_vert_glsl, NULL,
+ datatoc_edit_overlay_frag_glsl, "#define VERTEX_SELECTION\n");
+ }
+ if (!overlay_facedot_sh) {
+ overlay_facedot_sh = DRW_shader_create(datatoc_edit_overlay_facedot_vert_glsl, NULL,
+ datatoc_edit_overlay_facedot_frag_glsl, NULL);
+ }
+
+ if ((ts->selectmode & SCE_SELECT_VERTEX) != 0) {
+ ledge_sh = overlay_edge_vcol_sh;
+
+ if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
+ tri_sh = overlay_tri_vcol_fast_sh;
+ else
+ tri_sh = overlay_tri_vcol_sh;
+ }
+ else {
+ ledge_sh = overlay_edge_sh;
+
+ if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
+ tri_sh = overlay_tri_fast_sh;
+ else
+ tri_sh = overlay_tri_sh;
+ }
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);
- psl->edit_face_overlay_pass = DRW_pass_create("Edit Mesh Face Overlay Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
- if ((rv3d->rflag & RV3D_NAVIGATING) != 0)
- face_overlay_shgrp = DRW_shgroup_create(over_tri_fast_sh, psl->edit_face_overlay_pass);
- else
- face_overlay_shgrp = DRW_shgroup_create(over_tri_sh, psl->edit_face_overlay_pass);
- ledges_overlay_shgrp = DRW_shgroup_create(over_edge_sh, psl->edit_face_overlay_pass);
- lverts_overlay_shgrp = DRW_shgroup_create(over_vert_sh, psl->edit_face_overlay_pass);
- DRW_shgroup_uniform_vec2(face_overlay_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ psl->edit_face_overlay_pass = DRW_pass_create("Edit Mesh Face Overlay Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_POINT);
+
+ face_overlay_shgrp = DRW_shgroup_create(tri_sh, psl->edit_face_overlay_pass);
DRW_shgroup_uniform_block(face_overlay_shgrp, "globalsBlock", globals_ubo, 0);
+ DRW_shgroup_uniform_vec2(face_overlay_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+
+ ledges_overlay_shgrp = DRW_shgroup_create(ledge_sh, psl->edit_face_overlay_pass);
DRW_shgroup_uniform_vec2(ledges_overlay_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(lverts_overlay_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+
+ if ((ts->selectmode & (SCE_SELECT_VERTEX)) != 0) {
+ lverts_overlay_shgrp = DRW_shgroup_create(overlay_vert_sh, psl->edit_face_overlay_pass);
+ DRW_shgroup_uniform_vec2(lverts_overlay_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ }
+
+ if ((ts->selectmode & (SCE_SELECT_FACE)) != 0) {
+ facedot_overlay_shgrp = DRW_shgroup_create(overlay_facedot_sh, psl->edit_face_overlay_pass);
+ }
DRW_mode_passes_setup(NULL,
NULL,
@@ -96,26 +170,34 @@ void EDIT_MESH_cache_init(void)
void EDIT_MESH_cache_populate(Object *ob)
{
struct Batch *geom;
- struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts;
+ struct Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter;
const struct bContext *C = DRW_get_context();
Scene *scene = CTX_data_scene(C);
Object *obedit = scene->obedit;
+ ToolSettings *ts = scene->toolsettings;
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");
switch (ob->type) {
case OB_MESH:
- geom = DRW_cache_surface_get(ob);
if (ob == obedit) {
DRW_cache_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts);
DRW_shgroup_call_add(face_overlay_shgrp, geo_ovl_tris, ob->obmat);
DRW_shgroup_call_add(ledges_overlay_shgrp, geo_ovl_ledges, ob->obmat);
- DRW_shgroup_call_add(lverts_overlay_shgrp, geo_ovl_lverts, ob->obmat);
- }
- if (do_occlude_wire) {
- DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
- DRW_shgroup_wire_outline(ob, true, false, true);
+
+ if ((ts->selectmode & SCE_SELECT_VERTEX) != 0)
+ DRW_shgroup_call_add(lverts_overlay_shgrp, geo_ovl_lverts, ob->obmat);
+
+ if ((ts->selectmode & SCE_SELECT_FACE) != 0) {
+ geo_ovl_fcenter = DRW_cache_face_centers_get(ob);
+ DRW_shgroup_call_add(facedot_overlay_shgrp, geo_ovl_fcenter, ob->obmat);
+ }
+
+ if (do_occlude_wire) {
+ geom = DRW_cache_surface_get(ob);
+ DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
+ }
}
break;
case OB_LAMP:
@@ -160,3 +242,23 @@ void EDIT_MESH_collection_settings_create(CollectionEngineSettings *ces)
BLI_assert(ces);
BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false);
}
+
+void EDIT_MESH_engine_free(void)
+{
+ if (overlay_tri_sh)
+ DRW_shader_free(overlay_tri_sh);
+ if (overlay_tri_fast_sh)
+ DRW_shader_free(overlay_tri_fast_sh);
+ if (overlay_tri_vcol_sh)
+ DRW_shader_free(overlay_tri_vcol_sh);
+ if (overlay_tri_vcol_fast_sh)
+ DRW_shader_free(overlay_tri_vcol_fast_sh);
+ if (overlay_edge_sh)
+ DRW_shader_free(overlay_edge_sh);
+ if (overlay_edge_vcol_sh)
+ DRW_shader_free(overlay_edge_vcol_sh);
+ if (overlay_vert_sh)
+ DRW_shader_free(overlay_vert_sh);
+ if (overlay_facedot_sh)
+ DRW_shader_free(overlay_facedot_sh);
+} \ No newline at end of file
diff --git a/source/blender/draw/modes/edit_mesh_mode.h b/source/blender/draw/modes/edit_mesh_mode.h
index bb1794a5ed3..9eee473917b 100644
--- a/source/blender/draw/modes/edit_mesh_mode.h
+++ b/source/blender/draw/modes/edit_mesh_mode.h
@@ -34,4 +34,6 @@ void EDIT_MESH_cache_finish(void);
void EDIT_MESH_draw(void);
+void EDIT_MESH_engine_free(void);
+
#endif /* __EDIT_MESH_MODE_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/modes/shaders/edit_overlay_facedot_frag.glsl b/source/blender/draw/modes/shaders/edit_overlay_facedot_frag.glsl
new file mode 100644
index 00000000000..9b99247efec
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_facedot_frag.glsl
@@ -0,0 +1,55 @@
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+flat in int isSelected;
+
+out vec4 FragColor;
+
+void main()
+{
+ if (isSelected != 0)
+ FragColor = vec4(colorFaceDot.rgb, 1.0);
+ else
+ FragColor = vec4(colorWireEdit.rgb, 1.0);
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_facedot_vert.glsl b/source/blender/draw/modes/shaders/edit_overlay_facedot_vert.glsl
new file mode 100644
index 00000000000..ab7f760d8a1
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_facedot_vert.glsl
@@ -0,0 +1,57 @@
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in int data;
+
+flat out int isSelected;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ gl_PointSize = sizeFaceDot;
+ isSelected = data;
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_frag.glsl b/source/blender/draw/modes/shaders/edit_overlay_frag.glsl
new file mode 100644
index 00000000000..a3deaa237ee
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_frag.glsl
@@ -0,0 +1,223 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+flat in vec3 edgesCrease;
+flat in vec3 edgesBweight;
+flat in ivec3 flag;
+flat in vec4 faceColor;
+flat in int clipCase;
+#ifdef VERTEX_SELECTION
+smooth in vec3 vertexColor;
+#endif
+
+/* We use a vec4[2] interface to pass edge data
+ * (without fragmenting memory accesses)
+ *
+ * There is 2 cases :
+ *
+ * - Simple case : geometry shader return edge distances
+ * in the first 2 components of the first vec4.
+ * This needs noperspective interpolation.
+ * The rest is filled with vertex screen positions.
+ * eData1.zw actually contain v2
+ * eData2.xy actually contain v1
+ * eData2.zw actually contain v0
+ *
+ * - Hard case : two 2d edge corner are described by each
+ * vec4 as origin and direction. This is constant over
+ * the triangle and use to detect the correct case. */
+
+noperspective in vec4 eData1;
+flat in vec4 eData2;
+
+out vec4 FragColor;
+
+#define EDGE_EXISTS (1 << 0)
+#define EDGE_ACTIVE (1 << 1)
+#define EDGE_SELECTED (1 << 2)
+#define EDGE_SEAM (1 << 3)
+#define EDGE_SHARP (1 << 4)
+/* Vertex flag is shifted and combined with the edge flag */
+#define VERTEX_ACTIVE (1 << (0 + 8))
+#define VERTEX_SELECTED (1 << (1 + 8))
+#define FACE_ACTIVE (1 << (2 + 8))
+
+/* Style Parameters in pixel */
+
+/* Array to retreive vert/edge indices */
+const ivec3 clipEdgeIdx[6] = ivec3[6](
+ ivec3(1, 0, 2),
+ ivec3(2, 0, 1),
+ ivec3(2, 1, 0),
+ ivec3(2, 1, 0),
+ ivec3(2, 0, 1),
+ ivec3(1, 0, 2)
+);
+
+const ivec3 clipPointIdx[6] = ivec3[6](
+ ivec3(0, 1, 2),
+ ivec3(0, 2, 1),
+ ivec3(0, 2, 1),
+ ivec3(1, 2, 0),
+ ivec3(1, 2, 0),
+ ivec3(2, 1, 0)
+);
+
+const mat4 stipple_matrix = mat4(vec4(1.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 0.0));
+
+void colorDist(vec4 color, float dist)
+{
+ FragColor = (dist < 0) ? color : FragColor;
+}
+
+float distToEdge(vec2 o, vec2 dir)
+{
+ vec2 af = gl_FragCoord.xy - o;
+ float daf = dot(dir, af);
+ return sqrt(abs(dot(af, af) - daf * daf));
+}
+
+void main()
+{
+ vec3 e, p;
+
+ /* Step 1 : Computing Distances */
+
+ if (clipCase == 0) {
+ e.xy = eData1.xy;
+
+ /* computing missing distance */
+ vec2 dir = normalize(eData2.zw - eData2.xy);
+ e.z = distToEdge(eData2.zw, dir);
+
+ p.x = distance(eData2.zw, gl_FragCoord.xy);
+ p.y = distance(eData2.xy, gl_FragCoord.xy);
+ p.z = distance(eData1.zw, gl_FragCoord.xy);
+ }
+ else {
+ ivec3 eidxs = clipEdgeIdx[clipCase - 1];
+ ivec3 pidxs = clipPointIdx[clipCase - 1];
+
+ e[eidxs.x] = distToEdge(eData1.xy, eData1.zw);
+ e[eidxs.y] = distToEdge(eData2.xy, eData2.zw);
+
+ /* Three edges visible cases */
+ if (clipCase == 1 || clipCase == 2 || clipCase == 4) {
+ e[eidxs.z] = distToEdge(eData1.xy, normalize(eData2.xy - eData1.xy));
+ p[pidxs.y] = distance(eData2.xy, gl_FragCoord.xy);
+ }
+ else {
+ e[eidxs.z] = 1e10; /* off screen */
+ p[pidxs.y] = 1e10; /* off screen */
+ }
+
+ p[pidxs.x] = distance(eData1.xy, gl_FragCoord.xy);
+ p[pidxs.z] = 1e10; /* off screen */
+ }
+
+ /* Step 2 : coloring (order dependant) */
+
+ /* First */
+ FragColor = faceColor;
+
+ if ((flag[0] & FACE_ACTIVE) != 0) {
+ int x = int(gl_FragCoord.x) & 0x3; /* mod 4 */
+ int y = int(gl_FragCoord.y) & 0x3; /* mod 4 */
+ FragColor *= stipple_matrix[x][y];
+ }
+
+ /* Edges */
+ for (int v = 0; v < 3; ++v) {
+ if ((flag[v] & EDGE_EXISTS) != 0) {
+ float largeEdge = e[v] - sizeEdge * 2.0;
+ float innerEdge = e[v] - sizeEdge;
+
+ if ((flag[v] & EDGE_SEAM) != 0)
+ colorDist(colorEdgeSeam, largeEdge);
+ else if (edgesBweight[v] > 0.0)
+ colorDist(vec4(colorEdgeBWeight.rgb, edgesBweight[v]), largeEdge);
+ else if (edgesCrease[v] > 0.0)
+ colorDist(vec4(colorEdgeCrease.rgb, edgesCrease[v]), largeEdge);
+ else if ((flag[v] & EDGE_SHARP) != 0)
+ colorDist(colorEdgeSharp, largeEdge);
+#ifndef VERTEX_SELECTION
+ else
+ colorDist(colorWireEdit, innerEdge);
+
+ if ((flag[v] & EDGE_ACTIVE) != 0)
+ colorDist(vec4(colorEditMeshActive.xyz, 1.0), innerEdge);
+ else if ((flag[v] & EDGE_SELECTED) != 0)
+ colorDist(colorEdgeSelect, innerEdge);
+#else
+ colorDist(vec4(vertexColor, 1.0), innerEdge);
+#endif
+ }
+ }
+
+ /* Points */
+#ifdef VERTEX_SELECTION
+ for (int v = 0; v < 3; ++v) {
+ float size = p[v] - sizeVertex;
+
+ if ((flag[v] & VERTEX_ACTIVE) != 0)
+ colorDist(vec4(colorEditMeshActive.xyz, 1.0), size);
+ else if ((flag[v] & VERTEX_SELECTED) != 0)
+ colorDist(colorVertexSelect, size);
+ else
+ colorDist(colorVertex, size);
+ }
+#endif
+
+ /* don't write depth if not opaque */
+ if (FragColor.a == 0.0) discard;
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_geom_edge.glsl b/source/blender/draw/modes/shaders/edit_overlay_geom_edge.glsl
new file mode 100644
index 00000000000..f376969d083
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_geom_edge.glsl
@@ -0,0 +1,186 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+layout(lines) in;
+layout(triangle_strip, max_vertices=6) out;
+
+uniform mat4 ProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec4 vPos[];
+in vec4 pPos[];
+in ivec4 vData[];
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out vec3 edgesCrease;
+flat out vec3 edgesSharp;
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+#ifdef VERTEX_SELECTION
+smooth out vec3 vertexColor;
+#endif
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+#define VERTEX_ACTIVE (1 << 0)
+#define VERTEX_SELECTED (1 << 1)
+
+#define FACE_ACTIVE (1 << 2)
+#define FACE_SELECTED (1 << 3)
+
+/* Table 1. Triangle Projection Cases */
+const ivec4 clipPointsIdx[6] = ivec4[6](
+ ivec4(0, 1, 2, 2),
+ ivec4(0, 2, 1, 1),
+ ivec4(0, 0, 1, 2),
+ ivec4(1, 2, 0, 0),
+ ivec4(1, 1, 0, 2),
+ ivec4(2, 2, 0, 1)
+);
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], vec2 vpos, int v)
+{
+ /* endpoints of opposite edge */
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+ /* Edge normalized vector */
+ vec2 dir = normalize(e2 - e1);
+ /* perpendicular to dir */
+ vec2 orthogonal = vec2(-dir.y, dir.x);
+
+ return abs(dot(vpos - e1, orthogonal));
+}
+
+vec3 getVertexColor(int v)
+{
+ if ((vData[v].x & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0)
+ return colorEdgeSelect.rgb;
+ else
+ return colorWireEdit.rgb;
+}
+
+void doVertex(int v, vec4 pos)
+{
+#ifdef VERTEX_SELECTION
+ vertexColor = getVertexColor(v);
+#endif
+
+ gl_Position = pos;
+
+ EmitVertex();
+}
+
+void main()
+{
+ clipCase = 0;
+
+ /* Face */
+ faceColor = vec4(0.0);
+
+ /* Proj Vertex */
+ vec2 pos[2] = vec2[2](proj(pPos[0]), proj(pPos[1]));
+
+ /* little optimization use a vec4 to vectorize
+ * following operations */
+ vec4 dirs1, dirs2;
+
+ /* Edge normalized vector */
+ dirs1.xy = normalize(pos[1] - pos[0]);
+
+ /* perpendicular to dir */
+ dirs1.zw = vec2(-dirs1.y, dirs1.x);
+
+ /* Make it view independant */
+ dirs1 *= sizeEdgeFix / viewportSize.xyxy;
+
+ dirs2 = dirs1;
+
+ /* Perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* vPos[i].z is negative and we don't want
+ * our fixvec to be flipped */
+ dirs1 *= -vPos[0].z;
+ dirs2 *= -vPos[1].z;
+ }
+
+ /* Edge / Vert data */
+ eData1 = vec4(1e10);
+ eData2.zw = pos[0];
+ eData2.xy = pos[1];
+ flag[0] = (vData[0].x << 8);
+ flag[1] = (vData[1].x << 8);
+ flag[2] = 0;
+
+ doVertex(0, pPos[0] + vec4(-dirs1.xy, 0.0, 0.0));
+ doVertex(0, pPos[0] + vec4( dirs1.zw, 0.0, 0.0));
+ doVertex(0, pPos[0] + vec4(-dirs1.zw, 0.0, 0.0));
+
+ flag[2] = vData[0].y | (vData[0].x << 8);
+ edgesCrease[2] = vData[0].z / 255.0;
+ edgesSharp[2] = vData[0].w / 255.0;
+
+ doVertex(1, pPos[1] + vec4( dirs2.zw, 0.0, 0.0));
+ doVertex(1, pPos[1] + vec4(-dirs2.zw, 0.0, 0.0));
+
+ flag[2] = 0;
+ doVertex(1, pPos[1] + vec4( dirs2.xy, 0.0, 0.0));
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_geom_tri.glsl b/source/blender/draw/modes/shaders/edit_overlay_geom_tri.glsl
new file mode 100644
index 00000000000..59d7971f944
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_geom_tri.glsl
@@ -0,0 +1,314 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+layout(triangles) in;
+
+#ifdef EDGE_FIX
+/* To fix the edge artifacts, we render
+ * an outline strip around the screenspace
+ * triangle. Order is important.
+ * TODO diagram
+ */
+
+layout(triangle_strip, max_vertices=23) out;
+#else
+layout(triangle_strip, max_vertices=3) out;
+#endif
+
+uniform mat4 ProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec4 vPos[];
+in vec4 pPos[];
+in ivec4 vData[];
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out vec3 edgesCrease;
+flat out vec3 edgesSharp;
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+#ifdef VERTEX_SELECTION
+smooth out vec3 vertexColor;
+#endif
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+
+#define VERTEX_ACTIVE (1 << 0)
+#define VERTEX_SELECTED (1 << 1)
+
+#define FACE_ACTIVE (1 << 2)
+#define FACE_SELECTED (1 << 3)
+
+/* Table 1. Triangle Projection Cases */
+const ivec4 clipPointsIdx[6] = ivec4[6](
+ ivec4(0, 1, 2, 2),
+ ivec4(0, 2, 1, 1),
+ ivec4(0, 0, 1, 2),
+ ivec4(1, 2, 0, 0),
+ ivec4(1, 1, 0, 2),
+ ivec4(2, 2, 0, 1)
+);
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+float dist(vec2 pos[3], vec2 vpos, int v)
+{
+ /* endpoints of opposite edge */
+ vec2 e1 = pos[(v + 1) % 3];
+ vec2 e2 = pos[(v + 2) % 3];
+ /* Edge normalized vector */
+ vec2 dir = normalize(e2 - e1);
+ /* perpendicular to dir */
+ vec2 orthogonal = vec2(-dir.y, dir.x);
+
+ return abs(dot(vpos - e1, orthogonal));
+}
+
+vec3 getVertexColor(int v)
+{
+ if ((vData[v].x & (VERTEX_ACTIVE | VERTEX_SELECTED)) != 0)
+ return colorEdgeSelect.rgb;
+ else
+ return colorWireEdit.rgb;
+}
+
+vec4 getClipData(vec2 pos[3], ivec2 vidx)
+{
+ vec2 A = pos[vidx.x];
+ vec2 Adir = normalize(A - pos[vidx.y]);
+
+ return vec4(A, Adir);
+}
+
+void doVertex(int v, vec4 pos)
+{
+#ifdef VERTEX_SELECTION
+ vertexColor = getVertexColor(v);
+#endif
+
+ gl_Position = pos;
+
+ EmitVertex();
+}
+
+void main()
+{
+ /* First we detect which case we are in */
+ clipCase = 0;
+
+ /* if perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* See Table 1. Triangle Projection Cases */
+ clipCase += int(pPos[0].z / pPos[0].w < -1 || vPos[0].z > 0.0) * 4;
+ clipCase += int(pPos[1].z / pPos[1].w < -1 || vPos[1].z > 0.0) * 2;
+ clipCase += int(pPos[2].z / pPos[2].w < -1 || vPos[2].z > 0.0) * 1;
+ }
+
+ /* If triangle is behind nearplane, early out */
+ if (clipCase == 7)
+ return;
+
+ /* Edge */
+ ivec3 eflag; vec3 ecrease, esharp;
+ for (int v = 0; v < 3; ++v) {
+ flag[v] = eflag[v] = vData[v].y | (vData[v].x << 8);
+ edgesCrease[v] = ecrease[v] = vData[v].z / 255.0;
+ edgesSharp[v] = esharp[v] = vData[v].w / 255.0;
+ }
+
+ /* Face */
+ if ((vData[0].x & FACE_ACTIVE) != 0)
+ faceColor = colorEditMeshActive;
+ else if ((vData[0].x & FACE_SELECTED) != 0)
+ faceColor = colorFaceSelect;
+ else
+ faceColor = colorFace;
+
+ /* Vertex */
+ vec2 pos[3] = vec2[3](proj(pPos[0]), proj(pPos[1]), proj(pPos[2]));
+
+ /* Simple case : compute edge distances in geometry shader */
+ if (clipCase == 0) {
+
+ /* Packing screen positions and 2 distances */
+ eData1 = vec4(0.0, 0.0, pos[2]);
+ eData2 = vec4(pos[1], pos[0]);
+
+ /* Only pass the first 2 distances */
+ for (int v = 0; v < 2; ++v) {
+ eData1[v] = dist(pos, pos[v], v);
+ doVertex(v, pPos[v]);
+ eData1[v] = 0.0;
+ }
+
+ /* and the last vertex */
+ doVertex(2, pPos[2]);
+
+#ifdef EDGE_FIX
+ vec2 fixvec[6];
+ vec2 fixvecaf[6];
+ vec2 cornervec[3];
+
+ /* This fix the case when 2 vertices are perfectly aligned
+ * and corner vectors have nowhere to go.
+ * ie: length(cornervec[i]) == 0 */
+ const float epsilon = 1e-2; /* in pixel so not that much */
+ const vec2 bias[3] = vec2[3](
+ vec2( epsilon, epsilon),
+ vec2(-epsilon, epsilon),
+ vec2( 0.0, -epsilon)
+ );
+
+ for (int i = 0; i < 3; ++i) {
+ int i1 = (i + 1) % 3;
+ int i2 = (i + 2) % 3;
+
+ vec2 v1 = pos[i] + bias[i];
+ vec2 v2 = pos[i1] + bias[i1];
+ vec2 v3 = pos[i2] + bias[i2];
+
+ /* Edge normalized vector */
+ vec2 dir = normalize(v2 - v1);
+ vec2 dir2 = normalize(v3 - v1);
+
+ cornervec[i] = -normalize(dir + dir2);
+
+ /* perpendicular to dir */
+ vec2 perp = vec2(-dir.y, dir.x);
+
+ /* Backface case */
+ if (dot(perp, dir2) > 0) {
+ perp = -perp;
+ }
+
+ /* Make it view independant */
+ perp *= sizeEdgeFix / viewportSize;
+ cornervec[i] *= sizeEdgeFix / viewportSize;
+ fixvec[i] = fixvecaf[i] = perp;
+
+ /* Perspective */
+ if (ProjectionMatrix[3][3] == 0.0) {
+ /* vPos[i].z is negative and we don't want
+ * our fixvec to be flipped */
+ fixvec[i] *= -vPos[i].z;
+ fixvecaf[i] *= -vPos[i1].z;
+ cornervec[i] *= -vPos[i].z;
+ }
+ }
+
+ /* to not let face color bleed */
+ faceColor = vec4(0.0, 0.0, 0.0, 0.0);
+
+ /* we don't want other edges : make them far*/
+ eData1 = vec4(1e10);
+
+ /* Start with the same last vertex to create a
+ * degenerate triangle in order to "create"
+ * a new triangle strip */
+ for (int i = 2; i < 5; ++i) {
+ int vbe = (i - 1) % 3;
+ int vaf = (i + 1) % 3;
+ int v = i % 3;
+
+ /* Position of the "hidden" thrid vertex */
+ eData1.zw = pos[vbe];
+
+ doVertex(v, pPos[v]);
+ doVertex(v, pPos[v] + vec4(fixvec[v], 0.0, 0.0));
+
+ /* Now one triangle only shade one edge
+ * so we use the edge distance calculated
+ * in the fragment shader, the third edge;
+ * we do this because we need flat interp to
+ * draw a continuous triangle strip */
+ eData2.xy = pos[vaf];
+ eData2.zw = pos[v];
+ flag[0] = (vData[v].x << 8);
+ flag[1] = (vData[vaf].x << 8);
+ flag[2] = eflag[vbe];
+ edgesCrease[2] = ecrease[vbe];
+ edgesSharp[2] = esharp[vbe];
+
+ doVertex(vaf, pPos[vaf]);
+ doVertex(vaf, pPos[vaf] + vec4(fixvecaf[v], 0.0, 0.0));
+
+ /* corner vertices should not drax edges but draw point only */
+ flag[2] = (vData[vbe].x << 8);
+ doVertex(vaf, pPos[vaf]);
+ doVertex(vaf, pPos[vaf] + vec4(cornervec[vaf], 0.0, 0.0));
+ }
+
+ /* finish the loop strip */
+ doVertex(2, pPos[2]);
+ doVertex(2, pPos[2] + vec4(fixvec[2], 0.0, 0.0));
+#endif
+ }
+ /* Harder case : compute visible edges vectors */
+ else {
+ ivec4 vindices = clipPointsIdx[clipCase - 1];
+
+ eData1 = getClipData(pos, vindices.xz);
+ eData2 = getClipData(pos, vindices.yw);
+
+ for (int v = 0; v < 3; ++v)
+ doVertex(v, pPos[v]);
+ }
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_loosevert_vert.glsl b/source/blender/draw/modes/shaders/edit_overlay_loosevert_vert.glsl
new file mode 100644
index 00000000000..a046676b6e3
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_loosevert_vert.glsl
@@ -0,0 +1,91 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+/* keep in sync with GlobalsUboStorage */
+layout(std140) uniform globalsBlock {
+ vec4 colorWire;
+ vec4 colorWireEdit;
+ vec4 colorActive;
+ vec4 colorSelect;
+ vec4 colorTransform;
+ vec4 colorGroupActive;
+ vec4 colorGroup;
+ vec4 colorLamp;
+ vec4 colorSpeaker;
+ vec4 colorCamera;
+ vec4 colorEmpty;
+ vec4 colorVertex;
+ vec4 colorVertexSelect;
+ vec4 colorEditMeshActive;
+ vec4 colorEdgeSelect;
+ vec4 colorEdgeSeam;
+ vec4 colorEdgeSharp;
+ vec4 colorEdgeCrease;
+ vec4 colorEdgeBWeight;
+ vec4 colorEdgeFaceSelect;
+ vec4 colorFace;
+ vec4 colorFaceSelect;
+ vec4 colorNormal;
+ vec4 colorVNormal;
+ vec4 colorLNormal;
+ vec4 colorFaceDot;
+
+ vec4 colorDeselect;
+ vec4 colorOutline;
+ vec4 colorLampNoAlpha;
+
+ float sizeLampCenter;
+ float sizeLampCircle;
+ float sizeLampCircleShadow;
+ float sizeVertex;
+ float sizeEdge;
+ float sizeEdgeFix;
+ float sizeNormal;
+ float sizeFaceDot;
+};
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 viewportSize;
+
+in vec3 pos;
+in ivec4 data;
+
+/* these are the same for all vertices
+ * and does not need interpolation */
+flat out ivec3 flag;
+flat out vec4 faceColor;
+flat out int clipCase;
+
+/* See fragment shader */
+noperspective out vec4 eData1;
+flat out vec4 eData2;
+
+/* project to screen space */
+vec2 proj(vec4 pos)
+{
+ return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
+}
+
+void main()
+{
+ clipCase = 0;
+
+ vec4 pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+
+ /* there is no face */
+ faceColor = vec4(0.0);
+
+ /* only verterx position 0 is used */
+ eData1 = eData2 = vec4(1e10);
+ eData2.zw = proj(pPos);
+
+ flag = ivec3(0);
+ flag[0] = (data.x << 8);
+
+ gl_PointSize = sizeEdgeFix;
+ gl_Position = pPos;
+}
diff --git a/source/blender/draw/modes/shaders/edit_overlay_vert.glsl b/source/blender/draw/modes/shaders/edit_overlay_vert.glsl
new file mode 100644
index 00000000000..5bc9a8bef85
--- /dev/null
+++ b/source/blender/draw/modes/shaders/edit_overlay_vert.glsl
@@ -0,0 +1,23 @@
+
+/* Solid Wirefram implementation
+ * Mike Erwin, Clément Foucault */
+
+/* This shader follows the principles of
+ * http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf */
+
+uniform mat4 ModelViewMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in ivec4 data;
+
+out vec4 vPos;
+out vec4 pPos;
+out ivec4 vData;
+
+void main()
+{
+ vPos = ModelViewMatrix * vec4(pos, 1.0);
+ pPos = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vData = data;
+}