4

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

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

为什么映射到三角形的形状不会被扭曲?

解释:

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

4

4 回答 4

6

如果我正确理解了这个问题:您只需将正方形分成两个三角形,然后使用纹理坐标将纹理相应地划分。如果你做得对,你会在屏幕上以 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

于 2010-05-28T14:49:57.870 回答
5

很简单,纹理不会被扭曲,因为您只会选择三个纹理坐标 - 每个顶点一个。您必须使用上面概述的两个三角形,并“剪辑”纹理的不同部分。

请原谅我在这里以及在这篇文章的其余部分中对 ASCII 艺术的可怕使用:

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

你会制作两个三角形 - ADB 和 ACD。A点映射到纹理的左上角,B点映射到左下角,C点映射到右上角,D点映射到右下角。如果你只映射一个三角形或另一个,你只会得到一半的精灵(或纹理,对于更复杂的形状)。这同样适用于更大或更复杂的多边形。纹理可以是一个单一的统一块,但每个顶点的纹理坐标必须以与几何本身相同的方式对其进行切片。

更复杂的例子,一个六边形:

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

如果您添加“G”的中间点并将其切成六个三角形(ABG、BCG、CDG 等),您必须确保您使用的任何纹理都按坐标进行切片以匹配。如果您只是使用 ,这无关紧要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); 

The rect defines the coordinates of the texture you're going to snip out (in pixels, so this would be a 64x64 sprite) and then the actual call to glDrawTexiOES plops it right into the screen view with its lower-left corner on playerX and playerY.

Goodness, even I get the feeling of "tl;dr" here. I apologize for that.

于 2010-06-03T13:27:28.760 回答
3

原因是在最低级别的渲染管道中,它都是三角形。更复杂的形状(如多边形等)通过称为镶嵌的过程转换为三角形的集合。

因此,如果您想为复杂的马里奥角色建模,诀窍实际上是将他变成一组三角形,而不是单个三角形。

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

编辑:

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

下面是相关的draw方法:

- (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];
}
于 2010-05-28T14:37:22.330 回答
-1

openGL 实际上可以绘制多边形,但通常不使用它们更安全,特别是在复杂的形状中。多边形可以自行“扭曲”,并生成无法正确渲染的无效形状。对于三角形,这永远不会发生。这就是为什么人们通常将复杂的形状分解为三角形的原因。

请参阅http://www.glprogramming.com/red/chapter02.html#name2以获得更好、更完整的解释。

于 2010-05-16T23:22:48.317 回答