iDevGames Forums
Basic Texture Mapping - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Basic Texture Mapping (/thread-6029.html)



Basic Texture Mapping - hangt5 - Dec 13, 2004 11:11 PM

I am new to this so please bare with me Smile

Im generating a terrain using NeHe's tutorial ( http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=34 ) on height maps. Everything works great but i want to texture the terrain with something a little nicer then the blue he sets you up with.

My problem is the texture remaps on every quad (like id expect it to). Obviously i want the texture to (encompass/cover/skin) the entire height map not just one individual quad. I'v looked at some sample code that does just that and it doesn't look any different then mine. If someone could give me a nudge in the right direction it would be greatly appreciated.

Link To Image Of Problem

Thanks in advanced,
Joe.



My Current Code (Excluding loading, and setting up the texture) is:
Code:
glBindTexture( GL_TEXTURE_2D, texture[ 0 ] );
   glBegin( GL_QUADS );   // Render Polygons
   for( X = 0; X < MAP_SIZE; X += STEP_SIZE )
      for( Y = 0; Y < MAP_SIZE; Y += STEP_SIZE )
      {

         x = X;
         y = [ self heightFrom:theHeightMap x:X y:Y ];
         z = Y;

      glTexCoord2f(0.0f, 0.0f);
         glVertex3i( x, y, z );

         x = X;                                                  
         y = [ self heightFrom:theHeightMap x:X y:Y + STEP_SIZE ];
         z = Y + STEP_SIZE;
        
         glTexCoord2f(0.0f, 1.0f);
         glVertex3i( x, y, z );   // Send This Vertex To OpenGL To Be Rendered

         x = X + STEP_SIZE;
         y = [ self heightFrom:theHeightMap x:X + STEP_SIZE y:Y + STEP_SIZE ];
         z = Y + STEP_SIZE;
        
      glTexCoord2f(1.0f, 1.0f);
         glVertex3i( x, y, z );   // Send This Vertex To OpenGL To Be Rendered

         x = X + STEP_SIZE;
         y = [ self heightFrom:theHeightMap x:X + STEP_SIZE y:Y ];
         z = Y;
        
      glTexCoord2f(1.0f, 0.0f);
         glVertex3i( x, y, z );   // Send This Vertex To OpenGL To Be Rendered
      }

   glEnd();

EDIT: ----------

i tried using if statements to call the glTexCoord2f only when the corosponding corner of the entire mesh was being displayed. so for example

if(X == 0 && Y == 0)
glTexCoord2f(0,0);

But that didn't work i only got a uniform green color.


Basic Texture Mapping - Fenris - Dec 14, 2004 05:01 AM

Yeah, you have to set the corresponding texture coordinate for every vertex. So, for the calls to glTexCoord2f, you want (i * (1.0f / MAP_SIZE), j * (1.0f / MAP_SIZE)) (Make sure that MAP_SIZE is a float, too: something like 10.0f is needed.

For instance, if MAP_SIZE is 10.0f, the texcoords will be 0, 0.1, 0.2, 0.3, 0.4 and so on, which is what you want.


Basic Texture Mapping - hangt5 - Dec 14, 2004 08:51 AM

Awesome, thanks a lot.

Thats what i thought it would be, but the sample code in "openGL game programing" for terrain maps was almost identical to what i did, they certainly didn't 'scale' it like that. Weird.


Basic Texture Mapping - TomorrowPlusX - Dec 14, 2004 09:22 AM

Also, you can make texture coordinate generation a little simpler if you use automatic texture coordinate generation.

You can see it in my post from a few days ago:
http://www.idevgames.com/forum/showthread.php?t=7923

The relevant code is here:
Code:
glActiveTextureARB( GL_TEXTURE0_ARB );
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, _primaryTextureID );

        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        glTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
        glTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
        glEnable( GL_TEXTURE_GEN_S );
        glEnable( GL_TEXTURE_GEN_T );

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0f);
        
        glMatrixMode( GL_TEXTURE );
        glLoadIdentity();
        glScalef( _primaryTextureScale, _primaryTextureScale, 1.0f );
        glTranslatef( -_xyScaleOverTwo, -_xyScaleOverTwo, 0.0f );
        
        glMatrixMode( GL_MODELVIEW );

What it's doing is this: first it turns on tex coord generation for S & T in "object linear" space, which basically means the coordinates are generated in the object's space as opposed to eye space or some other transformation.

The important part are the glScalef and glTranslatef while the matrix mode is GL_TEXTURE. You can pass whatever values you want here, but if you want repeating texture you might pass something like ( 1 / numRepeats ) or for one-to-one correspondence you'de pass 1.0. The translation just moves the center of the texture to the middle of the terrain.

This approach is convenient if you're using vertex buffers since you don't have to pass/upload a texture coordinate array. And in my experience the performance is the same or better than passing texture coordinates per-vertex -- presumably because there's less back-n-forth with the video card.


Basic Texture Mapping - hangt5 - Dec 14, 2004 11:59 AM

Thanks for the tip il give it a try when i have a chance.


Basic Texture Mapping - hangt5 - Dec 14, 2004 12:29 PM

Both ways worked but for whatever reason automatic texture generation looked nicer. When i explicitly used glVertexCoord i could see the quad squares 'behind' the texture. I probably just didnt do it right.

Thanks a lot for the help Smile

EDIT----

Just to make sure im doing this right. the equations:

float i = X * (1.0f / MAP_SIZE_FLOAT);
float j = Y * (1.0f / MAP_SIZE_FLOAT);

get me the texCoords of my lower left vertex? so if i render my quads from the LL going clockwise, my points would be.

LL = (i,j)
UL = (i,j+1/MAP_SIZE_FLOAT)
UR = (i+1/MAP_SIZE_FLOAT, j+1/MAP_SIZE_FLOAT)
LR = (i+1/MAP_SIZE_FLOAT, j)
?

I hate to bother you guys again it just pisses me off that it doesnt look as good Mad