C++ 基于2D瓷砖的游戏,当我用相机放大时显示瓷砖精灵之间的间隙?

C++ 基于2D瓷砖的游戏,当我用相机放大时显示瓷砖精灵之间的间隙?,c++,direct3d,direct3d9,C++,Direct3d,Direct3d9,我正在使用D3DXSPRITE方法将我的地图分幅绘制到屏幕上,我刚刚添加了一个缩放功能,当您按住向上箭头时,它会放大,但是注意到您现在可以看到分幅之间的间隙,下面是一些屏幕截图 每个瓷砖的标准尺寸为32x32 放大可以看到瓷砖之间的白色间隙 缩小到最坏的程度 这是我翻译的代码snipplet,可以用来缩放世界 D3DXMATRIX matScale, matPos; D3DXMatrixScaling(&matScale, zoom_, zoom_, 0.0f); D3DXMatrix

我正在使用D3DXSPRITE方法将我的地图分幅绘制到屏幕上,我刚刚添加了一个缩放功能,当您按住向上箭头时,它会放大,但是注意到您现在可以看到分幅之间的间隙,下面是一些屏幕截图

每个瓷砖的标准尺寸为32x32

放大可以看到瓷砖之间的白色间隙

缩小到最坏的程度

这是我翻译的代码snipplet,可以用来缩放世界

D3DXMATRIX matScale, matPos;

D3DXMatrixScaling(&matScale, zoom_, zoom_, 0.0f);
D3DXMatrixTranslation(&matPos, xpos_, ypos_, 0.0f);

device_->SetTransform(D3DTS_WORLD, &(matPos * matScale));
这是我画的地图,瓦片是一个向量的一个向量的瓦片。。而且我还没有完成扑杀

LayerInfo *p_linfo = NULL;
  RECT rect = {0};
  D3DXVECTOR3 pos;
  pos.x = 0.0f;
  pos.y = 0.0f;
  pos.z = 0.0f;

  for (short y = 0; 
    y < BottomTile(); ++y)
  {
    for (short x = 0; 
          x < RightTile(); ++x)
    {
      for (int i = 0; i < TILE_LAYER_COUNT; ++i)
      {
        p_linfo = tile_grid_[y][x].Layer(i);

        if (p_linfo->Visible())
        {
          p_linfo->GetTextureRect(&rect);

          sprite_batch->Draw(
            p_engine_->GetTexture(p_linfo->texture_id), 
            &rect, NULL, &pos, 0xFFFFFFFF);
        }
      }
      pos.x += p_engine_->TileWidth();
    }
    pos.x = 0;
    pos.y += p_engine_->TileHeight();
  }

欢迎来到浮点世界。这些间隙是由于使用浮点数的缺陷而存在的

在进行浮点运算时,您可能会非常小心,从而改善这种情况,但除非您将地形制作成一个完整的网格,否则这些接缝将存在

正是光栅化器给出了视图和投影矩阵以及顶点位置,稍微偏离了。你也许可以在这方面有所改进,但我不知道你会有多成功


与绘制不同的四边形不同,您可以只索引构成地形的可见顶点,并使用纹理平铺技术在其上绘制不同的内容。我相信这不会给你带来难看的接缝,因为在这种情况下,从技术上讲,没有接缝。

欢迎来到浮点世界。这些间隙是由于使用浮点数的缺陷而存在的

在进行浮点运算时,您可能会非常小心,从而改善这种情况,但除非您将地形制作成一个完整的网格,否则这些接缝将存在

正是光栅化器给出了视图和投影矩阵以及顶点位置,稍微偏离了。你也许可以在这方面有所改进,但我不知道你会有多成功


与绘制不同的四边形不同,您可以只索引构成地形的可见顶点,并使用纹理平铺技术在其上绘制不同的内容。我相信这不会给你带来难看的接缝,因为在这种情况下,从技术上讲,没有接缝。

这就是放大和缩小的问题。你的纹理应该有一个不可见的边界,并用相邻纹理的一部分填充。然后放大和缩小过滤器将使用该边界来计算边缘像素的颜色,而不是默认的白色


我想是的。

这就是放大和缩小的问题。你的纹理应该有一个不可见的边界,并用相邻纹理的一部分填充。然后放大和缩小过滤器将使用该边界来计算边缘像素的颜色,而不是默认的白色


我想是的。

你的纹理指数错了。0,0,32,32不是正确的值-它应该是0,0,31,31。在256像素的纹理图集中,从零开始的索引将产生0到255的值,而不是0到256的值,32x32纹理应产生0,0,31,31的值。在这种情况下,错误像素的颜色取决于右侧和底部下一个纹理的颜色。

您的纹理索引错误。0,0,32,32不是正确的值-它应该是0,0,31,31。在256像素的纹理图集中,从零开始的索引将产生0到255的值,而不是0到256的值,32x32纹理应产生0,0,31,31的值。在这种情况下,不正确像素的颜色取决于右侧和底部下一个纹理的颜色。

我在纹理映射方面也有类似的问题。对我有效的是改变采样器状态描述中的纹理地址模式;纹理地址模式用于控制direct3d对[0.0f,1.0f]范围外的纹理坐标所做的操作:我将address_,address_V,address_W成员更改为D3D11_texture_address_CLAMP,它基本上将纹理坐标的所有超出范围的值钳制为[0.0f,1.0f]范围。

我在纹理贴图方面也有类似的问题。对我有效的是改变采样器状态描述中的纹理地址模式;纹理地址模式用于控制direct3d对[0.0f,1.0f]范围外的纹理坐标所做的操作:我将address_,address_V,address_W成员更改为D3D11_texture_address_CLAMP,它基本上将纹理坐标的所有超出范围的值钳制为[0.0f,1.0f]范围。

经过长时间的搜索和测试,我发现这些规则是我读过的最完整的规则


再加上我自己的经验,我发现如果sprite PPI是72,你应该试着用更多的PPI来处理那张图像96或者更多。它实际上使sprite更致密,并且没有显示白色间隙的空间。

经过长时间的搜索和测试,我发现这个规则是我读过的最完整的规则

再加上我自己的经验,我发现如果sprite PPI是72,

您应该尝试对该图像使用更多PPI 96或更多。它实际上使sprite更密集,并且没有显示白色间隙的空间。

这不是FP缺陷,它太规则了。@DeadMG-Hmm,不。我敢打赌这是光栅化器中的取整问题。考虑到事情是如何安排的。您可以尽量减少此类问题的可见性,但它们始终存在。舍入问题不会定期产生影响,因为浮点表示的分布不均匀。伪影会或多或少地出现在较低的范围内。好吧,但是如果视图和/或投影矩阵设置得不好怎么办?我在Unity中遇到了完全相同的问题。我很确定它的fp不完美。这不是fp不完美,它太规则了。@DeadMG-Hmm,不。我敢打赌这是光栅化器中的舍入问题。考虑到事情是如何安排的。您可以尽量减少此类问题的可见性,但它们始终存在。舍入问题不会定期产生影响,因为浮点表示的分布不均匀。伪影会或多或少地出现在较低的范围内。好吧,但是如果视图和/或投影矩阵设置得不好怎么办?我在Unity中遇到了完全相同的问题。我很确定它有缺陷。如果你改变背景颜色,线条会改变颜色吗?这可能是有趣的知道,实际上排除了你的纹理或过滤没有发生什么。你真的需要使用着色器和ID3DXEffect,而不是固定功能。线条不改变颜色,只是看起来白色,我尝试了清晰的红色、蓝色、黑色,所有的看起来都一样。我来看看。如果你改变背景颜色,线条会改变颜色吗?这可能是有趣的知道,实际上排除了你的纹理或过滤没有发生什么。你真的需要使用着色器和ID3DXEffect,而不是固定功能。线条不改变颜色,只是看起来白色,我尝试了清晰的红色、蓝色、黑色,所有的看起来都一样。我来看看这些接缝是右边和底部纹理的颜色!但是我尝试返回一个0,0,31,31的rect,现在我有一个1像素的间隔。为什么我只能在放大或缩小时才能看到接缝?如果我用屏幕截图和画图检查,每个瓷砖现在是31像素宽,缺少一列pixels@Kaije:很可能是您的布局代码已关闭,无法在屏幕上定位它们。每个磁贴在循环中的位置间隔为32像素,使用0,0,31,31,每个磁贴的每侧都有1像素的间隙,当我截图并放大时,我计算了1个平铺的像素数,它的31x31像素缺少了一些纹理,我认为它需要0-32,因为通常当你循环通过某个东西时,你喜欢i=0;i<32;i++,它将通过0-31@Kaije:您应该尝试单独加载纹理,并为rect传递NULL,然后查看这是否解决了ahnd处的问题接缝是纹理右侧和底部的颜色!但是我尝试返回一个0,0,31,31的rect,现在我有一个1像素的间隔。为什么我只能在放大或缩小时才能看到接缝?如果我用屏幕截图和画图检查,每个瓷砖现在是31像素宽,缺少一列pixels@Kaije:很可能是您的布局代码已关闭,无法在屏幕上定位它们。每个磁贴在循环中的位置间隔为32像素,使用0,0,31,31,每个磁贴的每侧都有1像素的间隙,当我截图并放大时,我计算了1个平铺的像素数,它的31x31像素缺少了一些纹理,我认为它需要0-32,因为通常当你循环通过某个东西时,你喜欢i=0;i<32;i++,它将通过0-31@Kaije:您应该尝试单独加载纹理并为rect传递NULL,看看这是否解决了ahndI的问题。我认为这是真正的答案。纹理插值访问多个纹理。在边界上,某些texel没有值,这会导致这些瑕疵。这种映射加剧了这些问题。但是你的纹理看起来很简单,也许你可以把模式设置为重复。我想这才是真正的答案。纹理插值访问多个纹理。在边界上,某些texel没有值,这会导致这些瑕疵。这种映射加剧了这些问题。但是你的纹理看起来很简单,也许你可以将模式设置为“重复”。另请参见