IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> Sprites and textures -> 正文阅读

[开发工具]Sprites and textures

系列文章

SFML-windows 篇
SFML-Events explained 篇
SFML-Keyboard, mouse and joystick 篇
SFML-Using OpenGL in a SFML window 篇
SFML-Drawing 2D stuff 篇
SFML-Shapes 篇
SFML-Sprites and textures 篇


一、Vocabulary


你们中的大多数人(如果不是所有人)已经熟悉这两个非常常见的对象Sprites and textures,那么让我们非常简单地定义它们。

texture是一个图像。但我们称之为“ texture”,因为它有一个非常特殊的角色:映射到2D实体。

sprite只不过是一个纹理矩形。
在这里插入图片描述这就是Sprite and texture

二、Loading a texture


在创建任何精灵之前,我们需要一个有效的纹理。令人惊讶的是,在SFML中封装纹理的类是sf::Texture。由于纹理的唯一作用是加载并映射到图形实体,因此其几乎所有功能都与加载和更新有关。

加载纹理最常见的方法是从磁盘上的图像文件加载纹理,这是通过loadFromFile函数完成的。

sf::Texture texture;
if (!texture.loadFromFile("image.png"))
{
    // error...
}

loadFromFile函数有时会在没有明显原因的情况下失败。首先,检查SFML打印到标准输出的错误消息(检查控制台)。如果消息是“无法打开文件”,请确保工作目录(即任何文件路径将被解释的相对目录)是您认为的:当您从桌面环境运行应用程序时,工作目录是可执行文件夹。但是,当您从IDE启动程序时(Visual Studio,代码::块,…)工作目录有时可能设置为项目目录。这通常可以在项目设置中很容易地更改。

您还可以从内存(loadFromMemory)、自定义输入流(loadFromStream)或已加载的图像(loadFromImage)加载图像文件。后者从sf::Image加载纹理,这是一个帮助存储和操作图像数据(修改像素、创建透明度通道等)的实用类。sf::image的像素保留在系统内存中,这确保了对它们的操作将尽可能快,而纹理的像素位于视频内存中,因此检索或更新速度较慢,但绘制速度非常快。

SFML支持最常见的图像文件格式。完整列表可在API文档中找到。

所有这些加载函数都有一个可选参数,如果您想加载图像的较小部分,可以使用该参数。

// load a 32x32 rectangle that starts at (10, 10)
if (!texture.loadFromFile("image.png", sf::IntRect(10, 10, 32, 32)))
{
    // error...
}

IntRect类是一个表示矩形的简单实用程序类型。其构造函数采用左上角的坐标和矩形的大小。

如果您不想从图像加载纹理,而是想直接从像素阵列中更新纹理,可以将其创建为空,稍后再更新:

// create an empty 200x200 texture
if (!texture.create(200, 200))
{
    // error...
}

请注意,此时纹理的内容未定义。

要更新现有纹理的像素,必须使用更新功能。它具有多种数据源的重载:

// update a texture from an array of pixels
sf::Uint8* pixels = new sf::Uint8[width * height * 4]; // * 4 because pixels have 4 components (RGBA)
...
texture.update(pixels);

// update a texture from a sf::Image
sf::Image image;
...
texture.update(image);

// update the texture from the current contents of the window
sf::RenderWindow window;
...
texture.update(window);

这些示例都假设源与纹理大小相同。如果不是这种情况,即如果只想更新纹理的一部分,可以指定要更新的子矩形的坐标。有关更多详细信息,请参阅文档。

此外,纹理有两个属性,可以更改其渲染方式。

第一个属性允许平滑纹理。平滑纹理会降低像素边界的可视性(但图像会变得更模糊),如果将其放大,这可能是可取的。

texture.setSmooth(true);

在这里插入图片描述

第二个属性允许在单个精灵中重复平铺纹理。

texture.setRepeated(true);

在这里插入图片描述

三、现在可以拥有我的sprite了吗?


Yes, you can now create your sprite.

sf::Sprite sprite;
sprite.setTexture(texture);

… 最后画出来。

// inside the main loop, between window.clear() and window.display()
window.draw(sprite);

如果不希望精灵使用整个纹理,可以设置其纹理矩形。

sprite.setTextureRect(sf::IntRect(10, 10, 32, 32));

你也可以改变Sprite的颜色。设置的颜色将随精灵的纹理进行调制(相乘)。这也可以用于更改精灵的全局透明度(alpha)

sprite.setColor(sf::Color(0, 255, 0)); // green
sprite.setColor(sf::Color(255, 255, 255, 128)); // half transparent

这些精灵都使用相同的纹理,但颜色不同:
在这里插入图片描述
精灵也可以变换:它们有位置、方向和比例。

// position
sprite.setPosition(sf::Vector2f(10.f, 50.f)); // absolute position
sprite.move(sf::Vector2f(5.f, 10.f)); // offset relative to the current position

// rotation
sprite.setRotation(90.f); // absolute angle
sprite.rotate(15.f); // offset relative to the current angle

// scale
sprite.setScale(sf::Vector2f(0.5f, 2.f)); // absolute scale factor
sprite.scale(sf::Vector2f(1.5f, 3.f)); // factor relative to the current scale

默认情况下,这三个变换的原点是精灵的左上角。如果要将原点设置为不同的点(例如精灵的中心或另一个角),可以使用setOrigin函数。

sprite.setOrigin(sf::Vector2f(25.f, 25.f));

由于转换函数对于所有SFML实体都是通用的,因此在单独的教程:Transforming entities.中对其进行了解释。

四、The white square problem


您成功加载了纹理,正确构建了精灵,然后。。。你现在在屏幕上看到的是一个白色的正方形。怎么搞的?

这是一个常见的错误。设置精灵的纹理时,它在内部所做的只是存储指向纹理实例的指针。因此,如果纹理被破坏或移动到内存中的其他位置,则精灵最终会使用无效的纹理指针。

编写此类函数时会出现此问题:

sf::Sprite loadSprite(std::string filename)
{
    sf::Texture texture;
    texture.loadFromFile(filename);

    return sf::Sprite(texture);
} // error: the texture is destroyed here

你必须正确地管理你的纹理的生命周期,并确保它们在任何精灵使用的时候都有效。

五、The importance of using as few textures as possible

使用尽可能少的纹理是一个很好的策略,原因很简单:更改当前纹理对于显卡来说是一项昂贵的操作。绘制多个使用相同纹理的精灵将产生最佳性能。

此外,使用单个纹理可以将静态几何体分组到单个实体中(每次绘制调用只能使用一个纹理),这将比绘制一组多个实体快得多。静态几何体的批处理涉及其他类,因此超出了本教程的范围,有关更多详细信息,请参阅vertex array教程。

在创建动画表或平铺集时,请记住这一点:使用尽可能少的纹理。

六、Using sf::Texture with OpenGL code


如果您使用的是OpenGL而不是SFML的图形实体,那么仍然可以使用sf::Texture作为OpenGL纹理对象的包装,并将其与OpenGL代码的其余部分一起使用。

要绑定用于绘制的sf::Texture(基本上是glBindTexture),可以调用bind static函数。

sf::Texture texture;
...

// bind the texture
sf::Texture::bind(&texture);

// draw your textured OpenGL entity here...

// bind no texture
sf::Texture::bind(NULL);
  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:10:55  更:2022-07-04 23:11:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 8:54:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计