OpenGL之多紋理地形

OpenGL之多紋理地形

多紋理地形使用『草地紋理(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();

}

演示程式下載:

 

評論