SFML community forums

Help => General => Topic started by: Veritas on May 03, 2014, 10:45:21 pm

Title: Laggy rendering.
Post by: Veritas on May 03, 2014, 10:45:21 pm
Hello everyone. I finished my game engine's prototype today and I decided to test it by making a rectangle and moving it by the arrow keys. Unfortunately the rendering lags noticeably. I believe this is a result of my engine's pipeline so I may have to explain how it works:

-GameObjects are containers of Components and hold a pointer to the Engine.
-Components are containers for data. Each component holds different types of data.
-The Engine is a container of Systems.
-Systems are containers of GameObjects.

Now every time we add a Component to the GameObject, it checks the requirements for the different systems and registers to them.
Each System has an update() function where the logic is kept. The pipeline goes through all the Systems consequently and calls their update() function.

For my example I do:

void World::run()
{
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");

        Engine engine;
        auto PIS = engine.addSystem<PlayerInputSystem>();
        PIS->window = &window;
        engine.addSystem<MovementSystem>();
        auto RS = engine.addSystem<RenderingSystem>();
        RS->window = &window;

        GameObject player(engine);
        player.addComponent<PlayerInputComponent>();
        player.addComponent<MovementComponent>();
        player.addComponent<VelocityComponent>();
        auto GC = player.addComponent<GraphicsComponent>();
        GC->sprite.setSize(sf::Vector2f(100,10));
        GC->sprite.setPosition(sf::Vector2f(0,0));

        sf::Clock clock;
        float elapsed;
        while (window.isOpen())
        {
                elapsed += clock.restart().asSeconds();
                while (elapsed > 1/60.f)
                {
                        engine.update(1/60.f);
                        elapsed -= 1/60.f;
                }
                RS->update();
        }
}

Here are the Components:

class VelocityComponent : public Component
{
public:
        sf::Vector2f velocity;
};

class MovementComponent : public Component
{
public:
        sf::Vector2f movement;
};

class PlayerInputComponent : public Component
{
        /* No need to add anything here */
};

class GraphicsComponent : public Component
{

public:
        sf::RectangleShape sprite;
};
 

And here are the Systems:

class PlayerInputSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
        sf::RenderWindow* window;
};

bool PlayerInputSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<PlayerInputComponent>().first &&
                object->hasComponent<VelocityComponent>().first );
}

void PlayerInputSystem::update(float dt = 0)
{
        for (auto &object : registered_objects)
        {
                auto velocity = object->getComponent<VelocityComponent>();
                velocity->velocity.x = 0;
                velocity->velocity.y = 0;
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        velocity->velocity.x = -500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        velocity->velocity.x = 500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        velocity->velocity.y = -500;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                {
                        velocity->velocity.y = 500;
                }
        }
}

//*****************************************************************************************************

class MovementSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
};

bool MovementSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<MovementComponent>().first &&
                object->hasComponent<VelocityComponent>().first );
}

void MovementSystem::update(float dt = 0)
{
        for (auto &object : registered_objects)
        {
                auto velocity = object->getComponent<VelocityComponent>();
                auto delta = object->getComponent<MovementComponent>();
                delta->movement.x = velocity->velocity.x * dt;
                delta->movement.y = velocity->velocity.y * dt;
        }
}

//******************************************************************************************************

class RenderingSystem : public System
{
public:
        bool registration_condition(GameObject*);
        void update(float);
        sf::RenderWindow* window;
};

bool RenderingSystem::registration_condition(GameObject* object)
{
        return (object->hasComponent<MovementComponent>().first &&
                object->hasComponent<GraphicsComponent>().first );
}

void RenderingSystem::update(float dt = 0)
{
        window->clear();
        for (auto &object : registered_objects)
        {
                auto delta = object->getComponent<MovementComponent>();
                auto graphics = object->getComponent<GraphicsComponent>();
                graphics->sprite.move(delta->movement);
                window->draw(graphics->sprite);
        }
        window->display();
}

The engine is by no means finished. It pretty much works with pointers everywhere and I would like to add Systems that don't take part in the pipeline. I hope I am doing something wrong with the game loop or else I may have to do way more work than I can handle atm.

EDIT: Wrong forum section again. Can this be moved to the help section?
Title: Re: Laggy rendering.
Post by: infinitebox on May 04, 2014, 03:37:38 am
It looks a lot like EntityX. I'd be interested in how your getComponent<> and hasComponent<> methods work.

I will take a stab at it. Depending on how the systems are stored in your data structure (and therefore ordered). During a single loop cycle, they might not get updated in the order you want (e.g. input->update-position->render), so the position update might not get updated till the next loop cycle (e.g. update-postion => input => render). I'm not sure how noticeable that would be though since it's only 1/60 of a second.

A few potential improvements:
Title: Re: Laggy rendering.
Post by: zsbzsb on May 04, 2014, 03:57:54 am
I will just leave this here.

http://scientificninja.com/blog/write-games-not-engines (http://scientificninja.com/blog/write-games-not-engines)
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 08:30:15 am
Quote
It looks a lot like EntityX. I'd be interested in how your getComponent<> and hasComponent<> methods work.

They are kind of a hack to be honest. A lot of ugly downcasting but in my defense I am not really using inheritance in the sense of having a parent class, I just needed a generic component container. Here is how it looks atm:

class GameObject
{
public:
        GameObject(Engine&);

        template <class T>
        std::pair<bool, std::vector<Component*>::iterator> hasComponent();

        template <class T>
        T* addComponent();

        template <class T>
        void eraseComponent();

        template <class T>
        T* getComponent();

private:
        Engine& m_engine;
        std::vector<Component*> m_components;
};

GameObject::GameObject(Engine& engine) : m_engine(engine), m_components() {}

template <class T>
std::pair<bool, std::vector<Component*>::iterator> GameObject::hasComponent()
{
        auto it = std::find_if(m_components.begin(),m_components.end(),
                [](Component* comp){ return dynamic_cast<T*>(comp); });
        return (std::make_pair(it != m_components.end(),it));
}

template <class T>
T* GameObject::addComponent()
{
        assert(!hasComponent<T>().first);
        auto comp = new T();
        m_components.push_back(comp);
        m_engine.registration_check(this);
        return comp;
}

template <class T>
void GameObject::eraseComponent()
{
        auto exists = hasComponent<T>();
        assert(exists.first);
        delete *exists.second;
        m_components.erase(exists.second);
        m_engine.unregistration_check(this);
}

template <class T>
T* GameObject::getComponent()
{
        auto exists = hasComponent<T>();
        assert(exists.first);
        return static_cast<T*>(*exists.second);
}
 

As you can see the internals are still kind of messy. I also don't like the hasComponent function returning an iterator to the component vector. It's not useful outside of the other internal functions. Remember that I wrote the engine within a few hours so I still have a lot of things to fix. I am also planning to allow the systems to remember the individual components so that they won't have to iterate through the components for every object. The asserts will go away.


Quote
I will take a stab at it. Depending on how the systems are stored in your data structure (and therefore ordered). During a single loop cycle, they might not get updated in the order you want (e.g. input->update-position->render), so the position update might not get updated till the next loop cycle (e.g. update-postion => input => render). I'm not sure how noticeable that would be though since it's only 1/60 of a second.

The update order should be fine. They are stored in a vector internally.

Quote
A few potential improvements:
  • In the input system, poll your inputs only once and store them, before iterating through all the objects.
  • Your render is still coupled to the logic loops since you've added the render system to your engine. It gets updated along with all the other systems?

I am aware of the input system being really badly written. I just needed something quick and dirty to check if I got things right. As for the render system, yes it's also updated in the pipeline. Now that I think of it it shouldn't need to exist outside of it ,it doesn't really render anything new anyway.

@zsbzsb This is an engine in the more literal sense, I needed a system to decouple things a bit and this design seemed intuitive. I didn't plan to reuse things, it just makes implementing things easier in my opinion.

UPDATE: I seperated systems from the pipeline. Now you have to manually add them to it. The rendering system is now updated as expected but the problem still persists. I will upload a video.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 11:32:19 am
I changed things a bit. The sprite is now moved in the MovementSystem. For simplicity's sake I also didn't put anything in the pipeline. The game loop is now very simple in order to demonstrate the problem better.

void World::run()
{
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");

        Engine engine;
        auto INPUT_SYSTEM = engine.addSystem<PlayerInputSystem>();
                INPUT_SYSTEM->window = &window;
        auto MOVEMENT_SYSTEM = engine.addSystem<MovementSystem>();
        auto RENDERING_SYSTEM = engine.addSystem<RenderingSystem>();
                RENDERING_SYSTEM->window = &window;

        GameObject player(engine);
        player.addComponent<PlayerInputComponent>();
        player.addComponent<MovementComponent>();
        player.addComponent<VelocityComponent>();
        auto GRAPHICS_COMPONENT = player.addComponent<GraphicsComponent>();
                GRAPHICS_COMPONENT->sprite.setFillColor(sf::Color::Red);
                GRAPHICS_COMPONENT->sprite.setSize(sf::Vector2f(100,100));
                GRAPHICS_COMPONENT->sprite.setPosition(sf::Vector2f(0,0));

        sf::Clock clock;
        float elapsed;
        while (window.isOpen())
        {
                elapsed = clock.restart().asSeconds();
                INPUT_SYSTEM->update();
                MOVEMENT_SYSTEM->update(elapsed);
                RENDERING_SYSTEM->update();
        }
}

Below is a video (Sorry for the bad quality) :

https://www.youtube.com/watch?v=sow38ljs25I&feature=youtu.be

UPDATE:

I logged the elapsed variable in the above loop. Even without any frame caps, it seems that I get anywhere between 30-100 fps. This looks like a performance issue and it's probably a result of not caching the components in the systems. I am starting to doubt if I can keep the systems and components as is. Pointers are not really cache friendly.
Title: Re: Laggy rendering.
Post by: infinitebox on May 04, 2014, 01:46:09 pm
I'm lost :S I would suggest writing a minimal sample that can replicate the problem.

30-100fps sounds way too low for something this barebone. From the video I can definitely see that the movement of the red square is very jerky. Hopefully the residential SFML gurus can help you :P
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 01:59:12 pm
Yes the performance is terrible. Technically the systems should only keep the components that they are interested in. As it is now they loop through all the components in the object and that requires downcasting among other things. This is probably the bottleneck but I have no idea if it can hurt performance to this degree.
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 02:02:06 pm
If you're developing engines, you should definitely use a profiler. It helps you find bottlenecks in no time and optimize code specifically. This approach is much more efficient than guessing.

And use std::unique_ptr, not raw memory management. See here (http://www.bromeon.ch/articles/raii.html) for reasons.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 02:21:08 pm
Yes I am planning to use the stl pointers, I built the prototype in a few hours and and I could do without having to handle downcasts when using them. It was mostly a test to see if such a structure would work, the code still needs a lot of changes.

By the way, I have never touched a profiler in my life. I will try to find something that works with codeblocks, there is a probably a plugin for that. Apparently this is not recommended, I will see what I can do.
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 02:28:22 pm
At the moment I'm working with the profiler integrated into Visual Studio, but earlier I used AMD CodeAnalyst. I don't know what's the best solution in your setting, you may have to research a bit.

Otherwise, even simple sf::Clock measurements are better than guessing, but it's a lot more cumbersome and less precise than a real profiler.

Concerning std::unique_ptr: there is no reason to not do things correctly from the beginning. I have heard this argument ("I'll rewrite it better later") so often that I've included it into the myth list in my RAII article. You actually have to think and write less when you use RAII unconditionally.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 02:37:26 pm
Yes I understand what you mean.  I will have to remove pointers from the interface anyway. Thanks for your help, I will try to find a profiler to work with and come back to post the results after I also make the systems cache the components.
Title: Re: Laggy rendering.
Post by: Jesper Juhl on May 04, 2014, 02:38:24 pm
Some options for profilers:

gprof : http://en.m.wikipedia.org/wiki/Gprof
Callgrind : http://valgrind.org/docs/manual/cl-manual.html (see also KCachegrind: http://kcachegrind.sourceforge.net/html/Home.html )
Intel VTune : https://software.intel.com/en-us/intel-vtune-amplifier-xe
perf : https://perf.wiki.kernel.org/index.php/Main_Page

There are plenty of other options, but the above are those that I've personally used.

Edit: remember to profile your code in release/optimized builds since performance between optimized and non-optimized builds will be very different and there's no point in optimizing something in a debug build that the compiler just removes anyway in a release build.
Title: Re: Laggy rendering.
Post by: Laurent on May 04, 2014, 03:07:52 pm
You can try Very Sleepy (http://www.codersnotes.com/sleepy). Probably the most simple and non-intrusive profiler I've seen. Works with both Visual C++ and GCC debugging information.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 04:13:30 pm
To be honest checking things with a profiler may be an overkill. The update functions are trivial for everything but the getComponent functions. Those call the hasComponent function which uses std::find_if with a dynamic cast comparison as predicate. So we have 7 find_if calls per frame, each processing 4 components. I have read that dynamic_cast is slow and it may not be viable for high performances. As I see it dynamic casting has to go as does linear searching.

I have 3 choices:

- Get rid of the getComponent function in the systems altogether. Components could be cached in the appropriate systems. This has the downside of making the implementation of every system harder since implementing the registration/unregistration functions will be required. As it is now you simply need a registration condition.

- Use an enum for comparisons. This gets rid of dynamic_cast comparisons and it's fast. This also has the downside of having to maintain an enum with enumerations similar to the system types and requiring access to the system interface.

- Use a map with typeindex as keys. I have seen something similar in some ActionScript implementations. The getComponent and hasComponent functions should be much faster to implement and maintain. The only thing I am not sure about this is whether the performance is going to be good enough. Has anyone tested the performance of typeindex comparisons?

Thanks for the help so far and sorry if this is getting out of the forum's theme. I would ask this on stackoverflow but those tend to kill all threads talking about downcasting because apparently there is a better design for all cases.
Title: Re: Laggy rendering.
Post by: Jesper Juhl on May 04, 2014, 04:27:14 pm
Checking things with a profiler is (IMHO) never overkill or a bad idea.
The days where you could read a bit of code and make a reasonable guess as to how it would perform are looong gone in all but the most trivial cases.
If you spend a bit of time looking into how modern optimizers transform the code you write and then investigate how modern hyperscalar out-of-order processors with complex cache hierarchies, branch predictors and whatnot will then execute it, you'll soon come to the realization that what your CPU ends up executing is lightyears from what you wrote and that any intuition you may have about its performance will be wrong in almost all cases.
Profile always, profile often. NEVER try to optimize something without profiling data to back up the optimization.

Profile, profile, profile (did I mention to profile?) !
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 04:41:14 pm
The problem is that I don't have any experience with profilers and many of the advised ones are for windows for which I don't really have a copy at the moment. I could spend a lot of time trying to find something that works for my system and I will, but right now I am just working on the project on my free time since I have to study for the university entry exams. Besides, the functions are simply wrappers for an std::find_if call using dynamic_casting comparison as a predicate. I heard that dynamic_casting is slow and std::find_if uses linear search. I don't think that it's far-fetched to believe that this is the bottle neck. I put some std::couts in the functions and putting the update functions aside, hasComponent and getComponent are pretty much the only ones that get called.
Title: Re: Laggy rendering.
Post by: Jesper Juhl on May 04, 2014, 04:49:34 pm
The problem is that I don't have any experience with profilers and many of the advised ones are for windows ...
All the ones I mentioned run om Linux (and other UNIX platforms)  ;)
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 04:55:22 pm
If you don't want to use profilers, then use one of the classical debugging approaches. Simplify the code, reduce various parts until things run fast, and you will know what caused the slow-down.

dynamic_cast is indeed often an indicator of bad design -- runtime polymorphism (virtual functions) exists for the whole reason of abstracting from dynamic types. However, I doubt it's the reason of bad performance if you call it only dozens of times per second. Maybe you're performing unnecessary and expensive copies somewhere.

A map with std::type_index sounds better -- you're still employing RTTI, but in an implicit way. The idea is to go away from explicit case differentiations, and let language or library mechanisms (VTable or map data structure) do it for you.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 05:13:26 pm
I understand that dynamic_cast is an indicator of bad design when there are actual hierarchical relations between the base and the derived classes. In my case they are simply bags of data, no functions whatsoever. They are "components" but for the components to have meaning you need to get the data they contain. Such things are easier to implement in dynamic languages than strong typed ones and if anyone has any better alternatives I am all ears.

As for copying, the two functions simply return pointers. I was very troubled on why there is such a performance issue and it's why I made the topic in the first place.


PS: Is it note worthy that I am using assert? It shouldn't create any problems since I have defined NDEBUG but just asking to be safe.
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 05:22:45 pm
I understand that dynamic_cast is an indicator of bad design when there are actual hierarchical relations between the base and the derived classes. In my case they are simply bags of data, no functions whatsoever. They are "components" but for the components to have meaning you need to get the data they contain.
The point is that your abstraction is not the best one if you have to query explicitly whether an object is of certain type. It doesn't matter if you use if/else, switch, dynamic_cast or typeid for this case differentiation. Since you seem to use it only internally, you can directly use a map and trade the O(n) search for a O(log n) or O(1) lookup. Not that performance would make any difference for such small numbers, but it's generally a better and more scalable design that would help in bigger scenarios.

The user should just ask your system: give me the component X, and component X not being there is typically a logic error.

Such things are easier to implement in dynamic languages than strong typed ones
Not really, unless your language has dynamic dispatch. Otherwise you have the same problems. Sometimes, it's even worse since you don't even have overloading and are forced to dispatch manually.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 05:27:18 pm
Yes dynamic_cast on the comparisons was a bad design, like I said I will have to replace them by using a map. The map however needs to store values of the same type. This is where downcasting is needed.

Anyway at this point, there isn't much that can be done about my problem. I will change the way GameObjects store the components and I will come back to you.
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 05:48:38 pm
This is where downcasting is needed.
Yes, but static downcasting -- you know the type in advance.
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 06:01:31 pm
I think there is a misunderstanding here. I used dynamic_cast as a predicate for type-checking in the hasComponent function. The getComponent function uses static casts but also calls the hasComponent function to validate the request. I realized that this just doesn't work, dynamic_casts are slow and linear search (especially using dynamic_cast as a comparison) is not effective. So I am looking for ways to improve the design. So far I think that a map using std::type_index as the key should be a good way to handle things. There is no need to cast everything for comparisons and checking for existance will be covered by the map. Plus we get logarithmic lookup which is always nice.
Title: Re: Laggy rendering.
Post by: Nexus on May 04, 2014, 06:10:31 pm
Yes, I think I understood that :)

What I meant is that -- since your map can only store base class pointers -- you will need a static cast to the derived class when requesting the component.
template <typename T>
T& GetComponent()
{
    std::unique_ptr<BaseComponent>& basePtr = map[typeid(T)];
    // better: map.find() or map.at() to not insert new ones
    return static_cast<T&>(*basePtr);
}
Title: Re: Laggy rendering.
Post by: Veritas on May 04, 2014, 06:14:02 pm
Oh yes I understand that. I said I will have to downcast the pointer, I didn't plan to use dynamic_cast. Even in my current code I only used it as a predicate for the find_if function. I used static_casts for the other cases. Maybe I didn't come across as I wanted, my English isn't perfect.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 12:05:21 am
Hello everyone again. I have almost finished rewriting the code. It should work after I manage to deal with one minor detail. The engine has two containers. One std::map that keeps the unique_ptrs to the systems and the pipeline which is a vector and should also refer to the wanted systems. Both containers need to keep pointers to the same systems. Am I wrong in assuming that I have to change the unique_ptrs to shared_ptrs? Also, the systems contain pointers of GameObject. They are not responsible for them though, they simply register the game object that meet the criteria. Shouldn't the container keep normal pointers to them instead of the stl ones?

Basically:

- The GameObjects own their Components so they should keep unique_ptrs.
- The Engine owns the system but it needs to keep them in two containers so it should keep shared_ptrs.
- The Systems don't own the Components so they should keep normal pointers to them.
Title: Re: Laggy rendering.
Post by: Ixrec on May 05, 2014, 12:18:45 am
It is an option, and likely the one you want, but there are other options, so it's not a good idea to simply assume shared pointers is what you want without thinking about the actual ownership semantics.

If you use shared pointers in both places, that means if either place destroys it, it will continue existing and the other place can continue to use it.  Both places will "own" the object they point to.  This is certainly the simplest solution.

You can also use shared pointers in one place and weak pointers in another.  That means if the first place destroys any, the second place will automatically lose it as well (in a safe and deterministic way, of course).  Only the first place "owns" the objects.

It's also valid to use unique pointers in one place and raw pointers in another *if* you can guarantee the first place won't start destroying objects until after the second place is done using them.  In the context of an entity system, this is almost certainly not the case, so you probably won't do this.  But it's worth noting that raw pointers are not evil if they are used only to point, and not to own.

I'm sure Nexus and the others will have more to add to this, but that's what I know.  In your case it probably boils down to whether you want the pipeline to be able to keep using objects the systems have already destroyed, and vice versa.  I'm not familiar enough with entity systems to know if there's an obvious answer to that.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 01:03:38 am
It wouldn't make sense to remove the system from the map if you removed it from the pipeline. You may want to free the pipeline from proccessing a system for some time. In this case a unique_ptr doesn't make sense. Now there is also the detail that registring is handled in the system map. You may want to keep processing the already registered objects but stop all the other registrations so you may not want to remove the system from the pipeline if you remove it from the systems container. I don't think I'm going to use such a feature but since I have to decide I may as well think of the different scenarios.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 09:36:14 am
UPDATE:

I officially have no idea what's wrong. I got rid of all dynamic_casts , used a map for fast retrieval and changed the raw pointers to the appropriate smart ones but the problem persists.

Here is a part of the fps log:

884.956
29.7389
831.947
32.1719
285.063
58.2479
87.0095
373.692
64.7166
80.8211
502.513
74.5657
26.6007
20.6979
480.538
33.0393
476.417
19.75
1584.79
70.4871

The fps jump from good to garbage. The logic is the same in every iteration, there are no any memory allocations in the loop and the only if statements are the ones in the input system. I am completely lost, I guess I will have to find some time to learn how to work with a profiler.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 03:00:11 pm
UPDATE:

Managed to get gprof to work with codeblocks.  I don't think I am using the profiler correctly though, the file is missing the call graph and the times are 0 for everything. I have the -g and -pg flags enabled.
Title: Re: Laggy rendering.
Post by: Nexus on May 05, 2014, 03:24:18 pm
I'm sure Nexus and the others will have more to add to this, but that's what I know.
Actually, you summed it up very nicely :)
I've once made a list of common ownership semantics in C++ (http://en.sfml-dev.org/forums/index.php?topic=13902.msg97463#msg97463), maybe that could also be helpful.

I officially have no idea what's wrong. I got rid of all dynamic_casts , used a map for fast retrieval and changed the raw pointers to the appropriate smart ones but the problem persists.
Yes. As I said before, a few dozens of operations per seconds won't degrade the performance, even if those are dynamic_casts. If you want us to help, you must reduce your code to a minimal example that shows the described behavior.

But be aware that FPS are not only affected by the application itself -- external factors like other processes, background tasks, anti-virus etc. may have considerable influence.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 03:39:05 pm
I want to provide a minimal example but the classes are dependent on each other. The whole thing is not that big though, it's around 250 lines including includes and blank lines. I could post it if you guys feel it's not too much but otherwise I don't think I can further reduce the amount of code.
Title: Re: Laggy rendering.
Post by: Nexus on May 05, 2014, 03:41:52 pm
I want to provide a minimal example but the classes are dependent on each other.
The idea of minimal examples is not to retain the original functionality, but rather to retain the problem. So, remove everything that doesn't contribute to your FPS issue, including class inter-dependencies.

Of course this takes some time, and now that you've installed the profiler, you could try to use it first.
Title: Re: Laggy rendering.
Post by: Veritas on May 05, 2014, 03:57:08 pm
The profiler seems to be broken. I searched a bit and many others have the same issue with no apparent solutions. I will try to find something else. Anyway I will try to reproduce the problem, this seems too much for me to handle at the moment but I will get to it.
Title: Re: Laggy rendering.
Post by: Jesper Juhl on May 05, 2014, 05:59:44 pm
UPDATE:

Managed to get gprof to work with codeblocks.  I don't think I am using the profiler correctly though, the file is missing the call graph and the times are 0 for everything. I have the -g and -pg flags enabled.
I've used gprof many times over the years and although it is not the best profiler around (I'd give that honor to Intel VTune) it does work.
Remember that you *must* use -pg both when compiling and when linking.
If you want you can send me your entire code in a private message and I'll take a look.
Title: Re: Laggy rendering.
Post by: Veritas on May 06, 2014, 11:22:49 am
After playing a bit with the profiler and if I read it correctly this appears to have to do with the typeid creations that take place when you want to fetch the components of every object in the update function. I will change the Systems interface so that the components will be cached. This should require more work for the user (will have to provide registration/unregistration functions) but hopefully the results will be worth it.
Title: Re: Laggy rendering.
Post by: Nexus on May 06, 2014, 11:34:23 am
After playing a bit with the profiler and if I read it correctly this appears to have to do with [...] hopefully the results will be worth it.
What does that mean? Why don't you measure with the profiler instead of playing around, guessing and hoping? You won't solve your problem by trying random things, you need a systematic approach.

I highly doubt that typeid is the performance bottleneck, especially if there are still only a few calls per second.

This should require more work for the user (will have to provide registration/unregistration functions)
That's a bad idea. Unless you can prove that this brings a real advantage, don't make the API inconvenient.
Title: Re: Laggy rendering.
Post by: Veritas on May 06, 2014, 04:50:46 pm
It seems that this may have nothing to do with my engine. I made a very naive gameloop and the rendering still lags. Could this be a driver problem?

void World::run()
{
        sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");
        sf::RectangleShape sprite;
        sprite.setFillColor(sf::Color::Red);
        sprite.setSize(sf::Vector2f(100,100));
        sprite.setPosition(sf::Vector2f(0,0));
        sf::Vector2f delta;
        sf::Vector2f velocity;
        sf::Clock clock;
        sf::Event event;
        float elapsed;
        while(window.isOpen())
        {
                elapsed = clock.restart().asSeconds();
                velocity.x = 0;
                velocity.y = 0;
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        velocity.x += -200;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        velocity.x += 200;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        velocity.y += -200;
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                {
                        velocity.y += 200;
                }
                delta.x = velocity.x * elapsed;
                delta.y = velocity.y * elapsed;
                sprite.move(delta);
                window.clear();
                window.draw(sprite);
                window.display();
        }
}
Title: Re: Laggy rendering.
Post by: select_this on May 06, 2014, 05:27:14 pm
It seems that this may have nothing to do with my engine. I made a very naive gameloop and the rendering still lags. Could this be a driver problem?

Ignore my previous (deleted) answer, I didn't look at the code properly  :-[

I ran your code and elapsed is nearly always smaller than 1/60.f so the majority of the time nothing will happen.

Here's a sample I got from running it:

Code: [Select]
Elapsed: 0.003635 1/60.f: 0.0166667
Elapsed: 0.002793 1/60.f: 0.0166667
Elapsed: 0.004756 1/60.f: 0.0166667
Elapsed: 0.003036 1/60.f: 0.0166667
Elapsed: 0.005751 1/60.f: 0.0166667
Elapsed: 0.004439 1/60.f: 0.0166667
Elapsed: 0.003327 1/60.f: 0.0166667
Elapsed: 0.008405 1/60.f: 0.0166667
Title: Re: Laggy rendering.
Post by: Veritas on May 06, 2014, 05:41:37 pm
Edited for simpler example.
The elapsed time for me is 10 times bigger.
Title: Re: Laggy rendering.
Post by: select_this on May 06, 2014, 06:00:38 pm
Yes that should be
elapsed += clock.restart().asSeconds();
I forgot to fix it after pasting.
The elapsed time for me is 10 times bigger.

The movement's pretty smooth on this computer (nb. not a high end machine by any means - dual core with integrated graphics).

You probably don't want to be testing for keypresses and setting the velocity in the while loop, so you might want to move that above the loop. Also, are you sure you want to be 'moving' the sprite repeatedly in the loop as well? It makes more sense to accumulate the distance for the sprite to move and then set the position afterward.
Title: Re: Laggy rendering.
Post by: Veritas on May 06, 2014, 06:05:24 pm
This is simply a naive gameloop to demonstrate my problem. The rendering lags a lot for me.
Title: Re: Laggy rendering.
Post by: select_this on May 06, 2014, 06:15:39 pm
This is simply a naive gameloop to demonstrate my problem. The rendering lags a lot for me.

I was just trying to eliminate possible bottlenecks; now that you've simplified your example, assuming the problem still persists, it looks like there's nothing there that would theoretically adversely affect performance (as I mentioned before, it runs perfectly smoothly on the computer I'm currently using).
Title: Re: Laggy rendering.
Post by: Veritas on May 06, 2014, 10:43:12 pm
Hello everyone! It was a driver problem. I can't believe I spent so much time looking for code problems while it was a simple driver issue! Thanks a lot for your help and sorry for the waste of time!
Title: Re: Laggy rendering.
Post by: Nexus on May 06, 2014, 10:44:23 pm
No problem. The time isn't wasted, I'm sure you've learned a lot of other useful things while trying to solve this issue.
Title: Re: Laggy rendering.
Post by: Veritas on May 08, 2014, 11:14:15 am
I updated my nvidia drivers and everything works. I have one issue with vertical sync though, it seems to cap rendering to 40 fps. As a result of this I get some stuttering. Does anyone have any idea how to fix this?
Title: Re: Laggy rendering.
Post by: eXpl0it3r on May 08, 2014, 11:22:04 am
I have one issue with vertical sync though, it seems to cap rendering to 40 fps. As a result of this I get some stuttering. Does anyone have any idea how to fix this?
What's the refresh rate of your screen?
Do you run it in window mode?
Title: Re: Laggy rendering.
Post by: Veritas on May 08, 2014, 12:21:31 pm
Screen's refresh rate is 60 hz.
Yes I run it window mode.

In case I am not measuring the frames correctly here is the testing loop:

        sf::RenderWindow window(sf::VideoMode(1024, 768), "Testing");
                window.setVerticalSyncEnabled(true);
        sf::Clock clock;
        sf::Event event;
        float elapsed;
        while(window.isOpen())
        {
                elapsed += clock.restart().asSeconds();
                std::cout << 1.f/elapsed << std::endl;
                while(elapsed > 1.f/60.f)
                {
                        while(window.pollEvent(event))
                        {
                                if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape)
                                {
                                        window.close();
                                }
                        }
                        elapsed -= 1.f/60.f;
                }
                window.clear();
                window.display();
        }

What happens is that it starts at 50 fps, goes up to 60 something and then falls down to 30 and starts incrementing again.
Title: Re: Laggy rendering.
Post by: eXpl0it3r on May 08, 2014, 12:36:38 pm
You can just do
std::cout << 1.f/clock.resetart().asSeconds() << std::endl;

But it's probably more a driver thing, some drivers change the refresh rate in window mode. Not sure, but there might be an option in your driver settings.
Title: Re: Laggy rendering.
Post by: Veritas on May 08, 2014, 09:32:49 pm
It seems that the same happens in fullscreen mode too.
I reinstall the driver but the problem persists. I am also concerned about the 40-500 fps rate range when not using vsync.
Title: Re: Laggy rendering.
Post by: Veritas on May 09, 2014, 04:01:03 pm
Fixed. I needed to use an extra variable to correctly keep track of the frames. Simply using the elapsed variable didn't cut it. I will now test some more and notify you about the performance.