fix color bleeding
This commit is contained in:
@@ -550,10 +550,11 @@
|
|||||||
<None Include="data\shaders\include\rand.glsl" />
|
<None Include="data\shaders\include\rand.glsl" />
|
||||||
<None Include="data\shaders\lambert.glsl" />
|
<None Include="data\shaders\lambert.glsl" />
|
||||||
<None Include="data\shaders\lightmap.glsl" />
|
<None Include="data\shaders\lightmap.glsl" />
|
||||||
|
<None Include="data\shaders\stroke-dilate.glsl" />
|
||||||
<None Include="data\shaders\stroke-instanced.glsl" />
|
<None Include="data\shaders\stroke-instanced.glsl" />
|
||||||
|
<None Include="data\shaders\stroke-pad.glsl" />
|
||||||
<None Include="data\shaders\stroke-preview.glsl" />
|
<None Include="data\shaders\stroke-preview.glsl" />
|
||||||
<None Include="data\shaders\stroke.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-alpha.glsl" />
|
||||||
<None Include="data\shaders\texture-blend.glsl" />
|
<None Include="data\shaders\texture-blend.glsl" />
|
||||||
<None Include="data\shaders\texture-colorize.glsl" />
|
<None Include="data\shaders\texture-colorize.glsl" />
|
||||||
|
|||||||
@@ -679,9 +679,6 @@
|
|||||||
<None Include="data\shaders\texture-alpha.glsl">
|
<None Include="data\shaders\texture-alpha.glsl">
|
||||||
<Filter>shaders</Filter>
|
<Filter>shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\shaders\texture-alpha-sep.glsl">
|
|
||||||
<Filter>shaders</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="data\shaders\texture-blend.glsl">
|
<None Include="data\shaders\texture-blend.glsl">
|
||||||
<Filter>shaders</Filter>
|
<Filter>shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
@@ -718,6 +715,12 @@
|
|||||||
<None Include="data\shaders\texture-mask.glsl">
|
<None Include="data\shaders\texture-mask.glsl">
|
||||||
<Filter>shaders</Filter>
|
<Filter>shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="data\shaders\stroke-dilate.glsl">
|
||||||
|
<Filter>shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="data\shaders\stroke-pad.glsl">
|
||||||
|
<Filter>shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="icon.ico">
|
<Image Include="icon.ico">
|
||||||
|
|||||||
@@ -52,12 +52,15 @@ void main()
|
|||||||
highp vec2 uv_base = use_fragcoord ? (gl_FragCoord.st / resolution) : uv;
|
highp vec2 uv_base = use_fragcoord ? (gl_FragCoord.st / resolution) : uv;
|
||||||
highp vec4 base = texture(tex, uv_base);
|
highp vec4 base = texture(tex, uv_base);
|
||||||
highp vec4 stroke = texture(tex_stroke, uv);
|
highp vec4 stroke = texture(tex_stroke, uv);
|
||||||
|
|
||||||
|
if (base.a == 0.0)
|
||||||
|
base.rgb = stroke.rgb;
|
||||||
|
|
||||||
if (stroke.a == 0.0)
|
// if (stroke.a == 0.0)
|
||||||
{
|
// {
|
||||||
frag = base * vec4(1.0, 1.0, 1.0, alpha);
|
// frag = base * vec4(1.0, 1.0, 1.0, alpha);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (use_pattern)
|
if (use_pattern)
|
||||||
{
|
{
|
||||||
|
|||||||
42
data/shaders/stroke-dilate.glsl
Normal file
42
data/shaders/stroke-dilate.glsl
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
[[vertex]]
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
in vec4 pos;
|
||||||
|
in vec2 uvs;
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = mvp * vec4(pos.xy, 0.0, 1.0);
|
||||||
|
uv = uvs;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[fragment]]
|
||||||
|
|
||||||
|
uniform sampler2D tex_bg;
|
||||||
|
|
||||||
|
in highp vec2 uv;
|
||||||
|
out highp vec4 frag;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
highp vec4 bg = texture(tex_bg, uv);
|
||||||
|
if (bg.a == 0.0)
|
||||||
|
{
|
||||||
|
highp vec4 sum = vec4(0.0);
|
||||||
|
for (int y = -1; y <= 1; y++)
|
||||||
|
{
|
||||||
|
for (int x = -1; x <= 1; x++)
|
||||||
|
{
|
||||||
|
highp vec4 c = textureOffset(tex_bg, uv, ivec2(x, y));
|
||||||
|
sum += vec4(c.rgb * c.a, c.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frag = sum.a > 0.0 ? vec4(sum.rgb / sum.a, 0.0) : bg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frag = bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
37
data/shaders/stroke-pad.glsl
Normal file
37
data/shaders/stroke-pad.glsl
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[[vertex]]
|
||||||
|
|
||||||
|
in vec4 pos;
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = pos;
|
||||||
|
uv = pos.xy * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[fragment]]
|
||||||
|
|
||||||
|
#include "include/ext-fb-fetch.glsl"
|
||||||
|
|
||||||
|
uniform sampler2D tex_bg;
|
||||||
|
uniform mediump vec4 col;
|
||||||
|
|
||||||
|
in highp vec2 uv;
|
||||||
|
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||||
|
inout highp vec4 frag;
|
||||||
|
#else
|
||||||
|
out highp vec4 frag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// sample from the background
|
||||||
|
#if defined(GL_EXT_shader_framebuffer_fetch)
|
||||||
|
highp vec4 bg = frag;
|
||||||
|
#elif defined(GL_ARM_shader_framebuffer_fetch)
|
||||||
|
highp vec4 bg = gl_LastFragColorARM;
|
||||||
|
#else
|
||||||
|
highp vec4 bg = texture(tex_bg, uv);
|
||||||
|
#endif
|
||||||
|
frag = bg.a == 0.0 ? vec4(col.rgb, 0.0) : bg;
|
||||||
|
}
|
||||||
@@ -61,8 +61,8 @@ void main()
|
|||||||
highp vec4 fg = vec4(col.rgb, brush_alpha);
|
highp vec4 fg = vec4(col.rgb, brush_alpha);
|
||||||
|
|
||||||
// early discard
|
// early discard
|
||||||
if (fg.a == 0.0)
|
// if (fg.a == 0.0)
|
||||||
discard;
|
// discard;
|
||||||
|
|
||||||
if (use_pattern)
|
if (use_pattern)
|
||||||
{
|
{
|
||||||
@@ -86,11 +86,14 @@ void main()
|
|||||||
highp vec4 bg = texture(tex_bg, uv2);
|
highp vec4 bg = texture(tex_bg, uv2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (bg.a == 0.0)
|
||||||
|
bg.rgb = col.rgb;
|
||||||
|
|
||||||
fg.a *= 1.0-rand(uv2+uv)*noise;
|
fg.a *= 1.0-rand(uv2+uv)*noise;
|
||||||
|
|
||||||
// no need to go further
|
// no need to go further
|
||||||
if (fg.a <= 0.0)
|
// if (fg.a <= 0.0)
|
||||||
discard;
|
// discard;
|
||||||
|
|
||||||
if (mix_alpha > 0.0)
|
if (mix_alpha > 0.0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
[[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 highp float alpha;
|
|
||||||
uniform bool highlight;
|
|
||||||
|
|
||||||
in highp vec2 uv;
|
|
||||||
out highp vec4 frag;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
highp vec3 rgb = texture(tex, uv).rgb;
|
|
||||||
highp float a = texture(tex_alpha, uv).a;
|
|
||||||
highp 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);
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@ void main()
|
|||||||
#include "include/blend.glsl"
|
#include "include/blend.glsl"
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
uniform sampler2D tex_alpha;
|
|
||||||
uniform sampler2D tex_bg;
|
uniform sampler2D tex_bg;
|
||||||
uniform highp float alpha;
|
uniform highp float alpha;
|
||||||
uniform int blend_mode;
|
uniform int blend_mode;
|
||||||
@@ -41,7 +40,7 @@ void main()
|
|||||||
highp vec4 bg = texture(tex_bg, uv);
|
highp vec4 bg = texture(tex_bg, uv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
highp vec4 fg = vec4(texture(tex, uv).rgb, texture(tex_alpha, uv).a);
|
highp vec4 fg = texture(tex, uv);
|
||||||
if (fg.a == 0.0)
|
if (fg.a == 0.0)
|
||||||
{
|
{
|
||||||
frag = bg;
|
frag = bg;
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ void App::initShaders()
|
|||||||
LOG("Failed to create shader TextureAlpha");
|
LOG("Failed to create shader TextureAlpha");
|
||||||
if (!ShaderManager::load(kShader::TextureMask, "data/shaders/texture-mask.glsl"))
|
if (!ShaderManager::load(kShader::TextureMask, "data/shaders/texture-mask.glsl"))
|
||||||
LOG("Failed to create shader TextureMask");
|
LOG("Failed to create shader TextureMask");
|
||||||
if (!ShaderManager::load(kShader::TextureAlphaSep, "data/shaders/texture-alpha-sep.glsl"))
|
|
||||||
LOG("Failed to create shader TextureAlphaSep");
|
|
||||||
if (!ShaderManager::load(kShader::TextureColorize, "data/shaders/texture-colorize.glsl"))
|
if (!ShaderManager::load(kShader::TextureColorize, "data/shaders/texture-colorize.glsl"))
|
||||||
LOG("Failed to create shader TextureColorize");
|
LOG("Failed to create shader TextureColorize");
|
||||||
if (!ShaderManager::load(kShader::TextureBlend, "data/shaders/texture-blend.glsl"))
|
if (!ShaderManager::load(kShader::TextureBlend, "data/shaders/texture-blend.glsl"))
|
||||||
@@ -59,6 +57,10 @@ void App::initShaders()
|
|||||||
LOG("Failed to create shader Atlas");
|
LOG("Failed to create shader Atlas");
|
||||||
if (!ShaderManager::load(kShader::Stroke, "data/shaders/stroke.glsl"))
|
if (!ShaderManager::load(kShader::Stroke, "data/shaders/stroke.glsl"))
|
||||||
LOG("Failed to create shader Stroke");
|
LOG("Failed to create shader Stroke");
|
||||||
|
if (!ShaderManager::load(kShader::StrokePad, "data/shaders/stroke-pad.glsl"))
|
||||||
|
LOG("Failed to create shader StrokePad");
|
||||||
|
if (!ShaderManager::load(kShader::StrokeDilate, "data/shaders/stroke-dilate.glsl"))
|
||||||
|
LOG("Failed to create shader StrokeDilate");
|
||||||
if (!ShaderManager::load(kShader::Checkerboard, "data/shaders/checkerboard.glsl"))
|
if (!ShaderManager::load(kShader::Checkerboard, "data/shaders/checkerboard.glsl"))
|
||||||
LOG("Failed to create shader Checkerboard");
|
LOG("Failed to create shader Checkerboard");
|
||||||
if (!ShaderManager::load(kShader::Equirect, "data/shaders/equirect.glsl"))
|
if (!ShaderManager::load(kShader::Equirect, "data/shaders/equirect.glsl"))
|
||||||
|
|||||||
@@ -301,23 +301,15 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
|||||||
{
|
{
|
||||||
sampler.bind(0);
|
sampler.bind(0);
|
||||||
sampler_linear.bind(1);
|
sampler_linear.bind(1);
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
ShaderManager::use(kShader::TextureAlpha);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index]->m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index]->m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, canvas->m_canvas->m_layers[layer_index]->m_hightlight);
|
ShaderManager::u_int(kShaderUniform::Highlight, canvas->m_canvas->m_layers[layer_index]->m_hightlight);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
251
src/canvas.cpp
251
src/canvas.cpp
@@ -475,7 +475,7 @@ void Canvas::stroke_draw()
|
|||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
|
|
||||||
m_sampler_brush.bind(0);
|
m_sampler_brush.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_nearest.bind(1);
|
||||||
m_sampler_stencil.bind(2);
|
m_sampler_stencil.bind(2);
|
||||||
m_sampler.bind(3);
|
m_sampler.bind(3);
|
||||||
//m_sampler_linear.bind(5);
|
//m_sampler_linear.bind(5);
|
||||||
@@ -517,7 +517,12 @@ void Canvas::stroke_draw()
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glActiveTexture(GL_TEXTURE3);
|
glActiveTexture(GL_TEXTURE3);
|
||||||
m_mixer.bindTexture();
|
m_mixer.bindTexture();
|
||||||
|
|
||||||
auto frames = stroke_draw_compute(*m_current_stroke);
|
auto frames = stroke_draw_compute(*m_current_stroke);
|
||||||
|
|
||||||
|
std::array<glm::vec4, 6> box_face = SIXPLETTE(glm::vec4(m_size, 0, 0));
|
||||||
|
std::array<bool, 6> box_dirty = SIXPLETTE(false);
|
||||||
|
glm::vec4 pad_color;
|
||||||
for (auto& f : frames)
|
for (auto& f : frames)
|
||||||
{
|
{
|
||||||
if (brush->m_tip_mix > 0.f)
|
if (brush->m_tip_mix > 0.f)
|
||||||
@@ -525,10 +530,6 @@ void Canvas::stroke_draw()
|
|||||||
stroke_draw_mix(xy(f.m_mixer_rect), zw(f.m_mixer_rect));
|
stroke_draw_mix(xy(f.m_mixer_rect), zw(f.m_mixer_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderManager::use(kShader::Stroke);
|
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, f.col);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, f.flow);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
auto& P = f.shapes[i];
|
auto& P = f.shapes[i];
|
||||||
@@ -536,17 +537,84 @@ void Canvas::stroke_draw()
|
|||||||
continue;
|
continue;
|
||||||
m_dirty_face[i] = true;
|
m_dirty_face[i] = true;
|
||||||
merge_faces[i] = true;
|
merge_faces[i] = true;
|
||||||
|
box_dirty[i] = true;
|
||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
auto rect = stroke_draw_samples(i, P);
|
|
||||||
|
ShaderManager::use(kShader::Stroke);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, f.col);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, f.flow);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Opacity, f.opacity);
|
||||||
|
auto box_sample = stroke_draw_samples(i, P);
|
||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], rect), glm::vec4(0), glm::vec4(m_width));
|
|
||||||
|
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], box_sample), glm::vec4(0), glm::vec4(m_width));
|
||||||
|
box_face[i] = box_union(box_face[i], box_sample);
|
||||||
|
// TODO: maybe average color?
|
||||||
|
pad_color = f.col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE3);
|
glActiveTexture(GL_TEXTURE3);
|
||||||
m_mixer.unbindTexture();
|
m_mixer.unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
brush->m_tip_texture->unbind();
|
brush->m_tip_texture->unbind();
|
||||||
|
|
||||||
|
// pad stroke
|
||||||
|
// In order to mitigate color bleeding at the edge of shapes in transparent layers
|
||||||
|
// we need to fill the area around the stroke with the same color because by default
|
||||||
|
// the transparent area may have black or other undefined color.
|
||||||
|
// This step is only useful for previewing the stroke because on commit the dilate
|
||||||
|
// algorithm fixes this issue.
|
||||||
|
// NOTE: at the moment this works on the whole canvas, but it can be optimized
|
||||||
|
// to only affect the current dirty box. In this case it may be necessary to do this
|
||||||
|
// work on documents that doesn't have the padding, so on document loading.
|
||||||
|
ShaderManager::use(kShader::StrokePad);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, pad_color);
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 1);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (!box_dirty[i])
|
||||||
|
continue;
|
||||||
|
const auto& b = box_face[i];
|
||||||
|
glm::vec2 box_size = zw(b) - xy(b);
|
||||||
|
glm::vec2 pad = { 20, 20 }; // pixels padding
|
||||||
|
glm::vec4 pad_box = {
|
||||||
|
glm::max({0, 0}, xy(b) - pad) * 2.f / m_size - 1.f,
|
||||||
|
glm::min(m_size, zw(b) + pad) * 2.f / m_size - 1.f
|
||||||
|
};
|
||||||
|
// B(xw)--(zw)C box
|
||||||
|
// | // | coordinates
|
||||||
|
// A(xy)--(zy)D mapping
|
||||||
|
std::array<vertex_t, 6> pad_quad = {
|
||||||
|
vertex_t({pad_box.x, pad_box.y}), // A
|
||||||
|
vertex_t({pad_box.x, pad_box.w}), // B
|
||||||
|
vertex_t({pad_box.z, pad_box.w}), // C
|
||||||
|
vertex_t({pad_box.x, pad_box.y}), // A
|
||||||
|
vertex_t({pad_box.z, pad_box.w}), // C
|
||||||
|
vertex_t({pad_box.z, pad_box.y}), // D
|
||||||
|
};
|
||||||
|
m_brush_shape.update_vertices(pad_quad.data(), pad_quad.size());
|
||||||
|
|
||||||
|
m_tmp[i].bindFramebuffer();
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
m_tex[i].bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, b.x, b.y, b.x, b.y, box_size.x, box_size.y);
|
||||||
|
}
|
||||||
|
m_brush_shape.draw_fill();
|
||||||
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
}
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// DRAW DUAL BRUSH
|
// DRAW DUAL BRUSH
|
||||||
|
|
||||||
if (brush->m_dual_enabled)
|
if (brush->m_dual_enabled)
|
||||||
@@ -573,18 +641,18 @@ void Canvas::stroke_draw()
|
|||||||
if (P.size() < 3)
|
if (P.size() < 3)
|
||||||
continue;
|
continue;
|
||||||
m_tmp_dual[i].bindFramebuffer();
|
m_tmp_dual[i].bindFramebuffer();
|
||||||
auto rect = stroke_draw_samples(i, P);
|
auto box_sample = stroke_draw_samples(i, P);
|
||||||
m_tmp_dual[i].unbindFramebuffer();
|
m_tmp_dual[i].unbindFramebuffer();
|
||||||
|
|
||||||
// this mode overflows the main brush boundries
|
// this mode overflows the main brush boundries
|
||||||
if (brush->m_dual_blend_mode == 0)
|
if (brush->m_dual_blend_mode == 0)
|
||||||
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], rect), glm::vec4(0), glm::vec4(m_width));
|
m_dirty_box[i] = glm::clamp(box_union(m_dirty_box[i], box_sample), glm::vec4(0), glm::vec4(m_width));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sampler_brush.unbind();
|
m_sampler_brush.unbind();
|
||||||
m_sampler_bg.unbind();
|
m_sampler_nearest.unbind();
|
||||||
m_sampler_stencil.unbind();
|
m_sampler_stencil.unbind();
|
||||||
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
@@ -751,8 +819,8 @@ void Canvas::stroke_commit()
|
|||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
m_tex2[i].bind();
|
m_tex2[i].bind();
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_nearest.bind(1);
|
||||||
m_sampler_mask.bind(2);
|
m_sampler.bind(2);
|
||||||
m_sampler.bind(3);
|
m_sampler.bind(3);
|
||||||
m_sampler_stencil.bind(4);
|
m_sampler_stencil.bind(4);
|
||||||
if (m_current_mode == kCanvasMode::Erase)
|
if (m_current_mode == kCanvasMode::Erase)
|
||||||
@@ -847,6 +915,15 @@ void Canvas::stroke_commit()
|
|||||||
// m_tex2[i].unbind();
|
// m_tex2[i].unbind();
|
||||||
// m_tmp[i].unbindTexture();
|
// m_tmp[i].unbindTexture();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Dilate borders to avoid interpolation bleeding
|
||||||
|
ShaderManager::use(kShader::StrokeDilate);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_tex2[i].bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
|
||||||
m_layers[m_current_layer_idx]->m_rtt[i].unbindFramebuffer();
|
m_layers[m_current_layer_idx]->m_rtt[i].unbindFramebuffer();
|
||||||
}
|
}
|
||||||
@@ -1000,40 +1077,16 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
ShaderManager::use(kShader::TextureAlpha);
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, m_layers[layer_index]->m_hightlight);
|
ShaderManager::u_int(kShaderUniform::Highlight, m_layers[layer_index]->m_hightlight);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
/*
|
|
||||||
m_sampler.bind(0);
|
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
ShaderManager::use(kShader::TextureColorize);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, { glm::vec3((float)layer_index / (float)m_order.size()), 1.f });
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_plane.draw_fill();
|
|
||||||
|
|
||||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_blend)
|
if (use_blend)
|
||||||
@@ -1045,22 +1098,20 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
|||||||
if (use_blend)
|
if (use_blend)
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
m_sampler.bind(2);
|
|
||||||
|
|
||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
m_sampler.bind(2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_merge_rtt.bindTexture();
|
m_merge_rtt.bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_merge_rtt.bindTexture();
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
@@ -1075,8 +1126,6 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
|||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_merge_tex.unbind();
|
m_merge_tex.unbind();
|
||||||
}
|
}
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_merge_rtt.unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_merge_rtt.unbindTexture();
|
m_merge_rtt.unbindTexture();
|
||||||
}
|
}
|
||||||
@@ -1120,6 +1169,8 @@ void Canvas::stroke_update(glm::vec3 point, float pressure)
|
|||||||
}
|
}
|
||||||
void Canvas::stroke_start(glm::vec3 point, float pressure)
|
void Canvas::stroke_start(glm::vec3 point, float pressure)
|
||||||
{
|
{
|
||||||
|
assert(App::I->is_render_thread());
|
||||||
|
|
||||||
// need to commit this now before starting a new stroke
|
// need to commit this now before starting a new stroke
|
||||||
if (m_current_stroke && m_commit_delayed)
|
if (m_current_stroke && m_commit_delayed)
|
||||||
{
|
{
|
||||||
@@ -1169,14 +1220,32 @@ void Canvas::stroke_start(glm::vec3 point, float pressure)
|
|||||||
m_dual_stroke->add_point(point, pressure);
|
m_dual_stroke->add_point(point, pressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto const& l = m_layers[m_current_layer_idx];
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
m_dirty_box[i] = glm::vec4(m_width, m_height, 0, 0); // reset bounding box
|
m_dirty_box[i] = glm::vec4(m_width, m_height, 0, 0); // reset bounding box
|
||||||
m_dirty_face[i] = false;
|
m_dirty_face[i] = false;
|
||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
if (l->m_dirty_face[i])
|
||||||
m_tmp[i].clear({ 0, 0, 0, 0 });
|
{
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
|
// clear
|
||||||
|
m_tmp[i].clear();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tex[i].bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
|
0, 0, 0, 0, m_width, m_height);
|
||||||
|
|
||||||
|
m_tmp[i].copy(l->m_rtt[i]);
|
||||||
|
m_tmp[i].clear_mask({ 0, 0, 0, 1 });
|
||||||
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_tmp[i].bindFramebuffer();
|
||||||
|
m_tmp[i].clear({ 0, 0, 0, 0 });
|
||||||
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_current_brush->m_dual_enabled)
|
if (m_current_brush->m_dual_enabled)
|
||||||
{
|
{
|
||||||
@@ -1244,7 +1313,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
m_tex2[i].unbind();
|
m_tex2[i].unbind();
|
||||||
|
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_nearest.bind(1);
|
||||||
{
|
{
|
||||||
ShaderManager::use(kShader::CompDraw);
|
ShaderManager::use(kShader::CompDraw);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0); // dest
|
ShaderManager::u_int(kShaderUniform::Tex, 0); // dest
|
||||||
@@ -1520,13 +1589,10 @@ bool Canvas::create(int width, int height)
|
|||||||
#else
|
#else
|
||||||
m_sampler_brush.create(GL_LINEAR, GL_CLAMP_TO_BORDER);
|
m_sampler_brush.create(GL_LINEAR, GL_CLAMP_TO_BORDER);
|
||||||
#endif
|
#endif
|
||||||
m_sampler.create(GL_NEAREST);
|
|
||||||
m_sampler.create(GL_LINEAR);
|
m_sampler.create(GL_LINEAR);
|
||||||
m_sampler_nearest.create(GL_NEAREST);
|
m_sampler_nearest.create(GL_NEAREST);
|
||||||
m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
||||||
m_sampler_brush.set_border({ 1, 1, 1, 1 });
|
m_sampler_brush.set_border({ 1, 1, 1, 1 });
|
||||||
m_sampler_bg.create(GL_NEAREST);
|
|
||||||
m_sampler_mask.create(GL_LINEAR);
|
|
||||||
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
|
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
|
||||||
m_sampler_mix.create(GL_NEAREST, GL_REPEAT);
|
m_sampler_mix.create(GL_NEAREST, GL_REPEAT);
|
||||||
m_sampler_linear.create();
|
m_sampler_linear.create();
|
||||||
@@ -1726,7 +1792,6 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
|
|
||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
@@ -1738,10 +1803,9 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
face.bind();
|
face.bind();
|
||||||
m_sampler_bg.bind(2);
|
m_sampler_nearest.bind(2);
|
||||||
}
|
}
|
||||||
m_sampler_bg.bind(0); // nearest
|
m_sampler_nearest.bind(0); // nearest
|
||||||
m_sampler_mask.bind(1); // linear
|
|
||||||
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
||||||
{
|
{
|
||||||
if (!m_layers[layer_index]->m_visible ||
|
if (!m_layers[layer_index]->m_visible ||
|
||||||
@@ -1757,12 +1821,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
m_layers[layer_index]->m_rtt[i].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
@@ -1776,7 +1836,7 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
ShaderManager::use(kShader::Texture);
|
ShaderManager::use(kShader::Texture);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
m_sampler_mask.bind(0); // linear
|
m_sampler.bind(0); // linear
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
face.bind();
|
face.bind();
|
||||||
// copy the framebuffer before clearing to white
|
// copy the framebuffer before clearing to white
|
||||||
@@ -1825,9 +1885,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
||||||
m_sampler_mask.bind(0);
|
m_sampler.bind(0);
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
m_sampler_mask.unbind();
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
m_latlong.unbindFramebuffer();
|
m_latlong.unbindFramebuffer();
|
||||||
});
|
});
|
||||||
@@ -1965,24 +2024,15 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
glm::scale(glm::vec3(2));
|
glm::scale(glm::vec3(2));
|
||||||
|
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
ShaderManager::use(kShader::TextureAlpha);
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers_merge.m_rtt[plane_index].bindTexture();
|
m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers_merge.m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
rtt.unbindFramebuffer();
|
rtt.unbindFramebuffer();
|
||||||
@@ -2016,7 +2066,6 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
glm::scale(glm::vec3(2));
|
glm::scale(glm::vec3(2));
|
||||||
|
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
ShaderManager::use(kShader::TextureColorize);
|
ShaderManager::use(kShader::TextureColorize);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, { glm::vec3((float)(layer_index + 1) / (float)(m_layers.size() + 1)), 1.f });
|
ShaderManager::u_vec4(kShaderUniform::Col, { glm::vec3((float)(layer_index + 1) / (float)(m_layers.size() + 1)), 1.f });
|
||||||
@@ -2098,43 +2147,12 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
{
|
{
|
||||||
App::I->render_task([&]
|
App::I->render_task([&]
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
// copy layer to cubemap
|
||||||
glViewport(0, 0, m_width, m_height);
|
m_layers[layer_index]->m_rtt[i].bindFramebuffer();
|
||||||
m_tmp[i].bindFramebuffer();
|
|
||||||
|
|
||||||
//if (seq == 0)
|
|
||||||
//{
|
|
||||||
// m_tmp[i].clear({ 1, 1, 1, 1 });
|
|
||||||
// ShaderManager::use(kShader::Checkerboard);
|
|
||||||
// ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
|
||||||
// m_plane.draw_fill();
|
|
||||||
// glEnable(GL_BLEND);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
m_tmp[i].clear({ 1, 1, 1, 0 });
|
|
||||||
//glDisable(GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
ShaderManager::use(kShader::TextureAlpha);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
|
||||||
|
|
||||||
m_sampler_mask.bind(0);
|
|
||||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
|
||||||
m_plane.draw_fill();
|
|
||||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
|
||||||
m_sampler_mask.unbind();
|
|
||||||
|
|
||||||
// copy result to cubemap
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
||||||
glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
|
glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
m_layers[layer_index]->m_rtt[i].unbindFramebuffer();
|
||||||
m_tmp[i].unbindFramebuffer();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
progress++;
|
progress++;
|
||||||
@@ -2158,9 +2176,8 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
m_sampler_mask.bind(0);
|
m_sampler_linear.bind(0);
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
m_sampler_mask.unbind();
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
m_latlong.unbindFramebuffer();
|
m_latlong.unbindFramebuffer();
|
||||||
});
|
});
|
||||||
@@ -2667,17 +2684,15 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
|
|
||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
blendtex.bind();
|
blendtex.bind();
|
||||||
m_sampler_bg.bind(2);
|
m_sampler_nearest.bind(2);
|
||||||
}
|
}
|
||||||
m_sampler_bg.bind(0); // nearest
|
m_sampler_nearest.bind(0); // nearest
|
||||||
m_sampler_mask.bind(1); // linear
|
|
||||||
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
||||||
{
|
{
|
||||||
if (!m_layers[layer_index]->m_visible ||
|
if (!m_layers[layer_index]->m_visible ||
|
||||||
@@ -2693,12 +2708,8 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
m_layers[layer_index]->m_rtt[i].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
@@ -2722,7 +2733,7 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
ShaderManager::use(kShader::Texture);
|
ShaderManager::use(kShader::Texture);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
m_sampler_mask.bind(0); // linear
|
m_sampler.bind(0); // linear
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|
||||||
blendtex.unbind();
|
blendtex.unbind();
|
||||||
|
|||||||
@@ -134,8 +134,6 @@ public:
|
|||||||
Sampler m_sampler_nearest;
|
Sampler m_sampler_nearest;
|
||||||
Sampler m_sampler_linear;
|
Sampler m_sampler_linear;
|
||||||
Sampler m_sampler_brush;
|
Sampler m_sampler_brush;
|
||||||
Sampler m_sampler_bg;
|
|
||||||
Sampler m_sampler_mask;
|
|
||||||
Sampler m_sampler_stencil;
|
Sampler m_sampler_stencil;
|
||||||
Sampler m_sampler_mix;
|
Sampler m_sampler_mix;
|
||||||
glm::mat4 m_cam_rot = glm::mat4(1);
|
glm::mat4 m_cam_rot = glm::mat4(1);
|
||||||
|
|||||||
@@ -1398,8 +1398,8 @@ void CanvasModeTransform::leave(kCanvasMode next)
|
|||||||
ShaderManager::u_int(kShaderUniform::BlendMode, 0);
|
ShaderManager::u_int(kShaderUniform::BlendMode, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::UseDual, false);
|
ShaderManager::u_int(kShaderUniform::UseDual, false);
|
||||||
ShaderManager::u_int(kShaderUniform::UsePattern, false);
|
ShaderManager::u_int(kShaderUniform::UsePattern, false);
|
||||||
Canvas::I->m_sampler_bg.bind(1);
|
Canvas::I->m_sampler_nearest.bind(1);
|
||||||
Canvas::I->m_sampler_bg.bind(0);
|
Canvas::I->m_sampler_nearest.bind(0);
|
||||||
m_tex[j].bind();
|
m_tex[j].bind();
|
||||||
m_shape[j].draw_fill();
|
m_shape[j].draw_fill();
|
||||||
m_tex[j].unbind();
|
m_tex[j].unbind();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ void NodeCanvas::init()
|
|||||||
m_canvas->m_node = this;
|
m_canvas->m_node = this;
|
||||||
|
|
||||||
m_sampler.create();
|
m_sampler.create();
|
||||||
m_sampler.set_filter(GL_LINEAR, GL_NEAREST);
|
//m_sampler.set_filter(GL_LINEAR, GL_NEAREST);
|
||||||
|
|
||||||
m_sampler_nearest.create(GL_NEAREST);
|
m_sampler_nearest.create(GL_NEAREST);
|
||||||
|
|
||||||
@@ -80,11 +80,6 @@ void NodeCanvas::draw()
|
|||||||
m_canvas->m_box = box;
|
m_canvas->m_box = box;
|
||||||
m_canvas->m_vp = c;
|
m_canvas->m_vp = c;
|
||||||
|
|
||||||
m_sampler.bind(0);
|
|
||||||
m_sampler.bind(1);
|
|
||||||
m_sampler.bind(2);
|
|
||||||
m_sampler.bind(3);
|
|
||||||
m_sampler_stencil.bind(4);
|
|
||||||
auto blend = glIsEnabled(GL_BLEND);
|
auto blend = glIsEnabled(GL_BLEND);
|
||||||
auto depth = glIsEnabled(GL_DEPTH_TEST);
|
auto depth = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
|
||||||
@@ -152,24 +147,15 @@ void NodeCanvas::draw()
|
|||||||
glm::translate(glm::vec3(0, 0, -1));
|
glm::translate(glm::vec3(0, 0, -1));
|
||||||
|
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
ShaderManager::use(kShader::TextureAlpha);
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,6 +223,9 @@ void NodeCanvas::draw()
|
|||||||
if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
|
m_sampler.bind(1);
|
||||||
|
m_sampler.bind(2);
|
||||||
|
|
||||||
ShaderManager::use(kShader::CompErase);
|
ShaderManager::use(kShader::CompErase);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
@@ -259,10 +248,14 @@ void NodeCanvas::draw()
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
else if(!App::I->keys[(int)kKey::KeyQ] && m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
|
m_sampler.bind(1);
|
||||||
|
m_sampler.bind(2);
|
||||||
|
m_sampler.bind(3);
|
||||||
|
m_sampler_stencil.bind(4);
|
||||||
|
|
||||||
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
||||||
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||||
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||||
@@ -318,25 +311,18 @@ void NodeCanvas::draw()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
if (App::I->keys[(int)kKey::KeyQ])
|
||||||
m_sampler_linear.bind(1);
|
glDisable(GL_BLEND);
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
m_canvas->m_cam_fov < 20.f ? m_sampler_nearest.bind(0) : m_sampler.bind(0);
|
||||||
|
ShaderManager::use(kShader::TextureAlpha);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight);
|
ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,12 +335,10 @@ void NodeCanvas::draw()
|
|||||||
if (use_blend)
|
if (use_blend)
|
||||||
{
|
{
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
m_sampler.bind(2);
|
m_sampler.bind(2);
|
||||||
|
|
||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode);
|
||||||
@@ -363,8 +347,6 @@ void NodeCanvas::draw()
|
|||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_blender_rtt.bindTexture();
|
m_blender_rtt.bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_blender_rtt.bindTexture();
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
@@ -380,8 +362,6 @@ void NodeCanvas::draw()
|
|||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
m_blender_bg.unbind();
|
m_blender_bg.unbind();
|
||||||
}
|
}
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_blender_rtt.unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_blender_rtt.unbindTexture();
|
m_blender_rtt.unbindTexture();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ enum class kShaderUniform : uint16_t
|
|||||||
{
|
{
|
||||||
MVP = const_hash("mvp"),
|
MVP = const_hash("mvp"),
|
||||||
Tex = const_hash("tex"),
|
Tex = const_hash("tex"),
|
||||||
TexA = const_hash("tex_alpha"),
|
|
||||||
TexFG = const_hash("tex_fg"),
|
TexFG = const_hash("tex_fg"),
|
||||||
TexBG = const_hash("tex_bg"),
|
TexBG = const_hash("tex_bg"),
|
||||||
TexMix = const_hash("tex_mix"),
|
TexMix = const_hash("tex_mix"),
|
||||||
@@ -60,7 +59,6 @@ enum class kShader : uint16_t
|
|||||||
TextureMask = const_hash("texture-mask"),
|
TextureMask = const_hash("texture-mask"),
|
||||||
TextureColorize = const_hash("texture-colorize"),
|
TextureColorize = const_hash("texture-colorize"),
|
||||||
TextureAlpha= const_hash("texture-alpha"),
|
TextureAlpha= const_hash("texture-alpha"),
|
||||||
TextureAlphaSep= const_hash("texture-alpha-sep"),
|
|
||||||
TextureBlend= const_hash("texture-blend"),
|
TextureBlend= const_hash("texture-blend"),
|
||||||
CompErase = const_hash("comp-erase"),
|
CompErase = const_hash("comp-erase"),
|
||||||
CompDraw = const_hash("comp-draw"),
|
CompDraw = const_hash("comp-draw"),
|
||||||
@@ -69,6 +67,8 @@ enum class kShader : uint16_t
|
|||||||
Font = const_hash("font"),
|
Font = const_hash("font"),
|
||||||
Atlas = const_hash("atlas"),
|
Atlas = const_hash("atlas"),
|
||||||
Stroke = const_hash("stroke"),
|
Stroke = const_hash("stroke"),
|
||||||
|
StrokePad = const_hash("stroke-pad"),
|
||||||
|
StrokeDilate= const_hash("stroke-dilate"),
|
||||||
StrokePreview = const_hash("stroke-preview"),
|
StrokePreview = const_hash("stroke-preview"),
|
||||||
Checkerboard= const_hash("checkerboard"),
|
Checkerboard= const_hash("checkerboard"),
|
||||||
Equirect = const_hash("equirect"),
|
Equirect = const_hash("equirect"),
|
||||||
|
|||||||
Reference in New Issue
Block a user