我不明白将精灵映射到 OpenGL 三角形的概念。
如果 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
你会制作两个三角形 - 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.
原因是在最低级别的渲染管道中,它都是三角形。更复杂的形状(如多边形等)通过称为镶嵌的过程转换为三角形的集合。
因此,如果您想为复杂的马里奥角色建模,诀窍实际上是将他变成一组三角形,而不是单个三角形。
我在另一个答案中看到您提到透明像素。我没有使用最新版本的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];
}
openGL 实际上可以绘制多边形,但通常不使用它们更安全,特别是在复杂的形状中。多边形可以自行“扭曲”,并生成无法正确渲染的无效形状。对于三角形,这永远不会发生。这就是为什么人们通常将复杂的形状分解为三角形的原因。
请参阅http://www.glprogramming.com/red/chapter02.html#name2以获得更好、更完整的解释。