Sign in to follow this  
Gothmog

Dissappearing textures

Recommended Posts

Gothmog    122
I have a problem. Some of the textures in my app dissappear while rotating the camera. Here are some example images: Before...


...and after


Has anybody got an idea what causes this problem? [Edited by - Gothmog on November 7, 2004 12:39:06 PM]

Share this post


Link to post
Share on other sites
Gothmog    122
Quote:

maybe post some rendering source?



glMatrixMode(GL_TEXTURE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,wdetail->texid);

glLoadIdentity();
glRotatef(t*0.01,0.0f,0.0f,1.0f);
glTranslatef(-deltaX,-deltaY,0.0f);
glScalef(100.0f,100.0f,1.0f);

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,waterTex->texid);

glLoadIdentity();
glTranslatef(deltaX,deltaY,0.0f);
glScalef(5.0f,5.0f,5.0f);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

glColor4f(1.0f,1.0f,1.0f,0.9f);
glNormal3f(0.0f,1.0f,0.0f);
glBegin(GL_QUADS);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1000.0f,wlev+wdelta,-1000.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
glVertex3f(1000+world->tilesX*world->tileSize,wlev+wdelta,-1000.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);
glVertex3f(1000+world->tilesX*world->tileSize,wlev+wdelta,world->tilesY*world->tileSize+1000);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
glVertex3f(-1000.0f,wlev+wdelta,world->tilesY*world->tileSize+1000);

glEnd();

glActiveTextureARB(GL_TEXTURE0_ARB);
glLoadIdentity();
glActiveTextureARB(GL_TEXTURE1_ARB);
glLoadIdentity();

glMatrixMode(GL_MODELVIEW);



Quote:

How are you constructing the projection matrix (more precisely, with which values)?


The whole world has about 400x400 units on the XZ plane. The water (a single quad, which causes this problem has 2400x2400 units on the XZ plane), the camera is about 2.0 units above the ground.

Share this post


Link to post
Share on other sites
zedzeek    529
im not sure what u mean bt disappearing textures ( the pictures look ok) but perhaps it is a depth precision problem, make the near clip plane 100x bigger

Share this post


Link to post
Share on other sites
Gothmog    122
Quote:
im not sure what u mean bt disappearing textures ( the pictures look ok)


Look at the water in the 2nd picture, i don't think it looks ok [smile]

Quote:
make the near clip plane 100x bigger


Nah, it doesn't work.

Quote:
Comment the scaling and rotating stuff and check if it still happens


It gives no effect.

Quote:
I think the rotation is based on the camera's view right?


No, the transformations affect the texture matrix, to create animation of the water. It has nothing to do with the camera.

Share this post


Link to post
Share on other sites
Lutz    462
Quote:
Original post by Gothmog
No, the transformations affect the texture matrix, to create animation of the water. It has nothing to do with the camera.


Maybe the texture matrix causes the problems. Does the water texture still disappear if you set the texture matrix to identity? Can you post more details on the texture matrix transformation?

Share this post


Link to post
Share on other sites
Gothmog    122
Quote:
Does the water texture still disappear if you set the texture matrix to identity?


Yes.

Quote:
Can you post more details on the texture matrix transformation?


Here is the full code of the water rendering function:


void DrawWater()
{
static texture * waterTex=NULL,*wdetail=NULL;
static const float wlev=50.0f;
static float wdelta=0.0f;
static float t=0.1;

static float deltaX=0.0f,deltaY=0.0f;

if(!waterTex)
{
waterTex=Engine->AddTexture("water.bmp",GE_AT_BUILD|GE_AT_GLUBUILD2DMIPMAPS|GE_AT_STDTEXFILTERS|GE_AT_STDLINEARFILTERS);
}

if(!wdetail)
{
wdetail=Engine->AddTexture("water017.bmp",GE_AT_BUILD|GE_AT_GLUBUILD2DMIPMAPS|GE_AT_STDTEXFILTERS|GE_AT_STDLINEARFILTERS);
}

glPushAttrib(0xFFFFFFFF);

glMatrixMode(GL_TEXTURE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,wdetail->texid);

glLoadIdentity();
glRotatef(t*0.01,0.0f,0.0f,1.0f);
glTranslatef(-deltaX,-deltaY,0.0f);

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,waterTex->texid);

glLoadIdentity();
glTranslatef(deltaX,deltaY,0.0f);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

glColor4f(1.0f,1.0f,1.0f,0.9f);
glNormal3f(0.0f,1.0f,0.0f);
glBegin(GL_QUADS);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
glVertex3f(-1000.0f,wlev+wdelta,-1000.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,5.0f,0.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,100.0f,0.0f);
glVertex3f(1000+world->tilesX*world->tileSize,wlev+wdelta,-1000.0f);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,5.0f,5.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,100.0f,100.0f);
glVertex3f(1000+world->tilesX*world->tileSize,wlev+wdelta,world->tilesY*world->tileSize+1000);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,5.0f);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,100.0f);
glVertex3f(-1000.0f,wlev+wdelta,world->tilesY*world->tileSize+1000);

glEnd();

glActiveTextureARB(GL_TEXTURE0_ARB);
glLoadIdentity();
glActiveTextureARB(GL_TEXTURE1_ARB);
glLoadIdentity();

glMatrixMode(GL_MODELVIEW);

deltaX+=0.0001f;
deltaY+=0.0001f;

if(t<360.0f)
t+=0.05f;
else t=0.05f;
wdelta=sinf(t)*0.5f;

glPopAttrib();
}


The textures are translated, and then the second texture is also rotated on the ST plane. In the prev. version of this code, the textures were scaled, but I removed it, and changed the tex coordinates manually.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Some things I noticed:

glPushAttrib(0xFFFFFFFF);
I've never seen this. Are you sure this works and is fast?
The GPU has to push every attrib (also the non-used ones), so it might be slow.

waterTex=Engine->AddTexture("water.bmp",GE_AT_BUILD|GE_AT_GLUBUILD2DMIPMAPS|GE_AT_STDTEXFILTERS|GE_AT_STDLINEARFILTERS);
I just wanted to ask whether you load the textures every frame, but then I noticed that waterTex and wdetail are static...

Does the problem only occur after a certain time, say 1 or 2 minutes? If so, set deltaX and deltaY back to 0 if they exceed 1.

Do the textures reappear if you rotate the camera back?

I've actually no idea what could cause the problem, the code looks OK so far. But maybe you can find the reason for the problem by successively simplifying the code:
1) Don't use blending
2) Don't use multitexture (only the water texture)
3) Disable lighting
and so on. Maybe this helps.

Share this post


Link to post
Share on other sites
Gothmog    122
Quote:
glPushAttrib(0xFFFFFFFF);
I've never seen this. Are you sure this works and is fast?
The GPU has to push every attrib (also the non-used ones), so it might be slow.


Yeah, your'e right. I've changed this.[smile]

I noticed, that when i resized the water surface to a smaller size, everything looks ok. So this could really be a depth precision problem or somethig.[wink]

So, the quad is actually too big [smile]. I'm wondering if there is a other solution for this (cause I don't think it would be a good idea to build the water surface out of a bigger number of quads - this would only decrease performance).

Share this post


Link to post
Share on other sites
mikeman    2942
I don't know if this is relevant to your problem, but I have noticed that there is definately an issue with big quads. More precisely, with large texture coordinates.

Take this piece of code:


glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex3f(-1,1,0);
glTexCoord2f(1,0);glVertex3f(1,1,0);
glTexCoord2f(1,1);glVertex3f(1,-1,0);
glTexCoord2f(0,1);glVertex3f(-1,-1,0);
glEnd();



It renders fine.
Now do this:


glBegin(GL_QUADS);
glTexCoord2f(100000,0);glVertex3f(-1,1,0);
glTexCoord2f(100001,0);glVertex3f(1,1,0);
glTexCoord2f(100001,1);glVertex3f(1,-1,0);
glTexCoord2f(100000,1);glVertex3f(-1,-1,0);
glEnd();



If I have wrap mode to GL_REPEAT, then this should be the same as the above code. Instead, the texture is horribly distorted. So, if you use large texcoords to repeat a small texture into a large quad, maybe you'll get that problem. I have no idea why it happens, or how it's fixed, other than higher tesselation.



Share this post


Link to post
Share on other sites
Enigma    1410
mikeman: The problem there is almost certainly floating point precision. I assume the drivers use floating point numbers internally for the texture coordinates. Now when you try and interpolate between 100000.0f and 100001.0f there is very little floating point precision remaining and your texture ends up horribly distorted.

Enigma

Share this post


Link to post
Share on other sites
mikeman    2942
Quote:
Original post by Enigma
mikeman: The problem there is almost certainly floating point precision. I assume the drivers use floating point numbers internally for the texture coordinates. Now when you try and interpolate between 100000.0f and 100001.0f there is very little floating point precision remaining and your texture ends up horribly distorted.

Enigma


Yes, but I don't think that 100000.0 is such a big value that could cause this. And the problem is visible even in 10000.0, it's just not that bad.

Share this post


Link to post
Share on other sites
Lutz    462
Oh yes! Floating point precision is 7-8 digits IIRC. So the floating point number after 10000.0 is something like 10000.001 which is not enough for sub-texel accuracy required for the water.

The problem can be solved easily: Keep all texture coords in double precision. Say they're stored in u[4] and v[4].

Instead of calling
glTexCoord2d(u[n],v[n])
for n=0,1,2,3, you just need to call
glTexCoord2d(u[n]-floor(u[0]),v[n]-floor(v[0])).

This gets you rid of the big numbers. Hope you know what I mean.

Share this post


Link to post
Share on other sites
Gothmog    122
Uhm, okay Lutz, but the coords i'm using range from 0.0 to 100.0, so the calculations should be quite precise, however i tried using the method you posted but it doesn't seem to work.

Now, i've simply reduced the size of the water quad, and made it move with the camera. I will not do anything else about it for now. This was for test purposes only - to see how the world will look with water. Later i plan creating something that imitates water more accurately - with reflections, waves, etc.

But anyway thanks for you all [smile].

Share this post


Link to post
Share on other sites
MARS_999    1627
Not sure if this will help or if anyone pointed this out, but what are your near and far planes set to? Try making you near plane .025 or some small number. Also what is your FOV? When you are close to the ground you tend to have issues. Also what values are you rendering you water plane at? Is it a value close to the plane of the ground textures? Just some ideas, that I had issues with when I put water in....

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this