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

Author Topic: [SOLVED]Zoom on view using too much ressources  (Read 1956 times)

0 Members and 1 Guest are viewing this topic.

schizo-boy

  • Newbie
  • *
  • Posts: 11
    • View Profile
[SOLVED]Zoom on view using too much ressources
« on: July 06, 2013, 02:32:21 pm »
Hello,
My colleague and I ran into an issue with views.
The following method

void    GameWindow::redrawMap(const int width, const int height, const bool recreateMap)
{
    sf::View view, view2;
    sf::RectangleShape rect;
    int altColor = 0;
    int posX = 0, posY = 0;
    int caseWidth = 32, caseHeight = 32;
    int sidePanelWidth = 200;
    sf::Sprite sidepanelImage;

    sidepanelImage.setTexture(sidePanel);
    screenWidth = caseWidth * 20 + sidePanelWidth;
    screenHeight = caseHeight * 20;
    if (recreateMap)
        renderWindow.create(sf::VideoMode(screenWidth, screenHeight), "UI", sf::Style::Titlebar | sf::Style::Close);
    renderWindow.clear(sf::Color(139, 115, 85));
    rect.setSize(sf::Vector2f(caseWidth, caseHeight));
    rect.setOutlineColor(sf::Color::Yellow);
    rect.setOutlineThickness(1);
    sidepanelImage.setPosition(screenWidth - sidePanelWidth, 0);
    rect.setPosition(posX, posY);
    view.reset(sf::FloatRect(0, 0, screenWidth, screenHeight));
    view.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
    view.zoom(curZoom);
    renderWindow.setView(view);
    while (posY <= caseHeight * height)
    {
        while (posX < caseWidth * width)
        {
            renderWindow.draw(rect);
            rect.setPosition(posX, posY);
            posX += caseWidth;
            rect.setFillColor(sf::Color(0, 123, 12));
            altColor++;
        }
        posX = 0;
        posY += caseHeight;
    }
    view2.reset(sf::FloatRect(0, 0, screenWidth, screenHeight));
    view2.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));
    renderWindow.setView(view2);
    renderWindow.draw(sidepanelImage);
    renderWindow.display();
}
 

Allow us to redraw the content of the window each time we want to zoom in or zoom out on this view by modifying the curZoom variable before entering this method.

The problem is that we have to redraw the whole content of the window each time we want to modify the view.

Our window look like this:


The green squares are all we want to zoom into.

The problem we are facing is that because the views are passed by copy into our renderWindow we can not find a way to access it later or to keep a reference on it. So we are just redrawing the squares as well as the other view on the right ( the grey "box").

If there was a way to do it in a "cleaner" way or any help idea or solution on that problem would be greatly appreciated.

Thanks
« Last Edit: July 07, 2013, 03:18:41 pm by schizo-boy »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Zoom on view using too much ressources
« Reply #1 on: July 06, 2013, 03:36:36 pm »
You actually have several problems.

Quote
The problem is that we have to redraw the whole content of the window each time we want to modify the view.

This is wrong, with SFML you must clear and redraw everything in every frame. Keeping old pixel data through frames is not the correct way to go about using SFML.


Quote
The problem we are facing is that because the views are passed by copy into our renderWindow we can not find a way to access it later or to keep a reference on it

You should read the tutorials again. To quote from the bright red section in the tutorial.

Quote
When you call setView, the render-target keeps a copy of the view, not a pointer to the original one. So whenever you update your view, you need to call setView again to apply the modifications.
Don't be afraid to copy views or to create them on the fly, they are lightweight objects (they just hold a few floats).


Your problem with resources is obviously not with views. It seems more to me that your problem comes from the number of draw calls you are sending the GPU. You should consider using a vertex array for drawing.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Ekami

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Zoom on view using too much ressources
« Reply #2 on: July 06, 2013, 04:12:14 pm »
You actually have several problems.

Quote
The problem is that we have to redraw the whole content of the window each time we want to modify the view.

This is wrong, with SFML you must clear and redraw everything in every frame. Keeping old pixel data through frames is not the correct way to go about using SFML.

This is what we are doing actually and it's ressource consuming to clear and redraw everything in every frame for me. We did not implemented any game loop and one frame to another can be considered as a zoom in/out.

Quote
The problem we are facing is that because the views are passed by copy into our renderWindow we can not find a way to access it later or to keep a reference on it

You should read the tutorials again. To quote from the bright red section in the tutorial.

Quote
When you call setView, the render-target keeps a copy of the view, not a pointer to the original one. So whenever you update your view, you need to call setView again to apply the modifications.
Don't be afraid to copy views or to create them on the fly, they are lightweight objects (they just hold a few floats).


Your problem with resources is obviously not with views. It seems more to me that your problem comes from the number of draw calls you are sending the GPU. You should consider using a vertex array for drawing.
Exactly, there i a huge amout of draws and we are trying to avoid that. As quoted on the tutorials: "the render-target keeps a copy of the view, not a pointer to the original one". Thus we can't just get our working view back outside of our function to zoom in/out on it as it will be a copy. We have to redraw all we want to display and act on new views to zoom.
I was wondering if there is a way to draw not on our renderWindow (sf::RenderWindow) but on a sf::View for example and then pass it to the renderWindow, this way we could act on our view without redrawing the entire map at each call of our function redrawMap.
« Last Edit: July 06, 2013, 04:17:44 pm by Ekami »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Zoom on view using too much ressources
« Reply #3 on: July 06, 2013, 05:00:49 pm »
Quote
I was wondering if there is a way to draw not on our renderWindow (sf::RenderWindow) but on a sf::View for example and then pass it to the renderWindow

I think you misunderstand views. All a view contains is a just a few floats that define where you draw stuff in your window. If you want an offscreen target use sf::RenderTexture.

Quote
Don't be afraid to copy views or to create them on the fly

As I said before, your bottleneck is not with views, creating a new view every frame is not hurting your performance.

Quote
there i a huge amout of draws and we are trying to avoid that

Once again as I said you need to use sf::VertextArray to reduce draw calls. Put all of the green squares you are drawing into one big vertex array and then all you need is 1 draw call and everything gets drawn all at once.


Quote
Thus we can't just get our working view back outside of our function to zoom in/out on it as it will be a copy

On a side note, why don't you just declare your working view outside of the function and reuse it if you don't feel like recreating it every frame?
« Last Edit: July 06, 2013, 05:02:55 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Zoom on view using too much ressources
« Reply #4 on: July 06, 2013, 06:28:22 pm »
Quote
Thus we can't just get our working view back outside of our function to zoom in/out on it as it will be a copy

On a side note, why don't you just declare your working view outside of the function and reuse it if you don't feel like recreating it every frame?

This^.  A little bookkeeping can go a long way.  I am currently working my way through the SFML Game Developement book that some of these forums heavy hitters put out and one of the things they do with views is maintain a 'default' one that is used when drawing text/hud on the screen, then another view in the 'World' class to help with drawing everything else.  So when the game draws it goes: Clear the screen, switch to WorldView, draw the world and all objects, switch back to GameView, draw hud.

schizo-boy

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Zoom on view using too much ressources
« Reply #5 on: July 07, 2013, 03:18:15 pm »
Thanks for the help guys!

You were right we were not handling the views correctly.

Took me quite some time to wrap my mind around it but we've finally managed to handle them correctly and now everything works as expected  :)

Thanks for the tip about vertex arrays as well our code is much more efficient now  8)