#include "pch.h" #include "app.h" #include "shader.h" using namespace ui; void App::initShaders() { static const char* shader_v = SHADER_VERSION "uniform mat4 mvp;" "in vec4 pos;" "in vec2 uvs;" "out vec3 uv;" "void main(){" " uv = vec3(uvs, pos.w);" " gl_Position = mvp * vec4(pos.xyz, 1.0);" "}"; static const char* shader_f = SHADER_VERSION "uniform sampler2D tex;" "in mediump vec3 uv;" "out mediump vec4 frag;" "void main(){" //" frag = texture(tex, uv.xy/uv.z);" " frag = texture(tex, uv.xy);" "}"; static const char* shader_uv_f = SHADER_VERSION "uniform sampler2D tex;" "in mediump vec3 uv;" "out mediump vec4 frag;" "void main(){" " frag = vec4(uv.xy, 0.0, 1.0);" "}"; // 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 vec3 uv;\n" "out mediump vec4 frag;\n" "void main(){\n" " mediump vec4 c = texture(tex, uv.xy);\n" " frag = highlight ? \n" " vec4(clamp(vec3(.3)+c.rgb, vec3(0), vec3(1)), c.a) : \n" " texture(tex, uv.xy) * vec4(1,1,1,alpha);\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 bool lock;\n" "in mediump vec3 uv;\n" "out mediump vec4 frag;\n" "void main(){\n" " mediump vec4 base = texture(tex, uv.xy);\n" " mediump vec4 stroke = texture(tex_stroke, uv.xy);\n" " mediump float a = base.a - (stroke.a * alpha);\n" " frag = vec4(base.rgb, clamp(a, 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 bool lock;\n" "uniform bool mask;\n" "in mediump vec3 uv;\n" "out mediump vec4 frag;\n" "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" "void main(){\n" " mediump vec4 base = texture(tex, uv.xy);\n" " mediump vec4 stroke = texture(tex_stroke, uv.xy);\n" " stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv.xy).r : stroke.a * alpha;\n" " mediump float contribution = (1.0 - base.a) * stroke.a;\n" " mediump float alpha_tot = base.a + contribution;" " mediump vec3 rgb = mix(base.rgb, stroke.rgb, (stroke.a / alpha_tot));\n" " frag = vec4(rgb, (lock ? base.a : alpha_tot));\n" "}\n"; // TEXTURE ATLAS static const char* shader_atlas_v = SHADER_VERSION "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);" "}"; static const char* shader_atlas_f = SHADER_VERSION "uniform sampler2D tex;" "in mediump vec2 uv;" "out mediump vec4 frag;" "void main(){" " frag = texture(tex, uv);" "}"; // SOLID COLOR static const char* shader_color_v = SHADER_VERSION "uniform mat4 mvp;" "in vec4 pos;" "void main(){" " gl_Position = mvp * pos;" " gl_PointSize = 5.0;" "}"; static const char* shader_color_f = SHADER_VERSION "uniform mediump vec4 col;" "out mediump vec4 frag;" "void main(){" " frag = col;" "}"; // COLOR QUAD static const char* shader_color_quad_v = SHADER_VERSION "uniform mat4 mvp;" "in vec4 pos;" "in vec2 uvs;" "out vec3 uv;" "void main(){" " gl_Position = mvp * pos;" " uv = vec3(uvs, pos.w);" "}"; static const char* shader_color_quad_f = SHADER_VERSION "uniform mediump vec4 col;" "in mediump vec3 uv;" "out mediump vec4 frag;" "void main(){" " mediump vec4 gradient_x = mix(col, vec4(1.0, 1.0, 1.0, 1.0), uv.x);" " frag = mix(gradient_x, vec4(0.0, 0.0, 0.0, 1.0), uv.y);" "}"; // HUE static const char* shader_color_hue_v = SHADER_VERSION "uniform mat4 mvp;" "in vec4 pos;" "in vec2 uvs;" "out vec3 uv;" "void main(){" " gl_Position = mvp * pos;" " uv = vec3(uvs, pos.w);" "}"; static const char* shader_color_hue_f = SHADER_VERSION "uniform mediump vec4 col;" "in mediump vec3 uv;" "out mediump vec4 frag;" "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);" "}" "void main(){" " frag = vec4(hsv2rgb(vec3(uv.y, 1.0, 1.0)), 1.0);" "}"; // FONT static const char* shader_font_v = SHADER_VERSION "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);" "}"; static const char* shader_font_f = SHADER_VERSION "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);" "}"; // STROKE static const char* shader_stroke_v = SHADER_VERSION "uniform mat4 mvp;\n" "in vec4 pos;\n" "in vec2 uvs;\n" "out vec2 uv;\n" "out float q;\n" "void main(){\n" " uv = uvs;\n" " q = pos.z;\n" " gl_Position = mvp * vec4(pos.xy, 0.0, 1.0);\n" "}\n"; static const char* shader_stroke_f = SHADER_VERSION #ifdef __IOS__ "#extension GL_EXT_shader_framebuffer_fetch : enable\n" #endif "uniform mediump sampler2D tex;\n" "uniform mediump sampler2D tex_bg;\n" "uniform mediump vec4 col;\n" "uniform mediump vec2 resolution;\n" "uniform mediump float alpha;\n" "in mediump vec2 uv;\n" "in mediump float q;\n" #ifdef __IOS__ "inout mediump vec4 frag;\n" #else "out mediump vec4 frag;\n" #endif "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" #ifdef __IOS__ " mediump vec4 bg = frag;\n" #else " mediump vec4 bg = texture(tex_bg, uv2);\n" #endif " if (fg.a < 1.0/255.0) { frag = bg; return; }\n" " mediump float contribution = max((1.0 - bg.a) * fg.a, 1.0/255.0);\n" " mediump float alpha_tot = bg.a + contribution;" " mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n" " frag = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\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" "}"; static const char* shader_checkerboard_f = SHADER_VERSION "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" " frag = mix(c1, c2, alpha);\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" "}"; 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" "}"; LOG("initializing shaders"); if (!ShaderManager::create(kShader::Texture, shader_v, shader_f)) LOG("Failed to create shader Texture"); if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f)) LOG("Failed to create shader TextureAlpha"); if (!ShaderManager::create(kShader::CompErase, shader_v, shader_comp_erase_f)) LOG("Failed to create shader CompErase"); if (!ShaderManager::create(kShader::CompDraw, shader_v, shader_comp_draw_f)) LOG("Failed to create shader CompDraw"); if (!ShaderManager::create(kShader::Color, shader_color_v, shader_color_f)) LOG("Failed to create shader Color"); if (!ShaderManager::create(kShader::ColorQuad, shader_color_quad_v, shader_color_quad_f)) LOG("Failed to create shader ColorQuad"); if (!ShaderManager::create(kShader::ColorHue, shader_color_hue_v, shader_color_hue_f)) LOG("Failed to create shader ColorHue"); if (!ShaderManager::create(kShader::UVs, shader_v, shader_uv_f)) LOG("Failed to create shader UVs"); if (!ShaderManager::create(kShader::Font, shader_font_v, shader_font_f)) LOG("Failed to create shader Font"); if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f)) LOG("Failed to create shader Atlas"); if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f)) LOG("Failed to create shader Stroke"); if (!ShaderManager::create(kShader::Checkerboard, shader_checkerboard_v, shader_checkerboard_f)) LOG("Failed to create shader Checkerboard"); if (!ShaderManager::create(kShader::Equirect, shader_equirect_v, shader_equirect_f)) LOG("Failed to create shader Equirect"); LOG("shaders initialized"); }