Trouble with alpha mask -- 1 vide on top of another

This problem should be a no-brainer for many of you. My problem is simple: I have two media (one video, one image), each with an alpha mask coming from a greyscale video. The goal is for the first video to play with its mask (which works) and then to have the other image play on top of it with its mask. The problem is that the second media, the image, maintains black pixels from the mask, and therefore shows over the entire thing. The first video is no longer visible.

// vids
ofVideoPlayer storm, stormOutMatte, redInMatte;
ofImage colorMatte;

glEnable(GL_BLEND);


//--------------------------------------------------------------
void ofApp::update(){    

  // storm cloud shrinks
  storm.update();

  // if storm out matte hasnt started playing yet...
  if (!stormOutMatte.isPlaying()) {
      stormOutMatte.play();
  }

  stormOutMatte.update();

  // same goes for red in matte...
  if (!redInMatte.isPlaying()) {
      redInMatte.play();
  }

  redInMatte.update();
    
}

//--------------------------------------------------------------
void ofApp::draw(){
  // storm goes OUT
  storm.getTexture().setAlphaMask(stormOutMatte.getTexture());
  storm.draw(0, 0, ofGetWidth(), ofGetHeight());

  // red comes IN
  colorMatte.getTexture().setAlphaMask(redInMatte.getTexture());
  colorMatte.draw(0, 0, ofGetWidth(), ofGetHeight());
    
}

Ok I got something to work by iterating thru the pixel array, but this is still on the CPU I guess? If someone wants to let me in on how to do this on the GPU I would be very grateful :wink:

edit: should I include ofEnableAlphaBlending(); in the setup?

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		
    ofVideoPlayer vidMask, vidContent;
    ofImage framePixels;    // from content
    ofImage alphaPixels;    // from mask
    
    unsigned char * outPixels;
};
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    
    // load in mask video and content video
    vidMask.load("mask.mp4");
    vidContent.load("content.mp4");
    
    // play em both
    vidMask.play();
    vidContent.play();
    
    // outPixels will store RGBA so it needs 4x the image dimensions
    outPixels = new unsigned char [960*540*4];
    
}

//--------------------------------------------------------------
void ofApp::update(){
    
    // update videos every frame of course
    vidMask.update();
    vidContent.update();
    
    // create a char array for the content and mask vids, to get at the
    // pixel data
    unsigned char * contentPixels = vidContent.getPixels();
    unsigned char * maskPixels = vidMask.getPixels();
    
    // iterate...
    for(int i = 0; i < 960*540; i++) {
        
        // outPixels is an array at 4x, while content and mask are at 3x,
        // since they are wimpy RGB
        outPixels[i*4+0] = contentPixels[i*3+0];
        outPixels[i*4+1] = contentPixels[i*3+1];
        outPixels[i*4+2] = contentPixels[i*3+2];
        
        // so for the alpha... R G and B are all the same on the mask image
        // so just grab red arbitrarily and use that for our alpha
        outPixels[i*4+3] = maskPixels[i*3+0];
        
    }
    
    // inject outPixels into framePixels ofImage type, using alpha of course
    framePixels.setFromPixels(outPixels, 960, 540, OF_IMAGE_COLOR_ALPHA);
    
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    ofClear(0,255);
    
    // draw!
    framePixels.draw(0,0);
    framePixels.draw(100,0);
}

maybe if you post a small sample project i could take a look at it.

in the meantime.
maybe you did not allocate your ofImage correctly?

ofImage colorMatte;
colorMatte.allocate(320, 240, OF_IMAGE_COLOR_ALPHA);

the blending should certainly be possible with textures, and there should be no need to go via CPU.

s.

Thanks for the tip. Still no dice, the 2nd video is drawn on top and blackness is rendered–

graysonearle.com/stuff/videoAlpha.zip

i think the problem is that your mask videos have a black background but would rather need a alpha == 0 background.
i tried replacing your video with a generated FBO as mask and that worked.

maybe you can change your source video.
or you try to use chroma keying to remove the black via some sort of shader.

you could also take a look at this example and see if it helps you
/Applications/of_v0.9.3_osx_release/examples/gl/alphaMaskingShaderExample

But isn’t the point of a mask to define what parts of the resulting image should be transparent?