SFML - 为什么绘制到 window 的精灵会使用 window 缩放(调整大小)
SFML - Why does a sprite drawn to a window scale with the window (resize)
这是一个MWE
#include <SFML/Graphics.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv)
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Title");
std::string image_filename;
image_filename = "image.png";
sf::Image image;
if(!image.loadFromFile(image_filename))
{
std::cout << "Error: Could not load file " << image_filename << std::endl;
}
sf::Texture texture;
texture.loadFromImage(image);
sf::Sprite sprite;
sprite.setTexture(texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
启动应用程序时,window 如下所示:
调整 window 大小后,window 看起来像这样:
调整大小前后精灵的全局和局部边界相同。
该行为(如屏幕截图所示)不是我期望的默认行为。
- window 的像素数(宽度和高度)已更改。
- image/texture/sprite 的相同区域绘制到 window。
- 已应用某种插值算法将初始 window 宽度和高度缩放到调整后的 window 宽度和高度。
也许这已经很明显了。这种行为在设计游戏**之类的东西时很有意义,但对于我打算实现的应用程序却没有意义。
**
(因为背景会随着 window 调整大小时“缩放”,而渲染分辨率会提前固定,可能由配置文件决定)
在尝试更改行为之前,我想了解行为为何如此。
大概打开一个具有初始默认分辨率(宽度 x 高度)的 RenderWindow
会在具有该宽度和高度的 GPU 上启动某种渲染实例。另一方面,调整 window 的大小可能会改变“window 系统”中 window 的宽度和高度(window 管理器,无论 OS它 运行 开启)但 不会 更新或更改 GPU 渲染实例上的相应宽度和高度。
或者至少这是我对发生的事情的最佳猜测。
有没有办法改变这种行为?也许使用像 SFML RenderWindow 这样的东西从根本上来说是错误的使用方法?
注意:我检查过,精灵的“比例”在调整大小操作期间没有改变。所以我的假设是初始 window 大小固定要渲染的像素数组的分辨率然后这是 upscaled/downscaled 以适应绘制像素数据时实际 window 的大小使用某种插值算法进入显示像素缓冲区。
您可以将以下事件侦听器添加到事件循环中:
if(event.type == sf::Event::Resized)
{
sf::FloatRect view(0, 0, event.size.width, event.size.height);
window.setView(sf::View(view));
}
这将在每次调整 window 大小时将渲染区域更新为 window 的尺寸,而不是缩放渲染区域以适应 window。
这是一个MWE
#include <SFML/Graphics.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv)
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Title");
std::string image_filename;
image_filename = "image.png";
sf::Image image;
if(!image.loadFromFile(image_filename))
{
std::cout << "Error: Could not load file " << image_filename << std::endl;
}
sf::Texture texture;
texture.loadFromImage(image);
sf::Sprite sprite;
sprite.setTexture(texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}
启动应用程序时,window 如下所示:
调整 window 大小后,window 看起来像这样:
调整大小前后精灵的全局和局部边界相同。
该行为(如屏幕截图所示)不是我期望的默认行为。
- window 的像素数(宽度和高度)已更改。
- image/texture/sprite 的相同区域绘制到 window。
- 已应用某种插值算法将初始 window 宽度和高度缩放到调整后的 window 宽度和高度。
也许这已经很明显了。这种行为在设计游戏**之类的东西时很有意义,但对于我打算实现的应用程序却没有意义。
** (因为背景会随着 window 调整大小时“缩放”,而渲染分辨率会提前固定,可能由配置文件决定)
在尝试更改行为之前,我想了解行为为何如此。
大概打开一个具有初始默认分辨率(宽度 x 高度)的 RenderWindow
会在具有该宽度和高度的 GPU 上启动某种渲染实例。另一方面,调整 window 的大小可能会改变“window 系统”中 window 的宽度和高度(window 管理器,无论 OS它 运行 开启)但 不会 更新或更改 GPU 渲染实例上的相应宽度和高度。
或者至少这是我对发生的事情的最佳猜测。
有没有办法改变这种行为?也许使用像 SFML RenderWindow 这样的东西从根本上来说是错误的使用方法?
注意:我检查过,精灵的“比例”在调整大小操作期间没有改变。所以我的假设是初始 window 大小固定要渲染的像素数组的分辨率然后这是 upscaled/downscaled 以适应绘制像素数据时实际 window 的大小使用某种插值算法进入显示像素缓冲区。
您可以将以下事件侦听器添加到事件循环中:
if(event.type == sf::Event::Resized)
{
sf::FloatRect view(0, 0, event.size.width, event.size.height);
window.setView(sf::View(view));
}
这将在每次调整 window 大小时将渲染区域更新为 window 的尺寸,而不是缩放渲染区域以适应 window。