update: 2012/04/17
reference:
1. 原文:
iPhone Development: OpenGL ES From the Ground Up, Part 6: Textures and Texture Mapping
2. 翻譯:
從零開始學習OpenGL ES之六 – 紋理及紋理映射
紋理及紋理映射: 更多的映射, 平鋪和箝位
A. 更多的映射方式
1. 上個例子中這個圖像都被映射到繪製的正方形上. 那是因為設定的紋理坐標所決定的. 我們可以改變坐標陣列僅使用來源圖像的中心部分.
開啓 ViewController.m 檔案, 修改如下:
....
// 紋理映射
- (void)TextureMapping
{
....
static const Vertex3D vertices[] = {
{-1.0, 1.0, -0.0},
{ 1.0, 1.0, -0.0},
{-1.0, -1.0, -0.0},
{ 1.0, -1.0, -0.0}
};
static const Vector3D normals[] = {
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0}
};
// Feel free to comment these texture coordinates out and use one
// of the ones below instead, or play around with your own values.
/*
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0
};
*/
static const GLfloat texCoords[] = {
0.25, 0.75,
0.75, 0.75,
0.25, 0.25,
0.75, 0.25
};
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(rot, 1.0, 1.0, 1.0);
....
}
....
編譯並執行:
銀幕上只顯示了紋理的中心部分.
開啓 ViewController.m 檔案, 修改如下:
....
// 紋理映射
- (void)TextureMapping
{
....
static const Vertex3D vertices[] = {
{-1.0, 1.0, -0.0},
{ 1.0, 1.0, -0.0},
{-1.0, -1.0, -0.0},
{ 1.0, -1.0, -0.0}
};
static const Vector3D normals[] = {
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0}
};
// Feel free to comment these texture coordinates out and use one
// of the ones below instead, or play around with your own values.
// 顯示完整的紋理
/*
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0
};
*/
// 顯示紋理的中心部分
/*
static const GLfloat texCoords[] = {
0.25, 0.75,
0.75, 0.75,
0.25, 0.25,
0.75, 0.25
};
*/
// 顯示紋理的左下部
static const GLfloat texCoords[] = {
0.0, 0.5,
0.5, 0.5,
0.0, 0.0,
0.5, 0.0
};
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(rot, 1.0, 1.0, 1.0);
....
}
....
編譯並執行:
B. 還有更多的方式
1. 說明: 我們可以通過非常規方式的映射來扭曲紋理.
2. 開啓 ViewController.m 檔案, 修改如下:
....
- (void)TextureMapping
{
NSLog(@"ViewController => TextureMapping");
//@update for more mapping
//static GLfloat rot = 0.0;
glColor4f(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
/*
static const Vertex3D vertices[] = {
{-1.0, 1.0, -0.0},
{ 1.0, 1.0, -0.0},
{-1.0, -1.0, -0.0},
{ 1.0, -1.0, -0.0}
};
static const Vector3D normals[] = {
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0}
};
*/
//@update for more mapping
static const Vertex3D vertices[] = {
{-1.0, 1.0, -0.0},
{ 1.0, 1.0, -0.0},
{ 0.0, -1.0, -0.0},
};
static const Vector3D normals[] = {
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
};
// Feel free to comment these texture coordinates out and use one
// of the ones below instead, or play around with your own values.
// 顯示完整的紋理
/*
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0
};
*/
// 顯示紋理的中心部分
/*
static const GLfloat texCoords[] = {
0.25, 0.75,
0.75, 0.75,
0.25, 0.25,
0.75, 0.25
};
*/
// 顯示紋理的左下部
/*
static const GLfloat texCoords[] = {
0.0, 0.5,
0.5, 0.5,
0.0, 0.0,
0.5, 0.0
};
*/
//@update for more mapping
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
};
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
//@update for more mapping
//glRotatef(rot, 1.0, 1.0, 1.0);
//@update for more mapping
glBindTexture(GL_TEXTURE_2D, texture[0]);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
//glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//@update for more mapping
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//@update for more mapping
/*
static NSTimeInterval lastDrawTime;
if (lastDrawTime)
{
NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
rot += 60 * timeSinceLastDraw;
}
lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
*/
}
....
3. 編譯並執行:
紋理正方形左下角的弧形花紋現在處於三角形的底部了.
(紋理上的任何一點都可以映射到多邊形的任何一點)
C. 平鋪(貼磚)和箝位
1. 說明:
我們的紋理坐標系統在兩個軸上都是從 0.0 到 1.0, 如果設置超出此範圍的值時,
根據視圖的設置方式有兩種選擇: 平鋪 Tiling (也叫重複)或箝位 Clamping.
2. 平鋪(也叫重複)
a. 開啓 ViewController.m 檔案, 修改如下:
....
-(void)setupView:(GLView *)view
{
....
// Configuring the Image
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//@add for Tiling
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
....
}
....
- (void)TextureMapping
{
NSLog(@"ViewController => TextureMapping");
static GLfloat rot = 0.0;
glColor4f(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
static const Vertex3D vertices[] = {
{-1.0, 1.0, -0.0},
{ 1.0, 1.0, -0.0},
{-1.0, -1.0, -0.0},
{ 1.0, -1.0, -0.0}
};
static const Vector3D normals[] = {
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, 1.0}
};
// Feel free to comment these texture coordinates out and use one
// of the ones below instead, or play around with your own values.
// 顯示完整的紋理
/*
static const GLfloat texCoords[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0
};
*/
// 顯示紋理的中心部分
/*
static const GLfloat texCoords[] = {
0.25, 0.75,
0.75, 0.75,
0.25, 0.25,
0.75, 0.25
};
*/
// 顯示紋理的左下部
/*
static const GLfloat texCoords[] = {
0.0, 0.5,
0.5, 0.5,
0.0, 0.0,
0.5, 0.0
};
*/
//@update for Tiling
static const GLfloat texCoords[] = {
0.0, 2.0,
2.0, 2.0,
0.0, 0.0,
2.0, 0.0
};
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(rot, 1.0, 1.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
static NSTimeInterval lastDrawTime;
if (lastDrawTime)
{
NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
rot += 60 * timeSinceLastDraw;
}
lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
}
....
b. 編譯並執行:
a. 說明
讓 OpenGL ES 簡單地將超過 1.0 的值限制為1.0, 任何低於 0.0 的值限制為 0.0.
這實際會引起邊緣像素重複, 從而產生奇怪的效果.
b. 開啓 ViewController.m 檔案, 修改如下:
....
-(void)setupView:(GLView *)view
{
....
// Configuring the Image
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//@add for Tiling
/*
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
*/
//@add for Clamping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
....
}
....
c. 編譯並執行:
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。