Jump to content
  • Advertisement
Sign in to follow this  
Cakemeister

OpenGL Need help with masking

This topic is 3850 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I want to be able to composite one image (the "object" image) onto another (the "background" image) using a third grayscale image (the "mask" image) as the alpha channel. ImageMagick has a command for this: composite image1 image2 mask result Unfortunately I don't know how to post images here, but I've zipped up an example of what I want to do at http://cpmaker.mameprojects.com/files/images.zip I have seem some examples of masking in OpenGL, but they usually involve a zero or one mask, not a grayscale image. What I have done so far is loading the object image as a texture, then copying the bytes from the mask image into the object's alpha channel, then blending the background and object images with GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA. That is slow and it also depends on the object and mask images being the same size. What I want to do is to load the object and mask images as textures and somehow render them as quads and have OpenGL do any necessary resizing of the images. I would appreciate any help, links to examples, or any kind of code I can use. Regards, Cakemeister

Share this post


Link to post
Share on other sites
Advertisement

Hi,

So your problem is that your alpha mask isn't always the same size as the images ? Also, is the performance a concern ? I mean, what is the purpose of this program ?

Practically, you could create 3 different textures (the background, the foreground and the alpha). With the correct texture operations you should be able to make the system to use the separate alpha texture for the texture blending. This would work even with 3 different sized textures.

Usually alpha map has all the shades of grey available rarely/never just black or white.

Cheers!

Share this post


Link to post
Share on other sites
My program is a front end application. It takes a list of items, displays them, and launches programs based on the users's input.

The program is meant to be used in a MAME cabinet. MAME is an arcade game emulator, which runs the exact code which ran on Pacman, Centipede, and other arcade games. When the user selects a game, my frontend launches MAME or another emulator.

My front end application can take an arbitrary set of images, text, and whatever and display them according to what the user has selected in the skin file. This "external alpha blending" is a feature that I want to add.

The background in the frontend is the default framebuffer. I could create a texture from it with glReadPixels, but I want to avoid that if possible, too slow.

If you want to check out my frontend there is a demo, which is a hefty 100+ megabytes: http://cpmaker.mameprojects.com/files/khdemo_full.zip

Share this post


Link to post
Share on other sites

Hi,

So your application is totally OpenGL based and you want to blend nicely some images over a background image?

At this point I am not totally sure what is the trouble here. I mean, you draw your front end background first, then you'll draw another image on top of it with an alpha map. It doesn't require any complex render states, and it should be rather efficient.

I am not sure why you'd need glreadpixels or why do you need to manipulate texture alpha channel.

Can you show a little bit of some code? or point out a problematic solution?

Cheers!

Share this post


Link to post
Share on other sites
Quote:
Original post by kauna

Hi,

So your application is totally OpenGL based and you want to blend nicely some images over a background image?

At this point I am not totally sure what is the trouble here. I mean, you draw your front end background first, then you'll draw another image on top of it with an alpha map. It doesn't require any complex render states, and it should be rather efficient.

I am not sure why you'd need glreadpixels or why do you need to manipulate texture alpha channel.

Can you show a little bit of some code? or point out a problematic solution?

Cheers!


Alpha map? What's that?

Basically, my code does something like:

1) ... sort objects by z coordinate...
2) glBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3) for (all objects)
{
glBegin(GL_QUADS);
... standard map texture to screen coordinates
glEnd();
}

Is there a glBlendMode that copies only the alpha channel?

When I last tried just a standard masking operation, which was:
glBlendMode(GL_SRC_ALPHA, GL_ZERO);
--- draw mask image ---
glBlendMode(GL_ONE, GL_ONE);
--- draw object image ---

This would leave black areas around the masked area where the background should have shown through.

I can post some real source code if you need something more specific.

Share this post


Link to post
Share on other sites


glBlendMode(GL_SRC_ALPHA, GL_ZERO);
--- draw mask image ---
glBlendMode(GL_ONE, GL_ONE);
--- draw object image ---





Hi, yeah now I figure out your problem. You'll need to draw the mask and the texture in one pass (ie. have both textures binded at the same time with the required render states).



//ie.

glBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-- draw object image with alpha map





An Alpha map is the same as your mask, it is usually a gray scale image, since alpha information needs only one channel.

I don't know the OpenGL syntax for setting up the correct texturing parameters, but practically you'll need to use multitexturing, get diffuse color from the texture, and alpha from the mask image. That should be all, and your texture map and mask can have different pixel resolutions.

Best regards!

Share this post


Link to post
Share on other sites
I'm very close. After studying the Nehe tutorials 6 and 22, I came up with this display code:


// clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glPushMatrix();
glTranslatef(0.0, 0.0, -5.0);

// first draw the background (image 1)
glBindTexture(GL_TEXTURE_2D, image_1_texture);

glBegin(GL_QUADS);
glTexCoord2f (0.0f, 0.0f);
glVertex3f( -1.0f, -1.0f, 1.0f);

glTexCoord2f(0.0f, 1.0f);
glVertex3f( -1.0, 1.0f, 1.0f);

glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f,1.0f, 1.0f);

glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);

glEnd();

#if 1
// now draw the object image (image 2) masked by the mask image
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, image_2_texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mask_texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_BLEND);

glBegin(GL_QUADS);
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f);
glVertex3f( -1.0f, -1.0f, 1.1f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f);
glVertex3f( -1.0f, 1.0f, 1.1f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f);
glVertex3f( 1.0f,1.0f, 1.1f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.1f);

glEnd();

#endif
glPopMatrix();

glFlush();



If the ifdef is changed to a zero, the background image displays as expected. When the ifdef is a one, the bottom half of the image shows the object image (image #2) as expected, also, but the top half is blacked out.

I think the problem is somewhere in the multitexturing calls.

Share this post


Link to post
Share on other sites

Hi,

I think that you are very close to the solution too, but too bad I cannot help you with the required OpenGL calls.

Good luck!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!