Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SFML Game Development.pdf
Скачиваний:
194
Добавлен:
28.03.2016
Размер:
4.19 Mб
Скачать

Keeping Track of Your Textures – Resource Management

Non-multimedia items such as scripts that describe the in-game world, menu content, or artificial intelligence are also considered resources. Configuration files containing user settings such as the screen resolution and the music volume are good examples of resources as well. However, when we mention resources in the book, we mostly refer to multimedia resources.

Resources are usually loaded from a file on the hard disk. Although being the most common approach, it is not the only one—other possible examples are the RAM or the network.

Resources in SFML

SFML offers classes to deal with a wide variety of resources. Often, the resource classes are not directly used to output multimedia on the periphery. Instead, there is an intermediate front-end class, which refers to the resource. In contrast to the resource class which holds all the data, the front-end class is lightweight and can be copied without severe performance impacts.

All resource classes contain member functions to load from different places. Depending on the exact resource type, there may be slight deviations. A typical method to load a resource from a file has the following signature:

bool loadFromFile(const std::string& filename);

The function parameter contains the path to the file, where the resource is stored, and the return value is a bool, which is true if loading was successful, and false if it failed. It is important to check return values in order to react to possible errors, such as invalid file paths.

SFML resources also provide methods to load resources from media other than the hard disk. The function loadFromMemory() loads a resource from RAM, which may be useful to load resources that are directly embedded into the executable. The member function loadFromStream() loads the resource using a custom sf::InputStream instance. This allows the user to exactly specify the loading process. Important use cases of user-defined streams are encrypted and/or compressed file archives.

SFML's resource classes are explained in more detail in the following sections. For this game, we will focus on loading from files.

[ 30 ]

www.it-ebooks.info

Chapter 2

Textures

The class sf::Texture represents a graphical image. The image is stored as an array of pixels in the graphics card's video memory, that is, it does not reside in the RAM. Each pixel is a 32 bit RGBA value, specifying a color with the components red, green, blue, and alpha (transparency), at a certain position in the image. Many common image formats are supported by SFML, for example, JPEG, BMP, PNG, or GIF.

Textures can be drawn on the screen with the sf::Sprite class. A sprite is a lightweight object that refers to a texture or a rectangular part of it. It stores attributes such as the position, rotation, scale, or color to affect the way the texture is represented on the screen. Multiple sprites can refer to the same texture and have different attributes, while the texture itself is not affected. The separation between sprites and textures has a big advantage that we have a simple possibility to deal with graphics using sf::Sprite, while the heavyweight sf::Texture need not be modified.

Images

The sf::Image class is a container for pixel values. It behaves similarly to sf::Texture; however it stores its pixels on the RAM instead of the video memory, which makes it possible to manipulate single pixels. sf::Image is able to load the same image formats as sf::Texture. It is also capable of saving the

stored image back to a file. It is interesting to know that sf::Texture loads the data using an intermediate sf::Image, more exactly, the sf::Texture::loadFromX() functions are just a shortcut for combined sf::Image::loadFromX() and

sf::Texture::loadFromImage() calls.

When we want to display a sf::Image on the screen, we first have to convert it into a sf::Texture, and create a sf::Sprite referring to it. It is also possible to construct a texture only from a rectangular part of an image, in situations where not all the pixels are going to be displayed. As a result, no memory on the graphics card is wasted. In cases where we do not need to access the single pixels of an image after loading, we are better off when we directly use sf::Texture.

[ 31 ]

www.it-ebooks.info

Keeping Track of Your Textures – Resource Management

An important use case for sf::Image is the situation where big textures are required. sf::Texture can only store textures on the graphics card that do not exceed a hardware-dependent size. This limit can be retrieved with sf::Texture::getMaximumSize(). If you try to load bigger textures into

sf::Texture, loading will fail. However, you sometimes still need to draw big sprites, for example, a static background for the whole window. What you can do is to load the pixels into sf::Image, which does not use the graphics card's memory to store them. Afterwards, you can create multiple sf::Texture objects, of which each one is only loaded from a rectangular part of the image. Eventually, the whole image can be drawn by using multiple sf::Sprite objects, where each sprite references one texture.

Fonts

The sf::Font class is SFML's resource type that stores a character font and provides an interface to manipulate it. A font consists of glyphs, where a glyph is the visual representation of a character. Glyphs are loaded on demand, that is, when the user needs to render a certain character with a certain font size, the corresponding glyph is sought in the font file. Therefore, sf::Font does not load the complete font data into memory. As a consequence, the font source (file, memory location, or stream) must remain accessible throughout the font's lifetime. SFML supports many font formats, most notably, true type fonts (TTF) and open type fonts (OTF).

To display text on the screen, we use the class sf::Text. Analogous to sprites, texts are lightweight objects that refer to fonts. In a game, there are usually only a few fonts, but many different places where text is rendered. Therefore, we have many sf::Text instances that refer to a small amount of sf::Font objects.

Shaders

A shader is a program that operates directly on the graphics card. Shaders are used to apply a variety of graphical effects to rendered objects. Examples include a bloom shader that amplifies bright parts of the scene, a toon shader that makes objects look like in a cartoon, or a blur effect which simulates flickering hot air. Since SFML builds upon OpenGL, its shader instances use the OpenGL Shading Language (GLSL), a programming language similar to C. SFML supports vertex shaders (which affect the geometry of objects in the scene) and fragment shaders (which manipulate pixels of the scene).

sf::Shader can be created from a std::string containing the GLSL code of a vertex or a fragment shader. It can also hold both shaders at once; in this case it can be loaded from two strings. It is also possible to initialize a sf::Shader instance by passing the filename of a GLSL source file to its constructor.

[ 32 ]

www.it-ebooks.info

Chapter 2

Sound buffers

The sf::SoundBuffer class is used to store a sound effect. It holds an array of 16 bit audio samples, where each sample specifies the amplitude of the audio waveform at a given time. A sound buffer allows access and modification of the samples, but it cannot play audio. Supported file formats are WAV, OGG, AIFF, and many more.

The MP3 format is not supported because of its restrictive license.

sf::Sound is the class that plays audio from a sound buffer. Like a sprite refers to a texture containing the pixels, a sound refers to a sound buffer containing the audio samples. Analogous to textures, sound buffers must remain alive while they are used by sounds. sf::Sound objects can be played, paused, and stopped and have configurable attributes such as volume or pitch. Note that a sf::Sound object must stay valid as long as it is played, destroying it ceases to play the sound effect immediately.

Music

sf::Music is the class to play music. While sf::SoundBuffer is appropriate for short sound effects (explosions, button clicks, and so on.), sf::Music is designed to handle music themes. Themes are usually much longer and thus require more memory than sound effects. As a result, sf::Music does not load all data at once. Instead, it streams the music, meaning that it continuously loads small chunks of samples. The streaming semantics imply that the source of the music (for example, a file or memory location) must remain valid while the music is in use. That is also

why sf::Music methods are called openFromX() instead of loadFromX(), where "X" denotes a source media such as "File". The supported audio formats are the same as

for sf::SoundBuffer.

For music themes, there is no separation between heavyweight resource and lightweight front-end. sf::Music manages all at once: in addition to the loading functionality, it offers many of the sf::Sound methods to play, pause, or stop a theme or to configure other parameters. Its objects must also remain alive while the music plays.

[ 33 ]

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]