views:

486

answers:

1

How can I efficently interpolate per-pixel two textures A and B by a dynamic texture C and draw them on a simple quad? Multi-pass algorithms accepted.

I've had moderate success calculating the C texture per-frame on the CPU and uploading it with glTexImage2D into an alpha-only texture.

While this worked, performance was lacking and I had to reduce the dimensions of C to half of the full size to get around the copying bandwidth bottleneck.

So, for performance reasons, I'm trying to do all of my C texture updates using render-to-texture.

I was able to set up the necessary buffers for rendering, but fundamentally, I get a texture in RGB or RGBA format with the mask encoded in lightness/RGB information, not alpha.

How do I convert this efficiently into the alpha texture I need to plug into the texturing pipeline? Keep in mind that there is no programmable pipeline (shaders) and only two texture units available on the iPhone.

Update: A and B are RGB-only textures, ie no alpha.

+5  A: 

Given that textures A and B are RGB images, then perhaps you can make one of them into an RGBA image, and render the mask in the alpha channel of one image. This gets you within the iPhone's limit of two texture units, allowing you to do this in one pass, without blending.

GLSL pseudocode:

vec4 a = texture2D(textureA, texcoord);
vec4 b = texture2D(textureB, texcoord);
gl_FragColor = vec4(a.rgb * a.a + b.rgb * (1-a.a), dont_care.a);

Texture Environment for Unit 0: (samples RGB image B, and passes it on to the next stage)

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

Texture Environment for Unit 1: (image B are available in Cp and 'Ap' source. A is available in 'Cs'. Mask is available in 'As'. see Table 3.15 in the GL spec).

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

Read section 3.7.12 Texture Environments and Texture Functions in the OpenGL ES 1.1 spec for full information.

To actually render your scene into the alpha channel of the image, it may be helpful to use glColorMask(), to allow writing to only the alpha channel. How you actually get the data into that channel really depends on exactly what you're drawing to generate that mask.

Frogblast
Awesome post. Was thinking of doing something like that.Neither A nor B has an alpha channel.How can I "render C into the unused alpha channel of one image"?
Andrew Pouliot