【发布时间】:2018-05-18 04:32:43
【问题描述】:
我已经实现了一个用于检查完美碰撞的像素掩码类。我使用的是 SFML,所以实现相当简单:
循环遍历图像的每个像素,并根据其透明度值决定其真假。这是我使用的代码:
// Create an Image from the given texture
sf::Image image(texture.copyToImage());
// measure the time this function takes
sf::Clock clock;
sf::Time time = sf::Time::Zero;
clock.restart();
// Reserve memory for the pixelMask vector to avoid repeating allocation
pixelMask.reserve(image.getSize().x);
// Loop through every pixel of the texture
for (unsigned int i = 0; i < image.getSize().x; i++)
{
// Create the mask for one line
std::vector<bool> tempMask;
// Reserve memory for the pixelMask vector to avoid repeating allocation
tempMask.reserve(image.getSize().y);
for (unsigned int j = 0; j < image.getSize().y; j++)
{
// If the pixel is not transparrent
if (image.getPixel(i, j).a > 0)
// Some part of the texture is there --> push back true
tempMask.push_back(true);
else
// The user can't see this part of the texture --> push back false
tempMask.push_back(false);
}
pixelMask.push_back(tempMask);
}
time = clock.restart();
std::cout << std::endl << "The creation of the pixel mask took: " << time.asMicroseconds() << " microseconds (" << time.asSeconds() << ")";
我使用了sf::Clock 的实例来测量时间。
我的问题是,对于较大的图像(例如 1280x720),此功能需要很长时间(例如 15 秒)。有趣的是,仅在调试模式下。编译发布版本时,相同的纹理/图像只需 0.1 秒或更短。
我尝试通过使用 resize() 方法来减少内存分配,但并没有太大变化。我知道循环通过近 100 万像素很慢,但应该不会慢 15 秒吧?
由于我想在调试模式下测试我的代码(出于显而易见的原因)并且我不想等待 5 分钟直到所有像素掩码都创建完毕,所以我正在寻找的基本上是一种方法:
- 优化代码/我是否遗漏了一些明显的东西?
- 或者在调试模式下获得类似于发布性能的东西
感谢您的帮助!
【问题讨论】:
-
调试模式总是很慢;不要为此进行优化。
-
你用的是什么编译器?如果是 Visual Studio,只需更改发布设置即可生成调试信息。另外,关闭发布模式的优化。 很多 VS 的缓慢是由于迭代器检查 - 去掉它,即使是未优化的发布程序运行速度也明显更快。
-
您可以使用单个向量来代替 向量的向量。这将节省大量分配(通常非常慢)。然后使用数学公式
mask[(x * width) + y]访问xy值 -
另外,pixel by pixel 检查碰撞可能比检查游戏实体占据的一般形状慢很多
-
@AdrianKoch 我通常有 3 种配置。发布、调试、ReleaseWIthDebugInfo。后者和release完全一样,只是开启了调试信息的生成,禁用了优化。
标签: c++ loops c++11 optimization sfml