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

Author Topic: just draw a image, not a sprite  (Read 4591 times)

0 Members and 1 Guest are viewing this topic.

kwuuak

  • Newbie
  • *
  • Posts: 11
    • View Profile
just draw a image, not a sprite
« on: November 17, 2008, 10:20:04 pm »
i have a question,

for example i want to make a tile-based game, so i have to draw a picture for each tile.

Creating a sprite for each tile, would be nonsense, so how do i just draw a image at a position if i dont need all informations a sprite includes


thx

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
just draw a image, not a sprite
« Reply #1 on: November 17, 2008, 10:40:07 pm »
As you may or may not know, dozens of sprites can use the same image and the image doesn't need to be loaded multiple times for each sprite to use them.

This system of sprites being able to reuse images without loading the images multiple times is why sf::Image and sf::Sprite aren't merged into one class.

If you're really just worried about SFML using a few more bytes per sprite than you need, I ensure you that worrying about such a thing is silly.

MrQuizzles

  • Newbie
  • *
  • Posts: 15
    • View Profile
just draw a image, not a sprite
« Reply #2 on: November 17, 2008, 11:21:36 pm »
To my knowledge, you cannot draw images directly to the screen. You must have a sprite that is tied to an image in order to render it.

Not to worry, though, sprites are very lightweight. They don't use up a lot of memory, and you can create, modify and destroy thousands of them each second without a large impact on performance.

It might just seem like another hurdle you have to jump through in your case, but the system makes a lot of sense when you have to deal with thousands of them each being transformed in different ways.


You could just create a function that takes an image and an x and y location and then, inside the function, create a sprite and render it in the correct location. If you keep everything else at the default, it won't change the image any.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
just draw a image, not a sprite
« Reply #3 on: November 17, 2008, 11:42:02 pm »
Quote from: "MrQuizzles"
You could just create a function that takes an image and an x and y location and then, inside the function, create a sprite and render it in the correct location. If you keep everything else at the default, it won't change the image any.

Although it does save memory, this is more redundant and runs slower than doing it how it's supposed to be done.

MrQuizzles

  • Newbie
  • *
  • Posts: 15
    • View Profile
just draw a image, not a sprite
« Reply #4 on: November 18, 2008, 04:37:30 am »
Quote from: "Wizzard"
Quote from: "MrQuizzles"
You could just create a function that takes an image and an x and y location and then, inside the function, create a sprite and render it in the correct location. If you keep everything else at the default, it won't change the image any.

Although it does save memory, this is more redundant and runs slower than doing it how it's supposed to be done.


The idea is to make it easiest for the programmer in this case. Take 2 minutes and make a function that makes sprites for you so you can pretend you're drawing images directly to the screen. Unless you're making hundreds of thousands of these things, performance won't be a problem.

devon

  • Newbie
  • *
  • Posts: 12
    • View Profile
just draw a image, not a sprite
« Reply #5 on: November 21, 2008, 07:33:16 am »
Well maybe creating thousands of sprites a second doesn't impact performance but creating 720 shape::lines a second (at 60fps) on a 1ghz machine has a large impact on performance :). Which is what I found out when I put this in my main loop:

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]);
}

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
just draw a image, not a sprite
« Reply #6 on: November 21, 2008, 09:01:15 am »
Quote from: "devon"
Well maybe creating thousands of sprites a second doesn't impact performance but creating 720 shape::lines a second (at 60fps) on a 1ghz machine has a large impact on performance :).

It isn't the drawing that is the bottleneck, it's the lines that are being generated each frame. You're computing a normal 12 times per asteroid every frame.

Edit:
Were not discussing creating sprites every frame in this thread, were discussing drawing the sprites each frame that were created already.

wizardofoz

  • Newbie
  • *
  • Posts: 18
    • View Profile
just draw a image, not a sprite
« Reply #7 on: November 21, 2008, 09:27:24 am »
Quote
It isn't the drawing that is the bottleneck, it's the lines that are being generated each frame. You're computing a normal 12 times per asteroid every frame.


True, but Draw() function calls glBegin/glEnd each time and this could have an impact on the performance in some situations.

If we talk about performance when whe have a huge amount of vertexes:

1) Worse: glBegin/glEnd
2) Better: Vertex arrays
3) Best: VBOs / Display List

This is an interesting article by NVIDIA about performance:
http://www.nvidia.com/content/nvision2008/tech_presentations/Professional_Visualization/NVISION08-Double_Your_Graphics_Performance.pdf

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
just draw a image, not a sprite
« Reply #8 on: November 21, 2008, 08:31:26 pm »
Quote from: "wizardofoz"
True, but Draw() function calls glBegin/glEnd each time and this could have an impact on the performance in some situations.

Is it the calls to glBegin and glEnd that impact performance, or the API calls in the scope of glBegin and glEnd calls that impact performance? Basically, if I were to bundle all my API calls into the scope of a single glBegin and a single glEnd, would it be more efficient than doing them separately?

Also, are you just making a general statement on how SFML's rendering performance could be better or are you targeting Shape's Render member to be inefficient?

wizardofoz

  • Newbie
  • *
  • Posts: 18
    • View Profile
just draw a image, not a sprite
« Reply #9 on: November 21, 2008, 09:25:42 pm »
According to the NVIDIA article:

Quote


Methods of data movement:

....
- glBegin() / glEnd(): easy to use but bad performance, spoon feeding, multiple layers per call, only a few words of data per API call, function calls are expensive.
....



My personal thought is that glBegin / glEnd is more than good for general purposes and it is easy to use. I think that only with a big amount of vertexes to render each frame these API calls could slow down the rendering time and it also depends on the hardware.

One thing that I learned that can improve the performance is to group your primitive rendering calls first by primitive type, then by texture, then by blending mode.

If we talk about SFML I think there is already in the roadmap a way to " Optimize rendering of huge amounts of drawables".

 

anything