PDA

View Full Version : Multitexture with independent texture color blend



pascalbamford
10-15-2009, 11:09 AM
Failing at this after too many days of experimenting/googling/red book digging:

I have several monochromatic (grayscale) source images that I would like to each blend with a different color and then render all to the screen on a simple quad.

I'm trying to use multitexturing with a pre-defined blend of each texture to a unique color. Here is the gist for two of the textures:

float[] red = { 1f, 0f, 0f, 1f };
float[] green = {0f, 1f, 0f, 1f};

// (ultimately, with your help, I'll have 5-9 textures and several colors - oranges, purples etc.)

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, redTexture.getID());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, red, 0);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, greenTexture.getID());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, green, 0);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

// The rendering is boilerplate.

The result I get is a great superposition of the two textures on the screen (I've done this for as many as I want) but they are all colored with the last color defined in texenv rather than independently colored (i.e. both textures are colored green in the example above).

I was under the impression that each texture environment would be independent using glActiveTexture(), but I'm missing something. Perhaps I need to identify each GL_CONSTANT uniquely???

I had a quick crack at the glBlend - equivalent results.
Also tried glSecondaryColor - brain not big enough to understand the mess that comes out.

I've only really found alpha blending examples which really aren't what I'm after. I need tex1*color1 + tex2*color2 + ....
(the bright areas of each texture are rarely co-localized spatially - lots of low gray values/background in each texture).

Help?

THANKS.

ZbuffeR
10-15-2009, 03:53 PM
Do you have a real reason not to use a GLSL fragment shader to do this ?
Is would be very easy to perform whatever complex mapping from texture to color, add, blend, etc.
Multitexture combine is very rigid.

pascalbamford
10-15-2009, 04:02 PM
Thanks for the reply.

No good reason - just pure ignorance. Any chance you would be so kind as to point me to a relevant example while I start to dig anew...? I'm finding it difficult to find a good example.

Alfonse Reinheart
10-15-2009, 05:18 PM
I need tex1*color1 + tex2*color2 +

This is a very difficult formula to do with standard texenv commands. Each ENV step can only perform one math operation. So it can multiply or add, but it can't do both.

I'm pretty sure that there is only one constant color for the texenv. But it has been awhile.

arekkusu
10-15-2009, 09:16 PM
DOT3 could make this easier, if your inputs are the same size. Merge greyscale textures into RGB:
tex1 -> tex0.r
tex2 -> tex0.g
tex3 -> tex0.b

then
tex0 DOT (weight0.rgb) will multiply and sum three greyscale textures at a time.

You still have to lerp multiple units if you need more than three inputs.

pascalbamford
10-16-2009, 09:34 AM
From initial reading, it seems that GLSL switches off the fixed function pipeline?

That could be my real reason right there because I'm writing this within a framework that uses the fixed pipeline to draw widgets on top of the image I'm rendering (FengGUI/JOGL). If using GLSL turns that off I guess I'll lose the rest of my rendering...

Looks like I'll use the CPU. How dull.

pascalbamford
10-16-2009, 09:36 AM
DOT3 could make this easier, if your inputs are the same size. Merge greyscale textures into RGB:
tex1 -> tex0.r
tex2 -> tex0.g
tex3 -> tex0.b

then
tex0 DOT (weight0.rgb) will multiply and sum three greyscale textures at a time.

You still have to lerp multiple units if you need more than three inputs.


Looks promising...don't suppose you can point me at a code snippet for the interpolation across more than three inputs?

ZbuffeR
10-16-2009, 12:08 PM
it seems that GLSL switches off the fixed function pipeline?
To be more precise, you can't use both glsl and fixed function at the same time. But you don't render your composited textures at the same time as the GUI, right ?
You can enable GLSL shader, render your composited stuff, disable GLSL shader before returning to the framework.

Alfonse Reinheart
10-16-2009, 12:39 PM
To be more precise, you can't use both glsl and fixed function at the same time.

To be even more precise, you cannot use them at the same time on the same stage. You can build a program with no vertex shader but has a fragment shader. You would get fixed-function vertex processing, but fragment shader fragment processing.

You need to use specific inputs for your fragment shader to make this work.

pascalbamford
10-16-2009, 03:29 PM
Oh! Great! Thanks very much to both of you for your help. I'll get this going...

pascalbamford
10-17-2009, 10:29 AM
Working flawlessly with GLSL. Thanks again! 100x faster than the CPU version.

:D

Only gotcha was having to set glActiveTexture(0) before any of the FengGUI calls.