implement frame buffer fetch extension for iOS, change composition on stroke drawing and commit, add rename layer dialog
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include "node_panel_color.h"
|
||||
#include "node_panel_stroke.h"
|
||||
#include "node_canvas.h"
|
||||
#include "node_dialog_layer_rename.h"
|
||||
|
||||
#if defined(__OBJC__) && defined(__IOS__)
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -131,9 +131,9 @@ void App::initLayout()
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
CanvasModePen* mode = (CanvasModePen*)canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Draw][0];
|
||||
if (mode)
|
||||
if (mode && canvas->m_canvas->m_current_mode == Canvas::kCanvasMode::Draw)
|
||||
{
|
||||
mode->m_picking = true;
|
||||
mode->m_picking = !mode->m_picking;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -376,6 +376,35 @@ void App::initLayout()
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
popup->find<NodeButtonCustom>("layer-rename")->on_click = [this](Node*) {
|
||||
// load thumbnail test
|
||||
auto open_dialog = std::make_shared<NodeDialogLayerRename>();
|
||||
open_dialog->m_manager = &layout;
|
||||
open_dialog->data_path = data_path;
|
||||
open_dialog->init();
|
||||
open_dialog->create();
|
||||
open_dialog->loaded();
|
||||
|
||||
layout[main_id]->add_child(open_dialog);
|
||||
layout[main_id]->update();
|
||||
|
||||
open_dialog->btn_ok->on_click = [this,open_dialog](Node*)
|
||||
{
|
||||
layers->m_current_layer->set_name(open_dialog->get_name().c_str());
|
||||
open_dialog->destroy();
|
||||
};
|
||||
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (layers->m_current_layer)
|
||||
popup->find<NodeButtonCustom>("layer-rename")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text(("Rename Layer " + layers->m_current_layer->m_label_text).c_str());
|
||||
else
|
||||
popup->find<NodeButtonCustom>("layer-rename")->
|
||||
find<NodeText>("menu-label")->
|
||||
set_text("Rename Layer (Select a layer)");
|
||||
};
|
||||
}
|
||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||
|
||||
@@ -43,6 +43,49 @@ void App::initShaders()
|
||||
"void main(){\n"
|
||||
" frag = 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 =
|
||||
@@ -164,26 +207,40 @@ void App::initShaders()
|
||||
"}\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"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\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, 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"
|
||||
@@ -191,32 +248,51 @@ void App::initShaders()
|
||||
"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)) { frag = bg; return; }\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, min(alpha_tot, msk.a));\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";
|
||||
|
||||
@@ -233,19 +309,36 @@ void App::initShaders()
|
||||
"}";
|
||||
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"
|
||||
" 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, alpha_tot);\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 =
|
||||
@@ -304,6 +397,10 @@ void App::initShaders()
|
||||
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))
|
||||
|
||||
@@ -81,9 +81,11 @@ void ui::Canvas::pick_update(int plane)
|
||||
{
|
||||
// copy to tmp2 for layer blending
|
||||
glActiveTexture(GL_TEXTURE0); // TODO: maybe remove this line
|
||||
#ifndef __IOS__
|
||||
m_tex2[i].bind();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
m_tex2[i].unbind();
|
||||
#endif
|
||||
|
||||
m_layers[layer_index].m_rtt[i].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
@@ -122,12 +124,12 @@ glm::vec4 ui::Canvas::pick_get(glm::vec2 canvas_loc)
|
||||
glm::vec3 ray_dir;
|
||||
glm::vec3 hit_pos;
|
||||
glm::vec3 hit_normal;
|
||||
glm::vec2 fb_pos;
|
||||
int plane_id;
|
||||
if (point_trace(canvas_loc, ray_origin, ray_dir, hit_pos, hit_normal, plane_id))
|
||||
if (point_trace(canvas_loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, plane_id))
|
||||
{
|
||||
pick_update(plane_id);
|
||||
glm::vec2 fbpos = (hit_pos.xy() * 0.5f + 0.5f) * glm::vec2(m_width, m_height);
|
||||
int i = (int)fbpos.x + (int)fbpos.y * m_width;
|
||||
int i = (int)fb_pos.x + (int)fb_pos.y * m_width;
|
||||
return glm::vec4(m_pick_data[plane_id][i]) / 255.f;
|
||||
}
|
||||
return {0,0,0,1};
|
||||
@@ -229,21 +231,21 @@ void ui::Canvas::stroke_draw()
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
if (m_state == kCanvasMode::Erase)
|
||||
{
|
||||
ShaderManager::use(ui::kShader::StrokeErase);
|
||||
//ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
}
|
||||
else if(m_layers[m_current_layer_idx].m_alpha_locked)
|
||||
{
|
||||
ShaderManager::use(kShader::StrokeLock);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
ShaderManager::u_int(kShaderUniform::TexMask, 2); // alpha mask
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_layers[m_current_layer_idx].m_rtt[i].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
}
|
||||
else
|
||||
// if (0 && m_state == kCanvasMode::Erase)
|
||||
// {
|
||||
// ShaderManager::use(ui::kShader::StrokeErase);
|
||||
// //ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
// }
|
||||
// else if(m_layers[m_current_layer_idx].m_alpha_locked)
|
||||
// {
|
||||
// ShaderManager::use(kShader::StrokeLock);
|
||||
// ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
// ShaderManager::u_int(kShaderUniform::TexMask, 2); // alpha mask
|
||||
// glActiveTexture(GL_TEXTURE2);
|
||||
// m_layers[m_current_layer_idx].m_rtt[i].bindTexture();
|
||||
// glActiveTexture(GL_TEXTURE1);
|
||||
// }
|
||||
// else
|
||||
{
|
||||
ShaderManager::use(ui::kShader::Stroke);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
@@ -311,10 +313,12 @@ void ui::Canvas::stroke_draw()
|
||||
glm::vec2 pad(1);
|
||||
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad , { 0, 0 }, { m_width, m_height });
|
||||
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz ) + pad*2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos));
|
||||
#ifndef __IOS__
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
tex_pos.x, tex_pos.y,
|
||||
tex_pos.x, tex_pos.y,
|
||||
tex_sz.x, tex_sz.y);
|
||||
#endif
|
||||
|
||||
m_dirty_box[i].xy = glm::min(m_dirty_box[i].xy(), (glm::vec2)tex_pos);
|
||||
m_dirty_box[i].zw = glm::max(m_dirty_box[i].zw(), (glm::vec2)(tex_pos + tex_sz));
|
||||
@@ -358,11 +362,10 @@ void ui::Canvas::stroke_draw()
|
||||
}
|
||||
}
|
||||
bool ui::Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
||||
glm::vec3& hit_pos, glm::vec3& hit_normal, int& out_plane_id)
|
||||
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id)
|
||||
{
|
||||
point_unproject(loc, { 0, 0, m_box.zw }, m_mv, m_proj, ray_origin, ray_dir);
|
||||
glm::vec3 hit;
|
||||
glm::vec2 fb_pos;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i], hit))
|
||||
@@ -450,7 +453,7 @@ void ui::Canvas::stroke_commit()
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); // reset bounding box
|
||||
//m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); // reset bounding box
|
||||
if (!m_dirty_face[i])
|
||||
continue; // no stroke on this face, skip it
|
||||
|
||||
@@ -483,21 +486,53 @@ void ui::Canvas::stroke_commit()
|
||||
m_sampler_bg.bind(1);
|
||||
if (m_state == kCanvasMode::Erase)
|
||||
{
|
||||
ShaderManager::use(ui::kShader::Texture);
|
||||
ui::ShaderManager::use(kShader::CompErase);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_tmp[i].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderManager::use(ui::kShader::StrokeLayer);
|
||||
ShaderManager::u_int(kShaderUniform::TexBG, 1);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||
ui::ShaderManager::use(kShader::CompDraw);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_tmp[i].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].unbind();
|
||||
}
|
||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||
m_plane.draw_fill();
|
||||
m_sampler.unbind();
|
||||
m_sampler_bg.unbind();
|
||||
m_tex2[i].unbind();
|
||||
m_tmp[i].unbindTexture();
|
||||
// else
|
||||
// {
|
||||
// ShaderManager::use(ui::kShader::StrokeLayer);
|
||||
// ShaderManager::u_int(kShaderUniform::TexBG, 1);
|
||||
// ShaderManager::u_int(kShaderUniform::Lock, m_layers[m_current_layer_idx].m_alpha_locked);
|
||||
// ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||
//
|
||||
// ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
// ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||
// m_plane.draw_fill();
|
||||
// m_sampler.unbind();
|
||||
// m_sampler_bg.unbind();
|
||||
// m_tex2[i].unbind();
|
||||
// m_tmp[i].unbindTexture();
|
||||
// }
|
||||
|
||||
m_layers[m_current_layer_idx].m_rtt[i].unbindFramebuffer();
|
||||
}
|
||||
@@ -539,15 +574,15 @@ void ui::Canvas::stroke_start(glm::vec2 point, float pressure, const ui::Brush&
|
||||
m_dirty_box[i] = glm::vec4(m_width, m_height, 0, 0); // reset bounding box
|
||||
m_dirty_face[i] = false;
|
||||
|
||||
if (m_state == kCanvasMode::Erase)
|
||||
{
|
||||
m_layers[m_current_layer_idx].m_rtt[i].bindFramebuffer();
|
||||
m_tmp[i].bindTexture();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
m_tmp[i].unbindTexture();
|
||||
m_layers[m_current_layer_idx].m_rtt[i].unbindFramebuffer();
|
||||
}
|
||||
else
|
||||
// if (m_state == kCanvasMode::Erase || m_layers[m_current_layer_idx].m_alpha_locked)
|
||||
// {
|
||||
// m_layers[m_current_layer_idx].m_rtt[i].bindFramebuffer();
|
||||
// m_tmp[i].bindTexture();
|
||||
// glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
// m_tmp[i].unbindTexture();
|
||||
// m_layers[m_current_layer_idx].m_rtt[i].unbindFramebuffer();
|
||||
// }
|
||||
// else
|
||||
{
|
||||
m_tmp[i].bindFramebuffer();
|
||||
m_tmp[i].clear({ 0, 0, 0, 0 });
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
kCanvasMode m_state{ kCanvasMode::Draw };
|
||||
static std::vector<CanvasMode*> modes[];
|
||||
std::vector<CanvasMode*>* m_mode = nullptr;
|
||||
kCanvasMode m_current_mode = kCanvasMode::Draw;
|
||||
static void set_mode(kCanvasMode mode)
|
||||
{
|
||||
if (I->m_mode)
|
||||
@@ -89,6 +90,7 @@ public:
|
||||
m->leave();
|
||||
I->m_mode = &modes[(int)mode];
|
||||
I->m_state = mode;
|
||||
I->m_current_mode = mode;
|
||||
}
|
||||
|
||||
std::vector<Layer::Snapshot> m_layers_snapshot;
|
||||
@@ -126,7 +128,7 @@ public:
|
||||
void point_unproject(glm::vec2 loc, glm::vec4 vp, glm::mat4 camera, glm::mat4 proj,
|
||||
glm::vec3 &out_origin, glm::vec3 &out_dir);
|
||||
bool point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
||||
glm::vec3& hit_pos, glm::vec3& hit_normal, int& out_plane_id);
|
||||
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id);
|
||||
bool point_trace_plane(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
||||
glm::vec3& hit_pos, glm::vec3& hit_normal, glm::vec2& hit_fb_pos, int plane_id);
|
||||
};
|
||||
|
||||
@@ -76,6 +76,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
{
|
||||
m_picking = true;
|
||||
canvas->pick_start();
|
||||
//canvas->m_show_tmp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -93,6 +94,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
if (m_dragging && m_picking)
|
||||
{
|
||||
node->mouse_release();
|
||||
//canvas->m_show_tmp = false;
|
||||
|
||||
glm::vec4 pix = canvas->pick_get(loc);
|
||||
auto hsv = convert_rgb2hsv(glm::vec3(pix[0], pix[1], pix[2]));
|
||||
@@ -230,7 +232,8 @@ void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
{
|
||||
node->mouse_capture();
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
if (canvas->point_trace(loc, ro, rd, hit_o, hit_d, m_plane_id))
|
||||
glm::vec2 fb_pos;
|
||||
if (canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id))
|
||||
{
|
||||
m_lines.push_back({ hit_o, hit_d });
|
||||
origin = hit_o;
|
||||
@@ -418,8 +421,9 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
case kEventType::MouseMove:
|
||||
{
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 fb_pos;
|
||||
int plane_id;
|
||||
if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, hit_d, plane_id))
|
||||
if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id))
|
||||
{
|
||||
ui::Shape::vertex_t v;
|
||||
v.pos = glm::vec4(hit_o, 1);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "log.h"
|
||||
#include "node_canvas.h"
|
||||
|
||||
#define RES 1024
|
||||
|
||||
Node* NodeCanvas::clone_instantiate() const
|
||||
{
|
||||
return new NodeCanvas();
|
||||
@@ -11,7 +13,7 @@ void NodeCanvas::init()
|
||||
{
|
||||
m_mouse_ignore = false;
|
||||
m_canvas = std::make_unique<ui::Canvas>();
|
||||
m_canvas->create(512, 512);
|
||||
m_canvas->create(RES, RES);
|
||||
m_sampler.create(GL_NEAREST);
|
||||
m_face_plane.create<1>(2, 2);
|
||||
m_line.create();
|
||||
@@ -25,7 +27,7 @@ void NodeCanvas::init()
|
||||
void NodeCanvas::restore_context()
|
||||
{
|
||||
Node::restore_context();
|
||||
m_canvas->create(512, 512);
|
||||
m_canvas->create(RES, RES);
|
||||
m_sampler.create(GL_NEAREST);
|
||||
m_face_plane.create<1>(2, 2);
|
||||
m_canvas->snapshot_restore();
|
||||
@@ -75,6 +77,7 @@ void NodeCanvas::draw()
|
||||
|
||||
|
||||
m_sampler.bind(0);
|
||||
m_sampler.bind(1);
|
||||
auto blend = glIsEnabled(GL_BLEND);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@@ -88,31 +91,60 @@ void NodeCanvas::draw()
|
||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||
m_face_plane.draw_fill();
|
||||
|
||||
ui::ShaderManager::use(kShader::TextureAlpha);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
for (auto layer_index : m_canvas->m_order)
|
||||
{
|
||||
if (m_canvas->m_layers[layer_index].m_opacity == .0f)
|
||||
continue;
|
||||
int z = m_canvas->m_order.size() - layer_index;
|
||||
int z = (int)m_canvas->m_order.size() - layer_index;
|
||||
auto plane_mvp_z = proj * camera * glm::scale(glm::vec3(z)) * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1));
|
||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
if (!(m_canvas->m_state == ui::Canvas::kCanvasMode::Erase &&
|
||||
m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index))
|
||||
|
||||
if (m_canvas->m_state == ui::Canvas::kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
{
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture();
|
||||
ui::ShaderManager::use(kShader::CompErase);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||
}
|
||||
if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
else if(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
{
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha,
|
||||
m_canvas->m_current_stroke->m_brush.m_tip_opacity * m_canvas->m_layers[layer_index].m_opacity);
|
||||
ui::ShaderManager::use(kShader::CompDraw);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui::ShaderManager::use(kShader::TextureAlpha);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||
}
|
||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[m_canvas->m_current_layer_idx].m_alpha_locked);
|
||||
|
||||
// if (!(m_canvas->m_state == ui::Canvas::kCanvasMode::Erase &&
|
||||
// m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index))
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_canvas->m_tmp[plane_index].bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture();
|
||||
}
|
||||
// if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
// {
|
||||
// ui::ShaderManager::use(kShader::TextureAlpha);
|
||||
// ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
// ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||
// ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
// ui::ShaderManager::u_float(kShaderUniform::Alpha,
|
||||
// m_canvas->m_current_stroke->m_brush.m_tip_opacity * m_canvas->m_layers[layer_index].m_opacity);
|
||||
// m_canvas->m_tmp[plane_index].bindTexture();
|
||||
// m_face_plane.draw_fill();
|
||||
// m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
// }
|
||||
}
|
||||
}
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
47
engine/node_dialog_layer_rename.cpp
Normal file
47
engine/node_dialog_layer_rename.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "node_dialog_layer_rename.h"
|
||||
#include "canvas.h"
|
||||
#include "node_image_texture.h"
|
||||
|
||||
Node* NodeDialogLayerRename::clone_instantiate() const
|
||||
{
|
||||
return new NodeDialogLayerRename();
|
||||
}
|
||||
|
||||
void NodeDialogLayerRename::clone_finalize(Node* dest) const
|
||||
{
|
||||
NodeDialogLayerRename* n = static_cast<NodeDialogLayerRename*>(dest);
|
||||
n->init_controls();
|
||||
}
|
||||
|
||||
void NodeDialogLayerRename::init()
|
||||
{
|
||||
auto tpl = static_cast<const NodeBorder*>(init_template("dialog-layer-rename"));
|
||||
m_color = tpl->m_color;
|
||||
m_border_color = tpl->m_border_color;;
|
||||
m_thinkness = tpl->m_thinkness;;
|
||||
init_controls();
|
||||
}
|
||||
|
||||
void NodeDialogLayerRename::init_controls()
|
||||
{
|
||||
btn_ok = find<NodeButton>("btn-ok");
|
||||
btn_cancel = find<NodeButton>("btn-cancel");
|
||||
input = find<NodeTextInput>("txt-input");
|
||||
btn_cancel->on_click = [this](Node*) {
|
||||
destroy();
|
||||
};
|
||||
}
|
||||
|
||||
void NodeDialogLayerRename::loaded()
|
||||
{
|
||||
// ui::Image thumb = ui::Canvas::I->thumbnail_read(data_path);
|
||||
// auto image_tex = find<NodeImageTexture>("thumb-tex");
|
||||
// image_tex->tex.create(thumb);
|
||||
}
|
||||
|
||||
std::string NodeDialogLayerRename::get_name()
|
||||
{
|
||||
return input ? input->m_string : "";
|
||||
}
|
||||
19
engine/node_dialog_layer_rename.h
Normal file
19
engine/node_dialog_layer_rename.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "node_border.h"
|
||||
#include "node_button.h"
|
||||
#include "node_text_input.h"
|
||||
|
||||
class NodeDialogLayerRename : public NodeBorder
|
||||
{
|
||||
public:
|
||||
NodeButton* btn_cancel;
|
||||
NodeButton* btn_ok;
|
||||
NodeTextInput* input;
|
||||
std::string data_path;
|
||||
virtual Node* clone_instantiate() const override;
|
||||
virtual void clone_finalize(Node* dest) const override;
|
||||
virtual void init() override;
|
||||
void init_controls();
|
||||
virtual void loaded() override;
|
||||
std::string get_name();
|
||||
};
|
||||
@@ -10,6 +10,8 @@ enum class kShaderUniform : uint16_t
|
||||
TexFG = const_hash("tex_fg"),
|
||||
TexBG = const_hash("tex_bg"),
|
||||
TexMask = const_hash("tex_mask"),
|
||||
TexStroke = const_hash("tex_stroke"),
|
||||
Lock = const_hash("lock"),
|
||||
Col = const_hash("col"),
|
||||
Tof = const_hash("tof"),
|
||||
Tsz = const_hash("tsz"),
|
||||
@@ -23,16 +25,18 @@ enum class kShader : uint16_t
|
||||
ColorQuad = const_hash("color-quad"),
|
||||
ColorHue = const_hash("color-hue"),
|
||||
Texture = const_hash("texture"),
|
||||
TextureAlpha = const_hash("texture-alpha"),
|
||||
TextureAlpha= const_hash("texture-alpha"),
|
||||
CompErase = const_hash("comp-erase"),
|
||||
CompDraw = const_hash("comp-draw"),
|
||||
UVs = const_hash("uvs"),
|
||||
Font = const_hash("font"),
|
||||
Atlas = const_hash("atlas"),
|
||||
Stroke = const_hash("stroke"),
|
||||
StrokeLock = const_hash("stroke-lock"),
|
||||
StrokeLock = const_hash("stroke-lock"),
|
||||
StrokeErase = const_hash("stroke-erase"),
|
||||
StrokeLayer = const_hash("stroke-layer"),
|
||||
Checkerboard= const_hash("checkerboard"),
|
||||
Equirect = const_hash("equirect"),
|
||||
Equirect = const_hash("equirect"),
|
||||
};
|
||||
|
||||
class Shader
|
||||
@@ -67,4 +71,4 @@ public:
|
||||
static void invalidate();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user