Urgent FBO use in FFGL

FFGL, OSC, GLSL. If you like abbreviations, this is the forum for you
Post Reply
Piotrus04
Is taking Resolume on a second date
Posts: 27
Joined: Mon Nov 06, 2017 12:05

Urgent FBO use in FFGL

Post by Piotrus04 »

Hi,

Dear Resolume team, do you have an example of correct FBO use inside the processopengl function ?

Ideally, could you publish the source of the trail effect ?

My aim is to make a ffgl pluging "Trail effect" (in pixel shader, not vertex) like the trails in Resolume but with more parameters.

Using a ping-pong buffer to store the previous FBO, thereafter FBO reinjected in the second input of the trail shader.

i succeeded to reproduce the trail effect but i have some blinking issues, depending on if i use one or two effects on different tracks, different resolutions between compositions, layers... I am missing something for sure...

moreover, easy issue to reproduce, if we click the clip and also the preview of this clip, the same ffgl plugin instance is called two times with different resolutions, this makes some strange behaviour in my plugin, picture stuck, blinks... , avenue memory rising very quickly to Gb of ram... , i need some help...

Some FBO example or trail effect source would be very very welcome to make proper use of the fbo !
we are missing documentation :)

thank you

Here is the code if somebody find a solution... :

Code: Select all

#include "ASlider.h"
using namespace ffglex;

static CFFGLPluginInfo PluginInfo(
	PluginFactory< ASlider >,// Create method
	"RE01",                      // Plugin unique ID of maximum length 4.
	"ASlider",            // Plugin name
	2,                           // API major version number
	1,                           // API minor version number
	1,                           // Plugin major version number
	0,                           // Plugin minor version number
	FF_EFFECT,                   // Plugin type
	"Slider",  // Plugin description
	"Alex"      // About
);

static const char _dummyvertexShaderCode[] = R"(#version 410 core
uniform vec2 MaxUV;

layout( location = 0 ) in vec4 vPosition;
layout( location = 1 ) in vec2 vUV;

out vec2 uv;

void main()
{
    gl_Position = vPosition;
    uv = vUV * MaxUV;
}
)";


static const char _dummyfragmentShaderCode[] = R"(#version 410 core
uniform sampler2D inputTexture;

in vec2 uv;

out vec4 fragColor;

void main()
{
   vec4 color = texture( inputTexture, uv );




    fragColor = color;
}
)";



static const char _vertexShaderCode[] = R"(#version 410 core
uniform vec2 MaxUV;



layout( location = 0 ) in vec4 vPosition;
layout( location = 1 ) in vec2 vUV;

out vec2 uv;


void main()
{
	gl_Position = vPosition;
    //uv = vUV * MaxUV;
    uv = vUV ;
}
)";

static const char _fragmentShaderCode[] = R"(#version 410 core
uniform sampler2D inputTexture;
uniform sampler2D inputTexture2;


uniform float Up;
uniform float Down;

in vec2 uv;

out vec4 fragColor;

void main()
{
    vec4 su;
    vec4 sd;
    vec4 up;
    vec4 down;
    vec4 amount;

    vec4 input0 = vec4(texture(inputTexture, uv));
    vec4 input1 = vec4(texture(inputTexture2, uv));


    // get contribution
    amount.x = (input0.x > input1.x) ? 1. : 0.0;
    amount.y = (input0.y > input1.y) ? 1. : 0.0;
    amount.z = (input0.z > input1.z) ? 1. : 0.0;
    amount.w = (input0.w > input1.w) ? 1. : 0.0;


    // calculate slide down
    float d = max(1.0, abs(Down));
    sd = vec4(1.0 / d);
    down = input1 + ((input0 - input1) * sd);

    // calculate slide up
    float u = max(1.0, abs(Up));
    su = vec4(1.0 / u);
    up = input1 + ((input0 - input1) * su);


    // mix between down and up
    vec4 out_color = mix(down, up, amount);

//    if(out_color.r < 0.0080) out_color.r = 0; //003921568627
//    if(out_color.g < 0.0080) out_color.g = 0; //003921568627
//    if(out_color.b < 0.0080) out_color.b = 0; //003921568627

    out_color -= vec4(0.004, 0.004, 0.004, 0.004);
    fragColor  = out_color;
}
)";




using namespace std;

ASlider::ASlider()
{
	// Input properties
	SetMinInputs( 1 );
	SetMaxInputs( 1 );

    AddParam( ffglqs::ParamRange::Create( "Up",  1., {1.0, 40.0} ) );
    AddParam( ffglqs::ParamRange::Create( "Down",  1., {1.0, 40.0} ) );
    
    last_width.clear();
    last_height.clear();
}
ASlider::~ASlider()
{
}

FFResult ASlider::InitGL( const FFGLViewportStruct* vp )
{
	if( !shader.Compile( _vertexShaderCode, _fragmentShaderCode ) )
	{
		DeInitGL();
		return FF_FAIL;
	}
    
    if( !dummy_shader.Compile(_dummyvertexShaderCode, _dummyfragmentShaderCode) )
    {
        DeInitGL();
        return FF_FAIL;
    }
    
	if( !quad.Initialise() )
	{
		DeInitGL();
		return FF_FAIL;
	}

	//Use base-class init as success result so that it retains the viewport.
	return CFFGLPlugin::InitGL( vp );
}

bool ASlider::resolutionChanged(int width, int height, int id_texture)
{
    if(id_texture == -1)
        return -1;
    
    bool bResolutionChange = false;
    
    if(last_width.find(id_texture) == last_width.end())
    {
        last_width[id_texture] = -1;
        last_height[id_texture] = -1;
    }
    
    if((width != last_width[id_texture] ) || (height != last_height[id_texture] ))
    {
        last_width[id_texture]  = width;
        last_height[id_texture] = height;
        bResolutionChange = true;
//        printf("init change size %u %u %u %u\n", width, height, last_width);
    }

    return bResolutionChange;
}


FFResult ASlider::ProcessOpenGL( ProcessOpenGLStruct* pGL )
{
	if( pGL->numInputTextures < 1 )
		return FF_FAIL;

	if( pGL->inputTextures[ 0 ] == NULL )
		return FF_FAIL;

    FFGLTexCoords maxCoords = GetMaxGLTexCoords( *pGL->inputTextures[ 0 ] );

    
    GLuint id_texture = pGL->inputTextures[0]->Handle;
    
    if(fbos.find(id_texture) == fbos.end())
    {
        fbos[id_texture][0].Initialise(pGL->inputTextures[ 0 ]->Width, pGL->inputTextures[ 0 ]->Height);
        fbos[id_texture][1].Initialise(pGL->inputTextures[ 0 ]->Width, pGL->inputTextures[ 0 ]->Height);
    }
    else if(resolutionChanged(pGL->inputTextures[ 0 ]->Width, pGL->inputTextures[ 0 ]->Height, id_texture))
    {
        cout << "release texture\n" ;
        
        fbos[id_texture][0].Release();
        fbos[id_texture][1].Release();
        fbos[id_texture][0].Initialise(pGL->inputTextures[ 0 ]->Width, pGL->inputTextures[ 0 ]->Height);
        fbos[id_texture][1].Initialise(pGL->inputTextures[ 0 ]->Width, pGL->inputTextures[ 0 ]->Height);
    }

    
    {
        ffglex::ScopedFBOBinding fbobind(fbos[id_texture][index].GetGLID(), ScopedFBOBinding::RestoreBehaviour::RB_REVERT);

        ScopedShaderBinding shaderBinding( shader.GetGLID() );

        ScopedSamplerActivation activateSampler( 0 );
        Scoped2DTextureBinding textureBinding( pGL->inputTextures[ 0 ]->Handle );
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
        
        ScopedSamplerActivation activateSampler2( 1 );
        Scoped2DTextureBinding textureBinding2( fbos[id_texture][1 - index].GetTextureInfo().Handle );
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
//        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

        shader.Set( "inputTexture", 0 );
        shader.Set( "inputTexture2", 1 );
        shader.Set( "MaxUV", maxCoords.s, maxCoords.t );

        SendParams( shader );
        
        cout << "Instance : " << this << "in " << pGL->inputTextures[0]->Handle << "fbo " << fbos[id_texture][1-index].GetTextureInfo().Handle << "\n" ;

        quad.Draw();
        
        
    }

    ScopedShaderBinding s_shader_binding( dummy_shader.GetGLID() );

    ScopedSamplerActivation s_activateSampler( 0 );
    Scoped2DTextureBinding s_textureBinding( fbos[id_texture][1-index].GetTextureInfo().Handle );
    dummy_shader.Set( "inputTexture", 0 );
    dummy_shader.Set( "MaxUV", maxCoords.s, maxCoords.t );

    SendParams( dummy_shader );

    quad.Draw();
    index = 1 - index;

	return FF_SUCCESS;
}

unsigned int ASlider::Resize( const FFGLViewportStruct* vp )
{
    
//    if(resolutionChanged(vp->width, vp->height, -1))
    {
//        fbos[0].Release();
//        fbos[1].Release();
//        fbos[0].Initialise(vp->width, vp->height);
//        fbos[1].Initialise(vp->width, vp->height);
    }

    

    currentViewport = *vp;

    return FF_SUCCESS;
}

FFResult ASlider::DeInitGL()
{
    shader.FreeGLResources();
    dummy_shader.FreeGLResources();
    
    for(auto& fbo : fbos)
    {
        fbo.second[0].Release();
        fbo.second[1].Release();
    }
    quad.Release();

	return FF_SUCCESS;
}
Attachments
aslider.zip
(3.45 KiB) Downloaded 656 times

Post Reply