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

Author Topic: Help drawing only onscreen sprites  (Read 2110 times)

0 Members and 1 Guest are viewing this topic.

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Help drawing only onscreen sprites
« on: April 21, 2015, 07:52:25 pm »
Hi there, im having some trouble streaming sprites that are within screen space. For example if i have 5000 sprites in my level but only 500 are within the screen, i only want to draw those 500 and not blindly draw the full 5000.

Here's some code, note that the windows view is always centered on pEngine->get_player().
for (auto& ColumnTile : Row)
{
    //Trying to check if tile is within the screen? or am i wrong
        if (ColumnTile.graphics_shape().getPosition().x > pEngine->get_player()->getPosition().x - (RenderTarget.getSize().x / 2) &&
                ColumnTile.graphics_shape().getPosition().x < pEngine->get_player()->getPosition().x + (RenderTarget.getSize().x / 2) &&
                ColumnTile.graphics_shape().getPosition().y > pEngine->get_player()->getPosition().y - (RenderTarget.getSize().y / 2) &&
                ColumnTile.graphics_shape().getPosition().y < pEngine->get_player()->getPosition().y + (RenderTarget.getSize().y / 2)
                )
        {
                //draw if it's on the screen
                RenderTarget.draw(ColumnTile);
        }
}

The problem is half of the map dissapears (is not drawn), or to many sprites are drawn when they shouldn't be - it just doesn't work. Anyone have any idea why?

Help is much appreciated, thanks.

EDIT: Also the sprites are definatly initialized to the correct position, as they are all drawn perfect without the attempted bounds check.
« Last Edit: April 21, 2015, 07:55:43 pm by Iggy »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Help drawing only onscreen sprites
« Reply #1 on: April 21, 2015, 08:14:02 pm »
No need to reinvent the wheel, use sf::FloatRect::intersects(). You can intersect the view's rectangle (constructed using center and size) and the entities' bounding rects (constructed with getGlobalBounds()).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Help drawing only onscreen sprites
« Reply #2 on: April 21, 2015, 08:16:35 pm »
Wow that simple? Thanks a lot, been bouncing off that code for a while now haha.

EDIT: It's still not working correct, do i need to convert any of the co-ords? If so which co-ords? Im really confused.

sf::View Camera = RenderTarget.getView();

sf::FloatRect StreamArea{ Camera.getCenter().x, Camera.getCenter().y, Camera.getSize().x, Camera.getSize().y };//same results as just passing the vectors

for (auto& ColumnTile : Row)
{
        if (ColumnTile.graphics_shape().getGlobalBounds().intersects(StreamArea))
        {
                //draw if it's on the screen
                RenderTarget.draw(ColumnTile);

                //count each draw call
                ++NumDraws;
        }
}

Didn't wana bump.

Thanks again.
« Last Edit: April 22, 2015, 12:06:23 am by Iggy »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Help drawing only onscreen sprites
« Reply #3 on: April 22, 2015, 07:35:14 am »
Quote
sf::FloatRect StreamArea{ Camera.getCenter().x, Camera.getCenter().y, Camera.getSize().x, Camera.getSize().y };//same results as just passing the vectors
 
Look at the documentation of the sf::FloatRect constructor again.
Laurent Gomila - SFML developer

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Help drawing only onscreen sprites
« Reply #4 on: April 22, 2015, 06:29:23 pm »
Hi, thanks for your reply. I took another look at the documentation, and adapted my code so that the rectangle is constructed with the topleft co-ordinates of the view (or so i think). But still having the same problems.

sf::View Cam = RenderTarget.getView();

sf::FloatRect StreamArea{
        Cam.getCenter().x - (Cam.getSize().x / 2),//i thought this would be rectLeft (minumum x value of rectangle?)
        Cam.getCenter().y - (Cam.getSize().y / 2),//rectTop?
        Cam.getSize().x,//full size of view...
        Cam.getSize().y
};

//loop through rows
for (auto& Row : m_VecTileRows)//std::vector<std::vector<CTile>> m_VecTileRows
{
        for (auto& ColumnTile : Row)
        {
                if (ColumnTile.graphics_shape().getGlobalBounds().intersects(StreamArea))
                {
                        RenderTarget.draw(ColumnTile);
                }
        }
}
 

Sorry if it's something silly that I'm doing within the sf::FloatRect constructor. If it is could someone tell me exactly what im doing wrong? I think i may be misunderstanding the docs.

Thanks again for the replies.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Help drawing only onscreen sprites
« Reply #5 on: April 22, 2015, 09:09:26 pm »
Looks good now. So what's your problem exactly?
Laurent Gomila - SFML developer

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Help drawing only onscreen sprites
« Reply #6 on: April 22, 2015, 11:31:58 pm »
I found my problem i was applying a transform elsewhere in code (very silly thing to do). Thanks for the help! Everything working as expected now. Glad i posted here my code looks cleaner now, and more importantly- works.