Blending problem (solved)

Started by
8 comments, last by Eldritch 18 years, 10 months ago
Hello there folks! Just had my hair torn off as I have tried to use the extremely crappy blending stuff in OpenGL, which apparently does not seem to work one bit. Here is what I am trying to do: I have two textures: 1. A texture that is black except for a half circle in the center in white. 2. A map of a city. Here is what I want to do: I want to put the first texture over the map and only draw the portion of the map that is covered by the white half circle. How would this be possible? I have tried every single definition for both source and destination in the glBlendFunc() method, I have tried alpha testing (another thing that is broken), and I have tried alpha masking (applying a mask to the first texture, even though that itself is a mask).. but this only f'cked everything up, even the map got affected by this. So.. I am in need of serious help.. I wish there was a method with which you could simply get rid of a certain color from the stuff you want to draw.. e.g. glColorMask3ub(255, 0, 0); glEnable(GL_COLOR_MASK); draw... glDisable(GL_COLOR_MASK); Something like that.. (the example masks all red color).. it would be so much easier and way cool. You'd have much better control over color masking. Anyways.. any help is greatly appreciated. [Edited by - Eldritch on June 21, 2005 5:34:17 AM]
Advertisement
Upload the black and white image as an alpha texture, then use texture combiners to take the color from the city map and the alpha from the alpha map, and then use alpha test to reject the fragments from the "black" area.
Hmm, sounds interestingly easy, but I do have some questions (eller frågor som vi skulle säga på svenska.. hehehe):

"Upload the black and white image as an alpha texture"

What do you mean with this? Should I load it differently somehow? I am using bitmaps, if that is of any importance.

"then use texture combiners"

I recognize this.. is there such a thing called "texture combiners" I can ready up on?

"then use alpha test to reject the fragments from the "black" area"

Well, I want to reject the white part on the half circle mask texture (#1) and draw the part of the map that it overlaps there instead...
bob is correct, u need to create an 8 bit alpha texture in a paint program
*bitmaps are different to textures
*colormask is something completely different
Quote:Original post by Eldritch
Hmm, sounds interestingly easy, but I do have some questions (eller frågor som vi skulle säga på svenska.. hehehe):

Sure (eller Javisst som vi säger på svenska).

Quote:Original post by Eldritch
"Upload the black and white image as an alpha texture"

What do you mean with this? Should I load it differently somehow? I am using bitmaps, if that is of any importance.

Since the image is black and white, I assume it's a single channel image (that is, you don't use an RGB image, where all three channels are the same). Then you specify GL_ALPHA as the internal format for glTexImage. If the image is indeed a three channel RGB image, then convert it to a single channel image.

Quote:Original post by Eldritch
"then use texture combiners"

I recognize this.. is there such a thing called "texture combiners" I can ready up on?

It's about multitexturing, so I sugegst you start with reading up on multitexturing if you haven't already. Then you can read about the texture combiners here. Keep in mind that this is a techincal specification, not a toturial, so it can be a bit difficult. I'm sure NeHe have some tutorials aswell.

Basically, what you need is something like this.
// Texture unit 0: pass through alpha channel from texture to next unit. rgb is irrelevant in this unit.glActiveTexture(GL_TEXTURE0);glBindTexture(alpha map ID goes here);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);// Texture unit 1: pass through alpha from previous unit and color from texture to next unit (output in this case).glActiveTexture(GL_TEXTURE1);glBindTexture(city map ID goes here);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);

This is taken from my head and it may not work entirely correct, but it describes the main idea.
Quote:Original post by Eldritch
"then use alpha test to reject the fragments from the "black" area"

Well, I want to reject the white part on the half circle mask texture (#1) and draw the part of the map that it overlaps there instead...


What part you want to reject doesn't really matter at this point if you do it as described above. Just reject fragmens with alpha value of 0 or 1 depending on what part you (don't) want.
glAlphaFunc(GL_EQUAL, 1); // keep alpha values equal to 1, which means from the white part.

Change 1 to 0 and you will keep the black part instead.
Ah, yes, now I recognize it. Did some multitexturing before, but it's amazing how fast I forget stuff. Thanks, will check up on that stuff :)

Stort tack!
Converting a texture to a single channel, here is what I did, and it turned out really wrong:

I converted the bitmap from RGB/8 in Photoshop to Greyscale/8.

I wrote this bitmap loading function:

// Load a single channel bitmap (greyscale).int Textures_LoadMonoTexture(char *filename, int id){	int status = 0;	AUX_RGBImageRec *Graphic[1];	memset(Graphic, 0, sizeof(void *)*1);	if (Graphic[0] = LoadBitmap(filename)) {		status = 1;		glGenTextures(1, &textures[id]);		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, Graphic[0]->sizeX, Graphic[0]->sizeY, 0,					 GL_ALPHA, GL_UNSIGNED_BYTE, Graphic[0]->data);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);		textureRatio[id] = Graphic[0]->sizeX;		char tmp[100];		sprintf(tmp, "Loaded texture %s\n", filename);		Log(tmp);	}	if (Graphic[0]) {		if (Graphic[0]->data) {			free(Graphic[0]->data);		}		free(Graphic[0]);	}	return status;}


Perhaps I missed something? Now, the texture appears as a big white rectangle :)
Took another approach. Wrote a TGA loader and then I use the alpha-channel to make the mask appear as I want to, and now it works :)

Thanks a bunch!
Quote:Original post by Eldritch
glGenTextures(...);
glTexImage2D(...);
I know you've already moved onto TGAs and got that working, but the thing that stands out about your 8bit bmp loader there is that you aren't binding the texture before you try to send data to it with glTexImage2D.
Now that's something I completely forgot :)

But it's strange though, I simply copy-pasted the regular bitmap loading function and changed the values... but anyways, TGA's did the trick more easily (and allows for better control over the alpha channel so the graphics designer can specify them easier).

This topic is closed to new replies.

Advertisement