diff options
Diffstat (limited to 'source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl')
-rw-r--r-- | source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl new file mode 100644 index 00000000000..de56a637536 --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_mesh_overlay_geom_edge.glsl @@ -0,0 +1,143 @@ + +/* 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 */ + +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 edgesBweight; +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; + edgesBweight[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(); +} |