我想绘制一个任意大小的精灵作为png,说一些完全疯狂的像56宽x 30高。两个维度都不是2的幂。此外,我可能想绘制另一个72宽x 33高的精灵。表明这是因为这里没有'技巧',我需要处理一般情况。
所以我有这个png(透明度),我想把它画成一个绝对没有拉伸,插值等的精灵。我希望它能在屏幕上用像素1:1进行映射。假装这些精灵是像素艺术(它们可能是也可能不是,但它们是为精确的分辨率绘制的。)
我理解精灵绘图 - 两个三角形作为四边形,通过纹理坐标映射渲染我的纹理 - 但是我只能理解它的2的幂。我也不明白如何调整我的'四边形'并设置我的GL矩阵使得我可以使精灵与像精灵一样的像素大小完全相同
我正在使用OpenGL ES,因此使用新扩展来使用非2次幂纹理是不可接受的。
我一次只吸引3-10个精灵,所以我愿意接受有关效率的建议,但我最感兴趣的是“准确”的结果。
答案 0 :(得分:5)
要获得像素完美的坐标系,您可以按如下方式设置矩阵:
glViewport(0, window_width, 0, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, 0, window_height, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
这确保了OpenGL坐标到像素的1:1映射,并将您的原点放在左下角。
关于你的纹理,如果你不想依赖非幂二扩展,你必须将它填充为2的幂。虽然OpenGL ES规范并没有说它必须是方形的(据我所知),我看到Android上出现奇怪的事情,纹理大小为512 x 128,所以最好坚持 square 两种纹理。
需要注意的是,无论纹理的像素大小是多少,OpenGL中的纹理坐标总是在0和1之间。因此,如果您的精灵宽度为48像素,并且将其填充为64 x 64的纹理,那么它将跨越0到0.75的x坐标:
1 +--------+
| |
| |
+-----+ |
|\_O_/| |
| O | |
| / \ | |
0 +-----+--+
0 0.75 1 <- texture coordinates
0 48 64 <- pixels
因此,您必须为四边形的角设置这些纹理坐标。因为我们有一个像素完美的投影,所以四边形也必须恰好是48像素宽。
总之,要在位置x, y
(从左下角开始的像素)中绘制精灵,请执行以下操作:
float texcoord_x = (float)sprite_width / texture_width;
float texcoord_y = (float)sprite_height / texture_height;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_id);
glBegin(GL_QUADS);
// bottom left
glTexCoord2f(0, 0);
glVertex2i(x, y);
// bottom right
glTexCoord2f(texcoord_x, 0);
glVertex2i(x + sprite_width, y);
// top right
glTexCoord2f(texcoord_x, texcoord_y);
glVertex2i(x + sprite_width, y + sprite_height);
// top left
glTexCoord2f(0, texcoord_y);
glVertex2i(x, y + sprite_height);
glEnd();
我知道OpenGL ES没有glVertex2i
等等,所以你必须将这些坐标放入缓冲区。并且它不允许四边形,因此您必须将其拆分为三角形。但这是基本的想法。