436 lines
15 KiB
C++
436 lines
15 KiB
C++
#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 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 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"
|
|
" stroke.a = stroke.a * alpha;\n"
|
|
|
|
" if (lock){\n"
|
|
" mediump float alpha_tot = stroke.a + (1.0 - stroke.a) * base.a;"
|
|
" mediump vec3 rgb = mix(base.rgb, stroke.rgb, stroke.a / alpha_tot);\n"
|
|
" frag = vec4(rgb, base.a);\n"
|
|
" } else {\n"
|
|
" mediump float alpha_tot = stroke.a + (1.0 - stroke.a) * base.a;"
|
|
" mediump vec3 rgb = mix(base.rgb, stroke.rgb, stroke.a / alpha_tot);\n"
|
|
" frag = vec4(rgb, alpha_tot);\n"
|
|
" }\n"
|
|
|
|
// " mediump float alpha_tot = stroke.a + (1.0 - stroke.a) * base.a;"
|
|
// " mediump vec3 rgb = mix(base.rgb, stroke.rgb, stroke.a / alpha_tot);\n"
|
|
// " frag = vec4(rgb, 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"
|
|
"void main(){\n"
|
|
" uv = uvs;\n"
|
|
" gl_Position = mvp * vec4(pos.xyz, 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"
|
|
#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).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 alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
|
" 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";
|
|
// ALPHA LOCK
|
|
static const char* shader_stroke_lock_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 sampler2D tex_mask;\n"
|
|
"uniform mediump vec4 col;\n"
|
|
"uniform mediump vec2 resolution;\n"
|
|
"uniform mediump float alpha;\n"
|
|
"in mediump vec2 uv;\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).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
|
|
" mediump vec4 msk = texture(tex_mask, uv2);\n"
|
|
//" if (fg.a < (1.0/255.0)) { return; }\n"
|
|
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
|
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
|
" frag = vec4(rgb, msk.a);\n"
|
|
"}\n";
|
|
// ERASER
|
|
static const char* shader_stroke_erase_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"
|
|
#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).r ) * alpha;\n"
|
|
#ifdef __IOS__
|
|
" mediump vec4 bg = frag;\n"
|
|
#else
|
|
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
|
#endif
|
|
" frag = vec4(bg.rgb, bg.a - bg.a * brush_alpha);\n"
|
|
"}\n";
|
|
|
|
// STROKE LAYER BLEND
|
|
static const char* shader_stroke_layer_v =
|
|
SHADER_VERSION
|
|
"uniform mat4 mvp;"
|
|
"in vec4 pos;"
|
|
"in vec2 uvs;"
|
|
"out vec2 uv;"
|
|
"void main(){"
|
|
" uv = uvs;"
|
|
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
|
"}";
|
|
static const char* shader_stroke_layer_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 vec2 resolution;\n"
|
|
"uniform mediump float alpha;\n"
|
|
"uniform bool lock;\n"
|
|
"uniform bool erase;\n"
|
|
"in mediump vec2 uv;\n"
|
|
#ifdef __IOS__
|
|
"inout mediump vec4 frag;\n"
|
|
#else
|
|
"out mediump vec4 frag;\n"
|
|
#endif
|
|
"void main(){\n"
|
|
" mediump vec4 fg = texture(tex, uv) * vec4(1,1,1,alpha);\n"
|
|
#ifdef __IOS__
|
|
" mediump vec4 bg = frag;\n"
|
|
#else
|
|
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
|
#endif
|
|
//" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
|
" if (erase){\n"
|
|
" frag = vec4(bg.rgb, bg.a - fg.a);\n"
|
|
" } else {\n"
|
|
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
|
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
|
" frag = vec4(rgb, lock ? bg.a : alpha_tot);\n"
|
|
" }\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::StrokeLock, shader_stroke_v, shader_stroke_lock_f))
|
|
LOG("Failed to create shader StrokeLock");
|
|
if (!ShaderManager::create(kShader::StrokeErase, shader_stroke_v, shader_stroke_erase_f))
|
|
LOG("Failed to create shader StrokeErase");
|
|
if (!ShaderManager::create(kShader::StrokeLayer, shader_stroke_layer_v, shader_stroke_layer_f))
|
|
LOG("Failed to create shader StrokeLayer");
|
|
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");
|
|
}
|
|
|
|
|