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

Author Topic: Loading huge amount of images  (Read 8930 times)

0 Members and 1 Guest are viewing this topic.

Bogdan

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Re: Loading huge amount of images
« Reply #15 on: May 07, 2015, 07:23:56 am »
Any feedback, if my code was the right approach for "storing integers and mapping them to colors/provinces"?

As for unloading something from memory, the best way is to have a vector and erasing elements (that seems to free memory), but images/textures don't really work with erasing, because of the white square problem due to dynamic memory allocation, whenever the vector size is changed.

Am I right in the assumption, that storing images/textures/sprites even in seperate vectors (similar to my code from May 5th but with seperate vectors for images/textures/sprite (as tested by me yesterday)) will not work with erasing images (erasing only the sprite is ok, but doesn't help to free memory). Maybe an array would help here with simply setting the element position of the image which I want to unload to NULL?

Last but not least: Does anyone know how the maps from paradox games like victoria, hoi2 etc. are done? (they have several thousands of provinces)

« Last Edit: May 07, 2015, 07:26:57 am by Bogdan »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
AW: Loading huge amount of images
« Reply #16 on: May 07, 2015, 10:07:00 am »
You should really consult a good C++ book and read up on STL containers, how they work and how they manage memory.
This is unrelated to SFML.

Textures and other heavy resource objects should either be stored in a different container or as a vector of smart pointers of said resource. That way the pointer location can change but the resource object will keep a fixed address.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Bogdan

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Re: Loading huge amount of images
« Reply #17 on: May 08, 2015, 07:23:21 am »
Ok, I'm going now for the array approach as the array is "more stable" than a vector. One small question: How to unload for example image0.png from memory or succesfully replace it by a 1x1 pixel png, so the memory is "freed". I tried out some attempts, but without success.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <array>

int main()
{
    sf::RenderWindow mMainWindow(sf::VideoMode(1000,500), "Map", sf::Style::Close);
        sf::View view(sf::Vector2f(500, 300), sf::Vector2f(1000, 500));
        mMainWindow.setFramerateLimit(60);
        mMainWindow.setKeyRepeatEnabled(false);

        sf::Image ImageName;
        sf::Texture TextureName;
        sf::Sprite SpriteName;

        std::array<sf::Image, 4> ImageArray = { {ImageName, ImageName, ImageName, ImageName} };
        std::array<std::string, 4> FileNameArray = { {"map0.png", "map1.png", "map2.png", "map3.png"} };
        std::array<sf::Texture, 4> TextureArray = { {TextureName, TextureName, TextureName, TextureName} };
        std::array<sf::Sprite, 4> SpriteArray = { {SpriteName, SpriteName, SpriteName, SpriteName} };
        std::array<sf::Vector2i, 4> TexturePositionArray = { {sf::Vector2i(0,0), sf::Vector2i(500,0), sf::Vector2i(1000,0), sf::Vector2i(1500,0)} };
       
        for(int i=0; i<4; i++)
        {
                (ImageArray[i]).loadFromFile((FileNameArray[i]));
                (TextureArray[i]).loadFromImage((ImageArray[i]));
                (SpriteArray[i]).setPosition(TexturePositionArray[i].x,TexturePositionArray[i].y);
                (SpriteArray[i]).setTexture((TextureArray[i]));
        }

    while (mMainWindow.isOpen())
    {
        sf::Event event;
                sf::Vector2i mousePos;
                bool leftclicked = false;

        while (mMainWindow.pollEvent(event))
        {
            switch (event.type)
            {
            case sf::Event::Closed:
                mMainWindow.close();
                break;
                        case sf::Event::MouseButtonPressed:
                if (event.mouseButton.button == sf::Mouse::Left)
                                {
                                        leftclicked = true;
                                        mousePos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
                                        break;
                                }
            }
                }
                if(leftclicked)
                {
                        //1. attempt:
                        //for (int i = 0; i < 4; i++)
                        //{
                        //      ImageArray[i].loadFromFile("white.png") ;     //Replacement by white texture of the same size: texture must have same size du to possible erros with collision detection... (not implemented here)
                        //      TextureArray[i].loadFromImage(ImageArray[i]);    // Memory usage goes up significantly
                        //      SpriteArray[i].setTexture((TextureArray[i]));
                        //}
                       
                        //2. attempt:
                        //ImageArray[0] = sf::Image();                         //Image still visible, memory usage unchanged......

                        //3. attempt:
                        //ImageArray[0].loadFromFile("");                                                  //Image still visible, memory usage unchanged......


                        //4. attempt:
                        ImageArray[0].loadFromFile("white.png");                                // .....Memory usage goes up significantly
                        TextureArray[0].update(ImageArray[0].getPixelsPtr());  
                }
        mMainWindow.clear();
                mMainWindow.setView(view);
                for(int i=0; i<4; i++)
                {
                        mMainWindow.draw(SpriteArray[i]);
                }
        mMainWindow.display();
    }
    return 0;
}




zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Loading huge amount of images
« Reply #18 on: May 08, 2015, 08:24:45 am »
Quote
Ok, I'm going now for the array approach as the array is "more stable" than a vector

Ehh?? You do realize that the only real difference is that a vector is dynamically sized? A fixed array won't be "more stable" as you put it.

Quote
How to unload for example image0.png from memory

You do also realize I assume that you declared your fixed arrays on the stack, so the only way to free them is to leave the scope they are declared in.

Quote
or succesfully replace it by a 1x1 pixel png

You could call Texture::create(...) but that is just a dirty workaround your real problem. As for the other arrays, good luck, you allocated the fixed array on the stack.

What you need to do is use a vector for storing your data so you can remove stuff from it and properly cleanup that memory.
« Last Edit: May 08, 2015, 08:29:23 am by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Bogdan

  • Jr. Member
  • **
  • Posts: 93
    • View Profile
Re: Loading huge amount of images
« Reply #19 on: May 08, 2015, 11:08:22 pm »
Finally it worked with vectors, but only if I didn't remove any Textures. But there were performance issues, so I decided to try something different.

I searched the whole internet on how to do pixelperfect collision and there is no up to date SFML code/information for this and I don't know where to look for it. I've found this: https://github.com/SFML/SFML/wiki/Source:-Simple-Collision-Detection
But it's seems to be outdated, didn't even compile and it's about Sprites colliding with each other. What I need is to pixelperfect-check on click, if Mouse is inside a given individually shaped Sprite (where several Sprite Collision Rects overlap).
Even in other forums nobody could help about how to get the collision information/map of a png sprite file.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Loading huge amount of images
« Reply #20 on: May 09, 2015, 12:12:07 am »
You know programming is not about running from forum to forum and let other people solve your problems, but it's about you solving your own problems.

There's an example of code, it might not compile with the latest SFML version, but that's no reason to just ignore it, just because you can't copy&paste it into your project. Look at the code and understand what it does and then fix it up or implement it yourself.

The same applies to your other issues. We've already given you enough pointers on how to approach things. Our "job" is done, now it's your job to do research on the topics and actually understand what is going on and then apply that knowledge to your code base.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/