lazy stroke preview rendering
This commit is contained in:
16
src/app.cpp
16
src/app.cpp
@@ -590,8 +590,6 @@ void App::update(float dt)
|
|||||||
{
|
{
|
||||||
auto box = n->m_clip_uncut;
|
auto box = n->m_clip_uncut;
|
||||||
Node* p = n->m_parent;
|
Node* p = n->m_parent;
|
||||||
if (dynamic_cast<NodeBrushPresetItem*>(n))
|
|
||||||
p = p;
|
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
float pt = YGNodeLayoutGetPadding(p->y_node, YGEdgeTop);
|
float pt = YGNodeLayoutGetPadding(p->y_node, YGEdgeTop);
|
||||||
@@ -607,7 +605,21 @@ void App::update(float dt)
|
|||||||
//auto box = n->m_clip;
|
//auto box = n->m_clip;
|
||||||
//glm::ivec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
|
//glm::ivec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
|
||||||
if (box.z <= 0.f || box.w <= 0.f)
|
if (box.z <= 0.f || box.w <= 0.f)
|
||||||
|
{
|
||||||
|
if (n->m_on_screen)
|
||||||
|
{
|
||||||
|
if (dynamic_cast<NodeStrokePreview*>(n))
|
||||||
|
p = p;
|
||||||
|
n->handle_on_screen(true, false);
|
||||||
|
n->m_on_screen = false;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (!n->m_on_screen)
|
||||||
|
{
|
||||||
|
n->handle_on_screen(false, true);
|
||||||
|
n->m_on_screen = true;
|
||||||
|
}
|
||||||
glm::ivec4 c = glm::vec4((int)box.x, (int)(height / zoom - box.y - box.w), (int)box.z, (int)box.w) * zoom;
|
glm::ivec4 c = glm::vec4((int)box.x, (int)(height / zoom - box.y - box.w), (int)box.z, (int)box.w) * zoom;
|
||||||
glScissor(c.x + off_x, c.y + off_y, c.z, c.w);
|
glScissor(c.x + off_x, c.y + off_y, c.z, c.w);
|
||||||
n->draw();
|
n->draw();
|
||||||
|
|||||||
17
src/node.cpp
17
src/node.cpp
@@ -63,7 +63,7 @@ void Node::watch(std::function<bool(Node*)> observer)
|
|||||||
{
|
{
|
||||||
for (auto& c : m_children)
|
for (auto& c : m_children)
|
||||||
{
|
{
|
||||||
if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
|
//if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
|
||||||
c->watch(observer);
|
c->watch(observer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,6 +268,21 @@ void Node::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Node::handle_on_screen(bool old_visibility, bool new_visibility)
|
||||||
|
{
|
||||||
|
if (new_visibility == false)
|
||||||
|
{
|
||||||
|
for (auto& c : m_children)
|
||||||
|
{
|
||||||
|
if (c->m_on_screen)
|
||||||
|
{
|
||||||
|
c->handle_on_screen(true, false);
|
||||||
|
c->m_on_screen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Node::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size)
|
void Node::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ public:
|
|||||||
glm::vec4 m_clip_uncut{ 0, 0, 0, 0 };
|
glm::vec4 m_clip_uncut{ 0, 0, 0, 0 };
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_display = true;
|
bool m_display = true;
|
||||||
|
// it's actually rendering
|
||||||
|
bool m_on_screen = false;
|
||||||
|
|
||||||
Node(const Node&) = delete;
|
Node(const Node&) = delete;
|
||||||
Node& operator=(const Node&) = delete;
|
Node& operator=(const Node&) = delete;
|
||||||
@@ -251,6 +253,7 @@ public:
|
|||||||
virtual kEventResult on_event(Event* e);
|
virtual kEventResult on_event(Event* e);
|
||||||
virtual kEventResult handle_event(Event* e);
|
virtual kEventResult handle_event(Event* e);
|
||||||
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size);
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size);
|
||||||
|
virtual void handle_on_screen(bool old_visibility, bool new_visibility);
|
||||||
virtual void handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size);
|
virtual void handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size);
|
||||||
virtual void create();
|
virtual void create();
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|||||||
@@ -37,20 +37,6 @@ class NodePanelBrush : public Node
|
|||||||
NodeButtonCustom* m_btn_down;
|
NodeButtonCustom* m_btn_down;
|
||||||
NodeButtonCustom* m_btn_remove;
|
NodeButtonCustom* m_btn_remove;
|
||||||
bool m_interacted = false;
|
bool m_interacted = false;
|
||||||
struct header_t {
|
|
||||||
char magic[5]{ 'P', 'P', 'B', 'R', 0 };
|
|
||||||
uint16_t version = 0;
|
|
||||||
uint16_t build = g_version_build;
|
|
||||||
uint16_t brushes = 0;
|
|
||||||
uint16_t deleted = 0;
|
|
||||||
};
|
|
||||||
struct item_t {
|
|
||||||
int m_name_len = 0;
|
|
||||||
int m_high_len = 0;
|
|
||||||
int m_thumb_len = 0;
|
|
||||||
bool m_deleted = false;
|
|
||||||
bool m_user_brush = false;
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
NodeScroll* m_container;
|
NodeScroll* m_container;
|
||||||
std::string m_dir_name;
|
std::string m_dir_name;
|
||||||
@@ -94,12 +80,6 @@ class NodePanelBrushPreset : public Node
|
|||||||
NodeButtonCustom* m_btn_down;
|
NodeButtonCustom* m_btn_down;
|
||||||
NodeButtonCustom* m_btn_delete;
|
NodeButtonCustom* m_btn_delete;
|
||||||
NodeButtonCustom* m_btn_save;
|
NodeButtonCustom* m_btn_save;
|
||||||
struct header_t {
|
|
||||||
char magic[5]{ 'P', 'P', 'P', 'R', 0 };
|
|
||||||
uint16_t version = 0;
|
|
||||||
uint16_t count = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Node* m_container;
|
Node* m_container;
|
||||||
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed;
|
std::function<void(Node* target, std::shared_ptr<Brush>& brush)> on_brush_changed;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ void NodeStrokePreview::empty_queue()
|
|||||||
s_queue.q.clear();
|
s_queue.q.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NodeStrokePreview::instances = 0;
|
||||||
|
|
||||||
Node* NodeStrokePreview::clone_instantiate() const
|
Node* NodeStrokePreview::clone_instantiate() const
|
||||||
{
|
{
|
||||||
return new NodeStrokePreview();
|
return new NodeStrokePreview();
|
||||||
@@ -271,7 +273,10 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
m_sampler_linear.bind(4);
|
m_sampler_linear.bind(4);
|
||||||
|
|
||||||
const auto& b = m_brush;
|
const auto& b = m_brush;
|
||||||
|
|
||||||
|
Stroke m_stroke;
|
||||||
|
Stroke m_dual_stroke;
|
||||||
|
|
||||||
m_stroke.m_filter_points = false;
|
m_stroke.m_filter_points = false;
|
||||||
m_stroke.m_max_size = m_max_size > 0 ? m_max_size : m_size.y * .75f;
|
m_stroke.m_max_size = m_max_size > 0 ? m_max_size : m_size.y * .75f;
|
||||||
m_stroke.m_camera.fov = Canvas::I->m_cam_fov;
|
m_stroke.m_camera.fov = Canvas::I->m_cam_fov;
|
||||||
@@ -518,10 +523,13 @@ void NodeStrokePreview::draw_stroke()
|
|||||||
node->m_brush->preload();
|
node->m_brush->preload();
|
||||||
|
|
||||||
node->async_start();
|
node->async_start();
|
||||||
|
|
||||||
gl_state gl;
|
gl_state gl;
|
||||||
gl.save();
|
gl.save();
|
||||||
|
|
||||||
auto new_size = node->m_tex_preview.size();
|
auto new_size = node->m_preview_size;
|
||||||
|
if (!node->m_tex_preview.ready() || node->m_tex_preview.size() != new_size)
|
||||||
|
node->m_tex_preview.create((int)new_size.x, (int)new_size.y);
|
||||||
if (m_tex.size() != new_size)
|
if (m_tex.size() != new_size)
|
||||||
{
|
{
|
||||||
m_rtt.create((int)new_size.x, (int)new_size.y);
|
m_rtt.create((int)new_size.x, (int)new_size.y);
|
||||||
@@ -558,7 +566,6 @@ void NodeStrokePreview::draw_stroke()
|
|||||||
|
|
||||||
void NodeStrokePreview::draw()
|
void NodeStrokePreview::draw()
|
||||||
{
|
{
|
||||||
//glEnable(GL_BLEND);
|
|
||||||
ShaderManager::use(kShader::Texture);
|
ShaderManager::use(kShader::Texture);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
|
ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
@@ -574,11 +581,10 @@ void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
|
|||||||
if (m_tex_preview.size() == new_size || !m_brush)
|
if (m_tex_preview.size() == new_size || !m_brush)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new_size *= root()->m_zoom;
|
m_preview_size = new_size * root()->m_zoom;
|
||||||
|
|
||||||
m_tex_preview.create((int)new_size.x, (int)new_size.y);
|
if (m_on_screen)
|
||||||
|
draw_stroke();
|
||||||
draw_stroke();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeStrokePreview::destroy_immediate()
|
void NodeStrokePreview::destroy_immediate()
|
||||||
@@ -586,3 +592,17 @@ void NodeStrokePreview::destroy_immediate()
|
|||||||
Node::destroy_immediate();
|
Node::destroy_immediate();
|
||||||
m_tex_preview.destroy();
|
m_tex_preview.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeStrokePreview::handle_on_screen(bool old_visibility, bool new_visibility)
|
||||||
|
{
|
||||||
|
parent::handle_on_screen(old_visibility, new_visibility);
|
||||||
|
if (new_visibility)
|
||||||
|
{
|
||||||
|
draw_stroke();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_queue.Remove(std::static_pointer_cast<NodeStrokePreview>(shared_from_this()));
|
||||||
|
m_tex_preview.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class NodeStrokePreview : public NodeBorder
|
|||||||
static DynamicShape m_brush_shape;
|
static DynamicShape m_brush_shape;
|
||||||
Texture2D m_tex_preview;
|
Texture2D m_tex_preview;
|
||||||
public:
|
public:
|
||||||
|
using parent = NodeBorder;
|
||||||
static std::atomic_int s_instances;
|
static std::atomic_int s_instances;
|
||||||
static std::atomic_bool s_running;
|
static std::atomic_bool s_running;
|
||||||
static std::thread s_renderer;
|
static std::thread s_renderer;
|
||||||
@@ -33,11 +34,8 @@ public:
|
|||||||
static void terminate_renderer();
|
static void terminate_renderer();
|
||||||
static void empty_queue();
|
static void empty_queue();
|
||||||
std::shared_ptr<Brush> m_brush;
|
std::shared_ptr<Brush> m_brush;
|
||||||
std::shared_ptr<Brush> m_dual_brush;
|
|
||||||
bool m_draw_first = false;
|
bool m_draw_first = false;
|
||||||
Stroke m_stroke;
|
glm::vec2 m_preview_size = { 0, 0 };
|
||||||
Stroke m_dual_stroke;
|
|
||||||
std::vector<glm::vec2> m_bez_points;
|
|
||||||
float m_min_flow = 0.f;
|
float m_min_flow = 0.f;
|
||||||
float m_max_size = 0.f;
|
float m_max_size = 0.f;
|
||||||
float m_pad_override = NAN;
|
float m_pad_override = NAN;
|
||||||
@@ -57,4 +55,5 @@ public:
|
|||||||
virtual void draw() override;
|
virtual void draw() override;
|
||||||
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) override;
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size) override;
|
||||||
virtual void destroy_immediate() override;
|
virtual void destroy_immediate() override;
|
||||||
|
virtual void handle_on_screen(bool old_visibility, bool new_visibility) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -198,6 +198,14 @@ public:
|
|||||||
}
|
}
|
||||||
get_cv.notify_one();
|
get_cv.notify_one();
|
||||||
}
|
}
|
||||||
|
void Remove(T pkt)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mutex);
|
||||||
|
auto it = std::find_if(q.begin(), q.end(), [&pkt](auto const& x) { return x.first == pkt; });
|
||||||
|
if (it != q.end())
|
||||||
|
q.erase(it);
|
||||||
|
if (Max > 0) post_cv.notify_all();
|
||||||
|
}
|
||||||
T Get()
|
T Get()
|
||||||
{
|
{
|
||||||
static T emptyT{};
|
static T emptyT{};
|
||||||
|
|||||||
Reference in New Issue
Block a user