Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gpencil_point_geom.glsl « shaders « gpencil « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a2f4c1f9b1524f95bcd1c4a536d155d6c9b6e4a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
uniform vec2 Viewport;
uniform int xraymode;
uniform int alignment_mode;

layout(points) in;
layout(triangle_strip, max_vertices = 4) out;

in vec4 finalColor[1];
in float finalThickness[1];
in vec2 finaluvdata[1];
in vec4 finalprev_pos[1];

out vec4 mColor;
out vec2 mTexCoord;

#define GP_XRAY_FRONT 0
#define GP_XRAY_3DSPACE 1

#define M_PI 3.14159265358979323846  /* pi */
#define M_2PI 6.28318530717958647692 /* 2*pi */
#define FALSE 0

/* keep this definition equals to GP_STYLE_FOLLOW_FIXED value */
#define FIXED 2

/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
  return vec2(vertex.xy / vertex.w) * Viewport;
}

/* get zdepth value */
float getZdepth(vec4 point)
{
  if (xraymode == GP_XRAY_FRONT) {
    return min(-0.05, (point.z / point.w));
  }
  if (xraymode == GP_XRAY_3DSPACE) {
    return (point.z / point.w);
  }

  /* in front by default */
  return 0.000001;
}

vec2 rotateUV(vec2 uv, float angle)
{
  /* translate center of rotation to the center of texture */
  vec2 new_uv = uv - vec2(0.5f, 0.5f);
  vec2 rot_uv;
  rot_uv.x = new_uv.x * cos(angle) - new_uv.y * sin(angle);
  rot_uv.y = new_uv.y * cos(angle) + new_uv.x * sin(angle);
  return rot_uv + vec2(0.5f, 0.5f);
}

vec2 rotatePoint(vec2 center, vec2 point, float angle)
{
  /* translate center of rotation to the center */
  vec2 new_point = point - center;
  vec2 rot_point;
  rot_point.x = new_point.x * cos(angle) - new_point.y * sin(angle);
  rot_point.y = new_point.y * cos(angle) + new_point.x * sin(angle);
  return rot_point + center;
}

/* Calculate angle of the stroke using previous point as reference.
 * The angle is calculated using the x axis (1, 0) as 0 degrees */
float getAngle(vec2 pt0, vec2 pt1)
{
  /* do not rotate one point only (no reference to rotate) */
  if (pt0 == pt1) {
    return 0.0;
  }

  if (alignment_mode == FIXED) {
    return 0.0;
  }

  /* default horizontal line (x-axis) in screen space */
  vec2 v0 = vec2(1.0, 0.0);

  /* vector of direction */
  vec2 vn = vec2(normalize(pt1 - pt0));

  /* angle signed (function ported from angle_signed_v2v2) */
  float perp_dot = (v0[1] * vn[0]) - (v0[0] * vn[1]);
  float angle = atan(perp_dot, dot(v0, vn));

  /* get full circle rotation */
  if (angle > 0.0) {
    angle = M_PI + (M_PI - angle);
  }
  else {
    angle *= -1.0;
  }

  return angle;
}

void main(void)
{
  /* receive points */
  vec4 P0 = gl_in[0].gl_Position;
  vec2 sp0 = toScreenSpace(P0);

  vec4 P1 = finalprev_pos[0];
  vec2 sp1 = toScreenSpace(P1);
  vec2 point;

  float size = finalThickness[0];
  vec2 center = vec2(sp0.x, sp0.y);

  /* get angle of stroke to rotate texture */
  float angle = getAngle(sp0, sp1);

  /* generate the triangle strip */
  mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y);
  mColor = finalColor[0];
  point = rotatePoint(center, vec2(sp0.x - size, sp0.y + size), angle);
  gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
  EmitVertex();

  mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y);
  mColor = finalColor[0];
  point = rotatePoint(center, vec2(sp0.x - size, sp0.y - size), angle);
  gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
  EmitVertex();

  mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y);
  mColor = finalColor[0];
  point = rotatePoint(center, vec2(sp0.x + size, sp0.y + size), angle);
  gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
  EmitVertex();

  mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y);
  mColor = finalColor[0];
  point = rotatePoint(center, vec2(sp0.x + size, sp0.y - size), angle);
  gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
  EmitVertex();

  EndPrimitive();
}