多紋理地形使用『草地紋理(2D紋理)』與『高度紋理(1D紋理)』相結合,根據海平面的高度為地形進行著色.『高度紋理(1D紋理)』即只有1行的紋理,載入後需按以下代碼載入紋理
Load_File_Texture(&terrain->height_texture, NULL, “height.tga”);// 載入”高度”紋理
Bind_Image_Texture(&terrain->height_texture); // 綁定”高度”紋理
glGenTextures(1, &texture->ID);// 生成紋理
glBindTexture(GL_TEXTURE_1D, texture->ID);// 綁定紋理
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);//夾持紋理
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, texture->width, 0,GL_RGB,GL_UNSIGNED_BYTE,texture->image); // 載入紋理
// 紋理單元1
glActiveTexture(GL_TEXTURE1);// 激活紋理單元1
glEnable(GL_TEXTURE_GEN_S);// S座標
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);//紋理坐標的生成模式
GLfloat waterPlane[] = { 0.0, 1.0, 0.0, -TERRAIN_WATER_HEIGHT };
glTexGenfv(GL_S, GL_OBJECT_PLANE, waterPlane);//紋理坐標的生成
// 紋理單元0
glActiveTexture(GL_TEXTURE0);// 激活紋理單元0
glEnable(GL_DEPTH_TEST);// 深度測試
glEnable(GL_TEXTURE_2D);// 啟用2D紋理映射
繪畫紋理地形的函是代碼
void Draw_Height_Terrain(TERRAIN_PTR terrain)
{
// 激活紋理單元0
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);// 2D紋理
glBindTexture(GL_TEXTURE_2D, terrain->grass.ID);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);// 平鋪效果
// 激活紋理單元1
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_1D);// 1D紋理(單行)
glBindTexture(GL_TEXTURE_1D, terrain->height_texture.ID);//高度紋理綁定到它上面
glMatrixMode(GL_TEXTURE);// 切換到紋理矩陣
glLoadIdentity();
glScalef(1.0f / TERRAIN_MAX_HEIGHT, 1.0, 1.0);// 設定s坐標比例尺.
glMatrixMode(GL_MODELVIEW);// 切換到視口矩陣
// 繪畫地形
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
for (int z = 0; z < terrain->width – 1; ++z)
{
glBegin(GL_TRIANGLE_STRIP);
for (int x = 0; x < terrain->width; ++x)
{
GLfloat scaledHeight = terrain->data[z * terrain->width + x] / terrain->scale;
GLfloat nextScaledHeight = terrain->data[(z + 1)*terrain->width + x] / terrain->scale;
// 指定紋理單元0的紋理座標
glMultiTexCoord2f(GL_TEXTURE0, (GLfloat)x / terrain->width * 8.0f , (GLfloat)z / terrain->width * 8.0f);
glVertex3f((GLfloat)x – terrain->width / 2.0f, scaledHeight, (GLfloat)z – terrain->width / 2.0f);
// 指定紋理單元0的紋理座標
glMultiTexCoord2f(GL_TEXTURE0, (GLfloat)x / terrain->width * 8.0f, (GLfloat)(z + 1) / terrain->width * 8.0f );
glVertex3f((GLfloat)x – terrain->width / 2.0f, nextScaledHeight, (GLfloat)(z + 1) – terrain->width / 2.0f);
}
glEnd();
}
glDisable(GL_TEXTURE_1D);// 禁用紋理單元1
glActiveTexture(GL_TEXTURE0);// 激活紋理單元0
//繪畫水面
glBindTexture(GL_TEXTURE_2D, terrain->water.ID);// 水面紋理
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-terrain->width / 2.1f, terrain->water_height, terrain->width / 2.1f);
glTexCoord2f(terrain->width / 4.0f, 0.0);
glVertex3f(terrain->width / 2.1f, terrain->water_height, terrain->width / 2.1f);
glTexCoord2f(terrain->width / 4.0f, terrain->width / 4.0f);
glVertex3f(terrain->width / 2.1f, terrain->water_height, -terrain->width / 2.1f);
glTexCoord2f(0.0, terrain->width / 4.0f);
glVertex3f(-terrain->width / 2.1f, terrain->water_height, -terrain->width / 2.1f);
glEnd();
}
演示程式下載: