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

Author Topic: framerate drops when drawing 100+ shape::lines  (Read 4257 times)

0 Members and 1 Guest are viewing this topic.

devon

  • Newbie
  • *
  • Posts: 12
    • View Profile
framerate drops when drawing 100+ shape::lines
« on: November 19, 2008, 05:06:03 am »
So in my asteroids game I get some major frame rate drops when I have 10+ asteroids being drawn and when running at 1ghz on battery. When I run the computer at full 1.86ghz the drop is less significant but still noticeable. All the same I want to make my code fast enough to do other things then move lines and be able run on slower computers.

since each asteroid is made up of 12 lines, 10 asteroids is 120 shapes then. And is that what's slowing it down? Is it the overhead for each line to be an individual drawable? Would it be faster to not recreate the shapes each frame and either use pointers to the x and ys?

If I did it in shape::polygons they would be turning concave and convex because of the rotation I have, and I think that may not draw properly.

Here's what happens every frame in the member functions:

Code: [Select]
void Asteroid::draw(sf::RenderWindow &win)
{
    sf::Shape astShape[12];
    int drawN = 12;
    //Draw asteroid's inner rectangle
    astShape[0] = sf::Shape::Line(x[0],y[0],x[1],y[1],1,sf::Color(255, 255, 255));
    astShape[1] = sf::Shape::Line(x[1],y[1],x[2],y[2],1,sf::Color(255, 255, 255));
    astShape[2] = sf::Shape::Line(x[2],y[2],x[3],y[3],1,sf::Color(255, 255, 255));
    astShape[3] = sf::Shape::Line(x[3],y[3],x[0],y[0],1,sf::Color(255, 255, 255));
   
    //Connect inner rectangle to top vertex
    astShape[4] = sf::Shape::Line(x[0],y[0],x[4],y[4],1,sf::Color(255, 255, 255));
    astShape[5] = sf::Shape::Line(x[1],y[1],x[4],y[4],1,sf::Color(255, 255, 255));
    astShape[6] = sf::Shape::Line(x[2],y[2],x[4],y[4],1,sf::Color(255, 255, 255));
    astShape[7] = sf::Shape::Line(x[3],y[3],x[4],y[4],1,sf::Color(255, 255, 255));

    //Connect inner rectangle to bottom vertex
    astShape[8] = sf::Shape::Line(x[0],y[0],x[5],y[5],1,sf::Color(255, 255, 255));
    astShape[9] = sf::Shape::Line(x[1],y[1],x[5],y[5],1,sf::Color(255, 255, 255));
    astShape[10] = sf::Shape::Line(x[2],y[2],x[5],y[5],1,sf::Color(255, 255, 255));
    astShape[11] = sf::Shape::Line(x[3],y[3],x[5],y[5],1,sf::Color(255, 255, 255));
   
    for(int i =0; i < drawN; i++)
        win.Draw(astShape[i]);
}

void Asteroid::move(int winX, int winY)
{  
//Rotate asteroid
y2Angle += spinSpeed;//Increase the angle by the amount of spinSpeed
y4Angle += spinSpeed;
y5Angle += spinSpeed;
y6Angle += spinSpeed;
    y[1] = centerY + radius * sin(y2Angle);//Trig = hypotenuse * sin(destination angle)
    y[3] = centerY + radius * sin(y4Angle);
    y[5] = centerY + radius * sin(y5Angle);
    y[4] = centerY + radius * sin(y6Angle);
   
    //Move asteroid1 down
    for (int i = 0; i < n; i++)
        y[i] += asteroidMoveY;
    centerY += asteroidMoveY;
}

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #1 on: November 19, 2008, 05:12:36 am »
Set this code outside of your game loop...
Code: [Select]
sf::Shape astShape[12];
int drawN = 12;
//Draw asteroid's inner rectangle
astShape[0] = sf::Shape::Line(x[0],y[0],x[1],y[1],1,sf::Color(255, 255, 255));
astShape[1] = sf::Shape::Line(x[1],y[1],x[2],y[2],1,sf::Color(255, 255, 255));
astShape[2] = sf::Shape::Line(x[2],y[2],x[3],y[3],1,sf::Color(255, 255, 255));
astShape[3] = sf::Shape::Line(x[3],y[3],x[0],y[0],1,sf::Color(255, 255, 255));

//Connect inner rectangle to top vertex
astShape[4] = sf::Shape::Line(x[0],y[0],x[4],y[4],1,sf::Color(255, 255, 255));
astShape[5] = sf::Shape::Line(x[1],y[1],x[4],y[4],1,sf::Color(255, 255, 255));
astShape[6] = sf::Shape::Line(x[2],y[2],x[4],y[4],1,sf::Color(255, 255, 255));
astShape[7] = sf::Shape::Line(x[3],y[3],x[4],y[4],1,sf::Color(255, 255, 255));

//Connect inner rectangle to bottom vertex
astShape[8] = sf::Shape::Line(x[0],y[0],x[5],y[5],1,sf::Color(255, 255, 255));
astShape[9] = sf::Shape::Line(x[1],y[1],x[5],y[5],1,sf::Color(255, 255, 255));
astShape[10] = sf::Shape::Line(x[2],y[2],x[5],y[5],1,sf::Color(255, 255, 255));
astShape[11] = sf::Shape::Line(x[3],y[3],x[5],y[5],1,sf::Color(255, 255, 255));

devon

  • Newbie
  • *
  • Posts: 12
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #2 on: November 19, 2008, 06:02:15 am »
That's fine for moving it. But to animate it I don't see any setPoint function, so the only way to change a point in the line is to call Line? And that happens every frame.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #3 on: November 19, 2008, 06:36:57 am »
Oh, so that's why you did it that way. I guess there really is no way to optimize it. You should just do the application in 3D instead of 2D honestly.

devon

  • Newbie
  • *
  • Posts: 12
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #4 on: November 19, 2008, 07:04:25 am »
haha yeah, except this is my first game in c++ and openGL is still scary. Although maybe simpler to do what I want than I think.

I only need ~10 asteroids on screen at most.  If I force a them to skip "frames" by making a counter that delays how often a shape is created it might work.

devon

  • Newbie
  • *
  • Posts: 12
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #5 on: November 19, 2008, 08:13:54 am »
yeah throwing this in my main loop did the trick, at least up to 50 asteroids or so.

where theTime = Clock.GetElapsedTime();

Code: [Select]
int intTime = theTime * 100;
//should probably fix this to do a typecast to int
if (intTime %2 == 0)

        {

            asteroid[i].rotate();
//recreate the 12 lines
        }

jdindia

  • Newbie
  • *
  • Posts: 13
    • View Profile
framerate drops when drawing 100+ shape::lines
« Reply #6 on: November 30, 2008, 12:54:39 pm »
I'm not completely sure what you're doing, but it doesn't look fast.  =/

I think you're generating a shape per edge of your asteroid, and then drawing each edge separately.  Ouch.

A few possible solutions.  

* Make a few different images of asteroids and then use one sprite per asteroid.
* Make your own asteroid drawable and use OpenGL to draw the lines that make up the asteroid.  This is easier than it seems.  It's quite literally glBegin(GL_LINES); glVertex2f (); ... glEnd(); You might need to glDisable(GL_TEXTURE_2D); and then glEnable(GL_TEXTURE_2D) when you finish.
* Cut your asteroid into convex polygons and use the polygon drawable.