help with openGL, alpha blending

I’m having trouble getting 2 images to blend and I have some questions about openGL. Can someone please explain how ofSetColor() affects images and transparencies? Is it added to every pixel? And what should I set it to so that it has no affect? 0xffffff? 0x000000?

I’m trying to capture a portion of the screen, then move that portion around the screen and all the black pixels in that portion should be invisible/transparent, while all the other pixels in that portion should have no transparency. Here’s some code:

  
  
void testApp::keyPressed  (int key){  
  drawHead = true;  
  head.grabScreen(211,65,72,95); //grab a chunk of screen  
  head.setImageType(OF_IMAGE_COLOR_ALPHA); //make sure it can have alphas  
  for(int i = 3; i < head.height*head.width*4; i+=4){  
    if(head.getPixels()[i-1]==0) { //if blue is 0 make pixel transparent  
      head.getPixels()[i]=0;  
    }  
}  
  
  
void testApp::draw(){  
  
	mainImg.draw(0,0); //draw what should be a rgb image as the background (no specified transparency)  
	if(drawHead) {  //move the cut piece and redraw it with black pixels transparent  
		glPushMatrix();  
		glTranslatef(247,112+angle/3,0);  
		glRotatef(angle++,0,0,1);  
		ofEnableAlphaBlending();  
		head.draw(-36,-47,72,95);  
		ofDisableAlphaBlending();	  
		glPopMatrix();	  
       }  
}  
  
  

What i see is the cut image moving around the screen, but the black pixels are not transparent at all. Does the mainImg need to have alpha values? Does AlphaBlending need to be enabled at all times? Can I provide some more information? The images were loaded from PNGs created with MSFT paint.

Thanks

Thanks

hi Jackson,

to draw a picture at full brightness, normal colours, full alpha (no transparency), use ofSetColor( 0xffffff ) or ofSetColor( 255,255,255,255 ); ofSetColor( 0x000000 ) will not draw the image at all. basically, the pixels in whatever you draw are multiplied by the colour you set, and then depending on the current glBlendFunc is multiplied or added to the current background colour.

to do what you want, with the black pixels not drawing, you’ll need to somehow set the alpha value for all of the black pixels to 0. but, since the array returned when you read pixels back from the screen is just RGB (24 bit, no alpha) you will need to convert it to a 32 bit (RGBA) image. then you can run through it and set the new alpha byte to 0 when you find black or 255 otherwise.

Thanks Damian.

I thought this code:

  
   
head.grabScreen(211,65,72,95); //grab a chunk of screen  
 head.setImageType(OF_IMAGE_COLOR_ALPHA); //make sure it can have alphas  
 for(int i = 3; i < head.height*head.width*4; i+=4){  
    if(head.getPixels()[i-1]==0) { //if blue is 0 make pixel transparent  
      head.getPixels()[i]=0;  
 }  
  

Would grab the screen and set full transparency for all pixels with 0 as their blue component. However, when I draw the image on a red background the pixels still look black. The setImageType function should allocate the space for the new alpha values right? The black pixels all seem to have an alpha of 0 but they still show up.

Does the background I’m drawing on need to have alpha values in order for the top image to be transparent? As of now, it is of type OF_IMAGE_COLOR while the top image is OF_IMAGE_COLOR_ALPHA. Do I ever need to call ofSetColor() in my code if I don’t want anything tinted and I want all my images to determine their transparency based on the alpha values for each of their pixels? I’m also never setting a glBlendFunc, could this be a problem?

Thanks.

hi jackson,

my apologies, i didn’t read your code very closely the first time.

i think what’s missing here is a call to head.update() after you’ve changed the pixels array: http://www.openframeworks.cc/documentation?detail=ofImage#ofImage-update

Exactly! Works like a charm, thanks. It’s always a lot simpler than you think.

Thanks again.