PDA

View Full Version : Multi-color Earth Texture to monocolor how ?



Tiaan
11-19-2005, 01:15 AM
Hi, I have an app using an earth texture with many colors. In some circumstances, I want the display to show it as two colors only e.g. green and blue without having to load a special monocolor texture. The high color texture is predominantly blue over the ocean and green/brown over land. Is there some magic drawing technique to reduce the colors in such a manner to achieve this ?

11-19-2005, 05:27 AM
You could modulate the texture with a cyan (0,1,1) primary color or texture if all you want to do is eliminate red.

Tiaan
11-19-2005, 07:10 AM
Sorry for asking more of your time but could you perhaps explain a bit more in terms of the relevant opengl calls to use ?

11-19-2005, 09:14 AM
The default texture environment mode is modulate:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

This means that your texture in unit 0 is modulated (multiplied) by the incoming primary color (glColor* for environment 0).

So you could do this:

// Assuming texture unit 0 is active
glBindTexture(GL_TEXTURE_2D,earthTexID);
glColor3f(0,1,1);
// Draw Earth...I'm not sure that's what you have in mind, but that's the general idea. You can do lots of cool stuff with the texture env combiners. Check out the OpenGL specification 2.0, starting on page 182. This is also covered in the redbook.

Close?

Tiaan
11-19-2005, 12:17 PM
thanks. I will experiment with it. first tries yielded no apparent results but I will shuffle things around a bit

Tiaan
11-19-2005, 01:12 PM
How can I set modulate when the texture is in the unit activated by
glActiveTextureARB(GL_TEXTURE0_ARB);
Nothing I seem to do has any effect when performing a glColor3f(0,1,1) prior to drawing

11-19-2005, 01:18 PM
Can you post some code so we can get a better feel for what you're doing?

If it matters, I'm starting to wig a little from lack of rem sleep... ;)

Tiaan
11-19-2005, 02:41 PM
to load texture ...

assert(t1.load("globe2048x1024.png"));
t2 = QGLWidget::convertToGLFormat(t1);
glGenTextures(1, &base[0]);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, base[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 3, t2.width(), t2.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, t2.bits());
if ((e = glGetError()) != GL_NO_ERROR)
{
fprintf(stderr, "OpenGL error %d\n", e);
exit(1);
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

... and in the draw OpenGL frame part ...

glActiveTextureARB(GL_TEXTURE0_ARB);
if (sizes[xi][yi])
{
glBindTexture(GL_TEXTURE_2D, textures[xi][yi]);
useBase = false;
}
else
glBindTexture(GL_TEXTURE_2D, base[0]);


glColor3f(0, 1, 1);

glBegin(GL_QUADS);

double z1 = cos(theta)*r1;
double x1 = sin(theta)*r1;
if (useBase)
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (theta+M_PI)/(2*M_PI), tr>
else
glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
if (selected->haveTexture())
glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (theta+M_PI)/(2*M_PI), tr>
glVertex3f(x1, y1, z1);
... // add other three corners of quad
glEnd();


sorry, the code indentation is hideous but this multi-line edit box is a bit limited. hope you get the idea and thanks for the help

11-20-2005, 08:20 AM
Your code looks OK but the meat is missing at the end, where you actually supply the vertex data, and it looks like you're using 2 texture units.

The modulate mode is the default, so unless you change it you don't need to set it. This should just work:

Bind texture, Set color, emit vertexes.

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,id);
glEnable(GL_TEXTURE_2D);

glColor3f(0,1,1);
glBegin(GL_TRIANGLES);
glTexCoord*(); glVertex*();
glTexCoord*(); glVertex*();
glTexCoord*(); glVertex*();
glEnd();

If you use texture unit 1 for something, then you need to configure the combiner for that unit. Each unit/environment has its own combiner; it takes input, performs an operation on the input, then spits something out for the next combiner to chew on, like a daisy-chained assembly line.

I don't see how unit 1 fits into the mix. More code or a better explanation or I need more coffee or something :)