在OpenGL中使用纹理集为单个瓦片计算纹理坐标

3

我正在写一个使用C# / OpenGl与OpenTK库的游戏程序,想要使用纹理图集。

我将我的纹理图集作为OpenGL中的纹理加载(尺寸为256x256),每个瓷砖为32x32。

要显示图集的第一个瓷砖,我使用了以下代码:

GL.Begin(BeginMode.Quads);
GL.TexCoord2(0, 0); GL.Vertex2(0, 0);
GL.TexCoord2(0.125f, 0); GL.Vertex2((32 * zoom), 0);
GL.TexCoord2(0.125f, 0.125f); GL.Vertex2((32 * zoom), (32 * zoom));
GL.TexCoord2(0, 0.125f); GL.Vertex2(0, (32 * zoom));
GL.End();

0.125是通过将1/8相除得出的,其中8是一行/列中的瓷砖数量。

我不知道如何用这种方法计算第二个瓷砖的坐标!我尝试在0和0.125的位置分别使用0.125和0.25,但没有任何效果。我猜测您不能在第一个(0)纹理坐标中使用大于零的值?

如果有人能够提供帮助或提供更好的解决方法,将不胜感激!


请在您的帖子中不要使用签名或标语 - user229044
3个回答

2
尝试一下这个:

给它一个机会:

int col = 0;
int row = 0;
float tex_w = 256;
float tex_h = 256;
float tile_w = 32;
float tile_h = 32;
float w_factor = tile_w / tex_w;
float h_factor = tile_h / tex_h;

float x_tex_beg = w_factor*(col+0);
float x_tex_end = w_factor*(col+1);
float y_tex_beg = h_factor*(row+0);
float y_tex_end = h_factor*(row+1);

非常感谢!这将在我的坐标生成例程中帮助很多 :) - CPatton

1
  1. 去掉“*缩放”。在gl.begin之前调用gl.scale(zoom,zoom,1)即可。
  2. 像这样嵌套循环查看8x8个瓷砖:

    GL.Scale(zoom*32,zoom*32,1);
    GL.Begin(BeginMode.Quads);
    for (int i=0; i<8; i++)
    for (int j=0; j<8; j++)
    {
    var x = i/8.0; // 纹理比例
    var y = j/8.0;
    GL.TexCoord2(x, y); GL.Vertex2(i, j);
    GL.TexCoord2(x+0.125f, y); GL.Vertex2(i+1, j);
    GL.TexCoord2(x+0.125f, y+0.125f); GL.Vertex2(i+1, j+1);
    GL.TexCoord2(x, y+0.125f); GL.Vertex2(i, j+1);
    }
    GL.End();
    GL.Scale(1.0/(zoom*32),1.0/(zoom*32),1); // 取消缩放


对于#1,这会提高性能,我猜测?感谢您的提示。我对此的数学计算感到相当困惑,我刚刚重新开始编程,经过了相当长的间歇期。非常感谢 :) - CPatton
抱歉发重复评论,但是有一个问题:我注意到当我使用这段代码时,纹理集的底部出现了灰色直线。只有4个纹理,其余部分都是透明的(32位png)。 有什么原因吗?谢谢 - CPatton
嗯...我不确定我理解问题。也许可以发布一张图片(试试imgur.com)。 - sharoz
当缩放比例为1且瓦片显示为32px时,灰线不可见,但如果缩放比例增加,则该线变得可见。我检查了Photoshop中的图集,但并不是那里的问题。 - CPatton
嗯...也许是你的卡片纹理采样出了问题。尝试在每个texcoord上添加0.001f:texcoord2(x + 0.001f,y + 0.001f)。 - sharoz

0

纹理坐标在0到1之间。可以将其想象为瓷砖网格的平移,但每个瓷砖不是32x32,而是0.125fx0.125f。 此外,256/8 = 32。您可以通过32/256计算得出该数字。

要获取第二个瓷砖(假设您正在水平方向上移动),需要将纹理坐标的x值进行移位(即添加0.125f)。例如:

GL.TexCoord2(0.125f, 0); GL.Vertex2(0, 0);
GL.TexCoord2(0.25f, 0); GL.Vertex2((32 * zoom), 0);
GL.TexCoord2(0.25f, 0.125f); GL.Vertex2((32 * zoom), (32 * zoom));
GL.TexCoord2(0.125f, 0.125f); GL.Vertex2(0, (32 * zoom));

啊哈!我通过1/8得到了这个数字,但是同样的事情! :) 啊哈!这里的0很容易让人感到困惑,我完全忽略了x和y之间的差异,只是看着它们的值。 非常感谢,我会尝试一下。 - CPatton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接