更新时间:2023-11-30 18:29:58
要获得像素完美的坐标系,可以按如下所示设置矩阵:
To get a pixel-perfect coordinate system, you could set up your matrices as follows:
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映射,并将原点放在左下角.
This ensures a 1:1 mapping of OpenGL coordinates to pixels, and puts your origin in the bottom left corner.
关于纹理,如果您不想依赖非2的幂次扩展,则必须 将其填充为2的幂.即使OpenGL ES规范没有说它也必须是正方形的(据我所知),但我已经看到Android在512 x 128的纹理尺寸上发生了奇怪的事情,因此***坚持使用 square 具有2的幂次幂.
As to your texture, if you don't want to rely on the non-power-of-two extension, you must pad it to be a power of two. Even though the OpenGL ES spec doesn't say it has to be square as well (as far as I know), I've seen strange things happen on Android with texture sizes like 512 x 128, so it might be best to stick to square power-of-two textures.
要注意的是,无论纹理的像素大小如何,OpenGL中的纹理坐标始终在0到1之间.因此,如果您的精灵为48像素宽,并且将其填充为64 x 64的纹理,则它将跨越0到0.75的x坐标:
The thing to note is that texture coordinates in OpenGL are always between 0 and 1, no matter what the pixel size of your texture is. So if your sprite is 48 pixels wide, and you padded it to a texture of 64 x 64, then it will span the x coordinates from 0 to 0.75:
1 +--------+
| |
| |
+-----+ |
|\_O_/| |
| O | |
| / \ | |
0 +-----+--+
0 0.75 1 <- texture coordinates
0 48 64 <- pixels
因此,您必须为四边形的角设置这些纹理坐标.因为我们有一个完美的像素投影,所以四边形也必须恰好是48像素宽.
So you have to set up these texture coordinates for the corners of your quad. Because we have a pixel-perfect projection, the quad must also be exactly 48 pixels wide.
最后,要在x, y
位置绘制精灵(从左下角开始以像素为单位),请执行以下操作:
In conclusion, to draw your sprite at position x, y
(in pixels from the bottom left), do something like this:
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
等,因此您必须将这些坐标放入缓冲区中.而且它不允许四边形,因此您必须将其分成三角形.但这是基本思想.
I know OpenGL ES doesn't have glVertex2i
and so on, so you'll have to put these coordinates into a buffer. And it doesn't allow quads, so you'll have to split it up into triangles. But this is the basic idea.