【问题标题】:Mapping a square texture to a triangle将正方形纹理映射到三角形
【发布时间】:2013-08-14 20:27:00
【问题描述】:

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

    // 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);

现在,经过无数次尝试,我无法让它为其他方面工作...... 将方形纹理映射到三角形时,是否有一些经验法则?

编辑:我想我知道应该如何进行映射。但它不适用于这个例子(一张脸)。有人可以验证我是否正确完成了映射(假设其余代码正常工作)?

非常感谢

【问题讨论】:

  • 我认为没有办法在重用相同顶点数据的同时将正方形巧妙地映射到立方体上。我会将您的立方体重新设计为 6 个独立的四边形 = 24 个顶点而不是 8 个。
  • 我怀疑您的 normals 数组有误。你能告诉我们你的普通指针的内容是什么吗?你改变了每张脸的法线吗?
  • 法线有点错误,但我不知道它们对纹理映射有影响。我以为它们只会影响光照......会检查一下。谢谢

标签: objective-c graphics opengl-es texture-mapping


【解决方案1】:

和其他人一样,我认为将四边形纹理映射到三角形上没有什么技巧。

您遇到的主要问题是每个角的纹理坐标不连续。如果一个角作为一个面的一些 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.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);

【讨论】:

  • 您能否验证我在上面的示例中正确映射了坐标。顺便提一句。感谢您的信息!
  • 他现在正在尝试画一张脸。不连续不是问题。
  • 是的,问题已被编辑(以前用于立方体);-) 现在映射似乎正确,所以如果屏幕上没有出现任何内容,我将首先禁用面部剔除和 GL_COLOR_MATERIAL。
  • 感谢您的回答。你帮我理清了一些事情,我意识到我不能以我想要的方式做我想做的事。 :)
【解决方案2】:

我没有尝试破解你的顶点列表,但我的猜测是你的坐标完全搞砸了并且映射错误,你指定的索引缓冲区格式不正确,或者你有背面剔除已打开,并且您的某些顶点的顺序错误。

至于纹理坐标本身,与四边形相比,映射到三角形应该没有什么技巧。你只需要有 6 个纹理坐标,而之前你有 4 个,因为有 6 个顶点(每个面两个重复)。您可以像使用多维数据集一样使用索引缓冲区来避免重复。

至于潜在的背面剔除问题,您必须每次都以相同的顺序定义顶点。全部顺时针,相对于纹理将面对的方向,或全部逆时针。

您使用什么命令来设置您的 OpenGL 管道,以及您使用什么命令来绘制这些顶点?请在问题中添加相应的代码。

【讨论】:

    猜你喜欢
    • 2014-07-08
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 1970-01-01
    • 2013-08-14
    • 2018-12-27
    • 1970-01-01
    相关资源
    最近更新 更多