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

### Author Topic: Drawing one time is slower than 100 times.  (Read 154 times)

0 Members and 1 Guest are viewing this topic.

#### Naofu

• Newbie
• Posts: 5
##### Drawing one time is slower than 100 times.
« on: August 05, 2019, 04:41:03 pm »
Hello, I'm new to SFML and also to C++.
This question is similar to previous one but I also stuck with this problem.

#include <SFML\Graphics.hpp>
#include <iostream>

class Block
{
public:
Block();
~Block();
void Allocate(sf::Vector2f position, sf::Vector2f size);
sf::VertexArray GetShape() { return shape; }
bool CheckAlive() { return alive; }
private:
sf::VertexArray shape;
bool alive;
};

Block::Block()
{
}

Block::~Block()
{
}

void Block::Allocate(sf::Vector2f position, sf::Vector2f size)
{
shape = sf::VertexArray(sf::Quads, 4);
shape[0].position = position;
shape[1].position = { position.x + size.x, position.y };
shape[2].position = { position.x + size.x, position.y + size.y };
shape[3].position = { position.x, position.y  + size.y};
shape[0].color = sf::Color::Red;
shape[1].color = sf::Color::Blue;
shape[2].color = sf::Color::Green;
shape[3].color = sf::Color::Yellow;
alive = true;
}

int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "TEST");
Block block[100];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
block[j + 10 * i].Allocate(sf::Vector2f(40.f * j, 40.f * i), sf::Vector2f(40.f, 40.f));
sf::Clock clock;
float frameTime = 0.f;
float timer = 0.f;
int fps = 0;
while (window.isOpen())
{
frameTime = clock.restart().asSeconds();
sf::Event e;
while (window.pollEvent(e))
{
if (e.type == sf::Event::Closed)
window.close();
}
timer += frameTime;
fps++;
if (timer >= 1.f)
{
std::cout << fps << std::endl;
fps = 0;
timer = 0.f;
}

window.clear();
// draw every shapes 100 times.
for (int i = 0; i < 100; i++)
if (block[i].CheckAlive())
window.draw(block[i].GetShape());
// draw one big shape.
/*for (int i = 0; i < 100; i++)
if (block[i].CheckAlive())
for (int j = 0; j < block[i].GetShape().getVertexCount(); j++)
bunchOfShapes.append(block[i].GetShape()[j]);
window.draw(bunchOfShapes);*/

window.display();
}
}

I expected drawing one time is faster but turned to be much worse. Each of those blocks has a state and it is to be changed frequently in game, so this one big shape has to be updated in every frame. This code is definitely wrong but I can't figure out.

#### Laurent

• Hero Member
• Posts: 32123
##### Re: Drawing one time is slower than 100 times.
« Reply #1 on: August 05, 2019, 08:18:42 pm »
The single draw code is a lot less efficient because you allocate, deallocate and copy much more than necessary. You should allocate the memory for everything once, and then just update stuff in-place.
Laurent Gomila - SFML developer

#### Naofu

• Newbie
• Posts: 5
##### Re: Drawing one time is slower than 100 times.
« Reply #2 on: August 06, 2019, 01:41:28 am »
Thanks for your reply. I still don't understand pointers, memories,,,etc. I gotta study hard.
In this case I'm bothered with discarding vertices of vanished entities.
Fairly improved by this way but still be defeated by drawing 100 times.

#include <SFML\Graphics.hpp>
#include <iostream>
#include <vector>

class Block
{
public:
Block();
~Block();
sf::Vertex* GetShape() { return shape; }
void Allocate(sf::Vector2f position, sf::Vector2f size);
bool CheckAlive() { return alive; }
int GetVertexCount() { return vertexCount; }
private:
sf::Vertex shape[8];
bool alive;
int vertexCount;
};

Block::Block()
{
}

Block::~Block()
{
}

void Block::Allocate(sf::Vector2f position, sf::Vector2f size)
{
shape[0] = sf::Vertex(position, sf::Color::Red);
shape[1] = sf::Vertex({ position.x + size.x, position.y }, sf::Color::Blue);
shape[2] = sf::Vertex({ position.x + size.x, position.y + size.y}, sf::Color::Green);
shape[3] = sf::Vertex({ position.x, position.y + size.y }, sf::Color::Yellow);
alive = true;
vertexCount = 4;
}

int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "TEST");
Block block[100];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
block[j + 10 * i].Allocate(sf::Vector2f(40.f * j, 40.f * i), sf::Vector2f(40.f, 40.f));
sf::Clock clock;
float frameTime = 0.f;
float timer = 0.f;
int fps = 0;
while (window.isOpen())
{
frameTime = clock.restart().asSeconds();
sf::Event e;
while (window.pollEvent(e))
{
if (e.type == sf::Event::Closed)
window.close();
}
timer += frameTime;
fps++;
if (timer >= 1.f)
{
std::cout << fps << std::endl;
fps = 0;
timer -= 1.f;
}

window.clear();
// draw every shapes 100 times.
/*for (int i = 0; i < 100; i++)
if (block[i].CheckAlive())

// draw one big shape.
std::vector<sf::Vertex> vertices(0);
int totalVertexCount = 0;
for (int i = 0; i < 100; i++)
if (block[i].CheckAlive())
for (int j = 0; j < block[i].GetVertexCount(); j++)
{
vertices.emplace_back(block[i].GetShape()[j]);
totalVertexCount++;
}

window.display();
}
}

#### Geheim

• Full Member
• Posts: 200
##### Re: Drawing one time is slower than 100 times.
« Reply #3 on: August 06, 2019, 05:44:19 pm »
That is because you are most likely running in Debug mode, try it with Release and it will be faster.
Failing to succeed does not mean failing to progress!