move shaders into .glsl files and add #include feature
This commit is contained in:
@@ -404,6 +404,37 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Xml>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\shaders\atlas.glsl" />
|
||||
<None Include="data\shaders\bake-uv.glsl" />
|
||||
<None Include="data\shaders\checkerboard.glsl" />
|
||||
<None Include="data\shaders\color-hue.glsl" />
|
||||
<None Include="data\shaders\color-quad.glsl" />
|
||||
<None Include="data\shaders\color-tri.glsl" />
|
||||
<None Include="data\shaders\color.glsl" />
|
||||
<None Include="data\shaders\comp-draw.glsl" />
|
||||
<None Include="data\shaders\comp-erase.glsl" />
|
||||
<None Include="data\shaders\equirect.glsl" />
|
||||
<None Include="data\shaders\font.glsl" />
|
||||
<None Include="data\shaders\include\blend-stroke.glsl" />
|
||||
<None Include="data\shaders\include\blend.glsl" />
|
||||
<None Include="data\shaders\include\blur.glsl" />
|
||||
<None Include="data\shaders\include\color.glsl" />
|
||||
<None Include="data\shaders\include\ext-fb-fetch.glsl" />
|
||||
<None Include="data\shaders\include\hsv.glsl" />
|
||||
<None Include="data\shaders\include\rand.glsl" />
|
||||
<None Include="data\shaders\lambert.glsl" />
|
||||
<None Include="data\shaders\lightmap.glsl" />
|
||||
<None Include="data\shaders\stroke-instanced.glsl" />
|
||||
<None Include="data\shaders\stroke-preview.glsl" />
|
||||
<None Include="data\shaders\stroke.glsl" />
|
||||
<None Include="data\shaders\texture-alpha-sep.glsl" />
|
||||
<None Include="data\shaders\texture-alpha.glsl" />
|
||||
<None Include="data\shaders\texture-blend.glsl" />
|
||||
<None Include="data\shaders\texture.glsl" />
|
||||
<None Include="data\shaders\uvs.glsl" />
|
||||
<None Include="data\shaders\vertex-color.glsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -52,6 +52,12 @@
|
||||
<Filter Include="libs\fmt">
|
||||
<UniqueIdentifier>{7b4f5b47-7a8b-4e4c-9e82-399bb5047ffc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="shaders">
|
||||
<UniqueIdentifier>{b55fb692-a845-4ef2-9b0e-5b2dd8bd125f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="shaders\include">
|
||||
<UniqueIdentifier>{a2cacb13-2854-44ee-9511-6cb8ac587428}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\app.cpp">
|
||||
@@ -543,4 +549,93 @@
|
||||
<Filter>extras</Filter>
|
||||
</Xml>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\shaders\texture.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\blend-stroke.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\blur.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\color.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\ext-fb-fetch.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\hsv.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\rand.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\include\blend.glsl">
|
||||
<Filter>shaders\include</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\comp-draw.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\comp-erase.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\equirect.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\font.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\lambert.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\lightmap.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\stroke.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\stroke-instanced.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\stroke-preview.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\texture-alpha.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\texture-alpha-sep.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\texture-blend.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\uvs.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\vertex-color.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\atlas.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\bake-uv.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\checkerboard.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\color.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\color-hue.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\color-quad.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
<None Include="data\shaders\color-tri.glsl">
|
||||
<Filter>shaders</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -164,7 +164,7 @@
|
||||
<node dir="col" align="center" grow="1" width="1" flood-events="1">
|
||||
<!--<node height="20" pad="1" width="100%" margin="5 0 5 0"><slider-h id="tip-shade" value="1"/></node>-->
|
||||
<button-custom id="preset-button" width="100%" height="40" margin="5 0 0 0" dir="row" pad="4">
|
||||
<image id="preset-thumb" path="data/thumbs/Round-Hard.png" width="32" height="100%"/>
|
||||
<image id="preset-thumb" width="32" height="100%"/>
|
||||
<stroke-preview id="preset-preview" width="10" grow="1" height="100%"/>
|
||||
</button-custom>
|
||||
<node dir="row" margin="5 0 0 0">
|
||||
@@ -309,7 +309,7 @@
|
||||
<text text="Offset"/>
|
||||
</node>
|
||||
<node height="20" justify="center">
|
||||
<text text="Opacity"/>
|
||||
<text text="Depth"/>
|
||||
</node>
|
||||
<node height="20" justify="center">
|
||||
<text text="Scale"/>
|
||||
@@ -355,7 +355,7 @@
|
||||
<text text="randomize"/>
|
||||
</node>
|
||||
<node height="20" pad="1" width="100%">
|
||||
<slider-h id="pattern-opacity" value="1"/>
|
||||
<slider-h id="pattern-depth" value="1"/>
|
||||
</node>
|
||||
<node height="20" pad="1" width="100%">
|
||||
<slider-h id="pattern-scale" value=".25"/>
|
||||
|
||||
21
data/shaders/atlas.glsl
Normal file
21
data/shaders/atlas.glsl
Normal file
@@ -0,0 +1,21 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
uniform vec2 tof;
|
||||
uniform vec2 tsz;
|
||||
in vec2 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = tof + uvs * tsz;
|
||||
gl_Position = mvp * vec4(pos, 0.0, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform sampler2D tex;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = texture(tex, uv);
|
||||
};
|
||||
27
data/shaders/bake-uv.glsl
Normal file
27
data/shaders/bake-uv.glsl
Normal file
@@ -0,0 +1,27 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec3 nor;
|
||||
in vec2 uvs;
|
||||
out vec3 n;
|
||||
out vec3 p;
|
||||
void main()
|
||||
{
|
||||
n = nor;
|
||||
p = vec3(mvp * pos);
|
||||
gl_Position = vec4(uvs * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform int mode;
|
||||
in highp vec3 n;
|
||||
in highp vec3 p;
|
||||
out highp vec3 frag;
|
||||
void main()
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case 0: frag = normalize(n); break;
|
||||
case 1: frag = p; break;
|
||||
}
|
||||
}
|
||||
24
data/shaders/checkerboard.glsl
Normal file
24
data/shaders/checkerboard.glsl
Normal file
@@ -0,0 +1,24 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform bool colorize;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
const mediump vec4 c1 = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const mediump vec4 c2 = vec4(0.9, 0.9, 0.9, 1.0);
|
||||
mediump vec2 c = floor(fract(uv * 10.0) * 2.0);
|
||||
mediump float alpha = mix(c.x, 1.0 - c.x, c.y);
|
||||
if (colorize) frag = mix(c1, c2, alpha) * vec4(fract(uv.x * 5.0), uv.y, 1.0, 1.0);
|
||||
else frag = mix(c1, c2, alpha);
|
||||
}
|
||||
22
data/shaders/color-hue.glsl
Normal file
22
data/shaders/color-hue.glsl
Normal file
@@ -0,0 +1,22 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec3 uv;
|
||||
void main()
|
||||
{
|
||||
gl_Position = mvp * pos;
|
||||
uv = vec3(uvs, pos.w);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/hsv.glsl"
|
||||
uniform mediump vec4 col;
|
||||
uniform bool dir; // 0:horizontal, 1:vertical
|
||||
in mediump vec3 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = vec4(hsv2rgb(vec3(dir?uv.y:uv.x, 1.0, 1.0)), 1.0);
|
||||
};
|
||||
|
||||
20
data/shaders/color-quad.glsl
Normal file
20
data/shaders/color-quad.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec3 uv;
|
||||
void main()
|
||||
{
|
||||
gl_Position = mvp * pos;
|
||||
uv = vec3(uvs, pos.w);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/hsv.glsl"
|
||||
uniform mediump vec4 col; // HSV
|
||||
in mediump vec3 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = vec4(hsv2rgb(vec3(col.x, uv.x, 1.0 - uv.y)), 1.0);
|
||||
};
|
||||
21
data/shaders/color-tri.glsl
Normal file
21
data/shaders/color-tri.glsl
Normal file
@@ -0,0 +1,21 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec3 uv;
|
||||
void main()
|
||||
{
|
||||
gl_Position = mvp * pos;
|
||||
uv = vec3(uvs, pos.w);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/hsv.glsl"
|
||||
uniform mediump vec4 col; // in HSV
|
||||
in mediump vec3 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump float sat = tan(atan(uv.y, uv.x)) * 0.5 + 0.5;
|
||||
frag = vec4(hsv2rgb(vec3(col.r, sat, uv.x)), 1.0);
|
||||
};
|
||||
16
data/shaders/color.glsl
Normal file
16
data/shaders/color.glsl
Normal file
@@ -0,0 +1,16 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
void main()
|
||||
{
|
||||
gl_Position = mvp * pos;
|
||||
gl_PointSize = 5.0;
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform mediump vec4 col;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = col;
|
||||
};
|
||||
74
data/shaders/comp-draw.glsl
Normal file
74
data/shaders/comp-draw.glsl
Normal file
@@ -0,0 +1,74 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/blur.glsl"
|
||||
#include "include/blend.glsl"
|
||||
#include "include/blend-stroke.glsl"
|
||||
#include "include/color.glsl"
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D tex_stroke;
|
||||
uniform sampler2D tex_mask;
|
||||
uniform mediump float alpha;
|
||||
uniform mediump float stroke_alpha;
|
||||
uniform mediump int blend_mode;
|
||||
uniform mediump vec2 resolution;
|
||||
uniform bool lock;
|
||||
uniform bool mask;
|
||||
|
||||
uniform bool use_dual;
|
||||
uniform sampler2D tex_dual;
|
||||
uniform mediump float dual_alpha;
|
||||
uniform mediump int dual_blend_mode;
|
||||
|
||||
uniform bool use_pattern;
|
||||
uniform sampler2D tex_pattern;
|
||||
uniform mediump vec2 pattern_scale;
|
||||
uniform mediump float pattern_bright;
|
||||
uniform mediump float pattern_contr;
|
||||
uniform mediump float pattern_depth;
|
||||
uniform mediump vec2 pattern_offset;
|
||||
uniform mediump bool pattern_invert;
|
||||
uniform mediump int patt_blend_mode;
|
||||
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
|
||||
void main()
|
||||
{
|
||||
mediump vec4 base = texture(tex, uv);
|
||||
mediump vec4 stroke = texture(tex_stroke, uv);
|
||||
if (use_pattern)
|
||||
{
|
||||
mediump vec2 rscale = resolution / vec2(512.0);
|
||||
mediump float patt = texture(tex_pattern, uv * (0.5 / pattern_scale) * rscale + pattern_offset).r;
|
||||
if (pattern_invert)
|
||||
patt = 1.0 - patt;
|
||||
//" patt = patt * pattern_alpha + (1.0 - pattern_alpha);
|
||||
if (pattern_bright != 0.5)
|
||||
patt = brightness1(patt, 1.0 - pattern_bright);
|
||||
if (pattern_contr != 0.5)
|
||||
patt = contrast1(patt, pattern_contr);
|
||||
//" mediump float pa = (1.0 - patt) * pow(pattern_depth, 0.25) + (stroke.a * pattern_depth * 10.0);
|
||||
mediump float pa = pow((1.0 - patt), max(1.0, (1.0 - pattern_depth) * 10.0)) * pow(pattern_depth, 0.25) + (stroke.a * pattern_depth * 5.0);
|
||||
stroke.a = mix(pa * stroke.a, stroke.a, 0.0);
|
||||
}
|
||||
if (use_dual)
|
||||
{
|
||||
mediump vec4 dual = texture(tex_dual, uv);
|
||||
stroke.a = blend_stroke(stroke.a, dual.a * dual_alpha, dual_blend_mode);
|
||||
}
|
||||
stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha;
|
||||
if (!lock && base.a == 0.0) { frag = stroke * vec4(1.0, 1.0, 1.0, alpha); return; }
|
||||
mediump vec4 blended = blend(base, stroke, blend_mode);
|
||||
frag = vec4(blended.rgb, (lock ? base.a : blended.a) * alpha);
|
||||
};
|
||||
29
data/shaders/comp-erase.glsl
Normal file
29
data/shaders/comp-erase.glsl
Normal file
@@ -0,0 +1,29 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/blur.glsl"
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D tex_stroke;
|
||||
uniform sampler2D tex_mask;
|
||||
uniform mediump float alpha;
|
||||
uniform mediump float stroke_alpha;
|
||||
uniform mediump vec2 resolution;
|
||||
uniform bool mask;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump vec4 base = texture(tex, uv);
|
||||
mediump vec4 stroke = texture(tex_stroke, uv);
|
||||
stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha;
|
||||
frag = vec4(base.rgb, clamp((base.a - stroke.a) * alpha, 0.0, 1.0));
|
||||
};
|
||||
29
data/shaders/equirect.glsl
Normal file
29
data/shaders/equirect.glsl
Normal file
@@ -0,0 +1,29 @@
|
||||
[[vertex]]
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = (vec2(1.0) - uvs + vec2(0.25,0.0)) * vec2(TWO_PI, PI);
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform samplerCube tex;
|
||||
in highp vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
highp float anglex = uv.x;
|
||||
highp float angley = uv.y;
|
||||
highp float sx = sin(anglex);
|
||||
highp float cx = cos(anglex);
|
||||
highp vec3 dir = vec3(0.0, 0.0, 0.0);
|
||||
dir.x = sin(angley) * cx;
|
||||
dir.y = cos(angley);
|
||||
dir.z = sin(angley) * sx;
|
||||
frag = texture(tex, dir);
|
||||
}
|
||||
22
data/shaders/font.glsl
Normal file
22
data/shaders/font.glsl
Normal file
@@ -0,0 +1,22 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec2 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos, 0.0, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform mediump sampler2D tex;
|
||||
uniform mediump vec4 col;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump float a = texture(tex, uv).r;
|
||||
frag = vec4(col.rgb, a);
|
||||
};
|
||||
|
||||
9
data/shaders/include/blend-stroke.glsl
Normal file
9
data/shaders/include/blend-stroke.glsl
Normal file
@@ -0,0 +1,9 @@
|
||||
mediump float blend_stroke(mediump float base, mediump float stroke, int mode)
|
||||
{
|
||||
if (mode == 0) /* normal */ return (base + stroke) * 0.5;
|
||||
else if (mode == 1) /* multiply */ return base * stroke;
|
||||
else if (mode == 2) /* screen */ return 1.0-(1.0-base)*(1.0-stroke);
|
||||
else if (mode == 3) /* color-dodge */ return base/(1.0-stroke);
|
||||
else if (mode == 4) /* overlay */ return mix(2.0*base*stroke, 1.0-2.0*(1.0-base)*(1.0-stroke), floor(base*2.0));
|
||||
else return 1.0;
|
||||
}
|
||||
20
data/shaders/include/blend.glsl
Normal file
20
data/shaders/include/blend.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
mediump vec3 blend_normal(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)
|
||||
{ return mix(base.rgb, stroke.rgb, stroke.a/alpha_tot); }
|
||||
mediump vec3 blend_multiply(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)
|
||||
{ return mix(stroke.rgb, mix(base.rgb, base.rgb*stroke.rgb, stroke.a/alpha_tot), base.a/alpha_tot); }
|
||||
mediump vec3 blend_screen(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)
|
||||
{ return mix(stroke.rgb, mix(base.rgb, 1.0-(1.0-base.rgb)*(1.0-stroke.rgb), stroke.a/alpha_tot), base.a/alpha_tot); }
|
||||
mediump vec3 blend_colorDodge(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)
|
||||
{ return mix(stroke.rgb, mix(base.rgb, base.rgb/(1.0-stroke.rgb), stroke.a/alpha_tot), base.a/alpha_tot); }
|
||||
mediump vec3 blend_overlay(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)
|
||||
{ return mix(stroke.rgb, mix(base.rgb, mix(2.0*base.rgb*stroke.rgb, 1.0-2.0*(1.0-base.rgb)*(1.0-stroke.rgb), floor(base.rgb*2.0)), stroke.a/alpha_tot), base.a/alpha_tot); }
|
||||
mediump vec4 blend(mediump vec4 base, mediump vec4 stroke, int mode) {
|
||||
mediump float contribution = (1.0 - base.a) * stroke.a;
|
||||
mediump float alpha_tot = base.a + contribution;
|
||||
if (mode == 0) return vec4(blend_normal(base, stroke, alpha_tot), alpha_tot);
|
||||
else if (mode == 1) return vec4(blend_multiply(base, stroke, alpha_tot), alpha_tot);
|
||||
else if (mode == 2) return vec4(blend_screen(base, stroke, alpha_tot), alpha_tot);
|
||||
else if (mode == 3) return vec4(blend_colorDodge(base, stroke, alpha_tot), alpha_tot);
|
||||
else if (mode == 4) return vec4(blend_overlay(base, stroke, alpha_tot), alpha_tot);
|
||||
else return vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
13
data/shaders/include/blur.glsl
Normal file
13
data/shaders/include/blur.glsl
Normal file
@@ -0,0 +1,13 @@
|
||||
mediump vec4 blur(sampler2D t, mediump vec2 uv)
|
||||
{
|
||||
mediump vec4 sum = texture(t, uv);
|
||||
sum += textureOffset(t, uv, ivec2(-1, -1));
|
||||
sum += textureOffset(t, uv, ivec2(-1, 0));
|
||||
sum += textureOffset(t, uv, ivec2(-1, 1));
|
||||
sum += textureOffset(t, uv, ivec2( 0, -1));
|
||||
sum += textureOffset(t, uv, ivec2( 0, 1));
|
||||
sum += textureOffset(t, uv, ivec2( 1, -1));
|
||||
sum += textureOffset(t, uv, ivec2( 1, 0));
|
||||
sum += textureOffset(t, uv, ivec2( 1, 1));
|
||||
return sum / vec4(9.0);
|
||||
}
|
||||
20
data/shaders/include/color.glsl
Normal file
20
data/shaders/include/color.glsl
Normal file
@@ -0,0 +1,20 @@
|
||||
mediump vec3 brightness3(mediump vec3 c, mediump float val)
|
||||
{
|
||||
return clamp(c + vec3(val * 2.0 - 1.0), vec3(0), vec3(1));
|
||||
}
|
||||
mediump vec3 contrast3(mediump vec3 c, mediump float val)
|
||||
{
|
||||
val = val * 2.0 - 1.0;
|
||||
mediump float factor = ((259.0 / 255.0) * (val + 1.0)) / (1.0 * ((259.0 / 255.0) - val));
|
||||
return clamp(factor * (c - 0.5) + 0.5, vec3(0), vec3(1));
|
||||
}
|
||||
mediump float brightness1(mediump float c, mediump float val)
|
||||
{
|
||||
return clamp(c + (val * 2.0 - 1.0), 0.0, 1.0);
|
||||
}
|
||||
mediump float contrast1(mediump float c, mediump float val)
|
||||
{
|
||||
val = val * 2.0 - 1.0;
|
||||
mediump float factor = ((259.0 / 255.0) * (val + 1.0)) / (1.0 * ((259.0 / 255.0) - val));
|
||||
return clamp(factor * (c - 0.5) + 0.5, 0.0, 1.0);
|
||||
}
|
||||
5
data/shaders/include/ext-fb-fetch.glsl
Normal file
5
data/shaders/include/ext-fb-fetch.glsl
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
#extension GL_EXT_shader_framebuffer_fetch : enable
|
||||
#elif defined(GL_ARM_shader_framebuffer_fetch)
|
||||
#extension GL_ARM_shader_framebuffer_fetch : enable
|
||||
#endif
|
||||
15
data/shaders/include/hsv.glsl
Normal file
15
data/shaders/include/hsv.glsl
Normal file
@@ -0,0 +1,15 @@
|
||||
mediump vec3 rgb2hsv(mediump vec3 c)
|
||||
{
|
||||
mediump vec4 k = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
mediump vec4 p = mix(vec4(c.bg, k.wz), vec4(c.gb, k.xy), step(c.b, c.g));
|
||||
mediump vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
mediump float d = q.x - min(q.w, q.y);
|
||||
mediump float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
mediump vec3 hsv2rgb(mediump vec3 c)
|
||||
{
|
||||
mediump vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
mediump vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
10
data/shaders/include/rand.glsl
Normal file
10
data/shaders/include/rand.glsl
Normal file
@@ -0,0 +1,10 @@
|
||||
// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
highp float rand(mediump vec2 co)
|
||||
{
|
||||
highp float a = 12.9898;
|
||||
highp float b = 78.233;
|
||||
highp float c = 43758.5453;
|
||||
highp float dt= dot(co.xy, vec2(a,b));
|
||||
highp float sn= mod(dt, 3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
23
data/shaders/lambert.glsl
Normal file
23
data/shaders/lambert.glsl
Normal file
@@ -0,0 +1,23 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec3 nor;
|
||||
in vec2 uvs;
|
||||
out vec3 n;
|
||||
void main()
|
||||
{
|
||||
n = nor;
|
||||
gl_Position = mvp * pos;
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform mediump vec3 light_dir;
|
||||
uniform mediump float ambient;
|
||||
in mediump vec3 n;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump float d = max(0.0, dot(normalize(n), light_dir));
|
||||
frag = vec4(vec3(d) + ambient, 1.0);
|
||||
//frag = vec4(normalize(n) * 0.5 + 0.5, 1.0);
|
||||
}
|
||||
27
data/shaders/lightmap.glsl
Normal file
27
data/shaders/lightmap.glsl
Normal file
@@ -0,0 +1,27 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec3 nor;
|
||||
in vec2 uvs;
|
||||
out vec3 n;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
n = nor;
|
||||
uv = uvs;
|
||||
gl_Position = mvp * pos;
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform mediump sampler2D tex;
|
||||
uniform mediump vec3 light_dir;
|
||||
uniform mediump float ambient;
|
||||
in mediump vec3 n;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump float d = max(0.0, dot(normalize(n), normalize(light_dir)));
|
||||
mediump vec4 c = texture(tex, uv);
|
||||
frag = vec4(c.rgb * d + ambient, 1.0);
|
||||
}
|
||||
31
data/shaders/stroke-instanced.glsl
Normal file
31
data/shaders/stroke-instanced.glsl
Normal file
@@ -0,0 +1,31 @@
|
||||
[[vertex]]
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
in mat4 a_mvp;
|
||||
in float a_flow;
|
||||
out vec3 uv;
|
||||
out float alpha;
|
||||
void main()
|
||||
{
|
||||
uv = vec3(uvs, pos.w);
|
||||
alpha = a_flow;
|
||||
gl_Position = a_mvp * vec4(pos.xyz, 1.0);
|
||||
}
|
||||
|
||||
[[fragment]]
|
||||
uniform mediump sampler2D tex;
|
||||
uniform mediump sampler2D tex_pattern;
|
||||
uniform mediump vec4 col;
|
||||
uniform mediump vec2 resolution;
|
||||
uniform mediump vec2 pattern_offset;
|
||||
uniform mediump float pattern_alpha;
|
||||
in mediump float alpha;
|
||||
in mediump vec3 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump vec2 uv2 = gl_FragCoord.st / resolution;
|
||||
mediump float pattern = 1.0 - (texture(tex_pattern, (uv2+pattern_offset)).r * 0.9) * pattern_alpha;
|
||||
mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * pattern;
|
||||
frag = vec4(col.rgb, a);
|
||||
}
|
||||
31
data/shaders/stroke-preview.glsl
Normal file
31
data/shaders/stroke-preview.glsl
Normal file
@@ -0,0 +1,31 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform sampler2D tex;
|
||||
uniform mediump vec4 col;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main() {
|
||||
mediump float stroke = 1.0 - texture(tex, uv).r;
|
||||
int zero_count = 0;
|
||||
if (textureOffset(tex, uv, ivec2(-1, -1)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2(-1, 0)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2(-1, +1)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2( 0, -1)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2( 0, 0)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2( 0, +1)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2(+1, -1)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2(+1, 0)).r > 0.99) zero_count++;
|
||||
if (textureOffset(tex, uv, ivec2(+1, +1)).r > 0.99) zero_count++;
|
||||
mediump float edge = (zero_count > 1 && zero_count < 9) ? 0.75 : 0.0;
|
||||
frag = vec4(col.rgb, edge * (1.0 - float(zero_count) / 9.f));
|
||||
};
|
||||
93
data/shaders/stroke.glsl
Normal file
93
data/shaders/stroke.glsl
Normal file
@@ -0,0 +1,93 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
in vec2 uvs2;
|
||||
out vec2 uv;
|
||||
out vec2 uv_2;
|
||||
out float q;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
uv_2 = uvs2;
|
||||
q = pos.w;
|
||||
gl_Position = mvp * vec4(pos.xy, 0.0, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/ext-fb-fetch.glsl"
|
||||
#include "include/rand.glsl"
|
||||
#include "include/color.glsl"
|
||||
|
||||
uniform mediump sampler2D tex;
|
||||
uniform mediump sampler2D tex_bg;
|
||||
uniform mediump sampler2D tex_mix;
|
||||
uniform mediump vec4 col;
|
||||
uniform mediump vec2 resolution;
|
||||
uniform mediump float alpha;
|
||||
uniform mediump float noise;
|
||||
uniform mediump float mix_alpha;
|
||||
uniform mediump float wet;
|
||||
|
||||
uniform bool use_pattern;
|
||||
uniform mediump sampler2D tex_pattern;
|
||||
uniform mediump vec2 pattern_scale;
|
||||
uniform mediump float pattern_bright;
|
||||
uniform mediump float pattern_contr;
|
||||
uniform mediump float pattern_depth;
|
||||
uniform mediump vec2 pattern_offset;
|
||||
uniform mediump bool pattern_invert;
|
||||
|
||||
in mediump vec2 uv;
|
||||
in mediump vec2 uv_2;
|
||||
in mediump float q;
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
inout mediump vec4 frag;
|
||||
#else
|
||||
out mediump vec4 frag;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
mediump vec2 uv2 = gl_FragCoord.st / resolution;
|
||||
mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;
|
||||
mediump vec4 fg = vec4(col.rgb, brush_alpha);
|
||||
if (use_pattern)
|
||||
{
|
||||
mediump vec2 rscale = resolution / vec2(512.0);
|
||||
mediump float patt = texture(tex_pattern, uv2 * (0.5 / pattern_scale) * rscale + pattern_offset).r;
|
||||
if (pattern_invert)
|
||||
patt = 1.0 - patt;
|
||||
patt = patt * pattern_depth + (1.0 - pattern_depth);
|
||||
if (pattern_bright != 0.5)
|
||||
patt = brightness1(patt, 1.0 - pattern_bright);
|
||||
if (pattern_contr != 0.5)
|
||||
patt = contrast1(patt, pattern_contr);
|
||||
fg.a = mix(fg.a, fg.a * patt, pattern_depth);
|
||||
}
|
||||
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
mediump vec4 bg = frag;
|
||||
#elif defined(GL_ARM_shader_framebuffer_fetch)
|
||||
mediump vec4 bg = gl_LastFragColorARM;
|
||||
#else
|
||||
mediump vec4 bg = texture(tex_bg, uv2);
|
||||
#endif
|
||||
|
||||
fg.a *= 1.0-rand(uv2+uv)*noise;
|
||||
if (fg.a == 0.0) discard;
|
||||
if (mix_alpha > 0.0)
|
||||
{
|
||||
mediump vec2 uv_mix = uv_2 / q;
|
||||
if (uv_mix.x < 0.0 || uv_mix.x > 1.0 || uv_mix.y < 0.0 || uv_mix.y > 1.0) discard;
|
||||
mediump vec4 mbg = texture(tex_mix, uv_mix);
|
||||
fg.rgb = mix(fg.rgb, mbg.rgb, mix_alpha * mbg.a);
|
||||
}
|
||||
mediump float contribution = (1.0 - bg.a) * fg.a;
|
||||
mediump float alpha_tot = bg.a + contribution;
|
||||
mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);
|
||||
mediump vec4 frag_wet = vec4(rgb, max(bg.a, fg.a * 1.2));
|
||||
mediump vec4 frag_dry = vec4(rgb, alpha_tot);
|
||||
frag = mix(frag_dry, frag_wet, wet);
|
||||
};
|
||||
|
||||
28
data/shaders/texture-alpha-sep.glsl
Normal file
28
data/shaders/texture-alpha-sep.glsl
Normal file
@@ -0,0 +1,28 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D tex_alpha;
|
||||
uniform sampler2D tex_bg;
|
||||
uniform mediump float alpha;
|
||||
uniform bool highlight;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump vec3 rgb = texture(tex, uv).rgb;
|
||||
mediump float a = texture(tex_alpha, uv).a;
|
||||
mediump vec4 c = vec4(rgb, a);
|
||||
frag = highlight ?
|
||||
vec4(clamp(vec3(0.3) + c.rgb, vec3(0.0), vec3(1.0)), c.a) :
|
||||
texture(tex, uv) * vec4(1.0, 1.0, 1.0, alpha);
|
||||
};
|
||||
24
data/shaders/texture-alpha.glsl
Normal file
24
data/shaders/texture-alpha.glsl
Normal file
@@ -0,0 +1,24 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform sampler2D tex;
|
||||
uniform mediump float alpha;
|
||||
uniform bool highlight;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
mediump vec4 c = texture(tex, uv);
|
||||
frag = highlight ?
|
||||
vec4(clamp(vec3(0.3) + c.rgb, vec3(0.0), vec3(1.0)), c.a) :
|
||||
c * vec4(1.0, 1.0, 1.0, alpha);
|
||||
};
|
||||
38
data/shaders/texture-blend.glsl
Normal file
38
data/shaders/texture-blend.glsl
Normal file
@@ -0,0 +1,38 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
#include "include/ext-fb-fetch.glsl"
|
||||
#include "include/blend.glsl"
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D tex_alpha;
|
||||
uniform sampler2D tex_bg;
|
||||
uniform mediump float alpha;
|
||||
uniform int blend_mode;
|
||||
in mediump vec2 uv;
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
inout highp vec4 frag;
|
||||
#else
|
||||
out mediump vec4 frag;
|
||||
#endif
|
||||
void main() {
|
||||
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||
highp vec4 bg = frag;
|
||||
#elif defined(GL_ARM_shader_framebuffer_fetch)
|
||||
highp vec4 bg = gl_LastFragColorARM;
|
||||
#else
|
||||
mediump vec4 bg = texture(tex_bg, uv);
|
||||
#endif
|
||||
mediump vec4 fg = vec4(texture(tex, uv).rgb, texture(tex_alpha, uv).a);
|
||||
if (fg.a == 0.0) { frag = bg; return; }
|
||||
mediump vec4 blended = blend(bg, fg, blend_mode);
|
||||
frag = vec4(blended.rgb, blended.a * alpha);
|
||||
};
|
||||
19
data/shaders/texture.glsl
Normal file
19
data/shaders/texture.glsl
Normal file
@@ -0,0 +1,19 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
uniform sampler2D tex;
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = texture(tex, uv);
|
||||
};
|
||||
18
data/shaders/uvs.glsl
Normal file
18
data/shaders/uvs.glsl
Normal file
@@ -0,0 +1,18 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
out vec2 uv;
|
||||
void main()
|
||||
{
|
||||
uv = uvs;
|
||||
gl_Position = mvp * vec4(pos.xyz, 1.0);
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
in mediump vec2 uv;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = vec4(uv, 0.0, 1.0);
|
||||
};
|
||||
19
data/shaders/vertex-color.glsl
Normal file
19
data/shaders/vertex-color.glsl
Normal file
@@ -0,0 +1,19 @@
|
||||
[[vertex]]
|
||||
uniform mat4 mvp;
|
||||
in vec4 pos;
|
||||
in vec4 col;
|
||||
out vec4 c;
|
||||
void main()
|
||||
{
|
||||
c = col;
|
||||
gl_Position = mvp * pos;
|
||||
gl_PointSize = 5.0;
|
||||
};
|
||||
|
||||
[[fragment]]
|
||||
in mediump vec4 c;
|
||||
out mediump vec4 frag;
|
||||
void main()
|
||||
{
|
||||
frag = c;
|
||||
};
|
||||
@@ -149,7 +149,7 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
|
||||
auto patt_uid = wstr2str(patt->value<String>("Idnt"));
|
||||
b->m_pattern_path = path + "/patterns/" + patt_uid + ".png";
|
||||
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
|
||||
b->m_pattern_opacity = p->value<UnitFloat>("textureDepth") * 0.01f;
|
||||
b->m_pattern_depth = p->value<UnitFloat>("textureDepth") * 0.01f;
|
||||
}
|
||||
ret.push_back(b);
|
||||
}
|
||||
|
||||
@@ -2,673 +2,8 @@
|
||||
#include "app.h"
|
||||
#include "shader.h"
|
||||
|
||||
#define SHADER_FUNCTION_BLUR \
|
||||
"mediump vec4 blur(sampler2D t, mediump vec2 uv){\n"\
|
||||
" mediump vec4 sum = texture(t, uv);\n"\
|
||||
" sum += textureOffset(t, uv, ivec2(-1, -1));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2(-1, 0));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2(-1, 1));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2( 0, -1));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2( 0, 1));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2( 1, -1));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2( 1, 0));\n"\
|
||||
" sum += textureOffset(t, uv, ivec2( 1, 1));\n"\
|
||||
" return sum / vec4(9.0);\n"\
|
||||
"}\n"
|
||||
|
||||
#define SHADER_FUNCTION_BLEND \
|
||||
"mediump vec3 blend_normal(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)"\
|
||||
"{ return mix(base.rgb, stroke.rgb, stroke.a/alpha_tot); }\n"\
|
||||
"mediump vec3 blend_multiply(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)"\
|
||||
"{ return mix(stroke.rgb, mix(base.rgb, base.rgb*stroke.rgb, stroke.a/alpha_tot), base.a/alpha_tot); }\n"\
|
||||
"mediump vec3 blend_screen(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)"\
|
||||
"{ return mix(stroke.rgb, mix(base.rgb, 1.0-(1.0-base.rgb)*(1.0-stroke.rgb), stroke.a/alpha_tot), base.a/alpha_tot); }\n"\
|
||||
"mediump vec3 blend_colorDodge(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)"\
|
||||
"{ return mix(stroke.rgb, mix(base.rgb, base.rgb/(1.0-stroke.rgb), stroke.a/alpha_tot), base.a/alpha_tot); }\n"\
|
||||
"mediump vec3 blend_overlay(mediump vec4 base, mediump vec4 stroke, mediump float alpha_tot)"\
|
||||
"{ return mix(stroke.rgb, mix(base.rgb, mix(2.0*base.rgb*stroke.rgb, 1.0-2.0*(1.0-base.rgb)*(1.0-stroke.rgb), floor(base.rgb*2.0)), stroke.a/alpha_tot), base.a/alpha_tot); }\n"\
|
||||
"mediump vec4 blend(mediump vec4 base, mediump vec4 stroke, int mode) {\n"\
|
||||
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"\
|
||||
" mediump float alpha_tot = base.a + contribution;\n"\
|
||||
" if (mode == 0) return vec4(blend_normal(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||
" else if (mode == 1) return vec4(blend_multiply(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||
" else if (mode == 2) return vec4(blend_screen(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||
" else if (mode == 3) return vec4(blend_colorDodge(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||
" else if (mode == 4) return vec4(blend_overlay(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||
" else return vec4(1.0, 0.0, 0.0, 1.0);\n"\
|
||||
"}\n"
|
||||
|
||||
#define SHADER_FUNCTION_BLEND_STROKE \
|
||||
"mediump float blend_stroke(mediump float base, mediump float stroke, int mode) {\n"\
|
||||
" if (mode == 0) return (base + stroke) * 0.5;\n"\
|
||||
" else if (mode == 1) return base * stroke;\n"\
|
||||
" else if (mode == 2) return 1.0-(1.0-base)*(1.0-stroke);\n"\
|
||||
" else if (mode == 3) return base/(1.0-stroke);\n"\
|
||||
" else if (mode == 4) return mix(2.0*base*stroke, 1.0-2.0*(1.0-base)*(1.0-stroke), floor(base*2.0));\n"\
|
||||
" else return 1.0;\n"\
|
||||
"}\n"
|
||||
|
||||
#define SHADER_FUNCTION_HSV \
|
||||
"mediump vec3 rgb2hsv(mediump vec3 c) {\n"\
|
||||
" mediump vec4 k = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n"\
|
||||
" mediump vec4 p = mix(vec4(c.bg, k.wz), vec4(c.gb, k.xy), step(c.b, c.g));\n"\
|
||||
" mediump vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n"\
|
||||
" mediump float d = q.x - min(q.w, q.y);\n"\
|
||||
" mediump float e = 1.0e-10;\n"\
|
||||
" return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"\
|
||||
"}\n"\
|
||||
"mediump vec3 hsv2rgb(mediump vec3 c) {\n"\
|
||||
" mediump vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"\
|
||||
" mediump vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"\
|
||||
" return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"\
|
||||
"}\n"
|
||||
|
||||
#define SHADER_FUNCTION_COLOR \
|
||||
"mediump vec3 brightness3(mediump vec3 c, mediump float val) {\n"\
|
||||
" return clamp(c + vec3(val * 2.0 - 1.0), vec3(0), vec3(1));\n"\
|
||||
"}\n"\
|
||||
"mediump vec3 contrast3(mediump vec3 c, mediump float val) {\n"\
|
||||
" val = val * 2.0 - 1.0;\n"\
|
||||
" mediump float factor = ((259.0 / 255.0) * (val + 1.0)) / (1.0 * ((259.0 / 255.0) - val));\n"\
|
||||
" return clamp(factor * (c - 0.5) + 0.5, vec3(0), vec3(1));\n"\
|
||||
"}\n"\
|
||||
"mediump float brightness1(mediump float c, mediump float val) {\n"\
|
||||
" return clamp(c + (val * 2.0 - 1.0), 0.0, 1.0);\n"\
|
||||
"}\n"\
|
||||
"mediump float contrast1(mediump float c, mediump float val) {\n"\
|
||||
" val = val * 2.0 - 1.0;\n"\
|
||||
" mediump float factor = ((259.0 / 255.0) * (val + 1.0)) / (1.0 * ((259.0 / 255.0) - val));\n"\
|
||||
" return clamp(factor * (c - 0.5) + 0.5, 0.0, 1.0);\n"\
|
||||
"}\n"
|
||||
|
||||
// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
#define SHADER_FUNCTION_RAND \
|
||||
"highp float rand(mediump vec2 co)\n"\
|
||||
"{\n"\
|
||||
" highp float a = 12.9898;\n"\
|
||||
" highp float b = 78.233;\n"\
|
||||
" highp float c = 43758.5453;\n"\
|
||||
" highp float dt= dot(co.xy, vec2(a,b));\n"\
|
||||
" highp float sn= mod(dt, 3.14);\n"\
|
||||
" return fract(sin(sn) * c);\n"\
|
||||
"}\n"
|
||||
|
||||
#define SHADER_EXT_FB_FETCH \
|
||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"\
|
||||
" #extension GL_EXT_shader_framebuffer_fetch : enable\n"\
|
||||
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"\
|
||||
" #extension GL_ARM_shader_framebuffer_fetch : enable\n"\
|
||||
"#endif\n"
|
||||
|
||||
void App::initShaders()
|
||||
{
|
||||
static const char* shader_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" frag = texture(tex, uv);\n"
|
||||
"}\n";
|
||||
static const char* shader_blend_f =
|
||||
SHADER_VERSION
|
||||
SHADER_EXT_FB_FETCH
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform sampler2D tex_alpha;\n"
|
||||
"uniform sampler2D tex_bg;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform int blend_mode;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||
" inout highp vec4 frag;\n"
|
||||
"#else\n"
|
||||
" out mediump vec4 frag;\n"
|
||||
"#endif\n"
|
||||
SHADER_FUNCTION_BLEND
|
||||
"void main() {\n"
|
||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||
" highp vec4 bg = frag;\n"
|
||||
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
|
||||
" highp vec4 bg = gl_LastFragColorARM;\n"
|
||||
"#else\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
||||
"#endif\n"
|
||||
" mediump vec4 fg = vec4(texture(tex, uv).rgb, texture(tex_alpha, uv).a);\n"
|
||||
" if (fg.a == 0.0) { frag = bg; return; }\n"
|
||||
" mediump vec4 blended = blend(bg, fg, blend_mode);\n"
|
||||
" frag = vec4(blended.rgb, blended.a * alpha);\n"
|
||||
"}\n";
|
||||
static const char* shader_uv_f =
|
||||
SHADER_VERSION
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" frag = vec4(uv, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
// TEXTURE ALPHA
|
||||
static const char* shader_alpha_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform bool highlight;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump vec4 c = texture(tex, uv);\n"
|
||||
" frag = highlight ? \n"
|
||||
" vec4(clamp(vec3(0.3) + c.rgb, vec3(0.0), vec3(1.0)), c.a) : \n"
|
||||
" c * vec4(1.0, 1.0, 1.0, alpha);\n"
|
||||
"}\n";
|
||||
// TEXTURE ALPHA SEPARATED
|
||||
static const char* shader_alpha_sep_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform sampler2D tex_alpha;\n"
|
||||
"uniform sampler2D tex_bg;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform bool highlight;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump vec3 rgb = texture(tex, uv).rgb;\n"
|
||||
" mediump float a = texture(tex_alpha, uv).a;\n"
|
||||
" mediump vec4 c = vec4(rgb, a);\n"
|
||||
" frag = highlight ? \n"
|
||||
" vec4(clamp(vec3(0.3) + c.rgb, vec3(0.0), vec3(1.0)), c.a) : \n"
|
||||
" texture(tex, uv) * vec4(1.0, 1.0, 1.0, alpha);\n"
|
||||
"}\n";
|
||||
// STROKE PREVIEW
|
||||
static const char* shader_stroke_preview_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump float stroke = 1.0 - texture(tex, uv).r;\n"
|
||||
" int zero_count = 0;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(-1, -1)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(-1, 0)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(-1, +1)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2( 0, -1)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2( 0, 0)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2( 0, +1)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(+1, -1)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(+1, 0)).r > 0.99) zero_count++;\n"
|
||||
" if (textureOffset(tex, uv, ivec2(+1, +1)).r > 0.99) zero_count++;\n"
|
||||
" mediump float edge = (zero_count > 1 && zero_count < 9) ? 0.75 : 0.0;\n"
|
||||
" frag = vec4(col.rgb, edge * (1.0 - float(zero_count) / 9.f));\n"
|
||||
"}\n";
|
||||
// TEXTURE COMP ERASE
|
||||
static const char* shader_comp_erase_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform sampler2D tex_stroke;\n"
|
||||
"uniform sampler2D tex_mask;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform mediump float stroke_alpha;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform bool mask;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
SHADER_FUNCTION_BLUR
|
||||
"void main() {\n"
|
||||
" mediump vec4 base = texture(tex, uv);\n"
|
||||
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
||||
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha;\n"
|
||||
" frag = vec4(base.rgb, clamp((base.a - stroke.a) * alpha, 0.0, 1.0));\n"
|
||||
"}\n";
|
||||
// TEXTURE COMP DRAW
|
||||
static const char* shader_comp_draw_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform sampler2D tex_stroke;\n"
|
||||
"uniform sampler2D tex_mask;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform mediump float stroke_alpha;\n"
|
||||
"uniform mediump int blend_mode;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform bool lock;\n"
|
||||
"uniform bool mask;\n"
|
||||
|
||||
"uniform bool use_dual;\n"
|
||||
"uniform sampler2D tex_dual;\n"
|
||||
"uniform mediump float dual_alpha;\n"
|
||||
"uniform mediump int dual_blend_mode;\n"
|
||||
|
||||
"uniform bool use_pattern;\n"
|
||||
"uniform sampler2D tex_pattern;\n"
|
||||
"uniform mediump float pattern_alpha;\n"
|
||||
"uniform mediump vec2 pattern_scale;\n"
|
||||
"uniform mediump float pattern_bright;\n"
|
||||
"uniform mediump float pattern_contr;\n"
|
||||
"uniform mediump vec2 pattern_offset;\n"
|
||||
"uniform mediump bool pattern_invert;\n"
|
||||
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
SHADER_FUNCTION_BLUR
|
||||
SHADER_FUNCTION_BLEND
|
||||
SHADER_FUNCTION_BLEND_STROKE
|
||||
SHADER_FUNCTION_COLOR
|
||||
"void main() {\n"
|
||||
" mediump vec4 base = texture(tex, uv);\n"
|
||||
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
||||
" if (use_pattern){\n"
|
||||
" mediump vec2 rscale = resolution / vec2(512.0);\n"
|
||||
" mediump float patt = texture(tex_pattern, uv * (0.5 / pattern_scale) * rscale + pattern_offset).r;\n"
|
||||
" if (pattern_invert)\n"
|
||||
" patt = 1.0 - patt;\n"
|
||||
" if (pattern_bright != 0.5)\n"
|
||||
" patt = brightness1(patt, 1.0 - pattern_bright);\n"
|
||||
" if (pattern_contr != 0.5)\n"
|
||||
" patt = contrast1(patt, pattern_contr);\n"
|
||||
" stroke.a = mix(stroke.a, stroke.a * patt, pattern_alpha);\n"
|
||||
" }\n"
|
||||
" if (use_dual){\n"
|
||||
" mediump vec4 dual = texture(tex_dual, uv);\n"
|
||||
" stroke.a = blend_stroke(stroke.a, dual.a * dual_alpha, dual_blend_mode);\n"
|
||||
" }\n"
|
||||
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha;\n"
|
||||
" if (!lock && base.a == 0.0) { frag = stroke * vec4(1.0, 1.0, 1.0, alpha); return; }\n"
|
||||
" mediump vec4 blended = blend(base, stroke, blend_mode);\n"
|
||||
" frag = vec4(blended.rgb, (lock ? base.a : blended.a) * alpha);\n"
|
||||
"}\n";
|
||||
|
||||
// TEXTURE ATLAS
|
||||
static const char* shader_atlas_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"uniform vec2 tof;\n"
|
||||
"uniform vec2 tsz;\n"
|
||||
"in vec2 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" uv = tof + uvs * tsz;\n"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_atlas_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" frag = texture(tex, uv);\n"
|
||||
"}\n";
|
||||
|
||||
// SOLID COLOR
|
||||
static const char* shader_color_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
" gl_PointSize = 5.0;\n"
|
||||
"}\n";
|
||||
static const char* shader_color_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" frag = col;\n"
|
||||
"}\n";
|
||||
|
||||
// COLOR QUAD
|
||||
static const char* shader_color_quad_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec3 uv;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
" uv = vec3(uvs, pos.w);\n"
|
||||
"}\n";
|
||||
static const char* shader_color_quad_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col; // HSV\n"
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
SHADER_FUNCTION_HSV
|
||||
"void main() {\n"
|
||||
" frag = vec4(hsv2rgb(vec3(col.x, uv.x, 1.0 - uv.y)), 1.0);\n"
|
||||
"}\n";
|
||||
// COLOR TRI
|
||||
static const char* shader_color_tri_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col;\n" // in HSV
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
SHADER_FUNCTION_HSV
|
||||
"void main() {\n"
|
||||
" mediump float sat = tan(atan(uv.y, uv.x)) * 0.5 + 0.5;\n"
|
||||
" frag = vec4(hsv2rgb(vec3(col.r, sat, uv.x)), 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// HUE
|
||||
static const char* shader_color_hue_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec3 uv;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
" uv = vec3(uvs, pos.w);\n"
|
||||
"}\n";
|
||||
static const char* shader_color_hue_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform bool dir;\n" // 0:horizontal, 1:vertical
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
SHADER_FUNCTION_HSV
|
||||
"void main() {\n"
|
||||
" frag = vec4(hsv2rgb(vec3(dir?uv.y:uv.x, 1.0, 1.0)), 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// FONT
|
||||
static const char* shader_font_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec2 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_font_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump float a = texture(tex, uv).r;\n"
|
||||
" frag = vec4(col.rgb, a);\n"
|
||||
"}\n";
|
||||
|
||||
// STROKE
|
||||
static const char* shader_stroke_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"in vec2 uvs2;\n"
|
||||
"out vec2 uv;\n"
|
||||
"out vec2 uv_2;\n"
|
||||
"out float q;\n"
|
||||
"void main() {\n"
|
||||
" uv = uvs;\n"
|
||||
" uv_2 = uvs2;\n"
|
||||
" q = pos.w;\n"
|
||||
" gl_Position = mvp * vec4(pos.xy, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_stroke_f =
|
||||
SHADER_VERSION
|
||||
SHADER_EXT_FB_FETCH
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump sampler2D tex_mix;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform mediump float noise;\n"
|
||||
"uniform mediump float mix_alpha;\n"
|
||||
"uniform mediump float wet;\n"
|
||||
|
||||
"uniform bool use_pattern;\n"
|
||||
"uniform mediump sampler2D tex_pattern;\n"
|
||||
"uniform mediump float pattern_alpha;\n"
|
||||
"uniform mediump vec2 pattern_scale;\n"
|
||||
"uniform mediump float pattern_bright;\n"
|
||||
"uniform mediump float pattern_contr;\n"
|
||||
"uniform mediump vec2 pattern_offset;\n"
|
||||
"uniform mediump bool pattern_invert;\n"
|
||||
|
||||
"in mediump vec2 uv;\n"
|
||||
"in mediump vec2 uv_2;\n"
|
||||
"in mediump float q;\n"
|
||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||
" inout mediump vec4 frag;\n"
|
||||
"#else\n"
|
||||
" out mediump vec4 frag;\n"
|
||||
"#endif\n"
|
||||
SHADER_FUNCTION_RAND
|
||||
SHADER_FUNCTION_COLOR
|
||||
"void main() {\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha;\n"
|
||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||
" if (use_pattern){\n"
|
||||
" mediump vec2 rscale = resolution / vec2(512.0);\n"
|
||||
" mediump float patt = texture(tex_pattern, uv2 * (0.5 / pattern_scale) * rscale + pattern_offset).r;\n"
|
||||
" if (pattern_invert)\n"
|
||||
" patt = 1.0 - patt;\n"
|
||||
" if (pattern_bright != 0.5)\n"
|
||||
" patt = brightness1(patt, 1.0 - pattern_bright);\n"
|
||||
" if (pattern_contr != 0.5)\n"
|
||||
" patt = contrast1(patt, pattern_contr);\n"
|
||||
" fg.a = mix(fg.a, fg.a * patt, pattern_alpha);\n"
|
||||
" }\n"
|
||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||
" mediump vec4 bg = frag;\n"
|
||||
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
|
||||
" mediump vec4 bg = gl_LastFragColorARM;\n"
|
||||
"#else\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
"#endif\n"
|
||||
" fg.a *= 1.0-rand(uv2+uv)*noise;\n"
|
||||
" if (fg.a == 0.0) discard;\n"
|
||||
" if (mix_alpha > 0.0){\n"
|
||||
" mediump vec2 uv_mix = uv_2 / q;\n"
|
||||
" if (uv_mix.x < 0.0 || uv_mix.x > 1.0 || uv_mix.y < 0.0 || uv_mix.y > 1.0) discard;\n"
|
||||
" mediump vec4 mbg = texture(tex_mix, uv_mix);\n"
|
||||
" fg.rgb = mix(fg.rgb, mbg.rgb, mix_alpha * mbg.a);\n"
|
||||
" }\n"
|
||||
" mediump float contribution = (1.0 - bg.a) * fg.a;\n"
|
||||
" mediump float alpha_tot = bg.a + contribution;\n"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" mediump vec4 frag_wet = vec4(rgb, max(bg.a, fg.a * 1.2));\n"
|
||||
" mediump vec4 frag_dry = vec4(rgb, alpha_tot);\n"
|
||||
" frag = mix(frag_dry, frag_wet, wet);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* shader_checkerboard_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_checkerboard_f =
|
||||
SHADER_VERSION
|
||||
"uniform bool colorize;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" const mediump vec4 c1 = vec4(1.0, 1.0, 1.0, 1.0);\n"
|
||||
" const mediump vec4 c2 = vec4(0.9, 0.9, 0.9, 1.0);\n"
|
||||
" mediump vec2 c = floor(fract(uv * 10.0) * 2.0);\n"
|
||||
" mediump float alpha = mix(c.x, 1.0 - c.x, c.y);\n"
|
||||
" if (colorize) frag = mix(c1, c2, alpha) * vec4(fract(uv.x * 5.0), uv.y, 1.0, 1.0);\n"
|
||||
" else frag = mix(c1, c2, alpha);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* shader_equirect_v =
|
||||
SHADER_VERSION
|
||||
"#define PI 3.1415926535897932384626433832795\n"
|
||||
"#define TWO_PI 6.283185307179586476925286766559\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" uv = (vec2(1.0) - uvs + vec2(0.25,0.0)) * vec2(TWO_PI, PI);\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_equirect_f =
|
||||
SHADER_VERSION
|
||||
"uniform samplerCube tex;\n"
|
||||
"in highp vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" highp float anglex = uv.x;\n"
|
||||
" highp float angley = uv.y;\n"
|
||||
" highp float sx = sin(anglex);\n"
|
||||
" highp float cx = cos(anglex);\n"
|
||||
" highp vec3 dir = vec3(0.0, 0.0, 0.0);\n"
|
||||
" dir.x = sin(angley) * cx;\n"
|
||||
" dir.y = cos(angley);\n"
|
||||
" dir.z = sin(angley) * sx;\n"
|
||||
" frag = texture(tex, dir);\n"
|
||||
"}\n";
|
||||
|
||||
// STROKE - INSTANCED
|
||||
static const char* shader_stroke_inst_v =
|
||||
SHADER_VERSION
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"in mat4 a_mvp;\n"
|
||||
"in float a_flow;\n"
|
||||
"out vec3 uv;\n"
|
||||
"out float alpha;\n"
|
||||
"void main() {\n"
|
||||
" uv = vec3(uvs, pos.w);\n"
|
||||
" alpha = a_flow;\n"
|
||||
" gl_Position = a_mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_stroke_inst_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_pattern;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump vec2 pattern_offset;\n"
|
||||
"uniform mediump float pattern_alpha;\n"
|
||||
"in mediump float alpha;\n"
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float pattern = 1.0 - (texture(tex_pattern, (uv2+pattern_offset)).r * 0.9) * pattern_alpha;\n"
|
||||
" mediump float a = (1.0 - texture(tex, uv.xy).r) * alpha * pattern;\n"
|
||||
" frag = vec4(col.rgb, a);\n"
|
||||
"}\n";
|
||||
|
||||
// VERTEX COLOR
|
||||
static const char* shader_vertcol_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec4 col;\n"
|
||||
"out vec4 c;\n"
|
||||
"void main() {\n"
|
||||
" c = col;\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
" gl_PointSize = 5.0;\n"
|
||||
"}\n";
|
||||
static const char* shader_vertcol_f =
|
||||
SHADER_VERSION
|
||||
"in mediump vec4 c;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" frag = c;\n"
|
||||
"}\n";
|
||||
|
||||
// LAMBERT
|
||||
static const char* shader_lambert_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec3 nor;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec3 n;\n"
|
||||
"void main() {\n"
|
||||
" n = nor;\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
"}\n";
|
||||
static const char* shader_lambert_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec3 light_dir;\n"
|
||||
"uniform mediump float ambient;\n"
|
||||
"in mediump vec3 n;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump float d = max(0.0, dot(normalize(n), light_dir));\n"
|
||||
" frag = vec4(vec3(d) + ambient, 1.0);\n"
|
||||
//" frag = vec4(normalize(n) * 0.5 + 0.5, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// LAMBERT LIGHTMAP
|
||||
static const char* shader_lambert_lightmap_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec3 nor;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec3 n;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" n = nor;\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * pos;\n"
|
||||
"}\n";
|
||||
static const char* shader_lambert_lightmap_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump vec3 light_dir;\n"
|
||||
"uniform mediump float ambient;\n"
|
||||
"in mediump vec3 n;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main() {\n"
|
||||
" mediump float d = max(0.0, dot(normalize(n), normalize(light_dir)));\n"
|
||||
" mediump vec4 c = texture(tex, uv);\n"
|
||||
" frag = vec4(c.rgb * d + ambient, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
// BAKE UVS
|
||||
static const char* shader_bakeuv_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec3 nor;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec3 n;\n"
|
||||
"out vec3 p;\n"
|
||||
"void main() {\n"
|
||||
" n = nor;\n"
|
||||
" p = vec3(mvp * pos);\n"
|
||||
" gl_Position = vec4(uvs * 2.0 - 1.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_bakeuv_f =
|
||||
SHADER_VERSION
|
||||
"uniform int mode;\n"
|
||||
"in highp vec3 n;\n"
|
||||
"in highp vec3 p;\n"
|
||||
"out highp vec3 frag;\n"
|
||||
"void main() {\n"
|
||||
" switch(mode) {\n"
|
||||
" case 0: frag = normalize(n); break;\n"
|
||||
" case 1: frag = p; break;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
GLint n_exts;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &n_exts);
|
||||
@@ -684,49 +19,49 @@ void App::initShaders()
|
||||
LOG("Shader Extension shader_framebuffer_fetch: %s", ShaderManager::ext_framebuffer_fetch ? "enabled" : "disabled");
|
||||
|
||||
LOG("initializing shaders");
|
||||
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
||||
if (!ShaderManager::load(kShader::Texture, "data/shaders/texture.glsl"))
|
||||
LOG("Failed to create shader Texture");
|
||||
if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f))
|
||||
if (!ShaderManager::load(kShader::TextureAlpha, "data/shaders/texture-alpha.glsl"))
|
||||
LOG("Failed to create shader TextureAlpha");
|
||||
if (!ShaderManager::create(kShader::TextureAlphaSep, shader_v, shader_alpha_sep_f))
|
||||
if (!ShaderManager::load(kShader::TextureAlphaSep, "data/shaders/texture-alpha-sep.glsl"))
|
||||
LOG("Failed to create shader TextureAlphaSep");
|
||||
if (!ShaderManager::create(kShader::TextureBlend, shader_v, shader_blend_f))
|
||||
if (!ShaderManager::load(kShader::TextureBlend, "data/shaders/texture-blend.glsl"))
|
||||
LOG("Failed to create shader TextureBlend");
|
||||
if (!ShaderManager::create(kShader::StrokePreview, shader_v, shader_stroke_preview_f))
|
||||
if (!ShaderManager::load(kShader::StrokePreview, "data/shaders/stroke-preview.glsl"))
|
||||
LOG("Failed to create shader StrokePreview");
|
||||
if (!ShaderManager::create(kShader::CompErase, shader_v, shader_comp_erase_f))
|
||||
if (!ShaderManager::load(kShader::CompErase, "data/shaders/comp-erase.glsl"))
|
||||
LOG("Failed to create shader CompErase");
|
||||
if (!ShaderManager::create(kShader::CompDraw, shader_v, shader_comp_draw_f))
|
||||
if (!ShaderManager::load(kShader::CompDraw, "data/shaders/comp-draw.glsl"))
|
||||
LOG("Failed to create shader CompDraw");
|
||||
if (!ShaderManager::create(kShader::Color, shader_color_v, shader_color_f))
|
||||
if (!ShaderManager::load(kShader::Color, "data/shaders/color.glsl"))
|
||||
LOG("Failed to create shader Color");
|
||||
if (!ShaderManager::create(kShader::ColorQuad, shader_color_quad_v, shader_color_quad_f))
|
||||
if (!ShaderManager::load(kShader::ColorQuad, "data/shaders/color-quad.glsl"))
|
||||
LOG("Failed to create shader ColorQuad");
|
||||
if (!ShaderManager::create(kShader::ColorTri, shader_color_quad_v, shader_color_tri_f))
|
||||
if (!ShaderManager::load(kShader::ColorTri, "data/shaders/color-tri.glsl"))
|
||||
LOG("Failed to create shader ColorTri");
|
||||
if (!ShaderManager::create(kShader::ColorHue, shader_color_hue_v, shader_color_hue_f))
|
||||
if (!ShaderManager::load(kShader::ColorHue, "data/shaders/color-hue.glsl"))
|
||||
LOG("Failed to create shader ColorHue");
|
||||
if (!ShaderManager::create(kShader::UVs, shader_v, shader_uv_f))
|
||||
if (!ShaderManager::load(kShader::UVs, "data/shaders/uvs.glsl"))
|
||||
LOG("Failed to create shader UVs");
|
||||
if (!ShaderManager::create(kShader::Font, shader_font_v, shader_font_f))
|
||||
if (!ShaderManager::load(kShader::Font, "data/shaders/font.glsl"))
|
||||
LOG("Failed to create shader Font");
|
||||
if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f))
|
||||
if (!ShaderManager::load(kShader::Atlas, "data/shaders/atlas.glsl"))
|
||||
LOG("Failed to create shader Atlas");
|
||||
if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f))
|
||||
if (!ShaderManager::load(kShader::Stroke, "data/shaders/stroke.glsl"))
|
||||
LOG("Failed to create shader Stroke");
|
||||
if (!ShaderManager::create(kShader::Checkerboard, shader_checkerboard_v, shader_checkerboard_f))
|
||||
if (!ShaderManager::load(kShader::Checkerboard, "data/shaders/checkerboard.glsl"))
|
||||
LOG("Failed to create shader Checkerboard");
|
||||
if (!ShaderManager::create(kShader::Equirect, shader_equirect_v, shader_equirect_f))
|
||||
if (!ShaderManager::load(kShader::Equirect, "data/shaders/equirect.glsl"))
|
||||
LOG("Failed to create shader Equirect");
|
||||
if (!ShaderManager::create(kShader::BrushStroke, shader_stroke_inst_v, shader_stroke_inst_f))
|
||||
if (!ShaderManager::load(kShader::BrushStroke, "data/shaders/stroke-instanced.glsl"))
|
||||
LOG("Failed to create shader BrushStroke");
|
||||
if (!ShaderManager::create(kShader::VertexColor, shader_vertcol_v, shader_vertcol_f))
|
||||
if (!ShaderManager::load(kShader::VertexColor, "data/shaders/vertex-color.glsl"))
|
||||
LOG("Failed to create shader VertexColor");
|
||||
if (!ShaderManager::create(kShader::Lambert, shader_lambert_v, shader_lambert_f))
|
||||
if (!ShaderManager::load(kShader::Lambert, "data/shaders/lambert.glsl"))
|
||||
LOG("Failed to create shader Lambert");
|
||||
if (!ShaderManager::create(kShader::LambertLightmap, shader_lambert_lightmap_v, shader_lambert_lightmap_f))
|
||||
if (!ShaderManager::load(kShader::LambertLightmap, "data/shaders/lightmap.glsl"))
|
||||
LOG("Failed to create shader LambertLightmap");
|
||||
if (!ShaderManager::create(kShader::BakeUV, shader_bakeuv_v, shader_bakeuv_f))
|
||||
if (!ShaderManager::load(kShader::BakeUV, "data/shaders/bake-uv.glsl"))
|
||||
LOG("Failed to create shader BakeUV");
|
||||
LOG("shaders initialized");
|
||||
}
|
||||
|
||||
@@ -100,7 +100,6 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size);
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 3);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index].m_opacity);
|
||||
ShaderManager::u_int(kShaderUniform::Lock, canvas->m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active);
|
||||
@@ -112,6 +111,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
float m_tip_angle = 0;
|
||||
float m_tip_angle_delay = 0;
|
||||
float m_tip_mix = 0;
|
||||
float m_pattern_opacity = 1.f;
|
||||
float m_tip_wet = 0;
|
||||
float m_tip_noise = 0;
|
||||
float m_tip_hue = 0;
|
||||
@@ -78,6 +77,7 @@ public:
|
||||
float m_pattern_brightness = 0.5f;
|
||||
float m_pattern_contrast = 0.5f;
|
||||
bool m_pattern_rand_offset = false;
|
||||
float m_pattern_depth = 1.f;
|
||||
|
||||
bool load_tip(const std::string& path, const std::string& thumb);
|
||||
bool load_dual(const std::string& path, const std::string& thumb);
|
||||
|
||||
@@ -249,7 +249,6 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 3);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||
ShaderManager::u_int(kShaderUniform::Lock, false/*m_layers[layer_index].m_alpha_locked*/);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, false/*m_smask_active*/);
|
||||
@@ -496,11 +495,11 @@ void Canvas::stroke_draw()
|
||||
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
|
||||
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, brush->m_pattern_opacity);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternScale, patt_scale);
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, brush->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, brush->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, brush->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, brush->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, m_pattern_offset);
|
||||
ShaderManager::u_int(kShaderUniform::UsePattern, brush->m_pattern_enabled && brush->m_pattern_eachsample);
|
||||
ShaderManager::u_float(kShaderUniform::MixAlpha, brush->m_tip_mix);
|
||||
@@ -799,7 +798,6 @@ void Canvas::stroke_commit()
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
||||
@@ -811,6 +809,7 @@ void Canvas::stroke_commit()
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, m_pattern_offset);
|
||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||
|
||||
|
||||
@@ -216,7 +216,6 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||
ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||
@@ -229,6 +228,7 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||
|
||||
|
||||
@@ -108,6 +108,14 @@ void NodeCheckBox::set_icon(const std::string& icon_path)
|
||||
update_icon();
|
||||
}
|
||||
|
||||
void NodeCheckBox::set_value(bool checked, bool trigger_event)
|
||||
{
|
||||
this->checked = checked;
|
||||
update_icon();
|
||||
if (trigger_event && on_value_changed)
|
||||
on_value_changed(this, checked);
|
||||
}
|
||||
|
||||
void NodeCheckBox::update_icon()
|
||||
{
|
||||
if (m_icon_path.empty())
|
||||
|
||||
@@ -20,6 +20,6 @@ public:
|
||||
virtual void draw() override;
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||
void set_icon(const std::string& icon_path);
|
||||
void set_value(bool checked) { this->checked = checked; update_icon(); }
|
||||
void set_value(bool checked, bool trigger_event = false);
|
||||
void update_icon();
|
||||
};
|
||||
|
||||
@@ -538,79 +538,80 @@ bool NodePanelBrushPreset::save()
|
||||
fwrite(&h, sizeof(h), 1, fp);
|
||||
for (int ci = 0; ci < m_container->m_children.size(); ci++)
|
||||
{
|
||||
auto b = static_cast<NodeBrushPresetItem*>(m_container->get_child_at(ci));
|
||||
auto bpi = static_cast<NodeBrushPresetItem*>(m_container->get_child_at(ci));
|
||||
auto& b = bpi->m_brush;
|
||||
item_t i;
|
||||
i.m_name_len = b->m_brush->m_name.size();
|
||||
i.m_brush_path_len = b->m_brush->m_brush_path.size();
|
||||
i.m_brush_thumb_path_len = b->m_brush->m_brush_thumb_path.size();
|
||||
i.m_dual_path_len = b->m_brush->m_brush_path.size();
|
||||
i.m_dual_thumb_path_len = b->m_brush->m_brush_thumb_path.size();
|
||||
i.m_stencil_path_len = b->m_brush->m_pattern_path.size();
|
||||
i.m_stencil_thumb_path_len = b->m_brush->m_texture_thumb_path.size();
|
||||
i.m_tip_color = b->m_brush->m_tip_color;
|
||||
i.m_tip_size = b->m_brush->m_tip_size;
|
||||
i.m_tip_spacing = b->m_brush->m_tip_spacing;
|
||||
i.m_tip_flow = b->m_brush->m_tip_flow;
|
||||
i.m_tip_opacity = b->m_brush->m_tip_opacity;
|
||||
i.m_tip_angle = b->m_brush->m_tip_angle;
|
||||
i.m_tip_angle_delay = b->m_brush->m_tip_angle_delay;
|
||||
i.m_tip_mix = b->m_brush->m_tip_mix;
|
||||
i.m_pattern_opacity = b->m_brush->m_pattern_opacity;
|
||||
i.m_tip_wet = b->m_brush->m_tip_wet;
|
||||
i.m_tip_noise = b->m_brush->m_tip_noise;
|
||||
i.m_tip_hue = b->m_brush->m_tip_hue;
|
||||
i.m_tip_sat = b->m_brush->m_tip_sat;
|
||||
i.m_tip_val = b->m_brush->m_tip_val;
|
||||
i.m_tip_angle_follow = b->m_brush->m_tip_angle_follow;
|
||||
i.m_tip_flow_pressure = b->m_brush->m_tip_flow_pressure;
|
||||
i.m_tip_size_pressure = b->m_brush->m_tip_size_pressure;
|
||||
i.m_jitter_scale = b->m_brush->m_jitter_scale;
|
||||
i.m_jitter_angle = b->m_brush->m_jitter_angle;
|
||||
i.m_jitter_spread = b->m_brush->m_jitter_spread;
|
||||
i.m_jitter_flow = b->m_brush->m_jitter_flow;
|
||||
i.m_jitter_hue = b->m_brush->m_jitter_hue;
|
||||
i.m_jitter_sat = b->m_brush->m_jitter_sat;
|
||||
i.m_jitter_val = b->m_brush->m_jitter_val;
|
||||
i.m_blend_mode = b->m_brush->m_blend_mode;
|
||||
i.m_name_len = b->m_name.size();
|
||||
i.m_brush_path_len = b->m_brush_path.size();
|
||||
i.m_brush_thumb_path_len = b->m_brush_thumb_path.size();
|
||||
i.m_dual_path_len = b->m_brush_path.size();
|
||||
i.m_dual_thumb_path_len = b->m_brush_thumb_path.size();
|
||||
i.m_stencil_path_len = b->m_pattern_path.size();
|
||||
i.m_stencil_thumb_path_len = b->m_texture_thumb_path.size();
|
||||
i.m_tip_color = b->m_tip_color;
|
||||
i.m_tip_size = b->m_tip_size;
|
||||
i.m_tip_spacing = b->m_tip_spacing;
|
||||
i.m_tip_flow = b->m_tip_flow;
|
||||
i.m_tip_opacity = b->m_tip_opacity;
|
||||
i.m_tip_angle = b->m_tip_angle;
|
||||
i.m_tip_angle_delay = b->m_tip_angle_delay;
|
||||
i.m_tip_mix = b->m_tip_mix;
|
||||
i.m_tip_wet = b->m_tip_wet;
|
||||
i.m_tip_noise = b->m_tip_noise;
|
||||
i.m_tip_hue = b->m_tip_hue;
|
||||
i.m_tip_sat = b->m_tip_sat;
|
||||
i.m_tip_val = b->m_tip_val;
|
||||
i.m_tip_angle_follow = b->m_tip_angle_follow;
|
||||
i.m_tip_flow_pressure = b->m_tip_flow_pressure;
|
||||
i.m_tip_size_pressure = b->m_tip_size_pressure;
|
||||
i.m_jitter_scale = b->m_jitter_scale;
|
||||
i.m_jitter_angle = b->m_jitter_angle;
|
||||
i.m_jitter_spread = b->m_jitter_spread;
|
||||
i.m_jitter_flow = b->m_jitter_flow;
|
||||
i.m_jitter_hue = b->m_jitter_hue;
|
||||
i.m_jitter_sat = b->m_jitter_sat;
|
||||
i.m_jitter_val = b->m_jitter_val;
|
||||
i.m_blend_mode = b->m_blend_mode;
|
||||
|
||||
i.m_tip_invert = b->m_brush->m_tip_invert;
|
||||
i.m_tip_flipx = b->m_brush->m_tip_flipx;
|
||||
i.m_tip_flipy = b->m_brush->m_tip_flipy;
|
||||
i.m_pattern_enabled = b->m_brush->m_pattern_enabled;
|
||||
i.m_dual_enabled = b->m_brush->m_dual_enabled;
|
||||
i.m_dual_blend_mode = b->m_brush->m_dual_blend_mode;
|
||||
i.m_dual_randflip = b->m_brush->m_dual_randflip;
|
||||
i.m_dual_size = b->m_brush->m_dual_size;
|
||||
i.m_dual_spacing = b->m_brush->m_dual_spacing;
|
||||
i.m_dual_scatter = b->m_brush->m_dual_scatter;
|
||||
i.m_dual_scatter_axis = b->m_brush->m_dual_scatter_axis;
|
||||
i.m_dual_invert = b->m_brush->m_dual_invert;
|
||||
i.m_dual_flipx = b->m_brush->m_dual_flipx;
|
||||
i.m_dual_flipy = b->m_brush->m_dual_flipy;
|
||||
i.m_tip_randflipx = b->m_brush->m_tip_randflipx;
|
||||
i.m_tip_randflipy = b->m_brush->m_tip_randflipy;
|
||||
i.m_tip_aspect = b->m_brush->m_tip_aspect;
|
||||
i.m_dual_flow = b->m_brush->m_dual_flow;
|
||||
i.m_dual_opacity = b->m_brush->m_dual_opacity;
|
||||
i.m_dual_rotate = b->m_brush->m_dual_rotate;
|
||||
i.m_tip_invert = b->m_tip_invert;
|
||||
i.m_tip_flipx = b->m_tip_flipx;
|
||||
i.m_tip_flipy = b->m_tip_flipy;
|
||||
i.m_pattern_enabled = b->m_pattern_enabled;
|
||||
i.m_dual_enabled = b->m_dual_enabled;
|
||||
i.m_dual_blend_mode = b->m_dual_blend_mode;
|
||||
i.m_dual_randflip = b->m_dual_randflip;
|
||||
i.m_dual_size = b->m_dual_size;
|
||||
i.m_dual_spacing = b->m_dual_spacing;
|
||||
i.m_dual_scatter = b->m_dual_scatter;
|
||||
i.m_dual_scatter_axis = b->m_dual_scatter_axis;
|
||||
i.m_dual_invert = b->m_dual_invert;
|
||||
i.m_dual_flipx = b->m_dual_flipx;
|
||||
i.m_dual_flipy = b->m_dual_flipy;
|
||||
i.m_tip_randflipx = b->m_tip_randflipx;
|
||||
i.m_tip_randflipy = b->m_tip_randflipy;
|
||||
i.m_tip_aspect = b->m_tip_aspect;
|
||||
i.m_dual_flow = b->m_dual_flow;
|
||||
i.m_dual_opacity = b->m_dual_opacity;
|
||||
i.m_dual_rotate = b->m_dual_rotate;
|
||||
|
||||
i.m_pattern_eachsample = b->m_brush->m_pattern_eachsample;
|
||||
i.m_pattern_invert = b->m_brush->m_pattern_invert;
|
||||
i.m_pattern_flipx = b->m_brush->m_pattern_flipx;
|
||||
i.m_pattern_flipy = b->m_brush->m_pattern_flipy;
|
||||
i.m_pattern_scale = b->m_brush->m_pattern_scale;
|
||||
i.m_pattern_brightness = b->m_brush->m_pattern_brightness;
|
||||
i.m_pattern_contrast = b->m_brush->m_pattern_contrast;
|
||||
i.m_pattern_rand_offset = b->m_brush->m_pattern_rand_offset;
|
||||
i.m_pattern_eachsample = b->m_pattern_eachsample;
|
||||
i.m_pattern_invert = b->m_pattern_invert;
|
||||
i.m_pattern_flipx = b->m_pattern_flipx;
|
||||
i.m_pattern_flipy = b->m_pattern_flipy;
|
||||
i.m_pattern_scale = b->m_pattern_scale;
|
||||
i.m_pattern_brightness = b->m_pattern_brightness;
|
||||
i.m_pattern_contrast = b->m_pattern_contrast;
|
||||
i.m_pattern_rand_offset = b->m_pattern_rand_offset;
|
||||
i.m_pattern_depth = b->m_pattern_depth;
|
||||
|
||||
fwrite(&i, sizeof(i), 1, fp);
|
||||
fwrite(b->m_brush->m_name.c_str(), 1, b->m_brush->m_name.size(), fp);
|
||||
fwrite(b->m_brush->m_brush_path.c_str(), 1, b->m_brush->m_brush_path.size(), fp);
|
||||
fwrite(b->m_brush->m_brush_thumb_path.c_str(), 1, b->m_brush->m_brush_thumb_path.size(), fp);
|
||||
fwrite(b->m_brush->m_dual_path.c_str(), 1, b->m_brush->m_brush_path.size(), fp);
|
||||
fwrite(b->m_brush->m_dual_thumb_path.c_str(), 1, b->m_brush->m_brush_thumb_path.size(), fp);
|
||||
fwrite(b->m_brush->m_pattern_path.c_str(), 1, b->m_brush->m_pattern_path.size(), fp);
|
||||
fwrite(b->m_brush->m_texture_thumb_path.c_str(), 1, b->m_brush->m_texture_thumb_path.size(), fp);
|
||||
fwrite(b->m_name.c_str(), 1, b->m_name.size(), fp);
|
||||
fwrite(b->m_brush_path.c_str(), 1, b->m_brush_path.size(), fp);
|
||||
fwrite(b->m_brush_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
||||
fwrite(b->m_dual_path.c_str(), 1, b->m_brush_path.size(), fp);
|
||||
fwrite(b->m_dual_thumb_path.c_str(), 1, b->m_brush_thumb_path.size(), fp);
|
||||
fwrite(b->m_pattern_path.c_str(), 1, b->m_pattern_path.size(), fp);
|
||||
fwrite(b->m_texture_thumb_path.c_str(), 1, b->m_texture_thumb_path.size(), fp);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
@@ -651,7 +652,6 @@ bool NodePanelBrushPreset::restore()
|
||||
b->m_tip_angle = i.m_tip_angle;
|
||||
b->m_tip_angle_delay = i.m_tip_angle_delay;
|
||||
b->m_tip_mix = i.m_tip_mix;
|
||||
b->m_pattern_opacity = i.m_pattern_opacity;
|
||||
b->m_tip_wet = i.m_tip_wet;
|
||||
b->m_tip_noise = i.m_tip_noise;
|
||||
b->m_tip_hue = i.m_tip_hue;
|
||||
@@ -696,6 +696,7 @@ bool NodePanelBrushPreset::restore()
|
||||
b->m_pattern_brightness = i.m_pattern_brightness;
|
||||
b->m_pattern_contrast = i.m_pattern_contrast;
|
||||
b->m_pattern_rand_offset = i.m_pattern_rand_offset;
|
||||
b->m_pattern_depth = i.m_pattern_depth;
|
||||
|
||||
b->m_name.resize(i.m_name_len);
|
||||
b->m_brush_path.resize(i.m_brush_path_len);
|
||||
|
||||
@@ -111,7 +111,6 @@ class NodePanelBrushPreset : public Node
|
||||
float m_tip_angle = 0;
|
||||
float m_tip_angle_delay = 0;
|
||||
float m_tip_mix = 0;
|
||||
float m_pattern_opacity = 0;
|
||||
float m_tip_wet = 0;
|
||||
float m_tip_noise = 0;
|
||||
float m_tip_hue = 0;
|
||||
@@ -158,6 +157,7 @@ class NodePanelBrushPreset : public Node
|
||||
float m_pattern_brightness = 0.5f;
|
||||
float m_pattern_contrast = 0.5f;
|
||||
bool m_pattern_rand_offset = false;
|
||||
float m_pattern_depth = 1.f;
|
||||
};
|
||||
public:
|
||||
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed;
|
||||
|
||||
@@ -31,7 +31,6 @@ void NodePanelStroke::update_controls()
|
||||
m_tip_opacity->m_value.x = b->m_tip_opacity;
|
||||
m_tip_angle->m_value.x = b->m_tip_angle;
|
||||
m_tip_angle_delay->m_value.x = b->m_tip_angle_delay;
|
||||
m_pattern_opacity->m_value.x = b->m_pattern_opacity;
|
||||
m_tip_wet->m_value.x = b->m_tip_wet;
|
||||
m_tip_noise->m_value.x = b->m_tip_noise;
|
||||
m_jitter_scale->m_value.x = b->m_jitter_scale;
|
||||
@@ -74,6 +73,7 @@ void NodePanelStroke::update_controls()
|
||||
m_pattern_scale->m_value.x = b->m_pattern_scale;
|
||||
m_pattern_brightness->m_value.x = b->m_pattern_brightness;
|
||||
m_pattern_contrast->m_value.x = b->m_pattern_contrast;
|
||||
m_pattern_depth->m_value.x = b->m_pattern_depth;
|
||||
|
||||
m_blend_mode->set_index(b->m_blend_mode);
|
||||
m_dual_blend_mode->set_index(b->m_dual_blend_mode);
|
||||
@@ -285,6 +285,7 @@ void NodePanelStroke::init_controls()
|
||||
};
|
||||
|
||||
m_pattern_popup->on_brush_changed = [this](Node*, int index) {
|
||||
m_pattern_enabled->set_value(true, true);
|
||||
if (on_pattern_changed)
|
||||
on_pattern_changed(this, m_pattern_popup->get_texture_path(index), m_pattern_popup->get_thumb_path(index));
|
||||
m_pattern_thumb->set_image(m_pattern_popup->get_thumb_path(index));
|
||||
@@ -308,7 +309,6 @@ void NodePanelStroke::init_controls()
|
||||
init_slider(m_tip_angle, "tip-angle", &Brush::m_tip_angle);
|
||||
init_slider(m_tip_angle_delay, "tip-angle-delay", &Brush::m_tip_angle_delay);
|
||||
init_slider(m_tip_mix, "tip-mix", &Brush::m_tip_mix);
|
||||
init_slider(m_pattern_opacity, "pattern-opacity", &Brush::m_pattern_opacity);
|
||||
init_slider(m_tip_wet, "tip-wet", &Brush::m_tip_wet);
|
||||
init_slider(m_tip_noise, "tip-noise", &Brush::m_tip_noise);
|
||||
init_slider(m_tip_hue, "tip-hue", &Brush::m_tip_hue);
|
||||
@@ -355,6 +355,7 @@ void NodePanelStroke::init_controls()
|
||||
init_slider(m_pattern_scale, "pattern-scale", &Brush::m_pattern_scale);
|
||||
init_slider(m_pattern_brightness, "pattern-brightness", &Brush::m_pattern_brightness);
|
||||
init_slider(m_pattern_contrast, "pattern-contrast", &Brush::m_pattern_contrast);
|
||||
init_slider(m_pattern_depth, "pattern-depth", &Brush::m_pattern_depth);
|
||||
|
||||
auto curve_cubic = [](float v) { return glm::pow(v, 3.f); };
|
||||
auto curve_quad = [](float v) { return glm::pow(v, 2.f); };
|
||||
|
||||
@@ -21,7 +21,6 @@ public:
|
||||
NodeSliderH* m_tip_angle;
|
||||
NodeSliderH* m_tip_angle_delay;
|
||||
NodeSliderH* m_tip_mix;
|
||||
NodeSliderH* m_pattern_opacity;
|
||||
NodeSliderH* m_tip_wet;
|
||||
NodeSliderH* m_tip_noise;
|
||||
NodeSliderH* m_tip_hue;
|
||||
@@ -78,6 +77,7 @@ public:
|
||||
NodeSliderH* m_pattern_scale;
|
||||
NodeSliderH* m_pattern_brightness;
|
||||
NodeSliderH* m_pattern_contrast;
|
||||
NodeSliderH* m_pattern_depth;
|
||||
|
||||
std::shared_ptr<NodePanelBrush> m_brush_popup;
|
||||
std::shared_ptr<NodePanelBrush> m_pattern_popup;
|
||||
|
||||
@@ -82,7 +82,6 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||
ShaderManager::u_int(kShaderUniform::Lock, false);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, false);
|
||||
@@ -95,7 +94,8 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f: 0.0f));
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f));
|
||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||
|
||||
m_sampler_linear.bind(0);
|
||||
@@ -297,11 +297,11 @@ void NodeStrokePreview::draw_stroke()
|
||||
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
|
||||
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, size);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternScale, patt_scale);
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f));
|
||||
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && b->m_pattern_eachsample);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho_proj);
|
||||
@@ -393,7 +393,6 @@ void NodeStrokePreview::draw_stroke()
|
||||
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, size);
|
||||
ShaderManager::u_float(kShaderUniform::StrokeAlpha, b->m_tip_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::PatternAlpha, b->m_pattern_opacity);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||
ShaderManager::u_int(kShaderUniform::Mask, false);
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
||||
@@ -405,6 +404,7 @@ void NodeStrokePreview::draw_stroke()
|
||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f));
|
||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||
|
||||
|
||||
127
src/shader.cpp
127
src/shader.cpp
@@ -1,11 +1,122 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "shader.h"
|
||||
#include "asset.h"
|
||||
|
||||
std::map<kShader, Shader> ShaderManager::m_shaders;
|
||||
Shader* ShaderManager::m_current;
|
||||
bool ShaderManager::ext_framebuffer_fetch = false;
|
||||
|
||||
std::string Shader::read(const std::string& path)
|
||||
{
|
||||
Asset a;
|
||||
std::string ret;
|
||||
if (a.open(path.c_str()))
|
||||
{
|
||||
std::regex reg_include(R"!(#include "([^"]+)")!");
|
||||
std::string data((char*)a.read_all(), a.m_len);
|
||||
|
||||
// split path
|
||||
std::string name, base, ext;
|
||||
std::regex reg_path(R"((.*)[\\/]([^\\/]+)\.(\w+)$)");
|
||||
std::smatch m;
|
||||
if (std::regex_search(path, m, reg_path))
|
||||
{
|
||||
base = m[1].str();
|
||||
name = m[2].str();
|
||||
ext = m[3].str();
|
||||
}
|
||||
|
||||
for (const auto& l : split(data, '\n'))
|
||||
{
|
||||
std::smatch m;
|
||||
if (std::regex_search(l, m, reg_include))
|
||||
{
|
||||
std::string inc = base + "/" + m[1].str();
|
||||
if (Asset::exist(inc.c_str()))
|
||||
{
|
||||
std::string subdata = read(inc);
|
||||
ret.append(subdata + "\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.append(l + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Shader::parse_error(const char* msg, const char* code)
|
||||
{
|
||||
auto code_lines = split(code, '\n');
|
||||
auto error_lines = split(msg, '\n');
|
||||
std::smatch m;
|
||||
std::regex r(R"(\((\d+)\))");
|
||||
for (const auto& line : error_lines)
|
||||
{
|
||||
LOG("%s", line.c_str());
|
||||
if (std::regex_search(line, m, r))
|
||||
{
|
||||
int ln = std::stoi(m[1].str());
|
||||
if (ln < code_lines.size())
|
||||
{
|
||||
int n = 2;
|
||||
int s = std::max(ln - n, 1);
|
||||
int e = std::min((int)code_lines.size() - 1, ln + n);
|
||||
for (int i = s; i < e; i++)
|
||||
{
|
||||
LOG("- line %02d: %s", i, code_lines[i - 1].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Shader::load(const std::string& path)
|
||||
{
|
||||
std::string data = read(path);
|
||||
if (data.empty()) return false;
|
||||
|
||||
std::map<std::string, std::shared_ptr<std::string>> sections;
|
||||
std::shared_ptr<std::string> current_section = nullptr;
|
||||
std::regex reg_section(R"!(\[\[(.*)\]\])!");
|
||||
for (const auto& l : split(data, '\n'))
|
||||
{
|
||||
std::smatch m;
|
||||
if (std::regex_search(l, m, reg_section))
|
||||
{
|
||||
std::string section_name = m[1].str();
|
||||
if (!sections[section_name])
|
||||
sections[section_name] = std::make_shared<std::string>();
|
||||
current_section = sections[section_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
// create an un-named section
|
||||
if (!current_section)
|
||||
current_section = sections[""] = std::make_shared<std::string>();
|
||||
current_section->append(l + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.find("vertex") != sections.end() && sections.find("fragment") != sections.end())
|
||||
{
|
||||
*sections["vertex"] = SHADER_VERSION + *sections["vertex"];
|
||||
*sections["fragment"] = SHADER_VERSION + *sections["fragment"];
|
||||
return create(sections["vertex"]->c_str(), sections["fragment"]->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("could not find [[vertex]] and [[fragment]] sections on %s", path.c_str());
|
||||
}
|
||||
|
||||
m_path = path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Shader::create(const char* vertex, const char* fragment)
|
||||
{
|
||||
GLint status;
|
||||
@@ -24,7 +135,10 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
|
||||
glGetShaderInfoLog(vs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
LOG("VERTEX SHADER:\n%s", infolog);
|
||||
{
|
||||
LOG("\nVERTEX SHADER:");
|
||||
parse_error(infolog, vertex);
|
||||
}
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteShader(vs);
|
||||
@@ -43,7 +157,10 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
|
||||
glGetShaderInfoLog(fs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
LOG("FRAGMENT SHADER:\n%s", infolog);
|
||||
{
|
||||
LOG("\nFRAGMENT SHADER:");
|
||||
parse_error(infolog, fragment);
|
||||
}
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteShader(vs);
|
||||
@@ -159,6 +276,12 @@ GLint Shader::GetAttribLocation(const char* name)
|
||||
return glGetAttribLocation(prog, name);
|
||||
}
|
||||
|
||||
bool ShaderManager::load(kShader id, const std::string& path)
|
||||
{
|
||||
m_shaders[id].name = id;
|
||||
return m_shaders[id].load(path);
|
||||
}
|
||||
|
||||
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
||||
{
|
||||
m_shaders[id].name = id;
|
||||
|
||||
@@ -40,6 +40,7 @@ enum class kShaderUniform : uint16_t
|
||||
PatternScale = const_hash("pattern_scale"),
|
||||
PatternBright = const_hash("pattern_bright"),
|
||||
PatternContrast = const_hash("pattern_contr"),
|
||||
PatternDepth = const_hash("pattern_depth"),
|
||||
Colorize = const_hash("colorize"),
|
||||
DualAlpha = const_hash("dual_alpha"),
|
||||
};
|
||||
@@ -73,10 +74,14 @@ enum class kShader : uint16_t
|
||||
|
||||
class Shader
|
||||
{
|
||||
std::string m_path;
|
||||
std::map<kShaderUniform, GLuint> m_umap;
|
||||
GLuint prog;
|
||||
std::string read(const std::string& path);
|
||||
public:
|
||||
kShader name;
|
||||
void parse_error(const char* msg, const char* code);
|
||||
bool load(const std::string& path);
|
||||
bool create(const char* vertex, const char* fragment);
|
||||
void use();
|
||||
void u_vec4(kShaderUniform id, const glm::vec4& v);
|
||||
@@ -94,6 +99,7 @@ class ShaderManager
|
||||
static Shader* m_current;
|
||||
public:
|
||||
static bool ext_framebuffer_fetch;
|
||||
static bool load(kShader id, const std::string& path);
|
||||
static bool create(kShader id, const char* vertex, const char* fragment);
|
||||
static void use(kShader id);
|
||||
static void use(const char* name);
|
||||
|
||||
Reference in New Issue
Block a user