繁体   English   中英

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

[英]Mapping irregular shapes or other polygons (cartoons, sprites) to triangles in OpenGL ES

我不明白显示精灵映射到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”并将其切成六个三角形(ABG,BCG,CDG等),你必须确保你正在使用的任何纹理都是以坐标方式切片以匹配。 如果您只使用GL_TRIANGLES ,这GL_TRIANGLES ,因为最简单的方法是将纹理保留为六边形,但是一旦开始绘制条带或扇形,如果不保持近距离跟踪,则可以翻转,倾斜或复制由于绘制顺序,什么顶点映射到纹理的哪个部分。

顺便说一句 ,如果你只关心2D屏幕对齐的四边形 - 这是精灵通常用于 - 使用iPhone上提供的OES_Draw_Texture扩展,并在获得显着的速度提升时节省一大堆心痛。

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定义了你要剪出的纹理的坐标(以像素为单位,所以这将是一个64x64精灵)然后实际调用glDrawTexiOES将其直接放到屏幕视图中,其左下角放在playerX上playerY。

天哪,即使我在这里感受到“tl; dr”的感觉。 我为此道歉。

原因是在最低级别的渲染管道中它是所有三角形。 诸如多边形等更复杂的形状通过称为曲面细分的过程被转换成三角形的集合。

因此,如果你想对复杂的马里奥角色进行建模,那么诀窍就是让他成为三角形的集合,而不是一个三角形。

我在另一个答案中看到你提到透明像素。 我没有使用最新版本的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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM