mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
All filters now derive from FrameBufferFilter, which is always used in a CloneSource. Default FrameBufferFilter is Passthrough filter. Others are Delay and Image filters. Implemented UI selection of filter type, XML session save and load. Linked ImageFilter to Code editor.
115 lines
3.0 KiB
C++
115 lines
3.0 KiB
C++
|
|
#include "Log.h"
|
|
#include "FrameBuffer.h"
|
|
#include "Resource.h"
|
|
#include "Primitives.h"
|
|
#include "Visitor.h"
|
|
|
|
#include "DelayFilter.h"
|
|
|
|
DelayFilter::DelayFilter(): FrameBufferFilter(),
|
|
temp_frame_(nullptr), now_(0.0), delay_(0.5)
|
|
{
|
|
|
|
}
|
|
|
|
DelayFilter::~DelayFilter()
|
|
{
|
|
// delete all frame buffers
|
|
while (!frames_.empty()) {
|
|
if (frames_.front() != nullptr)
|
|
delete frames_.front();
|
|
frames_.pop();
|
|
}
|
|
|
|
while (!elapsed_.empty())
|
|
elapsed_.pop();
|
|
}
|
|
|
|
void DelayFilter::update (float dt)
|
|
{
|
|
if (input_) {
|
|
|
|
// What time is it?
|
|
now_ += double(dt) * 0.001;
|
|
|
|
// if temporary FBO was pending to be deleted, delete it now
|
|
if (temp_frame_ != nullptr) {
|
|
delete temp_frame_;
|
|
temp_frame_ = nullptr;
|
|
}
|
|
|
|
// is the total buffer of images longer than delay ?
|
|
if ( !frames_.empty() && now_ - elapsed_.front() > delay_ )
|
|
{
|
|
// remember FBO to be reused if needed (see below) or deleted later
|
|
temp_frame_ = frames_.front();
|
|
|
|
// remove element from queue (front)
|
|
frames_.pop();
|
|
elapsed_.pop();
|
|
}
|
|
|
|
// add image to queue to accumulate buffer images until delay reached (with margin)
|
|
if ( frames_.empty() || now_ - elapsed_.front() < delay_ + ( double(dt) * 0.002) )
|
|
{
|
|
// create a FBO if none can be reused (from above) and test for RAM in GPU
|
|
if (temp_frame_ == nullptr && ( frames_.empty() || Rendering::shouldHaveEnoughMemory(input_->resolution(), input_->use_alpha()) ) ){
|
|
temp_frame_ = new FrameBuffer( input_->resolution(), input_->use_alpha() );
|
|
}
|
|
// image available
|
|
if (temp_frame_ != nullptr) {
|
|
// add element to queue (back)
|
|
frames_.push( temp_frame_ );
|
|
elapsed_.push( now_ );
|
|
// temp_frame_ FBO is now used, it should not be deleted
|
|
temp_frame_ = nullptr;
|
|
}
|
|
else {
|
|
// set delay to maximum affordable
|
|
delay_ = now_ - elapsed_.front() - (dt * 0.001);
|
|
Log::Warning("Cannot satisfy delay: not enough RAM in graphics card.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint DelayFilter::texture () const
|
|
{
|
|
if (!frames_.empty())
|
|
return frames_.front()->texture();
|
|
else if (input_)
|
|
return input_->texture();
|
|
else
|
|
return Resource::getTextureBlack();
|
|
}
|
|
|
|
glm::vec3 DelayFilter::resolution () const
|
|
{
|
|
if (input_)
|
|
return input_->resolution();
|
|
|
|
return glm::vec3(1,1,0);
|
|
}
|
|
|
|
void DelayFilter::draw (FrameBuffer *input)
|
|
{
|
|
input_ = input;
|
|
|
|
if ( enabled() ) // TODO TEST DISABLE
|
|
{
|
|
// make sure the queue is not empty
|
|
if ( input_ && !frames_.empty() ) {
|
|
// blit input framebuffer in the newest image in queue (back)
|
|
input_->blit( frames_.back() );
|
|
}
|
|
}
|
|
}
|
|
|
|
void DelayFilter::accept (Visitor& v)
|
|
{
|
|
FrameBufferFilter::accept(v);
|
|
v.visit(*this);
|
|
}
|
|
|