(fixed) Alpha mask animation

Hey there,
I’ve got a little problem adding an alpha mask to an animation…
I’m drawing the animation on an ofFbo ‘canvas’ (which I convert to an ofImage) which I later apply the mask to using the canvas and a black-and-white ofImage (which is the mask)

The thing is, the canvas works fine, just draws the image on a transparent background and when I draw this ([tt]canvas.draw(0,0)[/tt]) I just get the transparent background.

When I add it to the shader though, it doesn’t draw the area I don’t want to draw on, which is great, but what it does is adding a white background to the rest of the image I want to draw.

This is the first time I actually work with shaders, fbo and try to mask stuff so I would really appreciate any tips… I might just be doing things the wrong way!

Thanks for reading this, hope one of you can help me out!

Cheers!

  
  
#include "testApp.h"  
#include "MSAInterpolator.h"  
  
MSA::Interpolator1D             spline1D;  
MSA::Interpolator1D             sizeSpline;  
MSA::Interpolator2D		spline2D;  
MSA::Interpolator3D		spline3D;  
  
ofImage                         img;  
ofShader                        maskShader;  
ofImage                         note;  
ofImage                         mask;  
ofFbo                             canvas;  
  
MSA::InterpolationType			        interpolationType	        = MSA::kInterpolationCubic;  
bool							useLength			= true;  
  
float							imagePosPerc	= 0.5;			// 0....1 percentage of how far along the 3D path the sphere is  
float							imageSpeed = 0.0002f;  
  
//--------------------------------------------------------------  
void testApp::setup(){  
    ofEnableAlphaBlending();  
    ofSetFrameRate(30);  
    spline3D.push_back(MSA::Vec3f(247,555,0));  
    spline3D.push_back(MSA::Vec3f(417,565,0));      
    spline3D.push_back(MSA::Vec3f(480,309,0));      
    spline3D.push_back(MSA::Vec3f(518,348,0));          
    spline3D.setUseLength(true);  
	  
    spline1D.push_back(-20.0f);  
    spline1D.push_back(0.0f);  
    spline1D.push_back(30.0f);  
  
    spline1D.push_back(20.0f);  
    sizeSpline.push_back(0.0f);  
    sizeSpline.push_back(.9f);  
    sizeSpline.push_back(1.0f);  
    sizeSpline.push_back(.9f);      
    sizeSpline.push_back(0.1f);  
  
    // SETTING UP SHADER AND IMAGES  
  
    note.loadImage("note.png");  
    mask.loadImage("mask.png");  
    canvas.allocate(ofGetWidth(), ofGetHeight());  
    img.allocate(ofGetWidth(), ofGetHeight(), OF_IMAGE_COLOR_ALPHA);  
    maskShader.load("composite");  
	maskShader.begin();  
	maskShader.setUniformTexture("Tex0", img.getTextureReference(), 0);  
	maskShader.setUniformTexture("Tex1", mask.getTextureReference(), 1);  
	maskShader.end();  
}  
  
  
//--------------------------------------------------------------  
void testApp::draw() {  
        int numSteps = 10;  
	if(numSteps<10) numSteps = 10;  
	float spacing = 1.0/numSteps;	  
	  
	// draw image moving along 3D path  
	MSA::Vec3f imagePos = spline3D.sampleAt(imagePosPerc);  
        float rotation = spline1D.sampleAt(imagePosPerc);  
        float size = sizeSpline.sampleAt(imagePosPerc);  
  
  
  
    // DRAWING IN THE CANVAS AND CONVERSION TO IMAGE  
  
    canvas.begin();  
    ofClear(255, 255, 255, 0);  
    ofPushMatrix();  
    ofTranslate(imagePos.x, imagePos.y);  
    ofRotate(rotation);  
    note.draw(-note.width/2, -note.height/2, note.width*size, note.height*size);  
    ofPopMatrix();      
    canvas.end();  
    ofPixels pixels;  
    canvas.readToPixels(pixels);  
    img.setFromPixels(pixels);  
    img.update();  
  
//    works fine if I draw the image this way  
//    img.draw(0,0);  
  
//    when I use the mask though I get the white background  
    maskShader.begin();  
      
    glBegin(GL_QUADS);  
    glMultiTexCoord2d(GL_TEXTURE0_ARB, 0, 0);  
    glMultiTexCoord2d(GL_TEXTURE1_ARB, 0, 0);		  
    glVertex2f(0, 0);  
      
    glMultiTexCoord2d(GL_TEXTURE0_ARB, ofGetWidth(), 0);  
    glMultiTexCoord2d(GL_TEXTURE1_ARB, ofGetWidth(), 0);		  
    glVertex2f( ofGetWidth(), 0);  
      
    glMultiTexCoord2d(GL_TEXTURE0_ARB, ofGetWidth(), ofGetHeight());  
    glMultiTexCoord2d(GL_TEXTURE1_ARB, ofGetWidth(), ofGetHeight());  
    glVertex2f( ofGetWidth(), ofGetHeight());  
      
    glMultiTexCoord2d(GL_TEXTURE0_ARB, 0, ofGetHeight());  
    glMultiTexCoord2d(GL_TEXTURE1_ARB, 0, ofGetHeight());		  
    glVertex2f( 0, ofGetHeight() );  
	  
    glEnd();  
  
    glActiveTexture(GL_TEXTURE1_ARB);  
    mask.getTextureReference().unbind();  
	  
    glActiveTexture(GL_TEXTURE0_ARB);  
    canvas.getTextureReference().unbind();      
      
    maskShader.end();  
  
}  
  
void testApp::update() {  
        // just moving the image, nothing quite relevant  
	imagePosPerc += imageSpeed;  
	if(imagePosPerc > 1) {  
		imagePosPerc = 1;  
		imageSpeed *= -1;  
	} else if(imagePosPerc < 0) {  
		imagePosPerc = 0;  
		imageSpeed *= -1;  
	}  
  
}  
  

![](http://forum.openframeworks.cc/uploads/default/2402/using shader.png)

![](http://forum.openframeworks.cc/uploads/default/2404/drawing the image.png)

Fixed it!

Changed the following line in the ‘composite.frag’ file:
[tt]gl_FragData[0] = vec4(image.rgb,composite.r);[/tt]
to:
[tt]gl_FragData[0] = vec4(image.rgb,composite.r*image.a);[/tt]

Not really sure what I’m actually doing, but I guess this stuff defines the final color of the pixels in the shader from the given values… At least it’s working!

Thanks for reading anyway!

  
/*  
 *  ofxAlphaMask  
 *  
 * Example by James George, [http://www.jamesgeorge.org](http://www.jamesgeorge.org)  
 * in collaboration with FlightPhase [http://www.flightphase.com](http://www.flightphase.com)  
 *  
 * Permission is hereby granted, free of charge, to any person  
 * obtaining a copy of this software and associated documentation  
 * files (the "Software"), to deal in the Software without  
 * restriction, including without limitation the rights to use,  
 * copy, modify, merge, publish, distribute, sublicense, and/or sell  
 * copies of the Software, and to permit persons to whom the  
 * Software is furnished to do so, subject to the following  
 * conditions:  
 *  
 * The above copyright notice and this permission notice shall be  
 * included in all copies or substantial portions of the Software.  
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES  
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,  
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  
 * OTHER DEALINGS IN THE SOFTWARE.  
 *  
 * ----------------------  
 *  
 * ofxAlphaMask is not really an addon, but an example  
 * of how to use a shader to have one image become the alpha  
 * channel of another.  
 */  
   
uniform sampler2DRect Tex0, Tex1; //these are our texture names, set in openFrameworks on the shader object in set up  
  
void main (void)  
{  
	//sample both textures  
	vec4 image = texture2DRect(Tex0, gl_TexCoord[0].st);  
	vec4 composite = texture2DRect(Tex1, gl_TexCoord[1].st);  
	  
	//use the color from the image, but use the r channel of the mask as the alpha channel of our output  
	gl_FragData[0] = vec4(image.rgb,composite.r*image.a);        
	  
}