views:

18

answers:

1

I'm trying to add a simple repeating shaded gradient (think laminated layers) along the Z axis of arbitrary, highly tessellated objects (STL imports).

It's mostly working, but I get some really weird faces where the texture is not parallel to Z, but rotated and scaled differently. These faces are usually (possibly always) oriented vertically and some are quite large. I would think vertical faces would be the easiest to apply... so I'm currently stumped.

Here's the init:

glBindTexture(GL_TEXTURE_1D, _d->textures[0]);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //GL_DECAL);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, _d->sideImage.width(), 0,
  GL_BGRA_EXT, GL_UNSIGNED_BYTE, _d->sideImage.bits());

And in use:

glEnable(GL_TEXTURE_1D);
foreach(const STLTriangle& t, _model.triangles())
{
  glBegin(GL_TRIANGLES);
  glNormal3f(t.normal[0], t.normal[1], t.normal[2]);
  glTexCoord1f(fmod(t.v[0][2],1.0)); glVertex3f(t.v[0][0],t.v[0][1],t.v[0][2]);
  glTexCoord1f(fmod(t.v[1][2],1.0)); glVertex3f(t.v[1][0],t.v[1][1],t.v[1][2]);
  glTexCoord1f(fmod(t.v[2][2],1.0)); glVertex3f(t.v[2][0],t.v[2][1],t.v[2][2]);
  glEnd();
}
glDisable(GL_TEXTURE_1D);

Does anyone see something wrong in how I'm going about this?

+1  A: 

Okay, I've solved it. The fmod() was a clue.

Instead of:

glTexCoord1f(t.v[0][2]);

I needed to normalize Z along the part from 0 to 1: (or 0 to 1 * textureScaleFactor, really)

glTexCoord1f((t.v[0][2] - bounds.min[2]) / range);

I apply a scaling factor to range to get the texture density I want.

fmod() was really wrong. If a face has min and max vertex points 0 and 1, then you get the full texture. However, if you get 0 and 1.1, then that becomes 0.1, and it scales a tenth of the texture across the face. Oops. I'm amazed it worked on so many of the other faces. That's what I get for not taking a break and getting some sleep. :)

At least at some point (with fmod() removed), I was getting an aliasing effect that made more appear to be wrong than there really was. So, I also switched the texture to a mipmap. From:

glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, _d->sideImage.width(), 0,
  GL_BGRA_EXT, GL_UNSIGNED_BYTE, _d->sideImage.bits());

To:

gluBuild1DMipmaps(GL_TEXTURE_1D, GL_RGB, _d->sideImage.width(), GL_BGRA_EXT,
  GL_UNSIGNED_BYTE, _d->sideImage.bits());

Even with this, it's still aliasing at distance. Any suggestions on how to handle that? I'll play with the mipmap levels and see where that gets me...

darron
Did you change the MIN filter to a mipmapped one?
Matias Valdenegro
Ah, that's it. I'm still pretty much a novice at OpenGL. Works great now, thanks.
darron