1+ #include " ekg/gpu/opengl_pipeline_template.hpp"
2+
3+ void ekg::gpu::get_standard_vertex_shader (
4+ std::string glsl_version,
5+ ekg::os::opengl_version opengl_version,
6+ std::string &output_kernel_source
7+ ) {
8+ output_kernel_source = glsl_version + R"(
9+ layout (location = 0) in vec2 aPos;
10+ layout (location = 1) in vec2 aTexCoord;
11+
12+ uniform mat4 uProjection;
13+ uniform vec4 uRect;
14+
15+ out vec2 vTexCoord;
16+ out vec2 vPos;
17+ out vec4 vRect;
18+
19+ void main() {
20+ vec2 vertex = aPos;
21+
22+ if (uRect.z > -1.0f && uRect.w > -1.0f) {
23+ vertex *= uRect.zw;
24+ }
25+
26+ vertex += uRect.xy;
27+
28+ gl_Position = uProjection * vec4(vertex, 0.0f, 1.0f);
29+ vTexCoord = aTexCoord;
30+ vRect = uRect;
31+ vPos = aPos;
32+ }
33+ )" ;
34+ }
35+
36+ void ekg::gpu::get_standard_fragment_shader (
37+ std::string glsl_version,
38+ ekg::os::opengl_version opengl_version,
39+ std::string &output_kernel_source
40+ ) {
41+ output_kernel_source = glsl_version + R"(
42+ layout (location = 0) out vec4 aFragColor;
43+ uniform sampler2D uTextureSampler;
44+
45+ in vec2 vTexCoord;
46+ in vec2 vPos;
47+ in vec4 vRect;
48+
49+ uniform int uLineThickness;
50+ uniform int uActiveTexture;
51+ uniform float uViewportHeight;
52+ uniform float uContent[8];
53+
54+ void main() {
55+ aFragColor = vec4(
56+ uContent[0],
57+ uContent[1],
58+ uContent[2],
59+ uContent[3]
60+ );
61+
62+ vec2 fragPos = vec2(gl_FragCoord.x, uViewportHeight - gl_FragCoord.y);
63+
64+ /**
65+ * The scissoring works like swapchain-one (does not stack), of course,
66+ * this scissor is a little different, the pixel-perfect precision makes
67+ * a better cut of fragments. And does not require any overhead from
68+ * calling command buffers to GPU rastarizer.
69+ **/
70+ bool shouldDiscard = (
71+ fragPos.x <= uContent[4] ||
72+ fragPos.y <= uContent[5] ||
73+ fragPos.x >= uContent[4] + uContent[6] ||
74+ fragPos.y >= uContent[5] + uContent[7]
75+ );
76+
77+ float lineThicknessf = float(uLineThickness);
78+
79+ /**
80+ * The pixel-perfect outline is possible on fragment shader,
81+ * due the precision of fragments position, and the
82+ * normalised-space.
83+ **/
84+ if (uLineThickness > 0) {
85+ vec4 outline = vec4(
86+ vRect.x + lineThicknessf,
87+ vRect.y + lineThicknessf,
88+ vRect.z - (lineThicknessf * 2.0f),
89+ vRect.w - (lineThicknessf * 2.0f)
90+ );
91+
92+ shouldDiscard = (
93+ shouldDiscard || (
94+ fragPos.x > outline.x &&
95+ fragPos.x < outline.x + outline.z &&
96+ fragPos.y > outline.y &&
97+ fragPos.y < outline.y + outline.w
98+ )
99+ );
100+ } else if (uLineThickness < 0) {
101+ float radius = vRect.z / 2.0f;
102+
103+ vec2 diff = vec2(
104+ (vRect.x + radius) - fragPos.x,
105+ (vRect.y + radius) - fragPos.y
106+ );
107+
108+ float dist = (diff.x * diff.x + diff.y * diff.y);
109+ aFragColor.w = (
110+ 1.0f - smoothstep(0.0, radius * radius, dot(dist, dist))
111+ );
112+ }
113+
114+ /**
115+ * The discard must not call `discard` keyword,
116+ * discarding pixels using keyword is performanceless
117+ * comparated to alpha blending equals to zero.
118+ **/
119+ if (shouldDiscard) {
120+ aFragColor.w = 0.0f;
121+ } else {
122+ vec4 textureColor;
123+ switch (uActiveTexture) {
124+ case 1:
125+ textureColor = texture(uTextureSampler, vTexCoord);
126+
127+ /**
128+ * The sampler used here is the font, and this sampler needs swizzled mapped,
129+ * instead of doing swizzling on CPU-side, here is actually the best place.
130+ * Due the necessity of put swizzle for ttf text fonts, the emojis must not swizzle.
131+ * The non swizzable range masterfully fix it.
132+ *
133+ * vRect.z is negative, because any concave rendering shape does not have a fixed
134+ * dimension size. So the rendering engine re-uses the Rect width to calculate
135+ * when must stop the GPU-side swizzle.
136+ **/
137+ float non_swizzlable_range = -vRect.z;
138+
139+ if (vTexCoord.x < non_swizzlable_range) {
140+ textureColor = textureColor.aaar;
141+ textureColor = vec4(
142+ textureColor.rgb * aFragColor.rgb,
143+ textureColor.a
144+ );
145+ }
146+
147+ aFragColor = vec4(
148+ textureColor.rgb,
149+ textureColor.a - (1.0f - aFragColor.a)
150+ );
151+
152+ //aFragColor = vec4(aFragColor.a, 0.0f, 0.0f, 1.0f);
153+ break;
154+ case 2:
155+ textureColor = texture(uTextureSampler, vPos);
156+
157+ aFragColor = vec4(
158+ textureColor.rgb,
159+ textureColor.a - (1.0f - aFragColor.a)
160+ );
161+ break;
162+ }
163+ }
164+ }
165+ )" ;
166+ }
0 commit comments