在 OpenGL ES 中将不规则形状或其他多边形(卡通、精灵)映射到三角形

StackOverflow https://stackoverflow.com/questions/2842339

我不明白显示映射到 OpenGL 三角形的精灵的概念。

如果OpenGL ES仅绘制三角形和点,如何显示/映射非三角形形状?

为什么映射到三角形的形状不会变形?

解释:

在我看来,将马里奥的精灵映射到三角形会产生扭曲或裁剪的马里奥。在这种情况下,头部会被压扁或看不见。

有帮助吗?

解决方案

如果我理解正确的担忧:您只需划分方成两个三角形,并使用纹理坐标相应地划分质感起来。如果你做对了,你在屏幕上绘制1质地:1,就好像它是一个精灵。 (当然也有旋转和伸展和诸如此类的东西的选项。)

0     1  <-- If your square is divided up like this, say, set texcoord
+-----+      for point 0 to be the top left of the sprite; for point 3, the
|\    |      bottom right of the sprite; and correspondingly, for points
| \   |      1 and 2.
|  \  |
|   \ |
|    \|
+-----+
2     3

事实证明,你不会很你期待的方式得到一个压扁的精灵。我想你想象绘制三角形0-3-2从我上面的图片,比方说,用显而易见的方式映射,并获得顶部扫描无限挤压到一个点(0点)?但实际上这不会发生,因为只有一个纹理坐标点0,所以(如果点2和3适当映射),你永远只能得到精灵的切除部分。

(这就是说,你可以在同一texcoord分配到两分,不过,还是让纹理交叉网本身,搞错了这样 - 很多方面仍然有余地弄得一团糟,不要担心。 )

这是在OpenGL的编程指南解释说,虽然这是一年又一年,因为我学会了这东西,所以我不知道它是如何有帮助的,如果你遇到了困难:的 http://glprogramming.com/red/chapter09.html

其他提示

很简单,质感也不会失真,因为你只能捡三个纹理坐标 - 每个顶点之一。你将不得不使用两个三角形如上文所概述,以及“剪辑”纹理的不同部分。

原谅我糟糕使用ASCII艺术在这里,在这篇文章的其余部分:

  Polygon     Texture        ADB        ACD
  A-----C  |  x-----x  |  x        |  x-----x
  |\    |  |  | ___ |  |  |        |    ___ |
  | \   |  |  |<o.o>|  |  |<o      |     .o>|
  |  \  |  |  | ### |  |  | ##     |      # |
  |   \ |  |  | -|- |  |  | -|-    |        |
  |    \|  |  | / \ |  |  | / \    |        |
  B-----D  |  x-----x  |  x-----x  |        x

您会想办法让两个三角形 - 亚行和ACD。点A映射到左上方的纹理,B到左下,C到右上方,和d到右下角。如果只图一个三角形或其他的,你只能得到精灵的一半(或纹理,为更复杂的形状)。这同样适用于更大或更复杂的多边形。纹理可以是一个单一的统一件,但每个顶点的纹理坐标具有切片它以相同的方式作为几何本身。

更复杂的例子,六边形:

   a   b
    ___
   /   \
f /  .  \ c
  \  g  /
   \___/
  e     d

如果您添加的“G”的中间点和切片它分成了6个三角形(ABG,BCG,CDG等),你必须确保任何纹理您所使用的切片,协调,明智的比赛。这不要紧,如果你仅仅使用GL_TRIANGLES,因为它是最容易见好就收纹理在它的六边形,但一旦你开始画条或风扇可以翻转,歪斜,或重复的,如果你不保持密切跟踪什么顶点的是映射到纹理的哪一部分,由于描绘顺序。

顺便说一句,如果你只是关注的2D画面对齐的四边形 - 这就是精灵通常是 - 使用的 OES_Draw_Texture iPhone上可用,并保存自己而拿起一个显著速度升压心痛的负荷。

int rect[4] = {0, 0, 64, 64}; 
glBindTexture(GL_TEXTURE_2D, texMario); 
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect); 
glDrawTexiOES(playerX, playerY, spriteZ, width, height); 

rect定义你要剪断出来的纹理坐标(以像素为单位,所以这将是一个64×64的精灵),然后glDrawTexiOES实际调用扑通一声它的权利与它的左下角屏幕视图上PlayerX的和playerY。

天哪,甚至我得到的感觉“TL;博士”在这里。我该道歉。

原因是在最底层的渲染管线中都是三角形。更复杂的形状(如多边形等)通过称为曲面细分的过程转换为三角形的集合。

因此,如果你想对复杂的马里奥角色进行建模,诀窍实际上是将他制作成三角形的集合,而不是单个三角形。

我在另一个答案中看到您提到了透明像素。我没有使用最新版本的 openGL,但碰撞的传统定义是基于表面和纹理的相交,即使是透明的,也没有被考虑在内。

编辑:

快速谷歌找到了一个使用 iDevGames.com 上的 GL_TRIANGLE_STRIP 的解决方案,网址是 http://www.idevgames.com/forum/showpost.php?p=143983&postcount=6

这是相关的绘制方法:

- (void)drawView {

    // Replace the implementation of this method to do your own custom drawing

    const GLfloat squareVertices[] = {
        -0.5f, -0.5f,
        0.5f,  -0.5f,
        -0.5f,  0.5f,
        0.5f,   0.5f,
    };

    GLshort genericTexCoords[] = { 0, 1, 1, 1, 0, 0, 1, 0 };

    [EAGLContext setCurrentContext:context];

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
    glMatrixMode(GL_MODELVIEW);
    glRotatef(3.0f, 0.0f, 0.0f, 1.0f);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glTexCoordPointer(2, GL_SHORT, 0, genericTexCoords);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, sprite);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

openGL的其实可以绘制多边形,但它通常是安全的不使用它们,特别是在复杂的形状。多边形可以对自己的“扭曲”,并不能正确地渲染的无效形状。随着三角形,这永远不会发生。这就是为什么人们通常分手复杂形状的三角形。

请参阅 http://www.glprogramming.com/red/chapter02.html# NAME2 以更好,更完整的解释。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top