Thread: Heightfield Texture Coords

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    Heightfield Texture Coords

    Is there anyway to get texture coords from heightmap vertex data?

    What I mean is, can/how are texture coords from drawing a texture over the entire terrain, obtained from the terrains vertex data.
    To actually state the question properly; how do you generate texture coords for a heightfield terrain?

    terrain rendering code:
    Code:
    	glBegin(GL_TRIANGLES);
    	for(NxU32 i=0;i<HEIGHTFIELD_NB_FACES;i++)
    	{
    		glNormal3fv(&gHeightfieldNormals[gHeightfieldFaces[i*3+0]].x);
    		glVertex3fv(&gHeightfieldVerts[gHeightfieldFaces[i*3+0]].x);
    
    		glNormal3fv(&gHeightfieldNormals[gHeightfieldFaces[i*3+1]].x);
    		glVertex3fv(&gHeightfieldVerts[gHeightfieldFaces[i*3+1]].x);
    
    		glNormal3fv(&gHeightfieldNormals[gHeightfieldFaces[i*3+2]].x);
    		glVertex3fv(&gHeightfieldVerts[gHeightfieldFaces[i*3+2]].x);
    	}
    	glEnd();
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Are you tiling the terrain?

    If not it's:

    Code:
    float uinc=1.0f/width;
    float vinc=1.0f/height;
    
    float tu=0.0f;
    float tv=0.0f;
    
    for (float i=startx;....)
    {
      for (float j=starty;...)
      { 
       ..Create vertex at i,j with texture coords of tu,tv
        tu+=uinc
      }
      tv+=vinc;
    }
    I will show you my example but beware it's in Direct3D. Most of the code though is not related to Direct3D at all.

    Code:
    void CTerrain::Init(IDirect3DDevice9 *Device,
                        int NumVertsPerRow,
                        int NumVertsPerCol,
                        int CellSize)
    {
      m_pDevice=Device;
      m_iCellSize=CellSize;
      m_iNumVertsPerCol=NumVertsPerCol;
      m_iNumVertsPerRow=NumVertsPerRow;
    
      m_iNumCellsPerRow=NumVertsPerRow-1;
      m_iNumCellsPerCol=NumVertsPerCol-1;
      
      m_iWidth=m_iNumCellsPerRow*CellSize;
      m_iDepth=m_iNumCellsPerCol*CellSize;
      
      m_iNumVertices=m_iNumVertsPerRow*m_iNumVertsPerCol;
      m_iNumTris=m_iNumCellsPerRow*m_iNumCellsPerCol*2;
      
         
      m_pDevice->CreateVertexBuffer(m_iNumVertices*sizeof(TerrainVertex),
                                    D3DUSAGE_DYNAMIC,
                                    TerrainVertex::FVF,
                                    D3DPOOL_DEFAULT,
                                    &m_pVB,
                                    NULL);
    
      TerrainVertex *Vertices;
      m_pVB->Lock(0,0,(void **)&Vertices,0);
    
      int iStartX=-(m_iWidth>>1);
      int iStartZ=(m_iDepth>>1);
    
      int iEndX=m_iWidth>>1;
      int iEndZ=-m_iDepth>>1;
      
    
      unsigned int vnum=0;
      float fAngle=0.0f;
    
      int i=0;
      int j=0;
      int index=0;
      float angle=0.0f;
      float vy=0.0f;
    
      float uinc=1.0f/(float)(m_iWidth/2);
      float vinc=1.0f/(float)(m_iDepth/2);
    
    
      for (int vz=iStartZ;vz>=iEndZ;vz-=m_iCellSize)
      {
        for (int vx=iStartX;vx<=iEndX;vx+=m_iCellSize)
        {
          
    
          index=i*m_iNumVertsPerRow+j;
    
          Vertices[index]=TerrainVertex(D3DXVECTOR3((float)vx,0.0f,(float)vz),
                                       vx*uinc,
                                       vz*vinc);
          Vertices[index].Diffuse=D3DXCOLOR(0.0f,1.0f,0.0f,1.0f);
          Vertices[index].r=0.0f;
          Vertices[index].g=1.0f;
          Vertices[index].b=0.0f;
    
    
          j++;
                
        }
        i++;
        j=0;
    
      }
    
      m_pVB->Unlock();
    
      m_pDevice->CreateIndexBuffer(m_iNumTris*3*sizeof(WORD),
                                   D3DUSAGE_WRITEONLY,
                                   D3DFMT_INDEX16,
                                   D3DPOOL_MANAGED,
                                   &m_pIB,
                                   0);
      
      WORD *Indices=0;
      m_pIB->Lock(0,0,(void **)&Indices,0);
    
      unsigned int baseindex=0;
      
      i=0;j=0;
    
      for (i=0;i<m_iNumCellsPerCol;i++)
      {
        for (int j=0;j<m_iNumCellsPerRow;j++)
        {
    
          Indices[baseindex]=   i     * m_iNumVertsPerRow+  j;
          Indices[baseindex+1]= i     * m_iNumVertsPerRow+  j +1; 
          Indices[baseindex+2]= (i+1) * m_iNumVertsPerRow+  j;
          Indices[baseindex+3]= (i+1) * m_iNumVertsPerRow+  j;
          Indices[baseindex+4]= i     * m_iNumVertsPerRow+  j +1;
          Indices[baseindex+5]= (i+1) * m_iNumVertsPerRow+  j +1;
          baseindex+=6;
            
        }
      }
    
      m_pIB->Unlock();
      
    
    }
    That code generates a flat terrain.

    I perturb the terrain with this sphere algo. Essentially it picks a size and height value for the sphere. Then it perturbs all affected vertices relative to it's distance from the sphere.

    It's slow to generate on the fly, but you could generate the data, save it, and load it later to speed the process up.

    Code:
    void CTerrain::SphereGenerate(int numiterations)
    {
      TerrainVertex *Vertices;
    
      m_pVB->Lock(0,0,(void **)&Vertices,0);
    
      int num=0;
    
      do
      {
        int centerx=rand () % m_iNumVertsPerCol;
        int centery=rand () % m_iNumVertsPerRow;
        int size=15+rand () % 200;
        int height=-400 + (rand () % 800);
    
        
        for (int i=0;i<m_iNumCellsPerCol;i++)
        {
          for (int j=0;j<m_iNumCellsPerRow;j++)
          {
            int index=i*m_iNumCellsPerRow+j;
    
            int distx=centerx-i;
            int disty=centery-j;
    
            float dist=sqrt((distx*distx)+(disty*disty));
            dist*=2.0f;
            dist/=(float)size;
    
    
    
            if (fabs(dist)<=1.0f) 
            {
              float height2=(float)height *.5f;
    
              Vertices[index].Position.y+=height2+cosf(dist*3.14f)*height2;
            }
          }
        }
        num++;
      } while (num<numiterations);
    
      m_pVB->Unlock();
    }
    Then I set the texture to what I want. I won't show this code because it is pure Direct3D.

    Here is the end result...with some fogging added.
    Last edited by VirtualAce; 10-03-2005 at 09:58 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. d3d9 c++ texture wrapper... again...
    By yaya in forum Game Programming
    Replies: 0
    Last Post: 04-01-2009, 01:08 PM
  2. D3d Texture Wrapper == ARRRGGGGHHH
    By yaya in forum Game Programming
    Replies: 1
    Last Post: 03-25-2009, 06:41 PM
  3. Replies: 4
    Last Post: 02-27-2008, 03:10 PM
  4. OpenGL - look trough surface -nehe lesson
    By GanglyLamb in forum Game Programming
    Replies: 8
    Last Post: 08-24-2006, 11:06 PM
  5. Pong is completed!!!
    By Shamino in forum Game Programming
    Replies: 11
    Last Post: 05-26-2005, 10:50 AM