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

Author Topic: Sprite Efficiency  (Read 19187 times)

0 Members and 1 Guest are viewing this topic.

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Sprite Efficiency
« Reply #15 on: February 05, 2013, 06:46:56 pm »
Nexus, I fixed everything I could in this code, however I don't really know how to fix "window.draw" error
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Sprite Efficiency
« Reply #16 on: February 05, 2013, 07:51:48 pm »
Consult the API documentation. There are two overloads for draw(), one for a sf::Drawable and one for a sf::Vertex*. Since sf::VertexArray is derived from sf::Drawable, you take the first overload.

And in the future, please post more meaningful error descriptions than "window.draw doesn't work".
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Sprite Efficiency
« Reply #17 on: February 05, 2013, 08:10:08 pm »
Well, I looked through API over and over again and didn't find answer to my question, sorry.

The problem is with this line:

window.draw(sprite, &tileset);

It references pointer to tileset texture somehow, but I cannot find a way to assign a texture to a sf::VertexArray, because these examples are incomplete. I managed to draw one sprite, but I don't really get how to draw the whole map using sf::VertexArray
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

victorlevasseur

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: Sprite Efficiency
« Reply #18 on: February 05, 2013, 08:18:02 pm »
When you use a VertexArray, you pass the texture in the draw function, you don't affect the texture to the VertexArray.

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Sprite Efficiency
« Reply #19 on: February 05, 2013, 08:18:46 pm »
The RenderStates have a texture* alongside a blendmode and shader if any. Once again a look at the doc or the sources could have solved it without asking.

It would be better to construct the RenderStates with the texture (to be more explicit), a missing include can also be the cause of some compiling errors in the case you are not including the whole graphics module.
« Last Edit: February 05, 2013, 08:25:51 pm by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Sprite Efficiency
« Reply #20 on: February 05, 2013, 08:23:32 pm »
Sorry. It's now fixed.
Laurent Gomila - SFML developer

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Sprite Efficiency
« Reply #21 on: February 06, 2013, 09:19:55 am »
Thanks, everyone! I've got it working now. So my game used ~19132 kb or RAM, and now it uses ~18672kb. Considering a level is not very big it's pretty good result. However I'm wondering if I'm doing it right.
So, my Tile struct looks like this now:
struct Tile {
        //collision information, animation information will be there soon
        int tx, ty; // position of tile in a tileset texture
};

Tileset is defined like this:
std::map<char, Tile*> tilesetMap;

And map is just:
std::vector<char> map

So for example my level is

SSSSS
SSSSS
SSSSS
GGGGG

And it's very easy to get corresponding tile from a tileset:
Tile currentTile = &tilesetMap[map[x + y * width]];

So, back to rendering. Here's how I set up VertexArray:

//these are not changing so it's outside drawing function
sf::RenderStates states;
states.texture = &tileset.getTilesetTexture();
sf::VertexArray map(sf::Quads, 4 * levelWidth * levelHeight);
int w, h;
w = h = 16;

...

//left, right, top, down - these are the number of tiles currently seen on screen
        for (int i = left; i < right; ++i)
    for (int j = top; j < down; ++j)
    {
        id = i + j * levelWidth;
                float tx = tileset.getTile(tiles[id])->tx;
        float ty = tileset.getTile(tiles[id])->ty;

        map[(id) * 4 + 0] = sf::Vertex(sf::Vector2f(i * w, j * h), sf::Vector2f(tx, ty));
        map[(id) * 4 + 1] = sf::Vertex(sf::Vector2f((i + 1) * w, j * h), sf::Vector2f(tx + w, ty));
        map[(id) * 4 + 2] = sf::Vertex(sf::Vector2f((i + 1) * w, (j + 1) * h), sf::Vector2f(tx + w, ty + h));
        map[(id) * 4 + 3] = sf::Vertex(sf::Vector2f(i * w, (j + 1) * h), sf::Vector2f(tx, ty + h));
        }

//So let's draw it.
        mainWindow->draw(map, states);

 

Am I drawing my map efficiently now?
« Last Edit: February 06, 2013, 09:30:28 am by moarthenfeeling »
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Sprite Efficiency
« Reply #22 on: February 06, 2013, 09:37:27 am »
Looks good.

Since everything is static, you build the vertex array in the init function, not everytime you draw it, right? Then why do you keep a tile structure in parallel? Once the vertex array is built, you don't need to store a separate structure of tile objects just to keep the texture coordinates.
Laurent Gomila - SFML developer

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Sprite Efficiency
« Reply #23 on: February 06, 2013, 09:54:41 am »
It's pretty useless now, yeah. But it will be very useful in future when I'll implement collision system, so I can assign different properties to each tile. And I need to rebuilt VertexArray each time I draw my level(well, because I don't need to draw each tile, I just need to draw tiles which are on the screen at the moment).

Or maybe there's no need to do that?
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Sprite Efficiency
« Reply #24 on: February 06, 2013, 10:06:20 am »
There are three very different examples on the wiki, one of them is almost the same as yours but rebuilds only part of array at a time.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Sprite Efficiency
« Reply #25 on: February 06, 2013, 10:20:35 am »
There's also the strategy to have a small number of smaller chunks, organized in a partitionning system (like a quad-tree). It's a good compromise because you don't need to rebuild anything, yet you can draw a good approximation of what's visible on screen and with very few draw calls.

Partitionning structures also help to speed up collision tests.
Laurent Gomila - SFML developer

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Sprite Efficiency
« Reply #26 on: February 06, 2013, 10:28:46 am »
FRex, I can't find those examples. Can you post links, please?
Well, my method rebuilds only part of array too. For example if I want to draw sprites idX:[2-4], idY[6-7], for example, I set:
 
left = 2; right = 5; top = 6; down = 8;
And only 24 members of VertexArray are rebuilt. Actually this is what I use(viewRect is what is seen on the screen at the moment)
int left = 0;
        if(viewRect.left > 0) left = viewRect.left / tileWidth;
        int top = 0;
        if(viewRect.top > 0) top = viewRect.top / tileHeight;

        int right = (viewRect.left + viewRect.width) / tileWidth + 1;
        int down = (viewRect.top + viewRect.height) / tileHeight + 1; // '+1', because some tiles are chopped off
        if(right > width) right = levelWidth;
        if(down > height) down = levelHeight;

Laurent, this sounds interesting. But I can't understand how can I do that. I only draw 20 * 15 tiles, so how will quad-tree look like?
« Last Edit: February 06, 2013, 10:34:46 am by moarthenfeeling »
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Sprite Efficiency
« Reply #27 on: February 06, 2013, 10:48:53 am »
20x15? How can it be bigger than the window? What is the size of your tiles?
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Sprite Efficiency
« Reply #28 on: February 06, 2013, 10:50:50 am »
https://github.com/SFML/SFML/wiki/Sources

Quote
20x15? How can it be bigger than the window? What is the size of your tiles?
32x32 on a 640x480 window? ;)
Back to C++ gamedev with SFML in May 2023

krzat

  • Full Member
  • ***
  • Posts: 107
    • View Profile
Re: Sprite Efficiency
« Reply #29 on: February 06, 2013, 10:54:08 am »
I can't find those examples. Can you post links, please?
Well, I gave you one before. I wonder what was wrong with it. I tried to make it as universal as possible,
SFML.Utils - useful extensions for SFML.Net