在 OpenGL ES 中将不规则形状或其他多边形(卡通、精灵)映射到三角形
我不明白显示映射到 OpenGL 三角形的精灵的概念。
如果OpenGL ES仅绘制三角形和点,如何显示/映射非三角形形状?
为什么映射到三角形的形状不会变形?
解释一下:
在我看来,将马里奥的精灵映射到三角形会产生扭曲或裁剪的马里奥。在这种情况下,头部会被压扁或看不见。
I don't understand the concept of showing sprites mapped into OpenGL Triangles.
If OpenGL ES only draws triangles and points, How do you display/map non-triangular shapes?
Why would a shape mapped to a triangle not be distorted?
To explain:
In my mind, mapping, say, a sprite of Mario, to a triangle would produce a distorted or cropped Mario. In such a case, the head would be squished or invisible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我正确理解了这个问题:您只需将正方形分成两个三角形,然后使用纹理坐标相应地划分纹理即可。如果操作正确,您将在屏幕上以 1:1 的比例绘制纹理,就像它是一个精灵一样。 (当然,您还可以选择旋转和拉伸等。)
事实证明,您不会以您期望的方式获得压扁的精灵。我想象你正在想象从我上面的图片中绘制三角形 0-3-2,比如说,以明显的方式映射,并将顶部扫描线无限地压缩为一个点(点 0)?但事实上这不会发生,因为点 0 只有一个纹理坐标,所以(如果点 2 和 3 被正确映射)你将只能得到精灵的剪切部分。
(也就是说,您可以将相同的纹理坐标分配给两个点,或者使纹理自身交叉,这样就会出错——仍然有足够的空间造成混乱,不用担心。)
这是在 OpenGL 编程指南中进行了解释,尽管我已经学习这些东西很多年了,所以我不确定如果你遇到困难它会有多大帮助:http://glprogramming.com/red/chapter09.html
If I've understood the concern correctly: you simply divide the square into two triangles, and use texture coordinates to divide the texture up correspondingly. If you do it right, you get the texture drawn on screen, 1:1, as if it were a sprite. (Of course you also have the option of rotation and stretching and whatnot.)
As it turns out, you won't get a squished sprite in quite the way you're expecting. I imagine you're picturing drawing the triangle 0-3-2 from my picture above, say, mapped in the obvious fashion, and getting the top scanline infinitely squeezed into one point (point 0)? But in fact this won't happen, because there's only one texture coordinate for point 0, so (if points 2 and 3 are mapped appropriately) you'll only ever get the cut-out part of the sprite.
(That said, you could assign the same texcoord to two points, though, or make the texture cross over itself, and get it wrong that way -- there's still plenty of scope for making a mess, don't worry.)
This is explained in the OpenGL programming guide, though it's years and years since I learnt this stuff so I'm not sure how helpful it will be if you're having difficulty: http://glprogramming.com/red/chapter09.html
很简单,纹理不会扭曲,因为您只需选择三个纹理坐标 - 每个顶点一个。您必须使用上面概述的两个三角形,并“剪辑”纹理的不同部分。
请原谅我在这里以及本文的其余部分中对 ASCII 艺术的可怕使用:
您将制作两个三角形 - ADB 和 ACD。点 A 映射到纹理的左上角,B 映射到左下角,C 映射到右上角,D 映射到右下角。如果仅映射一个三角形或另一个三角形,则只能获得精灵的一半(或纹理,对于更复杂的形状)。这同样适用于更大或更复杂的多边形。纹理可以是一个统一的块,但每个顶点的纹理坐标必须以与几何体本身相同的方式将其分割。
更复杂的例子,六边形:
如果您添加“G”的中点并将其切成六个三角形(ABG、BCG、CDG 等),您必须确保您使用的任何纹理都被切片坐标方面进行匹配。如果您只使用 GL_TRIANGLES,这并不重要,因为最简单的方法是将纹理保留为六边形形状,但是一旦您开始绘制条带或扇形,您就可以翻转、倾斜或复制,如果由于绘制顺序,您无法密切跟踪哪个顶点映射到纹理的哪个部分。
顺便说一句,如果您只关心 2D 屏幕对齐的四边形(这就是精灵通常的用途),请使用 OES_Draw_Texture 扩展可在 iPhone 上使用,在显着提高速度的同时,可以让您省去不少麻烦。
rect
定义您要剪切的纹理的坐标(以像素为单位,因此这将是一个 64x64 精灵),然后对glDrawTexiOES
的实际调用将其扑通扑通右进入屏幕视图,其左下角位于玩家 X 和玩家 Y 上。天哪,连我都感受到了“tl;dr”的感觉。我对此表示歉意。
Quite simply, the texture won't be distorted because you'll only be picking three texture coordinates - one per vertex. You'll have to use two triangles as outlined above, and "clip" different portions of the texture.
Pardon my horrible use of ASCII art here, and in the rest of this post:
You'd make two triangles - ADB and ACD. Point A maps to the top-left of the texture, B to the bottom-left, C to the top-right, and D to the bottom-right. If you only map one triangle or the other, you only get half of the sprite (or texture, for a more complex shape.) The same applies for larger or more complex polygons. The texture can be a single unified piece, but the texture coordinates of each vertex has to slice it up in the same manner as the geometry itself.
More complex example, a hexagon:
If you add a middle point of "G" and slice it up into six triangles (ABG, BCG, CDG, etc) you'll have to make sure that whatever texture you're using is sliced up coordinate-wise to match. This doesn't matter if you're just using
GL_TRIANGLES
, since it's easiest to just leave the texture in its hexagonal shape, but once you start drawing strips or fans you can flip, skew, or duplicate if you don't keep close track of what vertex is mapping to what part of the texture, due to the drawing order.As an aside, if you're just concerned with 2D screen-aligned quads - which is what sprites are generally for - use the OES_Draw_Texture extension available on the iPhone and save yourself a load of heartache while picking up a significant speed boost.
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 toglDrawTexiOES
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.
原因是在最底层的渲染管线中都是三角形。更复杂的形状(例如多边形等)通过称为曲面细分的过程转换为三角形的集合。
因此,如果你想对复杂的马里奥角色进行建模,诀窍实际上是将他制作成三角形的集合,而不是单个三角形。
我在另一个答案中看到您提到了透明像素。我没有使用最新版本的 openGL,但碰撞的传统定义是基于表面和纹理的相交,即使是透明的,也没有被考虑在内。
编辑:
快速谷歌找到了一个使用 iDevGames.com 的 GL_TRIANGLE_STRIP 的解决方案,网址为 http://www.idevgames.com/forum/showpost.php?p=143983&postcount=6
这里是相关的抽奖方法:
The reason is in the rendering pipeline at the lowest level it is all triangles. More complicated shapes like polygons and the like are transformed into a collection of triangles through a process called tessellation.
So if you want to model your complicated Mario character the trick is actually to make him into a collection of triangles, not a single one.
I see in another answer you mentioned transparent pixels. I have not used the newest versions of openGL but the traditional definition a collision is based on intersecting the surface and the texture, even a transparent one, was not taken into account.
EDIT:
A quick google turned up a solution using a GL_TRIANGLE_STRIP off of iDevGames.com The Url is http://www.idevgames.com/forum/showpost.php?p=143983&postcount=6
Here is the relevant draw method:
openGL 实际上可以绘制多边形,但通常不使用它们更安全,特别是在复杂的形状中。多边形可能会“扭曲”自身并形成无法正确渲染的无效形状。对于三角形,这种情况永远不会发生。这就是为什么人们通常将复杂的形状分解为三角形。
请参阅http://www.glprogramming.com/red/chapter02.html#name2 以获得更好、更完整的解释。
openGL can actually draw polygons, but it's usually safer not to use them, specially in complex shapes. Polygons can "twist" on themselves and make an invalid shape that can't be correctly rendered. With triangles, this never happens. That's why people usually break up complex shapes to triangles.
See http://www.glprogramming.com/red/chapter02.html#name2 for a better, more complete explanation.