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

Chapter 8

Low-level rendering

Besides the high-level convenience classes sf::Sprite, sf::Text and sf::Shape, SFML provides a low-level graphics API which is more complicated to use, but allows more flexibility. In the next section, we are going to look behind the scenes of rendering and discuss corresponding techniques as they are implemented in SFML.

OpenGL and graphics cards

The graphics card architecture consists of many components. Notable are the graphics processing unit (GPU), which performs computations on the graphics card, and the video memory, which stores data such as textures. In contrast to their counterparts CPU and RAM, graphics cards' components are highly optimized to process 2D and 3D graphics.

SFML is built on top of the Open Graphics Library (OpenGL). OpenGL is, like DirectX, a specification of an interface to the graphics card. Operating systems provide an API written in C that allows applications to access graphic card functionality. Newer graphics cards support higher OpenGL versions and thus have the benefit of more modern features.

The way SFML is designed is heavily influenced by the underlying OpenGL functionality. SFML itself uses an object-oriented approach and abstracts low-level accesses away; therefore users can work with the library without even knowing OpenGL. It is, however, advantageous to be aware of basic underlying techniques, in order to see the whole picture. For specific requirements, it is also possible to mix

SFML and OpenGL.

Understanding render targets

A render target defines the place where 2D objects such as sprites, texts, or shapes are rendered. In SFML, this boils down to the abstract base class sf::RenderTarget. Apart from clear() and draw() methods, the class provides functionality to manipulate the current view.

A render window is a concrete implementation of a render target. Render windows represent application windows to which you can render graphical objects. In addition, they provide facilities for input handling and configurations such as

V-Sync. The class sf::RenderWindow, which we have been using all the time, inherits sf::RenderTarget and sf::Window.

[ 189 ]

www.it-ebooks.info

Every Pixel Counts – Adding Visual Effects

A render texture is another realization of the render target concept. Here, you do not draw objects to a window, but to a texture. Render textures can be used to render a scene that is not immediately displayed, but can be further processed—for example, saved to a file or edited as a whole. SFML provides the class sf::RenderTexture which derives from sf::RenderTarget. Notable is the method getTexture() which returns const sf::Texture& with the render texture's current contents. As with render windows, you must call display() before you can actually use that texture. This step is often forgotten.

Texture mapping

We have worked a lot with textures in the game, but not explained how they are actually displayed on the screen. Texel (texture element) is the term used for pixels in texture space. The case where every texel in the texture corresponds to a pixel on the window is an exception. In general, transforms of the graphical object and the view affect the way how pixels are displayed on the screen.

Every graphical object on the screen consists of vertices. A vertex is a point that defines the geometry of the object. Multiple vertices are grouped to geometric primitives such as lines, triangles, rectangles, and so on. In most cases, we have rectangular objects (such as sf::Sprite) that have four vertices, namely the four corners of the rectangle. Polygons (modeled by sf::Shape) allow a different number of vertices.

Each vertex consists of target coordinates (the position of the point on the render target, in world units) and texture coordinates (the position in the source texture, in texels). Texture coordinates are sometimes also called UV coordinates, because the variables u and v are often used instead of x and y. The process of texture mapping specifies how target coordinates are mapped onto texture coordinates, in order

to know which pixels have to be drawn where. This mapping is clarified in the following figure:

[ 190 ]

www.it-ebooks.info

Chapter 8

This figure only shows an aligned rectangle in the texture, the proportions of which are evenly maintained in the render target. In fact, you have a lot of freedom to place your vertices. This may result in distorted textures, but, you should just experiment yourself.

SFML provides the class sf::Vertex that represents a vertex of the geometric object. It has the following public member variables:

sf::Vector2f position: the target coordinates (x, y)

sf::Vector2f texCoords: the texture coordinates (u, v)

sf::Color color: used to colorize the vertex

Vertex arrays

All geometric primitives except points consist of more than one vertex. A vertex array is a collection of vertices that are drawn together. A vertex array need not necessarily represent a single geometric object; it may also store the vertices of many objects.

In SFML, the class sf::VertexArray is used to model vertex arrays. It is a thin

wrapper around std::vector<sf::Vertex> and derives from sf::Drawable. We can add new vertices to the end of the array, and access existing vertices using the index operator.

The primitive type determines how the vertices are interpreted to form a geometric primitive. For example, the primitive type sf::Triangles interprets three subsequent vertices as one triangle, the next three vertices as another triangle, and so on. sf::Quads interprets four subsequent vertices as a quadrilateral. When we work with rectangles, we will be using the sf::Quads primitive type.

A small, incomplete example should give you a rough idea how vertices, vertex arrays and render targets interact:

sf::Vertex v;

v.position = sf::Vector2f(x, y); v.texCoords = sf::Vector2f(u, v); v.color = sf::Color::Blue;

sf::VertexArray vertices; vertices.setPrimitiveType(sf::Quads); vertices.append(v);

...

[ 191 ]

www.it-ebooks.info

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