Layered Images and Alpha Channel

Hey

I have drawn something on a background (like a big blue square).

I want an effect like a circle following the mouse pointer to act like a “spotlight” or mask, in that only the area of the square currently within the circle radius is visible.

I tried drawing the square with alpha = 0, then additive blending or whatever (various incantations of glBlendFunc) but could not get the effect I wanted.

I saw the ofxAlphaMask addon which is cool, but it seems a bit complex or overkill for what I am trying to do. Im not 100% on the terminology, but I basically want to define a region with alpha 100% and everything gets drawn that falls in that region, then anywhere outside that region does not show up.

How should one go about this? Is ofxAlphaMask the way to go? The difference as I see it, is it uses and alpha mask to merge two images, where as I want an alpha mask to merge my drawing and the background, if that makes sense.

Cheers

OK

I’ve done some reading and looking at the example here http://forum.openframeworks.cc/t/masking-image-fade-infade-out-with-face-detection/6373/0

I have got this working using 2 images, but what I want is to mask what has been currently drawn, e.g. the red circle.

I tried using dispimg.grabScreen() to get the current screen but it doesnt seem to work. So close yet so far …

It seems like I could use an fbo but that seems a little overkill, any idea why using grabScreen() does not work? Is there some other way I could bind the current drawing as a texture?

  
  
string alphapath = "alpha-test1.bmp";  
string disppath = "disp-test2.jpg";  
  
ofImage alphamask;  
ofImage dispimg;  
//--------------------------------------------------------------  
void testApp::setup(){  
	alphamask.loadImage(alphapath);  
	alphamask.resize(ofGetWidth(), ofGetHeight());  
  
	dispimg.loadImage(disppath);  
	dispimg.resize(ofGetWidth(), ofGetHeight());  
	ofBackground(0, 0, 0);  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
	ofPushMatrix();  
	ofTranslate(ofGetWidth()/2, ofGetHeight()/2,0);  
	ofSetColor(200, 40, 40);  
	ofCircle(0, 0, 100);  
	ofPopMatrix();  
  
	//dispimg.grabScreen(0, 0, ofGetWidth(), ofGetHeight());  
	  
	ofSetColor(255, 255, 255);  
	ofEnableAlphaBlending();  
  
	glActiveTexture(GL_TEXTURE0);  
	dispimg.getTextureReference().bind();  
	glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);    
	glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);   
	  
	glActiveTexture(GL_TEXTURE1);  
	alphamask.getTextureReference().bind();  
	glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);    
	glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_BLEND);   
		  
	glBegin(GL_QUADS);  
  
	glMultiTexCoord2f(GL_TEXTURE0, 0.0f, ofGetHeight());  
	glMultiTexCoord2f(GL_TEXTURE1, 0.0f, ofGetHeight());  
	glVertex3f(0, ofGetHeight(), 0);  
	glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);  
	glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);  
	glVertex3f(0, 0, 0);  
	glMultiTexCoord2f(GL_TEXTURE0, ofGetWidth(), 0.0f);  
	glMultiTexCoord2f(GL_TEXTURE1, ofGetWidth(), 0.0f);  
	glVertex3f(ofGetWidth(), 0.0f, 0.0f);	  
	glMultiTexCoord2f(GL_TEXTURE0, ofGetWidth(), ofGetHeight());  
	glMultiTexCoord2f(GL_TEXTURE1, ofGetWidth(), ofGetHeight());  
	glVertex3f(ofGetWidth(), ofGetHeight(), 0);  
	  
	glEnd();  
	glFlush();  
	  
	alphamask.getTextureReference().unbind();  
	glActiveTexture(GL_TEXTURE0);  
	dispimg.getTextureReference().unbind();  
  
}  
  

Another question, if my alpha mask is going to be fixed, is this the best way to do it? I am still a bit of newb so any suggestions are welcome.

Cheers

alpha-test1.bmp.zip

ok!!!

  
  
	ofTexture t;  
	t.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA);  
	t.loadScreenData(0, 0,ofGetWidth(), ofGetHeight());  
  

and binding that as TEXTURE0 works

but not with my alphamask image that is a bmp with an alpha channel!

it works if i use a straight up png!!

what is this madness?!!! :slight_smile:

I thought the png has no alpha channel so blending that wouldn’t work.

But clearly it is blending RGBA.

And the bmp with just an Alpha channel blended when using an image, but not when using the ofTexture. What is going on there?

  
  
void testApp::draw(){  
  
	ofPushMatrix();  
	ofTranslate(ofGetWidth()/2, ofGetHeight()/2,0);  
	ofSetColor((int)(255 * ofGetMouseY()/(float)ofGetHeight()), 40, (int)(255 * ofGetMouseX()/(float)ofGetWidth()));  
	ofCircle(0, 0, 100);  
	ofPopMatrix();  
	  
	ofTexture t;  
	t.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA);  
	t.loadScreenData(0, 0,ofGetWidth(), ofGetHeight());  
	  
	ofSetColor(255, 255, 255, 255);  
	ofEnableAlphaBlending();  
	  
	glActiveTexture(GL_TEXTURE0);  
	t.bind();  
  
	glActiveTexture(GL_TEXTURE1);  
	alphamask.getTextureReference().bind();  
  
	glBegin(GL_QUADS);  
  
	glMultiTexCoord2f(GL_TEXTURE0, 0.0f, ofGetHeight());  
	glMultiTexCoord2f(GL_TEXTURE1, 0.0f, ofGetHeight());  
	glVertex3f(0, ofGetHeight(), 0);  
	glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);  
	glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);  
	glVertex3f(0, 0, 0);  
	glMultiTexCoord2f(GL_TEXTURE0, ofGetWidth(), 0.0f);  
	glMultiTexCoord2f(GL_TEXTURE1, ofGetWidth(), 0.0f);  
	glVertex3f(ofGetWidth(), 0.0f, 0.0f);	  
	glMultiTexCoord2f(GL_TEXTURE0, ofGetWidth(), ofGetHeight());  
	glMultiTexCoord2f(GL_TEXTURE1, ofGetWidth(), ofGetHeight());  
	glVertex3f(ofGetWidth(), ofGetHeight(), 0);  
	  
	glEnd();  
	  
	alphamask.getTextureReference().unbind();  
	glActiveTexture(GL_TEXTURE0);  
	t.unbind();  
}  
  
  

Also I could not see any material effect of the glTexEnvF(), so it went.