3
\$\begingroup\$

So I'm still learning about ECS (Entity Component System) and whenever I'm thinking about the architecture and actual implementation, I just can't figure out where should I put the SDL_Renderer*.

So far what I've learned is that the Entity class should have its own unique ID, there should be a Component and System class and things like RenderComponent and RenderSystem should be derived from them. RenderComponent should contain all the data and the RenderSystem should contain the actual algorithms (correct me if I'm wrong so far).

I'm using C++ and SDL2 and I don't know how about you guys but I never really used more than one SDL_Renderer and I'm not intending to do so either. I always just create a renderer for the window and copy everything to that one renderer and than I present that renderer to the screen. So my questions are:

  • In an ECS design like I explained above, where should I put my SDL_Renderer?
  • What should the RenderComponent, and RenderSystem, contain?
\$\endgroup\$
3
\$\begingroup\$

If you only have a single SDL_Renderer, it should be managed outside of the ECS code and just passed to the rendering system when you call it to render the visual data for each entity. In this way it's like you are associating your single SDL_Renderer with all renderable entities. If for some reason you had multiple, differently configured SDL_Renderer objects that different sets of entities used, then it might be useful to represent SDL_Renderer objects as entities themselves (by making something like a RendererComponent for those entities that stores a pointer to a SDL_Renderer object). You would then be able to store the ID of these renderer entities in the visual data component of each renderable entity so that the rendering system can get the right renderer needed to render each entity.

EDIT: To clarify my first comment, here is some code:

void RenderingSystem::Update(SDL_Renderer *renderer)
{
    for (int i = 0; i < this->GetEntityCount(); ++i)
    {
        Entity *entity = this->GetEntity(i);

        SpatialComponent *spatialComponent = entity->GetComponent<SpatialComponent>();
        VisualComponent *visualComponent = entity->GetComponent<VisualComponent>();

        SDL_Rect dstrect = visualComponent->srcrect;
        dstrect.x = spatialComponent->positionX;
        dstrect.y = spatialComponent->positionY;
        SDL_RenderCopy(
            renderer,
            visualComponent->texture,
            &visualComponent->srcrect,
            &dstrect
        );
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thats what I was thinking about at first, to create an SDL_Renderer outside it and then just pass it as a parameter to the rendercomponent, or wich ever class needs it. Is there a way to make this happen without me having to pass the same SDL_Renderer as a parameter to all the objects that need it? \$\endgroup\$ – Marko Kitonjics Dec 6 '14 at 23:31
  • \$\begingroup\$ It depends on how you implement ECS. Sometimes components are just implemented as structs, without methods of their own. An entity might have one component with spatial data like position, rotation, scale and another component with visual data like the texture and a blending color. In this way, you'd only have to pass the SDL_Renderer pointer as a parameter to a method on the rendering system that iterates through all the sets of those two components for each entity that has them and uses the spatial and visual data to render each one with the renderer. \$\endgroup\$ – Mars Dec 6 '14 at 23:56
  • \$\begingroup\$ Thanks a lot! Seems like I tried to overcomplicate something thats so simple. \$\endgroup\$ – Marko Kitonjics Dec 7 '14 at 0:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.