Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - red1939

Pages: [1]
1
Graphics / Multiple layers + multiple atlases
« on: February 06, 2013, 10:07:20 pm »
Assumptions & requirements:
  • max texture size that can be expected (on most machines) is at least 1k * 1k (while my very old ATI Mobility Radeon HD 3400 can handle 8k * 8k...)
  • every sprite will be of 64 * 64 size
  • there will be more than 256 sprites
  • more than one texture might be required while rendering
  • sprites will be grouped logically (one texture for units, other for tiles, etc.)
  • large number of sprites will be rendered on the screen every frame
  • in order to run efficiently least number of context switches is required, thus least number of texture changes
  • isometric projection (or at least impression of it) will be used
  • iso. proj. (IP) requires to draw sprites in very ordered fashion (column-major-like order)

So the question is as follows:
How to efficiently render sprites which are on different textures?

The solution I would choose is:
  • Draw static backgrounds to off-screen texture (RenderTexture) and forget about them
  • Assign a Z-order to every sprite basing in what order the drawing has to be done
  • Group all vertices of all rendered sprites by their textures and push them to VBO (VertexArray?)
  • Issue draw calls for every VBO + Texture pair
  • Let the logical draw ordering be handled by Z buffer

It seems efficient and clean for me, but AFAIK there is no support for Z-order in sfml. Is there any other efficient way of rendering sprites in this scenario, or I am left with just iteratively drawing sprites basing on their draw order?

2
Graphics / Re: Optimizing dynamic text rendering
« on: January 15, 2013, 12:14:22 am »
1 quad(letter) is 80 bytes(4x color + position + tex coords) so it's normal.

Yeah, I just checked it.

DataSize (B)
Font pointer4
Character size4
Text style4
Color4
Bounds16
Vertex array (not counting underlines etc.)4 * 20 * glyphs
String24 + 4 * glyphs

Which gives us 56 + 84 * glyph, and for 13 character we get whooping 1148B. Hoped it will be less, but I won't cry :).

3
Graphics / Re: Optimizing dynamic text rendering
« on: January 14, 2013, 08:14:58 pm »
So I've implemented the prallocated solution. Results are as follows:

Unique sf::Text objects drawn every update: 160 801
Speed up of using preallocation: 240%
Average memory consumption per sf::Text: 1.261 kB

On one hand we have a nice gain, but I have to say that I am quite surprised because of the amount of memory that sf::Text is taking.

4
Graphics / Re: Optimizing dynamic text rendering
« on: January 13, 2013, 11:00:08 pm »
Quote
What type does the ... expression on the right hand side of const auto str = have?

const auto& str = std::to_string(a) + ":"
                                + std::to_string(b) + ":"
                                + std::to_string(c);

Where a, b and c are ints.

Quote
And if you really only iterate 100 times, this is not an expressive measurement. Use far higher numbers.

For 160k iterations the results are slightly different:
Operation% time taken
drawing shape22%
generating string11%
setting string43%
drawing text19%

Quote
Pre-allocating them is the only solution.

Before I play around with some pre-allocation prototype I would like to ask one question: what type memory does the sf::Text require? RAM (the glyph texture is stored in sf::Font), or VRAM (because it creates a texture instance of the mapped glyphs)?

5
Graphics / Optimizing dynamic text rendering
« on: January 13, 2013, 05:55:10 pm »
Hello all!

I've been playing around with SFML and I have to say it's a neat little library. For debugging purposes I have several texts rendered on the screen, which (as I checked) quite drastically lowered my FPS. This is not the end of the world, but I would like to ask you several questions regarding this matter and how to make text rendering faster.

Specs
SFML: 2.0 custom built (527bb287a5538f547b5b29c464d22a0ebfa0baa2)
IDE: Visual Studio 2012 Professional
OS: Windows 7 x64
GPU: ATI Radeon HD 4850 (512 GDDR3) + Catalyst 12.4
CPU: Athlon Phenom X2 3.1GHz (2 cores)
RAM: 6GB DDR2

Splitting the loop

This is basically the main part of rendering which takes the most time (82%), while RenderWindow.clear() and RenderWindow.display() takes the rest (~18%).

void render(sf::RenderWindow& rw, const sf::Font& font)
{
        sf::ConcaveShape shape = ...;

        sf::Text t;
        t.setFont(font);

        for ( 100 ) {
                auto pos = ...;
                shape.setPosition(pos);
                rw.draw(shape);
#ifdef DRAW_TEXT
                const auto str = ...;
                t.setString(str);
                t.setPosition(pos);
                rw.draw(t);
#endif // DRAW_TEXT
        }
}
 

Text: 365 fps
No text: 1850 fps (!)

So I decided to check whether splitting the loop into 2 helps.

void render(sf::RenderWindow& rw, const sf::Font& font)
{
        sf::ConcaveShape shape = ...;

        sf::Text t;
        t.setFont(font);

        for ( 100 ) {
                auto pos = ...;
                shape.setPosition(pos);
                rw.draw(shape);
        }

#ifdef DRAW_TEXT
        for ( 100 ) {
                auto pos = ...;
                const auto str = ...;
                t.setString(str);
                t.setPosition(pos);
                rw.draw(t);
        }
#endif // DRAW_TEXT
}
 

Text: 640 fps
No text: 1850 fps

There is a huge (1.75x) increase in performance! I am assuming this is due to the fact that the render state is not swapped back and forth between shape and font?

Profiling

This is what VS2012 profiler shows:

void render(sf::RenderWindow& rw, const sf::Font& font)
{
        sf::ConcaveShape shape = ...;

        sf::Text t;
        t.setFont(font);

        for ( 100 ) {
                auto pos = ...;
                shape.setPosition(pos);
                rw.draw(shape); // 26.7%
        }

#ifdef DRAW_TEXT
        for ( 100 ) {
                auto pos = ...;
                const auto str = ...; // 13%
                t.setString(str); // 34.5%
                t.setPosition(pos);
                rw.draw(t); // 25.3%
        }
#endif // DRAW_TEXT
}
 

Percentage values describe how much of the whole time for this method was taken by the given line.

Optimization

Ok, so the question remains: how can I make it faster?
  • Precreation and caching of all texts (they are not that dynamic) in sf::Texts. It would take a lot of resources I assume.
  • Using bitmap fonts. I am not sure how this could help as the string would still have to be "parsed" and mapped to glyphs.
I would be glad for any other suggestions and comments.

Pages: [1]