I’m using a .RAW height map and want to apply two textures to the terrain, but without using mulitexturing. My scaled terrain height ranges between 0 to 40, I have taken a simple texture for grass, copied it and modified it for my snow texture. I have a variable called SNOW_CAP (approx scaled height 32) which is the starting point for the “snow-line”, above this value I want to use my snow texture, below this value I will use a grass texture. Currently in trying to use a multi-pass approach:
- draw the terrain above the “snowline” with the snow texture (1st pass)
- draw the grass section below the “snowline”.(2nd pass)
- draw the water level (scaled height of 8 - 3rd pass)
here is the initializing code
image.Load("grass.tga");
glGenTextures(1, &m_grassTexture);
glBindTexture(GL_TEXTURE_2D, m_grassTexture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image.GetWidth(),
image.GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, image.GetImage());
image.Release();
image.Load("snow.tga");
glGenTextures(1, &m_snowTexture);
glBindTexture(GL_TEXTURE_2D, m_snowTexture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image.GetWidth(),
image.GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, image.GetImage());
image.Release();
image.Load("water.tga");
glGenTextures(1, &m_waterTexture);
glBindTexture(GL_TEXTURE_2D, m_waterTexture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, image.GetWidth(),
image.GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, image.GetImage());
image.Release();
And this is my drawing function:
void CGfxOpenGL::DrawTerrain()
{
//draw the terrain using the snow texture ABOVE SNOW_CAP
//first pass
glBindTexture(GL_TEXTURE_2D, m_snowTexture);
//glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,WHITE);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
for (int z = 0; z < TERRAIN_SIZE - 1; ++z)
{
glBegin(GL_TRIANGLE_STRIP);
for (int x = 0; x < TERRAIN_SIZE ; ++x)
//for (int x = TERRAIN_SIZE; x < 0; --x)
{
if ((heightmap[z * TERRAIN_SIZE + x] / SCALE_FACTOR) >= SNOW_CAP)
{
// render two vertices of the strip at once
float scaledHeight = heightmap[z * TERRAIN_SIZE + x] / SCALE_FACTOR;
float nextScaledHeight = heightmap[(z + 1)* TERRAIN_SIZE + x] / SCALE_FACTOR;
float color = 0.35 + 1.0f * scaledHeight / MAX_HEIGHT;
float nextColor = 0.35 + 1.0f * nextScaledHeight / MAX_HEIGHT;
glColor3f(color, color, color);
glTexCoord2f((GLfloat)x/TERRAIN_SIZE*8, (GLfloat)z/TERRAIN_SIZE*8);
glVertex3f(static_cast<GLfloat>(x - TERRAIN_SIZE/2), scaledHeight,
static_cast<GLfloat>(z - TERRAIN_SIZE/2));
glColor3f( nextColor, nextColor, nextColor);
glTexCoord2f((GLfloat)x/TERRAIN_SIZE*8, (GLfloat)(z+1)/TERRAIN_SIZE*8);
glVertex3f(static_cast<GLfloat>(x - TERRAIN_SIZE/2), nextScaledHeight,
static_cast<GLfloat>(z + 1 - TERRAIN_SIZE/2));
}
}
glEnd();
}
//second pass
//only draw the area BELOW the
//SNOW_CAP
glBindTexture(GL_TEXTURE_2D, m_grassTexture);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
for (int z = 0; z < TERRAIN_SIZE - 1; ++z)
{
glBegin(GL_TRIANGLE_STRIP);
for (int x = 0; x < TERRAIN_SIZE; ++x)
//for (int x = TERRAIN_SIZE; x < 0; --x)
{
if((heightmap[z * TERRAIN_SIZE + x] / SCALE_FACTOR) <= SNOW_CAP)
{
// render two vertices of the strip at once
float scaledHeight = heightmap[z * TERRAIN_SIZE + x] / SCALE_FACTOR;
float nextScaledHeight = heightmap[(z + 1)* TERRAIN_SIZE + x] / SCALE_FACTOR;
float color = 0.5 + 1.0f * scaledHeight / MAX_HEIGHT;
float nextColor = 0.5 + 1.0f * nextScaledHeight / MAX_HEIGHT;
glColor3f(color,color,color);
glTexCoord2f((GLfloat)x/TERRAIN_SIZE*8, (GLfloat)z/TERRAIN_SIZE*8);
glVertex3f(static_cast<GLfloat>(x - TERRAIN_SIZE/2), scaledHeight,
static_cast<GLfloat>(z - TERRAIN_SIZE/2));
glColor3f(nextColor, nextColor, nextColor);
glTexCoord2f((GLfloat)x/TERRAIN_SIZE*8, (GLfloat)(z+1)/TERRAIN_SIZE*8);
glVertex3f(static_cast<GLfloat>(x - TERRAIN_SIZE/2), nextScaledHeight,
static_cast<GLfloat>(z + 1 - TERRAIN_SIZE/2));
}
}
glEnd();
}
//draw the water (functional)
glBindTexture(GL_TEXTURE_2D, m_waterTexture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-TERRAIN_SIZE/2.1f, WATER_HEIGHT, TERRAIN_SIZE/2.1f);
glTexCoord2f(TERRAIN_SIZE/4.0f, 0.0);
glVertex3f(TERRAIN_SIZE/2.1f, WATER_HEIGHT, TERRAIN_SIZE/2.1f);
glTexCoord2f(TERRAIN_SIZE/4.0f, TERRAIN_SIZE/4.0f);
glVertex3f(TERRAIN_SIZE/2.1f, WATER_HEIGHT, -TERRAIN_SIZE/2.1f);
glTexCoord2f(0.0, TERRAIN_SIZE/4.0f);
glVertex3f(-TERRAIN_SIZE/2.1f, WATER_HEIGHT, -TERRAIN_SIZE/2.1f);
glEnd();
}
At this point I get a "snow bridge from one snow cap peak to another, and I have “wholes” in a few locations are ound the snow line, How can I correct this?