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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Clash

Pages: [1]
1
I didn't want to use Boost. As previously discussed, there is a max size for RenderImage, so a map may be larger than a RenderImage, that's why I might need more than one.
Correct me if I'm wrong, but RenderImage also contains a pixel array and an OpenGL texture. I'm sure it contains a pixel array though.

2
Quote from: "Nexus"
Quote from: "Clash"
Why can't I add RenderImage to a container?
Because STL containers require copy semantics and sf::RenderImage is noncopyable. But you can store it in Boost's pointer containers, for example.

Quote from: "Clash"
If you switch from dynamic to "normal" memory, the program will crash as soon as it leaves the function.
Try to extract that piece of code so that everything specific to your project is omitted, and we are left with a main() function and plain SFML. If you can't reproduce the error in a minimal complete example, you are probably doing something wrong in your own code. You can also try to find out with the debugger what exactly raises the error.

Why is RenderImage NonCopyable and Image is copyable?
When am I allowed to destroy a RenderImage?
Thanks

Edit: I'm now using STL but saving the pointers instead, this way I can delete then when needed... however I wish there was something more elegant.

3
Quote from: "Nexus"
Quote from: "Clash"
Is RenderImage supposed to be a forever lasting variable like RenderWindow?
Neither of them is. They are supposed to be destroyed (manually or automatically) as soon as they aren't used anymore.

Quote from: "Clash"
Edit: So, using dynamic memory (which I do not like) to avoid the destructors
Not calling destructors is not really a solution, since it leads to memory/resource leaks. If the destructor really crashes if you are using the class correctly, then it is likely to be a bug in SFML.

Do you have a minimal code reproducing this problem?

Why can't I add RenderImage to a container?
This is how I'm doing it right now

When I say groupedTile I refer to the RenderImage, that is simply a group of tiles. startingX is the id, for example, for a 512x512 block, we copy from tile 0 (startingX), 0 (startingY) to 32 (endingX),32 (endingY)
Code: [Select]
void Map::getGroupedTiles(int startingX, int endingX, int startingY, int endingY)
{
    sf::RenderImage *renderImage = new sf::RenderImage();
    if (!renderImage->Create(TILES_HORIZONTAL_RENDERIMAGE*TILE_WIDTH, TILES_VERTICAL_RENDERIMAGE*TILE_HEIGHT))
    {
        return; // failed
    }

    sf::Image *tileset = gImageManager.getResource("world.png");
    for (int y=startingY; y<endingY; y++)
    {
        for (int x=startingX; x<endingX; x++)
        {
            sf::Sprite sprite;
            sprite.SetImage(*tileset);
            sprite.SetPosition((x-startingX)*TILE_WIDTH, (y-startingY)*TILE_HEIGHT);
            sprite.SetSubRect(tilesRects[mapTiles[y][x]]);
            renderImage->Draw(sprite);
        }
    }

    renderImage->Display();
    sf::Sprite sprite;
    sprite.SetImage(renderImage->GetImage());
    sprite.SetPosition(startingX*TILE_WIDTH, startingY*TILE_HEIGHT);
    map.push_back(sprite);
}

If you switch from dynamic to "normal" memory, the program will crash as soon as it leaves the function.
I suppose I'm doing this the wrong way?

4
Quote from: "Groogy"
It's fairly new to SFML so don't think there's any tutorials, all I can recommend is the documentation at: http://www.sfml-dev.org/documentation/2.0/classsf_1_1RenderImage.php

The max size of an image is based on the GPU and can be discovered by using: http://www.sfml-dev.org/documentation/2.0/classsf_1_1Image.php#acb15b7adf8aa6f2155e6f5ce3c11baf5
But I think you are guaranteed to around 2048x2048

Hi, thanks for the help!

I have a question, RenderImage is NonCopyable, I then tried creating it inside a function and associating it to a sprite, but as soon as the function ends the destructor from the RenderImage is called and the program crashes. As it's NonCopyable I can't add it to a container either. Is RenderImage supposed to be a forever lasting variable like RenderWindow?

BTW I couldn't follow the beginning the tutorial. Error C2039: 'IsAvailable' : is not a member of 'sf::RenderImage'

Edit: So, using dynamic memory (which I do not like) to avoid the destructors and get the code to work, the FPS increased to 166~250, and that is drawing the whole map with 512x512 images, even what's outside the screen. Awesome!

5
Quote from: "Groogy"
Hmm sounds really weird that it would go so slow for you to render only 16x16 sized tiles.... hmmm...  Do you have the latest drivers? I don't know why it would be so slow for you to render tiles.

Anyway you can get it to work with render image too with camera but it will be a bit more tricky as you'll have to divide the map into several images as there is a limit to how big a texture on the GPU can be.

The tiles are static, so this seems perfect. Could you link me to some documentation or tutorial? How big can the images be? Thanks a lot in advance!

So RenderImage works like instead of displaying tiles of 16x16, I group a bunch of tiles together and display tiles of for example 256x256? Sounds awesome. Memory is basically free these days so I'd trade in for performance any day.

6
Quote from: "Groogy"
The libraries are not at fault, you should try and set Vertical sync trough the sf::Window class to false.
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Window.php#a824ae1c61ddf2b45f7fa00472f0b6b4e

Also my point was that you actually do loop trough every tile even if they are not shown. If that is done every frame you will get an FPS drop, especially if you do it in debug with STL containers.

Anyway I seem having a hard time understanding what you are actually doing.
Because the impression I get is that you are never moving the camera? You add the visible tiles once to the map variable and then the variable is never touched other to iterate trough for rendering? And map ONLY contain the tiles that are visible? But the camera, or whatever you have to represent a camera, never moves? How large are your tiles actually?

Also try some lightweight benchmarking, try and comment out parts of code you think is the culprit, like the actual call to sf::Window::Draw and compare how much your FPS go up.

Also about RenderImage, what you can do there to speed it up is that if you got a static background(tiles don't animate or change often and so on) then you can render the tiles to the render image at initiation/loading. Then use that image to render as a background in the actual window. So instead of rendering 3k+ Tiles you only render one gigantic image instead.

Sorry if I wasn't clear Groogy. But you got it, right now I don't have a camera, it's never touched or moved again. All tiles on map are visible. It was just a test to see how fast it can go. I'm going to implement the camera and add all tiles when I get it work faster. The tiles are 16x16. Here are my constants:

const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const int SCREEN_HORIZONTAL_TILES = SCREEN_WIDTH / 16;
const int SCREEN_VERTICAL_TILES = SCREEN_HEIGHT / 16;
const int SCREEN_BPP = 32;
const int FRAMES_PER_SECOND = 30;
const int TILESET_WIDTH = 256;
const int TILESET_HEIGHT = 704;
const int TILESET_HORIZONTAL_TILES = TILESET_WIDTH / 16;
const int TILESET_VERTICAL_TILES = TILESET_HEIGHT / 16;
const int TILE_WIDTH = 16;
const int TILE_HEIGHT = 16;

The Vertical Sync didn't change anything. When I commented draw, FPS went to between 500 and 1000 (to calculate it I'm simply doing 1000.f / window.GetFrameTime())

Would the RenderImage give me a better speed? I will have to move camera in the future though.

Thanks again!

7
Quote from: "Laurent"
This should be much faster with SFML 2. Are you using a recent revision? It's weird that you get the same results in both debug and release...

The 60 FPS are probably due to v-sync which is enabled by default in your driver.

I used the snapshot provided at the download section.
Do I have to change anything else at SMFL 2 besides pollEvent and rect.width/height to make it faster? I heard about RenderImage but I don't know what to do with it.
Yes, I also found it weird, that the FPSs are the same. I even deleted the debug DLLs and tried running as debug and it complained the debug DLLs were missing. Then I deleted the release DLLs and tried running the program and it complained the release DLLs were missing. They are also different size, so I don't know what could be it.

Release, linker:
sfml-system.lib
sfml-graphics.lib
sfml-window.lib
sfml-audio.lib
tinyxml.lib

Debug, linker:
sfml-system-d.lib
sfml-graphics-d.lib
sfml-window-d.lib
sfml-audio-d.lib
tinyxml.lib

Thanks alot in advance for your help!

Quote from: "Groogy"
Still how do you check for if the tile is viewed? If you do a per-tile check then you definitely need to do what I wrote on the specified post. Are you assuming that it's the draw that slows down the application or do you actually have data to support that it's the render that does it?

At the example I gave, I'm only adding the tiles of the map that fit the screen (SCREEN_VERTICAL_TILES, SCREEN_HORIZONTAL_TILES), so I'm not even trying or checking if the other tiles are drawable. To actually draw all tiles of the map, without checking if they should be drawn, this would be the code (which makes it even slower, obviously):

Code: [Select]
   for (int y=0; y<mapTiles.size(); y++)
    {
        for (int x=0; x<mapTiles[y].size(); x++)
        {
            sf::Sprite sprite;
            sprite.SetImage(*tileset);
            sprite.SetPosition(x*TILE_WIDTH, y*TILE_HEIGHT);
            sprite.SetSubRect(tilesRects[mapTiles[y][x]]);
            map.push_back(sprite);
        }
    }

So what my code is doing right now, as shown on the first post, is as if I added a map that is exactly the size of the screen.

8
Quote from: "Groogy"
Drawing tiles is a heavy task no matter what library you use or no matter what optimizations you do(like tilesets/spritesheet). Imagine that you will be doing 3000 Draw calls to the GPU each frame. Also among that there's a lot of calculations to map the texture to the correct point on the sprite and so on. It is pretty heavy. And most of those tiles are not even being viewed on the display!

I recommend a space partitioning algorithm to decrease the amount of tiles you are drawing by only testing against the tiles in view and only drawing those. Why you need space partitioning is because if you test against every tile you have in the world that will become a bottleneck of the application.
An easy one to get you started are implementing a grid as I have explained here: http://www.sfml-dev.org/forum/viewtopic.php?p=32767&highlight=#32767

The 3k tiles are the screen tiles, the map itself is larger, the code there is only drawing the screen size (3072 tiles). Previously with SDL this was much faster so there must be a way to speed this up. I will look into your thread, thanks for the help, but as I am akready drawing the minimum, I dont see how this will help.

The suggestion from the other guy would never speed it up.

9
Hi guys, I must be doing something wrong (hopefully). I'm compiling it with VS 2008.

Here is how I load the tileset and create the sprites
Code: [Select]

    std::vector<std::vector<int> > mapTiles; // contains the id of the tiles
    std::vector<sf::Sprite> map; // contains the tiles itself (3072)
    sf::Rect<int> tilesRects[(TILESET_HORIZONTAL_TILES*TILESET_VERTICAL_TILES)+1]; // contains the subrects of each kind of tile
    // Load tiles (subrects)
    for (int y=0; y<TILESET_VERTICAL_TILES; y++)
    {
        for (int x=0; x<TILESET_HORIZONTAL_TILES; x++)
        {
            sf::Rect<int> rect;
            rect.Top = y * TILE_HEIGHT;
            rect.Bottom = y * TILE_HEIGHT + TILE_HEIGHT;
            rect.Left = x * TILE_WIDTH;
            rect.Right = x * TILE_WIDTH + TILE_WIDTH;
            tilesRects[1+x+y*TILESET_HORIZONTAL_TILES] = rect;
        }
    }

    // Create tiles (3072 sprites)
    sf::Image *tileset = gImageManager.getResource("world.png");
    for (int y=0; y<SCREEN_VERTICAL_TILES; y++)
    {
        for (int x=0; x<SCREEN_HORIZONTAL_TILES; x++)
        {
            sf::Sprite sprite;
            sprite.SetImage(*tileset);
            sprite.SetPosition(x*TILE_WIDTH, y*TILE_HEIGHT);
            sprite.SetSubRect(tilesRects[mapTiles[y][x]]);
            map.push_back(sprite);
        }
    }


Drawing
Code: [Select]
   for (int i=0; i<map.size(); i++)
    {
        window.Draw(map[i]);
    }
    window.Display();


My computer specs are
i5 2.26Ghz
Intel GMA
On dedicated card (Radeon HD 5650) I only get 60FPS (60 fps release, 10fps debug), which I find extremely low for such task.

I've read that SMFL 2 boosts the speed, but is it normal that with SMFL 1.6 it's this slow?

Thanks A LOT in advance.

Edit: Tried it with SMFL 2 and now debug and release have 15 FPS... weird

Pages: [1]
anything