Strange texture behaviour

Started by
5 comments, last by German 16 years, 1 month ago
Hello. I'm implementing an algorithm for 3d terrain generation. When I apply a texture to the terrain, it looks strange (its colors). And the texture is repeated along the terrain. I have a 256x256 texture which is mapped from (0.0f, 0.0f) to (1.0f, 1.0f) just once, but it appears repeated and its color channels look strange. How can I post an image so that you can see the texture and the result? This is the code to load the texture: glGenTextures(1, &id_); glBindTexture(GL_TEXTURE_2D, id_); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, data_.width, data_.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_.data); This is the code to render the terrain: float texleft, texbottom, textop; glEnable( GL_CULL_FACE ); if (textureenabled_) { glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, texture_.getId() ); } else glBindTexture(GL_TEXTURE_2D, 0); for (std::size_t z = 0; z < size_ - 1; ++z) { glBegin(GL_TRIANGLE_STRIP); for (std::size_t x = 0; x < size_ - 1; ++x) { std::cout << texleft << " " << texbottom << std::endl; std::cout << texleft << " " << textop << std::endl; //calculate the texture coordinates texleft = static_cast<float>(x)/size_; texbottom = static_cast<float>(z)/size_; textop = static_cast<float>(z + 1)/size_; //color = getTrueHeightAtPoint(x, z); glColor3ub(255, 255, 255); glTexCoord2f(texleft, texbottom); glVertex3f(x, getScaleHeightAtPoint(x, z), z); //color = getTrueHeightAtPoint(x, z + 1); glColor3ub(255, 255, 255); glTexCoord2f(texleft, textop); glVertex3f(x, getScaleHeightAtPoint(x, z + 1), z + 1); } glEnd(); } And I'd like to show you the images, but I don't know how to post them. Some points in the image look very green, some very red...
Advertisement
Hey,

I don't see anything definitely wrong with this code, although I'm curious why you did these things:

1) else glBindTexture(GL_TEXTURE_2D, 0);

Why not use else glDisable(GL_TEXTURE_2D) ? It will render faster...

2) static_cast<float>(x)/size_;

Why not just (float)x/size ? Also, it seems like the for loop could use ints instead of size_t. Changing these things might solve the repeating look you're seeing.

To fix the colors, my instinct is to check your image loading library. What image format are you using, and how are they being loaded from the file? Can you render the texture image in a 2D way directly to the screen? If so, does it look correct there?

Hope this helps...
-----------------------Codito, ergo sumhttp://www.klaymore.net
Quote:Original post by klaymore142
Hey,

I don't see anything definitely wrong with this code, although I'm curious why you did these things:

1) else glBindTexture(GL_TEXTURE_2D, 0);

Why not use else glDisable(GL_TEXTURE_2D) ? It will render faster...

2) static_cast<float>(x)/size_;

Why not just (float)x/size ? Also, it seems like the for loop could use ints instead of size_t. Changing these things might solve the repeating look you're seeing.

To fix the colors, my instinct is to check your image loading library. What image format are you using, and how are they being loaded from the file? Can you render the texture image in a 2D way directly to the screen? If so, does it look correct there?

Hope this helps...


1) Yes, I should do that. I'm a newbie.
2) I did static_cast<float> simply because it's C++ style. I prefer it.
The size_t is to disable compiler warnings because container.size() return size_t.

I'm using tga and I'm under linux. The textures I think that are from Photoshop. I'm using CImg template library (http://cimg.sourceforge.net/) to load images and this library shows the image as it should. But I don't know how the texture is stored in memory.
Anyway, with the code above the texture shouldn't be repeated. It should fit the terrain I think. And it doesn't.
The texture should repeat as the default wrap mode is GL_REPEAT and it doesn't look like you change the state. Change it with glTexParameter (http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml).
Have you printed out the UV coordinates to cout or a logfile to make sure they are correct? Also, have you done the same for your vertices to make sure they are being passed to OpenGL in the correct order?

The CImg library's website doesn't say how the data is stored internally, but I do know that TGA files store their data in BGR format, not RGB...so if the CImg library doesn't translate the BGR data into RGB when storing it in memory, then OpenGL will have the wrong data when you create the texture.

You could try using GL_BGR in your call to glTexImage2D() - if your version of OpenGL supports it.
-----------------------Codito, ergo sumhttp://www.klaymore.net
BTW - static_cast resolves the variables at compile time, NOT runtime. I think you want to use dynamic_cast instead - otherwise, you won't get the values you want at runtime.
This is why I just use C-style casts, such as (float)x/size_ - the compiler can decide to optimize it as a static_cast or a dynamic_cast without these issues.
-----------------------Codito, ergo sumhttp://www.klaymore.net
OK. It's done. It was a problem with the memory layout of the textures. I switched my code to use GIL (Adobe generic image library). Great library, by the way, although I just need to do
some basic stuff.

This topic is closed to new replies.

Advertisement