I need to implement a color function (removing a solid colored background) in an openFrameworks application.
I will play many (10 or more) videos at the same time (in the same frame) and draw them on the screen along with alternative backgrounds. I can achieve the effect characteristic of color, iterating through each pixel of the frame and setting alpha values ββfor each of them based on the green threshold, but with so many videos at once, this pixel offset becomes prohibitive.
Is there a simple OpenGL blending or masking mode that can avoid drawing all the pixels of a particular color value? Or is there another openFrameworks or openFrameworks-compatible C ++ library that can do this efficiently?
Alternatively, is there a good (space-efficient) way to store the alpha channel in QuickTime-compatible video files? We are going to store terabytes of video (weeks of continuous recording), so it is important that we use spatially efficient formats.
One note: the color color in the source files will be "perfect" - it is added digitally. Therefore, if there is some threshold or bitwise logical trick for this, this can also work.
EDIT : this is what worked following the VJo suggestion for a pixel shader. We used the glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)following pixel shader (for magenta as the replaced color):
"Data / Shaders / chromakey.frag":
uniform sampler2DRect src_tex_unit0;
vec4 color;
void main( void )
{
vec2 st = gl_TexCoord[0].st;
vec4 sample = texture2DRect(src_tex_unit0, st );
gl_FragColor = sample;
if((sample.r > 0.5) && (sample.g < 0.5) && (sample.b > 0.5)) {
gl_FragColor.a = 0.0;
}
}
"Data / Shaders / chromakey.vert":
void main()
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord[0];
}
C ++ proxy classes for shaders - shaderChromakey.h:
#include "ofMain.h"
#include "ofxShader.h"
#include "ofxFBOTexture.h"
class shaderChromakey{
public:
void setup(int fboW, int fboH);
void beginRender();
void endRender();
void draw(int x, int y, int width, int height);
ofxShader shader;
ofxFBOTexture fbo;
};
shaderChromakey.cpp:
#include "shaderChromakey.h"
void shaderChromakey::setup(int fboW, int fboH){
ofBackground(255,255,255);
ofSetVerticalSync(true);
fbo.allocate(fboW, fboH, true);
shader.loadShader("shaders/chromakey");
}
void shaderChromakey::beginRender(){
fbo.swapIn();
}
void shaderChromakey::endRender(){
fbo.swapOut();
}
void shaderChromakey::draw(int x, int y, int width, int height){
shader.setShaderActive(true);
fbo.draw(x, y, width, height);
shader.setShaderActive(false);
}
:
shaderChromakey chromakey;
chromakey.setup(HORIZONTAL, VERTICAL)
, :
chromakey.beginRender();
chromakey.endRender();