Help with blending puzzle blocks

Started by
14 comments, last by tacostev 13 years, 12 months ago
@szecs: I feel kind of dumb now, I never thought about using the alpha channel of an image to help me with my opengl goodness. I realized now that the masking textures I've been creating were more or less 2bit alpha channels and

(GL_DST_COLOR, GL_ZERO) with the mask on the first pass then, (GL_DST_COLOR, GL_ONE) with the texture on the second pass is totally unnecessary.

I have a decent grasp of blending and I've textured plenty before. Back to your original suggestion:

(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

If I do the math for 2 cases it makes sense to me:
(using just the red channel and the alpha channel)
red source = .2
alpha source = 1
red destination = .8

we get .2*1 + (1-1)*.8 = .2 (the color of the red source!)

or we can do
red source = .2
alpha source = 0
red destination = .8

we get .2*0 + (1-0)*.8 = .8 (the color of the red destination!)

So, am I understanding this correctly? It definitely seems like what I want. I'll try it when I get home.
Advertisement
I didn't check your math. But it's a fact, that this is what you want.
Ok, I've been screwing around with this for a while and I'm still not getting it to work.

I've made a png in gimp with an alpha channel here

My texture is loaded with a GL_RGBA type as so:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);


Then, as a very simple test, I try to do two passes on a square. I'm doing a red base color and then blending the texture using the src_alpha method we talked about:

//TESTING	point_t verts[] = {		1.0f,-1.0f,0,		1.0f,1.0f,0,		-1.0f,-1.0f,0,		-1.0f,1.0f,0	};	uv_t uvs[] = {0,1,0,0,1,1,1,0};		glEnable(GL_BLEND);	glEnable(GL_TEXTURE_2D);	glDisable(GL_DEPTH_TEST);	//FIRST PASS	glBlendFunc(GL_ONE, GL_ZERO);		glEnableClientState(GL_VERTEX_ARRAY);	glColor4f(0.8f,0.0f,0.0f,1.0f);	glVertexPointer(3, GL_FLOAT, 0, verts);	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);	glDisableClientState(GL_VERTEX_ARRAY);	//SECOND PASS	glBindTexture(GL_TEXTURE_2D, texture);	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);		glEnableClientState(GL_VERTEX_ARRAY);	glEnableClientState(GL_TEXTURE_COORD_ARRAY);	glColor4f(1.0f,1.0f,1.0f,1.0f);	glVertexPointer(3, GL_FLOAT, 0, verts);	glTexCoordPointer(2, GL_FLOAT, 0, uvs);	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);	glDisableClientState(GL_TEXTURE_COORD_ARRAY);	glDisableClientState(GL_VERTEX_ARRAY);		glEnable(GL_DEPTH_TEST);	glDisable(GL_TEXTURE_2D);	glDisable(GL_BLEND);


I keep ending up with just the second pass and no red:



Any ideas on what I'm missing here?

[Edited by - tacostev on April 26, 2010 11:58:55 PM]
If you comment out the second pass, do you see the red square? My concern is that you're enabling texturing before your first pass, so I'm not sure if you're really drawing a red square, or just drawing a textured square with a null texture and all uv's at 0.0f.

Also you should disable blending on your first pass. Blending with GL_ONE, GL_ZERO is equivalent to doing no blending at all, but I don't know if the driver is smart enough to realize this (may be a performance hit for no reason).
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Exactly. Disable blending and texturing in the first pass, then enable them in the second.
This is perfect! Thank you szecs and karwosts!

Here's the code I ended up with:

[source lang='cpp']//TESTING	point_t verts[] = {		1.0f,-1.0f,0,		1.0f,1.0f,0,		-1.0f,-1.0f,0,		-1.0f,1.0f,0	};	uv_t uvs[] = {0,1,0,0,1,1,1,0};			glDisable(GL_DEPTH_TEST);	glEnableClientState(GL_VERTEX_ARRAY);	glColor4f(0.8f,0.0f,0.0f,1.0f);	glVertexPointer(3, GL_FLOAT, 0, verts);	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);	glDisableClientState(GL_VERTEX_ARRAY);	 	glEnable(GL_BLEND);	glEnable(GL_TEXTURE_2D);		glBindTexture(GL_TEXTURE_2D, texture);	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);		glEnableClientState(GL_VERTEX_ARRAY);	glEnableClientState(GL_TEXTURE_COORD_ARRAY);	glColor4f(1.0f,1.0f,1.0f,1.0f);	glVertexPointer(3, GL_FLOAT, 0, verts);	glTexCoordPointer(2, GL_FLOAT, 0, uvs);	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);	glDisableClientState(GL_TEXTURE_COORD_ARRAY);	glDisableClientState(GL_VERTEX_ARRAY);		glDisable(GL_TEXTURE_2D);	glDisable(GL_BLEND);		glEnable(GL_DEPTH_TEST);


and a screenshot of the idea working:


Now to make the blocks not look like crap...

This topic is closed to new replies.

Advertisement