Search code examples
c++graphicsgame-loopallegro5

al_draw_filled_rectangle() seems to work only in some classes


I am trying to write a basic program with a game loop (it can't be called a game any time soon). Almost everything I have (which isn't much, frankly) is fine, just the one object in my render tree doesn't render!

The game loop:

void Game::enterMainLoop() {
    running = true;
    double lastTime = al_get_time();
    std::cout << "Entering main loop!" << std::endl;
    while (running) { // Never mind the infinite loop. This isn't the final version
        double current = al_get_time();
        double timePassed = current - lastTime;
        processInput();
        processUpdatables();
        processPhysicalObjects();
        processRenderables();

        update(timePassed);
        physics(timePassed);
        render(renderTree);

        lastTime = current;
    }
}

I have verified it loops correctly (and quickly - the called methods don't do much).

The Game::render() method:

void Game::render(std::vector<IRenderable*> toRender) {
    al_clear_to_color(al_map_rgb(0,0,90));
    IRenderable *renderable;
    for (std::vector<IRenderable*>::iterator it = toRender.begin(); it != toRender.end(); ++it) {
        renderable = *it;
        renderable->render();
        render(renderable->getChildren());
    }
    al_draw_filled_rectangle(10, 10, 120, 120, al_map_rgb(255, 255, 255));
    al_flip_display();
}

I verified the one object in the render tree's render method is called (by putting a cout statement in its body, which prints every frame). The filled rectangle is visible on screen.

The Player::render method at first drew a square at (this.x, this.y) with dimensions this.width x this.height, but I saw nothing on screen, so I simplified it to this:

void Player::render() {
    std::cout << "Player::render called! x: " << x << ", y: " << y << std::endl;
    al_draw_filled_rectangle(120, 120, 120, 120, al_map_rgb(255, 255, 255));
}

Yes, the cout statement prints every frame, so the render() method is called correctly. Yet I don't see a second rectangle.

Why can't I draw from the Player class?

(Note: everything compiles without output with -Wall enabled. During runtime I also don't have any output besides what I generate with cout statements.)


Solution

  • It cant realiably be deduced without a mcve, but from the code shown, and assuming renderable->getChildren() returns a std::vector, the problem is most propably related to the fact that after rendering one of the elements you always recurse and call al_clear_to_color as a result:

    al_clear_to_color(al_map_rgb(0,0,90)); //1: clear screen
    IRenderable *renderable;
    for (std::vector<IRenderable*>::iterator it = toRender.begin(); it != toRender.end(); ++it) {
        renderable = *it;
    
        //renders one element
        renderable->render();
    
        //recurses and therefore reaches 1(clear screen) again(even if there are no children)
        render(renderable->getChildren());
    }