1
Graphics / 'Slow' performance - what am I doing wrong?
« on: May 28, 2014, 07:17:13 pm »
So I am trying to make SFML integrate nicely with Artemis-C++ port(Entity component system).
At the moment it is using about 0.39-0.5sec to draw a frame when drawing 713 "meshes" as a tiled background.
This is obviously something I'm doing wrong so if anyone can point me in the right direction that would be great!
Edit
Meant to press preview, not save.
I know that I am calculating the transform every frame.
/Edit
Here is my current code;
Renderer
Mesh
MeshCollection
Transform
And here is my test.
At the moment it is using about 0.39-0.5sec to draw a frame when drawing 713 "meshes" as a tiled background.
This is obviously something I'm doing wrong so if anyone can point me in the right direction that would be great!
Edit
Meant to press preview, not save.
I know that I am calculating the transform every frame.
/Edit
Here is my current code;
Renderer
Quote
class Renderer
{
public:
void addToQueue(MeshCollection* mc, Transform* t) {
m_meshCollections.push_back(mc);
m_transforms.push_back(t);
m_count++;
}
void render(sf::RenderTarget* target) {
sf::RenderStates rs = sf::RenderStates::Default;
sf::Transform original = rs.transform;
clock.restart();
for (int i = 0; i < m_count; i++) {
rs.transform = original;
rs.transform *= Renderer::getTransform(m_transforms);;
target->draw(*m_meshCollections, rs);
}
std::cout << m_count << " mesh collections drawn in " << clock.getElapsedTime().asSeconds() << "sec" << std::endl;
m_meshCollections.clear();
m_transforms.clear();
m_count = 0;
}
private:
static inline sf::Transform getTransform(Transform* t) {
float angle = -t->rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(std::cos(angle));
float sine = static_cast<float>(std::sin(angle));
float sxc = cosine;
float syc = cosine;
float sxs = sine;
float sys = sine;
float tx = -0 * sxc - 0 * sys + t->position.x;
float ty = 0 * sxs - 0 * syc + t->position.y;
return sf::Transform(sxc, sys, tx, -sxs, syc, ty, 0.f, 0.f, 1.f);
}
private:
std::vector<MeshCollection*> m_meshCollections;
std::vector<Transform*> m_transforms;
int m_count;
sf::Clock clock;
};
Mesh
Quote
class Mesh
{
friend class MeshCollection;
public:
sf::Vector2f offset;
sf::Texture texture;
sf::Vector2f size;
float rotation;
private:
sf::Vertex m_vertices[4];
sf::Vector2f m_origin = sf::Vector2f(0, 0);
void updateVertices() {
sf::Vector2u size = texture.getSize();
m_vertices[0].position = sf::Vector2f(0.0f, 0.0f);
m_vertices[1].position = sf::Vector2f(0, size.y);
m_vertices[2].position = sf::Vector2f(size.x, size.y);
m_vertices[3].position = sf::Vector2f(size.x, 0);
}
sf::Transform getTransform() {
float angle = -rotation * 3.141592654f / 180.f;
float cosine = static_cast<float>(std::cos(angle));
float sine = static_cast<float>(std::sin(angle));
float sxc = size.x * cosine;
float syc = size.y * cosine;
float sxs = size.x * sine;
float sys = size.y * sine;
float tx = -m_origin.x * sxc - m_origin.y * sys + offset.x;
float ty = m_origin.x * sxs - m_origin.y * syc + offset.y;
return sf::Transform(sxc, sys, tx, -sxs, syc, ty, 0.f, 0.f, 1.f);
}
};
MeshCollection
Quote
class MeshCollection : public sf::Drawable
{
public:
void add(sf::Vector2f offset, sf::Texture texture, float rotation = 0.0f, sf::Vector2f size = sf::Vector2f(1.0f, 1.0f)) {
Mesh m;
m.offset = offset;
m.texture = texture;
m.rotation = rotation;
m.size = size;
m.updateVertices();
m_meshes.push_back(m);
}
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
// sf::Transform originalTransform = states.transform;
for (auto m : m_meshes) {
// states.transform = states.transform.scale(m.size).rotate(m.rotation).translate(m.offset);
states.transform *= m.getTransform();
states.texture = &m.texture;
target.draw((sf::Vertex*)&m.m_vertices, 4, sf::PrimitiveType::Quads, states);
// states.transform = originalTransform;
}
}
private:
std::vector<Mesh> m_meshes;
};
Transform
Quote
class Transform : public artemis::Component
{
public:
sf::Vector2f position;
float rotation;
// size ?
Transform() {
}
};
And here is my test.
Quote
int main() {
sf::RenderWindow window(sf::VideoMode(1024, 768), "");
Renderer r;
sf::Texture texture;
texture.loadFromFile("Assets\\32x32_red.png");
const int debugsize = 50;
MeshCollection mcArray[debugsize * debugsize];
Transform tArray[debugsize * debugsize];
int c = 0;
for (int x = 0; x < debugsize; x++)
{
for (int y = 0; y < debugsize; y++)
{
MeshCollection m;
m.add(sf::Vector2f(0, 0), texture);
mcArray[c] = m;
tArray[c].position = sf::Vector2f(x * 32, y * 32);
tArray[c].rotation = 0.0f;
c++;
}
}
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
window.close();
}
window.clear(sf::Color::Black);
int c = 0;
for (int x = 0; x < debugsize; x++)
{
for (int y = 0; y < debugsize; y++)
{
if (tArray[c].position.x > 0 && tArray[c].position.x < 1024 &&
tArray[c].position.y > 0 && tArray[c].position.y < 768)
r.addToQueue(&mcArray[c], &tArray[c]);
c++;
}
}
/*
for (int i = 0; i < debugsize * debugsize; i++)
{
r.addToQueue(&mcArray, &tArray);
}
*/
r.render(&window);
window.display();
}
return 0;
}