alpha over and opacity nodes are now functional

This commit is contained in:
itsmattkc
2019-09-06 15:45:12 +10:00
parent a5fb8693d0
commit c2e59b0855
16 changed files with 104 additions and 19 deletions
+2 -2
View File
@@ -131,8 +131,8 @@ private:
intType gcd(intType &x, intType &y);
};
#define RATIONAL_MIN rational(LONG_MIN, 1)
#define RATIONAL_MAX rational(LONG_MAX, 1)
#define RATIONAL_MIN rational(INT32_MIN, 1)
#define RATIONAL_MAX rational(INT32_MAX, 1)
Q_DECLARE_METATYPE(rational)
+3
View File
@@ -307,6 +307,9 @@ void Core::CreateNewSequence()
// Connect track to timeline
NodeParam::ConnectEdge(to->track_output(), tb->track_input());
// Connect timeline end point to renderer
NodeParam::ConnectEdge(tb->length_output(), rp->length_input());
// FIXME: Test code
AlphaOverBlend* blend = new AlphaOverBlend();
new_sequence->AddNode(blend);
+11 -3
View File
@@ -64,8 +64,13 @@ QVariant AlphaOverBlend::Value(NodeOutput *param, const rational &time)
RenderTexturePtr base = base_input()->get_value(time).value<RenderTexturePtr>();
RenderTexturePtr blend = blend_input()->get_value(time).value<RenderTexturePtr>();
// Set compositing strategy to alpha over
renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (base == nullptr && blend == nullptr) {
return 0;
} else if (base == nullptr) {
return QVariant::fromValue(blend);
} else if (blend == nullptr) {
return QVariant::fromValue(base);
}
// Attach framebuffer to the backbuffer of base
renderer->buffer()->Attach(base);
@@ -74,13 +79,16 @@ QVariant AlphaOverBlend::Value(NodeOutput *param, const rational &time)
// Bind blend
blend->Bind();
// Set compositing strategy to alpha over
renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Draw blend on base
olive::gl::Blit(renderer->default_pipeline());
// Release all
blend->Release();
renderer->buffer()->Detach();
renderer->buffer()->Release();
renderer->buffer()->Detach();
// Return base texture which now has blend composited on top
// NOTE: Blend texture will be implicitly deleted here (if it's not used anywhere else)
+15 -1
View File
@@ -73,6 +73,10 @@ QVariant OpacityNode::Value(NodeOutput *output, const rational &time)
if (output == texture_output_) {
RenderTexturePtr input_tex = texture_input_->get_value(time).value<RenderTexturePtr>();
if (input_tex == nullptr) {
return 0;
}
// Attach texture's back buffer as frame buffer
renderer->buffer()->AttachBackBuffer(input_tex);
renderer->buffer()->Bind();
@@ -82,17 +86,27 @@ QVariant OpacityNode::Value(NodeOutput *output, const rational &time)
// Set opacity to value
ShaderPtr pipeline = renderer->default_pipeline();
pipeline->bind();
pipeline->setUniformValue("opacity", opacity_input_->get_value(time).toFloat()*0.01f);
pipeline->release();
renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ZERO);
// Blit
olive::gl::Blit(renderer->default_pipeline());
olive::gl::Blit(pipeline);
// Reset to full opacity
pipeline->bind();
pipeline->setUniformValue("opacity", 1.0f);
pipeline->release();
input_tex->Release();
renderer->buffer()->Release();
renderer->buffer()->Detach();
input_tex->SwapFrontAndBack();
return QVariant::fromValue(input_tex);
}
return 0;
+9
View File
@@ -57,6 +57,8 @@ void Node::AddParameter(NodeParam *param)
if (param->type() == NodeParam::kInput) {
connect(param, SIGNAL(ValueChanged(rational, rational)), this, SLOT(InputChanged(rational, rational)));
connect(param, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(InputConnectionChanged(NodeEdgePtr)));
connect(param, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(InputConnectionChanged(NodeEdgePtr)));
}
}
@@ -360,3 +362,10 @@ void Node::InputChanged(rational start, rational end)
{
InvalidateCache(start, end, static_cast<NodeInput*>(sender()));
}
void Node::InputConnectionChanged(NodeEdgePtr edge)
{
Q_UNUSED(edge)
InvalidateCache(RATIONAL_MIN, RATIONAL_MAX, static_cast<NodeInput*>(sender()));
}
+3
View File
@@ -288,6 +288,9 @@ private:
private slots:
void InputChanged(rational start, rational end);
void InputConnectionChanged(NodeEdgePtr edge);
};
template<class T>
+21 -2
View File
@@ -32,6 +32,10 @@ TimelineOutput::TimelineOutput() :
track_input_->add_data_input(NodeParam::kTrack);
AddParameter(track_input_);
length_output_ = new NodeOutput("length_out");
length_output_->set_data_type(NodeParam::kRational);
AddParameter(length_output_);
connect(this, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(TrackConnectionAdded(NodeEdgePtr)));
connect(this, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackConnectionRemoved(NodeEdgePtr)));
}
@@ -96,10 +100,25 @@ NodeInput *TimelineOutput::track_input()
return track_input_;
}
NodeOutput *TimelineOutput::length_output()
{
return length_output_;
}
QVariant TimelineOutput::Value(NodeOutput *output, const rational &time)
{
Q_UNUSED(output)
Q_UNUSED(time)
if (output == length_output_) {
Q_UNUSED(time)
rational length;
// Retrieve each track's end point and return the longest of the tracks
foreach (TrackOutput* track, track_cache_) {
length = qMax(track->in(), length);
}
return QVariant::fromValue(length);
}
return 0;
}
+4
View File
@@ -45,6 +45,8 @@ public:
NodeInput* track_input();
NodeOutput* length_output();
protected:
virtual QVariant Value(NodeOutput* output, const rational& time) override;
@@ -65,6 +67,8 @@ private:
NodeInput* track_input_;
NodeOutput* length_output_;
/**
* @brief A cache of connected Tracks
*/
+1
View File
@@ -226,6 +226,7 @@ QString NodeParam::GetDefaultDataTypeName(const DataType& type)
case kBlock: return tr("Block");
case kFootage: return tr("Footage");
case kTrack: return tr("Track");
case kRational: return tr("Rational");
case kAny: return tr("Any");
}
+1
View File
@@ -68,6 +68,7 @@ public:
kBlock,
kFootage,
kTrack,
kRational,
kAny
};
+17 -4
View File
@@ -42,6 +42,10 @@ RendererProcessor::RendererProcessor() :
texture_input_->add_data_input(NodeInput::kTexture);
AddParameter(texture_input_);
length_input_ = new NodeInput("length_in");
length_input_->add_data_input(NodeInput::kRational);
AddParameter(length_input_);
texture_output_ = new NodeOutput("tex_out");
texture_output_->set_data_type(NodeInput::kTexture);
AddParameter(texture_output_);
@@ -126,18 +130,22 @@ void RendererProcessor::InvalidateCache(const rational &start_range, const ratio
{
Q_UNUSED(from)
// Adjust range to min/max values
rational start_range_adj = qMax(rational(0), start_range);
rational end_range_adj = qMin(length_input()->get_value(0).value<rational>(), end_range);
qDebug() << "[RendererProcessor] Cache invalidated between"
<< start_range.toDouble()
<< start_range_adj.toDouble()
<< "and"
<< end_range.toDouble();
<< end_range_adj.toDouble();
// Snap start_range to timebase
double start_range_dbl = start_range.toDouble();
double start_range_dbl = start_range_adj.toDouble();
double start_range_numf = start_range_dbl * static_cast<double>(timebase_.denominator());
int64_t start_range_numround = qFloor(start_range_numf/static_cast<double>(timebase_.numerator())) * timebase_.numerator();
rational true_start_range(start_range_numround, timebase_.denominator());
for (rational r=true_start_range;r<=end_range;r+=timebase_) {
for (rational r=true_start_range;r<=end_range_adj;r+=timebase_) {
if (!cache_queue_.contains(r)) {
cache_queue_.append(r);
}
@@ -395,6 +403,11 @@ NodeInput *RendererProcessor::texture_input()
return texture_input_;
}
NodeInput *RendererProcessor::length_input()
{
return length_input_;
}
NodeOutput *RendererProcessor::texture_output()
{
return texture_output_;
+4
View File
@@ -100,6 +100,8 @@ public:
NodeInput* texture_input();
NodeInput* length_input();
NodeOutput* texture_output();
protected:
@@ -145,6 +147,8 @@ private:
NodeInput* texture_input_;
NodeInput* length_input_;
NodeOutput* texture_output_;
int width_;
+8 -6
View File
@@ -95,7 +95,7 @@ void RenderFramebuffer::Attach(RenderTexturePtr texture)
}
texture_ = texture;
AttachInternal(texture_->texture());
AttachInternal(texture_->texture(), false);
}
void RenderFramebuffer::AttachBackBuffer(RenderTexturePtr texture)
@@ -105,10 +105,7 @@ void RenderFramebuffer::AttachBackBuffer(RenderTexturePtr texture)
}
texture_ = texture;
AttachInternal(texture_->back_texture());
context_->functions()->glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
context_->functions()->glClear(GL_COLOR_BUFFER_BIT);
AttachInternal(texture_->back_texture(), true);
}
void RenderFramebuffer::Detach()
@@ -137,7 +134,7 @@ const GLuint &RenderFramebuffer::buffer() const
return buffer_;
}
void RenderFramebuffer::AttachInternal(GLuint tex)
void RenderFramebuffer::AttachInternal(GLuint tex, bool clear)
{
Detach();
@@ -150,6 +147,11 @@ void RenderFramebuffer::AttachInternal(GLuint tex)
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0
);
if (clear) {
context_->functions()->glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
context_->functions()->glClear(GL_COLOR_BUFFER_BIT);
}
// release framebuffer
f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
+1 -1
View File
@@ -56,7 +56,7 @@ public slots:
void Destroy();
private:
void AttachInternal(GLuint tex);
void AttachInternal(GLuint tex, bool clear);
QOpenGLContext* context_;
+1
View File
@@ -77,6 +77,7 @@ bool RenderInstance::Start()
// Set viewport to the compositing dimensions
ctx_->functions()->glViewport(0, 0, width_, height_);
ctx_->functions()->glEnable(GL_BLEND);
// Set up default pipeline
default_pipeline_ = olive::ShaderGenerator::DefaultPipeline();
@@ -52,6 +52,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeParam::kTexture:
case NodeParam::kMatrix:
case NodeParam::kTrack:
case NodeParam::kRational:
break;
case NodeParam::kInt:
{
@@ -63,6 +64,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
case NodeParam::kFloat:
{
FloatSlider* slider = new FloatSlider();
slider->SetValue(base_input->get_value(0).toDouble());
widgets_.append(slider);
connect(slider, SIGNAL(ValueChanged(double)), this, SLOT(WidgetCallback()));
break;
@@ -125,6 +127,7 @@ void NodeParamViewWidgetBridge::WidgetCallback()
case NodeParam::kTexture:
case NodeParam::kMatrix:
case NodeParam::kTrack:
case NodeParam::kRational:
break;
case NodeParam::kInt:
{