将方形纹理映射到三角形 [英] Mapping a square texture to a triangle

查看:136
本文介绍了将方形纹理映射到三角形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始玩OpenGL ES 1.0,遇到一些(初学者)问题:我尝试将方形纹理映射到由三角形描述的立方体。

  //在
上启用必要的功能glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_SRC_COLOR);
glEnable(GL_CULL_FACE);
// glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

//绑定我们需要的纹理数量,在本例中为1。
glGenTextures(1,& texture [0]);
glBindTexture(GL_TEXTURE_2D,texture [0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

//绘图代码
static GLfloat rot = 0.0;

static const Vertex3D顶点[] = {
-1.0f,-1.0f,-1.0f,// 0 00
1.0f,-1.0f,-1.0f ,// 1 10
1.0f,1.0f,-1.0f,// 2 11
-1.0f,1.0f,-1.0f,// 3 01
};


static const int vertexCnt = 3 * 2;

static const GLubyte cube [] = {
3,0,2,
1,2,0,
};

static const GLfloat texCoords [] = {
0,1,
0,0,
1,1,
1,0,
1,1,
0,0,
};


glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glTranslatef(0.0f,0.0f,-3.0f);

glBindTexture(GL_TEXTURE_2D,texture [0]);

glEnableClientState(GL_VERTEX_ARRAY);
// glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_COLOR_MATERIAL);


glTexCoordPointer(2,GL_FLOAT,0,texCoords);
glVertexPointer(3,GL_FLOAT,0,vertices);

// glColorPointer(4,GL_FLOAT,0,colors);
glNormalPointer(GL_FLOAT,0,法线);



glDrawElements(GL_TRIANGLES,vertexCnt,GL_UNSIGNED_BYTE,cube);


glDisableClientState(GL_VERTEX_ARRAY);
// glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

现在,经过数十万次尝试后,我无法让它适用于其他方面......
在将平方纹理映射到三角形时,是否存在一些经验法则?

编辑:我想我应该如何完成映射。但这对于这个例子来说不起作用(一张脸)。有人可以请验证我是否正确地进行了映射(假设代码的其余部分正在工作)?

非常感谢

解决方案

和其他人一样,我不认为有一种把四边形纹理映射到三角形的技巧。

您遇到的主要问题是因为每个角落的纹理坐标不连续。如果一个角为一个面的一些UV坐标{u,v},这并不意味着它将具有共享该顶点的其他两个面的相同值。可以找到一个映射,以使UV在立方体的每个角上都是唯一的(由3个面共享),并且所有4个UV值({0,0},{1,0},{1,1}和{0,1})出现在每张脸上,但是一些纹理会被完全扭曲。尝试在一张纸上进行验证:{1,1}并不总是与{0,0}相反。



最简单的方法是,将明确宣布6个四边形,每个四边形由2个三角形组成。这给你总共24个顶点(24个位置和24个tex坐标,交错与否)和36个指标(6个四边形由两个三角形组成,6 * 2 * 3 = 36)。

这里是你的代码更新显示一个立方体(可能有一些缠绕问题,所以我禁用脸部剔除,以确保):

  glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);

static const float vertices [] = {
0.0f,1.0f,0.0f,
1.0f,1.0f,0.0f,
0.0f,0.0 f,0.0f,
1.0f,0.0f,0.0f,

0.0f,1.0f,1.0f,
0.0f,0.0f,1.0f,
1.0f,1.0f,1.0f,
1.0f,0.0f,1.0f,

0.0f,1.0f,1.0f,
1.0f,1.0f ,1.0f,
0.0f,1.0f,0.0f,
1.0f,1.0f,0.0f,

0.0f,0.0f,1.0f,
0.0f,0.0f,0.0f,
1.0f,0.0f,1.0f,
1.0f,0.0f,0.0f,

1.0f,1.0f, 0.0f,
1.0f,1.0f,1.0f,
1.0f,0.0f,0.0f,
1.0f,0.0f,1.0f,

0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,
0.0f,1.0f,1.0f,
0.0f,0.0f,1.0f
};


static const int vertexCnt = 6 * 4;

static const GLubyte cube [] = {
0,1,2,1,2,3
4,5,6,5,6,7
8,9,10,9,10,11,
12,13,14,13,14,15,
16,17,18,17,18,19,
20,21,22,21,22,23
};

static const GLfloat texCoords [] = {
0.0f,0.0f,
1.0f,0.0f,
0.0f,1.0f,
1.0f,1.0f,

1.0f,0.0f,
1.0f,1.0f,
0.0f,0.0f,
0.0f,1.0f,

0.0f,0.0f,
1.0f,0.0f,
0.0f,1.0f,
1.0f,1.0f,

0.0f,1.0f,
0.0f,0.0f,
1.0f,1.0f,
1.0f,0.0f,

0.0f,0.0 f,
1.0f,0.0f,
0.0f,1.0f,
1.0f,1.0f,

1.0f,0.0f,
1.0f,1.0f,
0.0f,0.0f,
0.0f,1.0f
};

glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// glLoadIdentity();

//glTranslatef(0.0f,0.0f,-3.0f);
glRotatef(3.1415927f,1.0f,1.0f,0.0f);

glBindTexture(GL_TEXTURE_2D,spriteTexture);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glTexCoordPointer(2,GL_FLOAT,0,texCoords);
glVertexPointer(3,GL_FLOAT,0,vertices);

glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_BYTE,cube);


I started to play with a OpenGL ES 1.0 and I run into some (beginners) problem: I tried to map a square texture to the cube described by triangles.

    // Turn necessary features on
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_SRC_COLOR);
    glEnable(GL_CULL_FACE);
    //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  

    // Bind the number of textures we need, in this case one.
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

//Drawing code
static GLfloat rot = 0.0;

static const Vertex3D vertices[] = {
    -1.0f,-1.0f,-1.0f, //0  00  
     1.0f,-1.0f,-1.0f, //1  10
     1.0f, 1.0f,-1.0f, //2  11
    -1.0f, 1.0f,-1.0f, //3  01      
};


static const int vertexCnt = 3 * 2;

static const GLubyte cube[] = {
    3,0,2,
    1,2,0,
};

static const GLfloat texCoords[] = {
    0,1,
    0,0,
    1,1,
    1,0,
    1,1,
    0,0,
};


glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glTranslatef(0.0f, 0.0f, -3.0f);

glBindTexture(GL_TEXTURE_2D, texture[0]);

glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_COLOR_MATERIAL);


glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);

//glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);



glDrawElements(GL_TRIANGLES, vertexCnt, GL_UNSIGNED_BYTE, cube);


glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Now, after a zillion attempts, I just can't get it work for other sides... Is there some rule of thumb for case when mapping square texture to triangles?

EDIT: I think I figure out how the mapping should be done. But it doesn't work for this example (one face). Can someone just please verify if I done mapping correctly (assuming that the rest of code is working)?

Many thanks

解决方案

Just like others, I don't think there is a trick to map your quad textures onto triangles.

The main problem you're experiencing is because of discontinuities in texture coords for each corner. If one corner as some UV coords {u,v} for one face, it doesn't mean it will have the same value for the other two faces that share the vertex. It is possible to find a mapping so that UV is unique at each corner of the cube (shared by 3 faces) and so that all 4 UV values ({0,0}, {1,0}, {1,1} and {0,1}) are present on each face but then some textures would be completely distorted. Try to verify this on a piece of paper: {1,1} is not always at the opposite of {0,0}.

The easiest way to start with, would be to declare explicitly 6 quads, each one of them composed of 2 triangles. That gives you a total of 24 vertices (24 positions and 24 tex coords, interleaved or not) and 36 indices (6 quads composed of two triangles, 6 * 2 * 3 = 36 ).

Here is your code updated to display a cube (there might be some winding problem so I disabled face culling to be sure):

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);

static const float vertices[] = {
        0.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,

        0.0f, 1.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 1.0f,

        0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        0.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,

        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f,

        1.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 1.0f,

        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 1.0f,
        0.0f, 0.0f, 1.0f
        };


static const int vertexCnt = 6 * 4;

static const GLubyte cube[] = {
     0,  1,  2,  1,  2,  3,
     4,  5,  6,  5,  6,  7,
     8,  9, 10,  9, 10, 11,
    12, 13, 14, 13, 14, 15,
    16, 17, 18, 17, 18, 19,
    20, 21, 22, 21, 22, 23 
};

static const GLfloat texCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,

    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,

    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,

    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f
    };

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//glLoadIdentity();

//glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(3.1415927f, 1.0f, 1.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D, spriteTexture);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cube);

这篇关于将方形纹理映射到三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆