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

Author Topic: Running Heavy Graphics  (Read 2766 times)

0 Members and 1 Guest are viewing this topic.

K55

  • Newbie
  • *
  • Posts: 2
    • View Profile
Running Heavy Graphics
« on: September 28, 2011, 02:29:56 am »
Hi everyone, I've been messing around with SFML lately and have really come to like the language. However, I am running into roadblocks literally when it comes to drawing large png images or tiles. When I draw my titlescreen images or tilemap, the framerate drags down to 8 or so fps. For example:

Code: [Select]
px = 0;
py = 0;

for (float qq = 0; qq <= 800; qq +=32)
{
for (float ii = 0; ii <= 608; ii += 32)
{
if (map[px][py] == 0)
{
App.Draw(Tile1);
Tile1.SetPosition(qq,ii);
}

if (map[px][py] == 1)
{
App.Draw(Tile2);
Tile2.SetPosition(qq,ii);
}
py++;
}
px++;
py=0;
}


Is a simple script I wrote to display tiles in a 800x600 window (yes I could have gotten the resolution and changed the array size, but that's not the point). This script running constantly to draw 475 png tiles is really slow.

So my question is, is there a way to draw a sprite or an image only once, so that it does not eat up memory or processing time?
Thanks
-K55

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
Running Heavy Graphics
« Reply #1 on: September 28, 2011, 04:25:45 am »
We need a complete and minimal code to see exactly what the problem is and to test it on our machines.
I use the latest build of SFML2

thePyro_13

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Running Heavy Graphics
« Reply #2 on: September 28, 2011, 04:30:15 am »
You should be using one sprite per map cell. Reusing them like this may be the cause of your performance loss.

Do your math upfront and reuse it, rather than calculating which tile goes where every frame.

sbroadfoot90

  • Jr. Member
  • **
  • Posts: 77
    • View Profile
Running Heavy Graphics
« Reply #3 on: September 28, 2011, 06:11:13 am »
Quote
You should be using one sprite per map cell. Reusing them like this may be the cause of your performance loss.


Rather, you should load each tile into a texture (or image if you are using 1.6), or your tileset into a single texture only once, and reuse this texture for each sprite that needs to use it, you can use the setsubrect member function of sprite to choose which portion of the tileset you want to use for that particular sprite .

K55

  • Newbie
  • *
  • Posts: 2
    • View Profile
Running Heavy Graphics
« Reply #4 on: September 28, 2011, 07:01:34 pm »
Here's the code:
(the two tiles are 32x32 png images)
Code: [Select]
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML\System.hpp>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>

////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
    // Create the main rendering window
    sf::RenderWindow App(sf::VideoMode(800, 600, 8), "A-Mazing Game");
float movespeed = (32.0f);

sf::Image T1;
if (!T1.LoadFromFile("grass (2).png"))
return EXIT_FAILURE;
T1.SetSmooth(false);

sf::Image T2;
if (!T2.LoadFromFile("water.png"))
return EXIT_FAILURE;
T2.SetSmooth(false);

   

    // Create the sprite
    //sf::Sprite Sprite(Image);
sf::Sprite Tile1(T1);
sf::Sprite Tile2(T2);

int map[25][19]= {0};

map[24][0]= 1;


    // Start game loop
    while (App.IsOpened())
    {
        // Process events
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
                App.Close();
        }

App.Clear();
int px = 0;
int py = 0;

for (float qq = 0; qq <= 800; qq +=32)
{
for (float ii = 0; ii <= 608; ii += 32)
{
if (map[px][py] == 0)
{
App.Draw(Tile1);
Tile1.SetPosition(qq,ii);
}

if (map[px][py] == 1)
{
App.Draw(Tile2);
Tile2.SetPosition(qq,ii);
}
py++;
}
px++;
py=0;
}



        // Clear screen
        // Display sprite in our window
        // Display window contents on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}

Just a question, how would I go about using only one sprite per cell?

David

  • Jr. Member
  • **
  • Posts: 71
    • View Profile
Running Heavy Graphics
« Reply #5 on: October 11, 2011, 07:26:07 pm »
Just out of curiousity, why are you using floats for "ii" and "qq"?

slotdev

  • Sr. Member
  • ****
  • Posts: 385
    • View Profile
Running Heavy Graphics
« Reply #6 on: October 12, 2011, 01:39:54 pm »
In addition to the above comments, there is no frame rate control, nor are you handing any time back to the CPU between, so your app will be running at 100% CPU.
SFML 2.1

thePyro_13

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Running Heavy Graphics
« Reply #7 on: October 12, 2011, 01:58:54 pm »
Quote from: "K55"
Here's the code:
(the two tiles are 32x32 png images)
Code: [Select]
<codes>

Just a question, how would I go about using only one sprite per cell?


Create a std::vector or std::list and move your for loop above the main loop(your while loop). For each tile you create, push it into your vector or list.

Then in your draw step iterate through your list and draw every entry.

Something like this(not working code, but should get the point across), modified version of parts of your code.

Code: [Select]

//before while
for (float qq = 0; qq <= 800; qq +=32)
      {
         for (float ii = 0; ii <= 608; ii += 32)
         {
            if (map[px][py] == 0)
            {
               //App.Draw(Tile1);
               Tile1.SetPosition(qq,ii);
               vector.push_back(Tile1); //load into vecotr
            }

            if (map[px][py] == 1)
            {
               //App.Draw(Tile2);
               Tile2.SetPosition(qq,ii);
               vector.push_back(tile2); //load into vector
            }
            py++;
            }
         px++;
         py=0;
      }

//between clear() and display()

vector<sprite>::iterator iter = vector.begin()
whlie (iter != vecotr.end())
{
App.Draw(*iter);
iter++;
}