fix rtt copy/move

This commit is contained in:
2019-10-15 16:59:55 +02:00
parent 9ccd6ed2f4
commit 5f002cca53
6 changed files with 161 additions and 73 deletions

View File

@@ -1322,8 +1322,11 @@ void App::initLayout()
auto frame_text = layout[main_id]->find<NodeText>("timeline-frame");
slider->on_value_changed = [this, frame_text](Node*, float value)
{
auto& l = Canvas::I->layer();
l.m_frame_index = (int)glm::clamp<int>(
floor(value * l.m_frames.size()), 0, (int)l.m_frames.size() - 1);
/*
auto& c = *Canvas::I;
for (int i = 0; i < c.m_layers.size(); i++)
{
auto l = layers->get_layer_at(i);
@@ -1353,11 +1356,12 @@ void App::initLayout()
snprintf(str, sizeof(str), "%02d", current_layer);
frame_text->set_text(str);
}
*/
};
if (auto btn_add = timeline->find<NodeButtonCustom>("btn-add"))
{
btn_add->on_click = [this, slider] (Node*) {
layers->add_layer(true, true);
Canvas::I->layer().add_frame();
slider->set_value(1.f, true);
};
}

View File

@@ -175,6 +175,7 @@ public:
void destroy();
bool create(int width, int height);
void resize(int width, int height);
Layer& layer() { return *m_layers[m_current_layer_idx]; }
void layer_remove(int idx);
void layer_add(std::string name, std::shared_ptr<Layer> layer = nullptr, int index = 0);
void layer_order(int idx, int pos);

View File

@@ -158,17 +158,17 @@ void Layer::restore(const Snapshot& snap)
//m_rtt[i].recreate();
App::I->render_task_async([this, i, &snap]
{
rtt(i).bindTexture();
glm::vec2 box_sz = zw(box(i)) - xy(box(i));
glTexSubImage2D(GL_TEXTURE_2D, 0,
box(i).x, box(i).y,
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE,
snap.image[i].get());
rtt(i).unbindTexture();
LOG("restore face %d - %d bytes (%dx%d)", i,
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
});
{
rtt(i).bindTexture();
glm::vec2 box_sz = zw(box(i)) - xy(box(i));
glTexSubImage2D(GL_TEXTURE_2D, 0,
box(i).x, box(i).y,
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE,
snap.image[i].get());
rtt(i).unbindTexture();
LOG("restore face %d - %d bytes (%dx%d)", i,
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
});
}
App::I->render_sync();
}
@@ -189,13 +189,13 @@ Layer::Snapshot Layer::snapshot(std::array<glm::vec4, 6>* dirty_box /*= nullptr*
snap.image[i] = std::make_unique<uint8_t[]>(rtt(i).bytes());
App::I->render_task_async([this, i, &snap]
{
rtt(i).bindFramebuffer();
glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]);
glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y,
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
rtt(i).unbindFramebuffer();
});
{
rtt(i).bindFramebuffer();
glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]);
glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y,
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
rtt(i).unbindFramebuffer();
});
}
App::I->render_sync();
return snap;
@@ -203,36 +203,7 @@ Layer::Snapshot Layer::snapshot(std::array<glm::vec4, 6>* dirty_box /*= nullptr*
void Layer::clear(const glm::vec4& c)
{
App::I->render_task([&]
{
// push clear color state
GLfloat cc[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
glClearColor(c.r, c.g, c.b, c.a);
bool erase = (c.a == 0.f);
for (int i = 0; i < 6; i++)
{
rtt(i).bindFramebuffer();
glClear(GL_COLOR_BUFFER_BIT);
rtt(i).unbindFramebuffer();
if (erase)
{
box(i) = glm::vec4(w, h, 0, 0); // reset bounding box
face(i) = false;
}
else
{
box(i) = glm::vec4(0, 0, w, h); // reset bounding box
face(i) = true;
}
}
// restore clear color state
glClearColor(cc[0], cc[1], cc[2], cc[3]);
});
frame().clear(c);
}
bool Layer::create(int width, int height, std::string name)
@@ -240,26 +211,18 @@ bool Layer::create(int width, int height, std::string name)
m_name = name;
w = width;
h = height;
m_frame_index = 0;
if (m_frames.empty())
m_frames.emplace_back();
App::I->render_task([&]
{
for (int i = 0; i < 6; i++)
{
rtt(i).create(width, height);
rtt(i).bindFramebuffer();
rtt(i).clear();
rtt(i).unbindFramebuffer();
box(i) = glm::vec4(w, h, 0, 0); // reset bounding box
face(i) = false;
}
});
frame().create(width, height);
return true;
}
bool Layer::add_frame()
{
return true;
m_frames.emplace_back();
m_frame_index = m_frames.size() - 1;
return frame().create(w, h);
}
void Layer::resize(int width, int height)
@@ -335,11 +298,52 @@ int Layer::Snapshot::memsize() const
///////////////////////////////////////////////////////////////////////////////////////////
/*
LayerFrame::LayerFrame(LayerFrame&& other)
{
LOG("LayerFrame move-ctor");
for (int i = 0; i < 6; i++)
{
m_rtt[i] = std::move(other.m_rtt[i]);
m_dirty_box[i] = other.m_dirty_box[i];
m_dirty_face[i] = other.m_dirty_face[i];
}
m_duration = other.m_duration;
w = other.w;
h = other.h;
}
LayerFrame& LayerFrame::operator=(LayerFrame&& other)
{
LOG("LayerFrame move-assignment");
for (int i = 0; i < 6; i++)
{
m_rtt[i] = std::move(other.m_rtt[i]);
m_dirty_box[i] = other.m_dirty_box[i];
m_dirty_face[i] = other.m_dirty_face[i];
}
m_duration = other.m_duration;
w = other.w;
h = other.h;
return *this;
}
*/
bool LayerFrame::create(int width, int height, int duration /*= 1*/)
{
for (auto& rtt : m_rtt)
if (!rtt.create(width, height))
return false;
App::I->render_task([&]
{
for (int i = 0; i < 6; i++)
{
if (!m_rtt[i].create(width, height))
return false;
m_rtt[i].bindFramebuffer();
m_rtt[i].clear();
m_rtt[i].unbindFramebuffer();
m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box
m_dirty_face[i] = false;
}
});
m_duration = duration;
w = width;
h = height;
@@ -359,3 +363,37 @@ bool LayerFrame::resize(int width, int height)
h = height;
return true;
}
void LayerFrame::clear(const glm::vec4& c)
{
App::I->render_task([&]
{
// push clear color state
GLfloat cc[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
glClearColor(c.r, c.g, c.b, c.a);
bool erase = (c.a == 0.f);
for (int i = 0; i < 6; i++)
{
m_rtt[i].bindFramebuffer();
glClear(GL_COLOR_BUFFER_BIT);
m_rtt[i].unbindFramebuffer();
if (erase)
{
m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box
m_dirty_face[i] = false;
}
else
{
m_dirty_box[i] = glm::vec4(0, 0, w, h); // reset bounding box
m_dirty_face[i] = true;
}
}
// restore clear color state
glClearColor(cc[0], cc[1], cc[2], cc[3]);
});
}

View File

@@ -10,9 +10,19 @@ struct LayerFrame
std::array<bool, 6> m_dirty_face = SIXPLETTE(false);
int m_duration = 1;
int w = 0, h = 0;
LayerFrame() = default;
//// default
//LayerFrame() = default;
//// copy
//LayerFrame(const LayerFrame&) = delete;
//LayerFrame& operator=(const LayerFrame&) = delete;
//// move
//LayerFrame(LayerFrame&& other);
//LayerFrame& operator=(LayerFrame&&);
bool create(int width, int height, int duration = 1);
bool resize(int width, int height);
void clear(const glm::vec4& c);
};
class Layer

View File

@@ -4,8 +4,31 @@
#include "util.h"
#include "app.h"
RTT& RTT::operator=(RTT&& other)
{
LOG("RTT-move-assignment");
int_fmt = other.int_fmt;
texID = other.texID;
fboID = other.fboID;
rboID = other.rboID;
w = other.w;
h = other.h;
bound = other.bound;
other.int_fmt = 0;
other.texID = 0;
other.fboID = 0;
other.rboID = 0;
other.w = 0;
other.h = 0;
other.bound = false;
return *this;
}
RTT::RTT()
{
int_fmt = 0;
fboID = 0;
rboID = 0;
w = 0;
@@ -15,12 +38,18 @@ RTT::RTT()
RTT::RTT(RTT&& other)
{
LOG("RTT-move-ctor");
int_fmt = other.int_fmt;
texID = other.texID;
fboID = other.fboID;
rboID = other.rboID;
w = other.w;
h = other.h;
bound = other.bound;
other.int_fmt = 0;
other.texID = 0;
other.fboID = 0;
other.rboID = 0;
other.w = 0;
@@ -30,6 +59,7 @@ RTT::RTT(RTT&& other)
RTT::~RTT()
{
LOG("RTT-dtor");
//destroy();
if (texID || rboID || fboID)
LOG("RTT not destroyed");

View File

@@ -3,19 +3,24 @@
class RTT
{
int w = 0;
int h = 0;
GLuint fboID = 0;
GLuint texID = 0;
GLuint rboID = 0;
GLint int_fmt = 0;
bool bound = false;
GLint oldRFboID = 0;
GLint oldDFboID = 0;
GLuint fboID = 0;
GLuint rboID = 0;
GLuint texID = 0;
GLint int_fmt = 0;
int w = 0;
int h = 0;
public:
// copy
RTT(const RTT&) = delete;
RTT& operator=(const RTT&) = delete;
// move
RTT(RTT&& other);
RTT& operator=(RTT&&);
// default
RTT();
~RTT();