use single shared framebuffer to render stroke previews

This commit is contained in:
2019-03-29 09:31:30 +01:00
parent d6804e95cd
commit 15db5c233b
2 changed files with 58 additions and 30 deletions

View File

@@ -12,6 +12,17 @@ std::atomic_bool NodeStrokePreview::s_running{ false };
std::thread NodeStrokePreview::s_renderer;
BlockingQueue<NodeStrokePreview*> NodeStrokePreview::s_queue;
RTT NodeStrokePreview::m_rtt;
RTT NodeStrokePreview::m_rtt_mixer;
Texture2D NodeStrokePreview::m_tex; // blending tmp texture
Texture2D NodeStrokePreview::m_tex_dual;
Texture2D NodeStrokePreview::m_tex_background;
Sampler NodeStrokePreview::m_sampler_linear;
Sampler NodeStrokePreview::m_sampler_linear_repeat;
Sampler NodeStrokePreview::m_sampler_mipmap;
DynamicShape NodeStrokePreview::m_brush_shape;
void NodeStrokePreview::terminate_renderer()
{
if (s_running && s_renderer.joinable())
@@ -45,11 +56,6 @@ void NodeStrokePreview::clone_finalize(Node* dest) const
void NodeStrokePreview::init_controls()
{
m_sampler_linear.create();
m_sampler_linear_repeat.create(GL_LINEAR, GL_REPEAT);
m_sampler_mipmap.create();
m_sampler_mipmap.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
m_brush_shape.create();
// TextureManager::load("data/thumbs/Round-Hard.png");
// Canvas::I->m_current_brush.m_tex_id = const_hash("data/thumbs/Round-Hard.png");
}
@@ -59,14 +65,14 @@ void NodeStrokePreview::restore_context()
NodeBorder::restore_context();
init_controls();
if (m_size.x > 0 && m_size.y > 0)
m_rtt.create(m_size.x, m_size.y);
m_tex_preview.create(m_size.x, m_size.y);
draw_stroke();
}
void NodeStrokePreview::clear_context()
{
NodeBorder::clear_context();
m_rtt.destroy();
m_tex_preview.destroy();
}
void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
@@ -470,7 +476,12 @@ void NodeStrokePreview::draw_stroke_immediate()
glBindTexture(GL_TEXTURE_2D, 0);
m_plane.draw_fill();
// copy the result to the actual preview
m_tex_preview.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
m_rtt.unbindFramebuffer();
glViewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
}
@@ -485,6 +496,13 @@ void NodeStrokePreview::draw_stroke()
s_running = true;
s_renderer = std::thread([] {
BT_SetTerminate();
App::I.async_start();
m_sampler_linear.create();
m_sampler_linear_repeat.create(GL_LINEAR, GL_REPEAT);
m_sampler_mipmap.create();
m_sampler_mipmap.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
m_brush_shape.create();
App::I.async_end();
while (s_running)
{
auto node = s_queue.Get();
@@ -498,6 +516,16 @@ void NodeStrokePreview::draw_stroke()
gl_state gl;
gl.save();
auto new_size = node->m_tex_preview.size();
if (m_tex.size() != new_size)
{
m_rtt.create((int)new_size.x, (int)new_size.y);
m_rtt_mixer.create((int)new_size.x, (int)new_size.y);
m_tex.create((int)new_size.x, (int)new_size.y);
m_tex_dual.create((int)new_size.x, (int)new_size.y);
m_tex_background.create((int)new_size.x, (int)new_size.y);
}
node->m_brush->load();
node->draw_stroke_immediate();
if (to_unload)
@@ -509,6 +537,14 @@ void NodeStrokePreview::draw_stroke()
std::this_thread::sleep_for(std::chrono::milliseconds(30));
}
}
App::I.async_start();
m_rtt.destroy();
m_rtt_mixer.destroy();
m_tex.destroy();
m_tex_dual.destroy();
m_tex_background.destroy();
m_brush_shape.destroy();
App::I.async_end();
});
}
s_queue.mutex.unlock();
@@ -521,25 +557,21 @@ void NodeStrokePreview::draw()
ShaderManager::use(kShader::Texture);
ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
ShaderManager::u_int(kShaderUniform::Tex, 0);
m_rtt.bindTexture();
m_tex_preview.bind();
m_sampler_linear.bind(0);
m_plane.draw_fill();
m_sampler_linear.unbind();
m_rtt.unbindTexture();
m_tex_preview.unbind();
}
void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
{
if ((m_rtt.getWidth() == new_size.x && m_rtt.getHeight() == new_size.y) || !m_brush)
if (m_tex_preview.size() == new_size || !m_brush)
return;
new_size *= root()->m_zoom;
m_rtt.create((int)new_size.x, (int)new_size.y);
m_rtt_mixer.create((int)new_size.x, (int)new_size.y);
m_tex.create((int)new_size.x, (int)new_size.y);
m_tex_dual.create((int)new_size.x, (int)new_size.y);
m_tex_background.create((int)new_size.x, (int)new_size.y);
m_tex_preview.create((int)new_size.x, (int)new_size.y);
draw_stroke();
}
@@ -547,10 +579,5 @@ void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
void NodeStrokePreview::destroy_immediate()
{
Node::destroy_immediate();
m_rtt.destroy();
m_rtt_mixer.destroy();
m_tex.destroy();
m_tex_dual.destroy();
m_tex_background.destroy();
m_brush_shape.destroy();
m_tex_preview.destroy();
}

View File

@@ -15,15 +15,16 @@ class NodeStrokePreview : public NodeBorder
glm::vec4 m_mixer_rect;
};
RTT m_rtt;
RTT m_rtt_mixer;
Texture2D m_tex; // blending tmp texture
Texture2D m_tex_dual;
Texture2D m_tex_background;
Sampler m_sampler_linear;
Sampler m_sampler_linear_repeat;
Sampler m_sampler_mipmap;
DynamicShape m_brush_shape;
static RTT m_rtt;
static RTT m_rtt_mixer;
static Texture2D m_tex; // blending tmp texture
static Texture2D m_tex_dual;
static Texture2D m_tex_background;
static Sampler m_sampler_linear;
static Sampler m_sampler_linear_repeat;
static Sampler m_sampler_mipmap;
static DynamicShape m_brush_shape;
Texture2D m_tex_preview;
public:
static std::atomic_int s_instances;
static std::atomic_bool s_running;