SFML community forums

Help => Graphics => Topic started by: JollyGent on May 27, 2015, 01:56:17 pm

Title: texture.update() problem
Post by: JollyGent on May 27, 2015, 01:56:17 pm
I am making a mini zombie survival game in SFML, and what I'm trying to do at the moment is to render the map. However, when I try to use the line:

this->texture->update(tile1,x*64,y*64);


it crashes, and at first I thought it is because the image size is too big or something, or I made a derp in the development process, so I created a minimal code, and please note, I made sure the
"Stones.png"
is 64x64.


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

int main(){

    sf::Image image;
    sf::RenderWindow window(sf::VideoMode(800,600),"minimal code");
    sf::Texture texture;
    sf::Event event;

    while(window.isOpen()){

        while(window.pollEvent(event)){

            if(event.type == sf::Event::Closed){
                window.close();
            }

        }


        image.create(64,64);
        image.loadFromFile("Stones.png");
        texture.update(image,64,64);


    }


}

 


now that the context of the minimal code is given, I should also tell you that

 texture.update(image,64,64);
is what causes the problem.

(http://s12.postimg.org/3x1ftd9fd/Stones.png) (http://postimage.org/)

here is the png, just so you can do a quick test.
Title: Re: texture.update() problem
Post by: Antonio9227 on May 27, 2015, 02:22:24 pm
Hi JollyGent!
I've looked over your code and I think I know what's causing the problem. Remember that the code you write inside while(window.isOpen()) is repeated until the window is no longer opened. Basically your program loads the image file over and over again while the window is opened.
Usually it's a good idea to load all the textures you need (textures/sounds/etc) at the beginging of your program. Once loaded, the textures are kept in the memory and you don't need to load them again every time you need to use them. In this case you should load the textures before the while loop.

What I would also recommend is loading the file in a sf::Texture object like this:
sf::Texture texture;
texture.loadFromFile("Stones.png");
You don't really need to load it into an image and then transfer it to a texture. It looks much more simpler to just load them directly into a sf::Texture ^_^. If you later need to use just a part from your image as a texture, you can use the setTextureRect() method for your sprite (if you decide to use a sprite).

I hope this helps, if you need further help use the SFML documentation (http://www.sfml-dev.org/learn.php) or come back and ask on the forum. Have a nice day!
Title: Re: texture.update() problem
Post by: JollyGent on May 27, 2015, 02:34:08 pm
Thank you for the reply.

Now we know the problem, I'm going to post the bigger picture.

First of all, how my program works is that in the MainGameState's constructor, Map->load() function is called, which look like this.

void Map::load(std::string filename){

   // this->texture->loadFromFile("resources/" + filename);

    std::ifstream openMap("resources/" + filename);

    std::getline(openMap,this->tileset);

    this->tile_width = 64; // there are no methods of converting string to integer in 32 bitMinGW, so let's just fix it to 64 bits.
    this->tile_length = 64;
    this->width = 20;
    this->length = 12;


    this->tile->loadFromFile("resources/tiles.png");

    this->data = new int[this->width * this->length];

    for(int y = 0;y < this->length;y++){
        for(int x =0;x < this->width;x++){
            char temp;
            openMap >> this->data[x + y * this->width] >> temp;
          //  std::cout << this->data[x+y*this->width];
          //  manage.add("stone",stone);
        }
    }

    openMap.close();

    sf::Image tile1,tile2,tile3,tile4,tile5;

    tile1.create(64,64);
    tile2.create(64,64);
    tile3.create(64,64);
    tile4.create(64,64);
    tile5.create(64,64);

    tile1.copy(*this->tile,0,0,sf::IntRect(0,0,this->tile_width,tile_width)); // stone
    tile2.copy(*this->tile,0,0,sf::IntRect(64,0,this->tile_width,tile_width)); // dark stone
    tile3.copy(*this->tile,0,0,sf::IntRect(0,64,this->tile_width,tile_width));
    tile4.copy(*this->tile,0,0,sf::IntRect(64,64,this->tile_width,tile_width));
    tile5.copy(*this->tile,0,0,sf::IntRect(128,0,this->tile_width,tile_width));



    for(int y = 0;y<this->length;y++){ //runs through all of the data[] and assigns each to a texture.
        for(int x =0;x < this->width;x++){

            switch(this->data[x+y*this->width]){

            case 1:

              /*  this->texture->loadFromImage(tile1);
                this->tiles->setTexture(*this->texture);
                this->tiles->setPosition(x*64,y*64);
                manage.add("tile2",tiles);*/


                this->texture->loadFromImage(tile1);


                break;

            case 2:

               /* this->texture->loadFromImage(tile2);
                this->tiles->setTexture(*this->texture);
                this->tiles->setPosition(x*64,y*64);
                manage.add("tile2",tiles); */



                this->texture->update(tile2,x*64,y*64);

                break;

            case 3:

                /*this->texture->loadFromImage(tile3);
                this->tiles->setTexture(*this->texture);
                this->tiles->setPosition(x*64,y*64);
                manage.add("tile3",tiles); */


                this->texture->update(tile3,x*64,y*64);


                break;

            case 4:

                /*this->texture->loadFromImage(tile4);
                this->tiles->setTexture(*this->texture);
                this->tiles->setPosition(x*64,y*64);
                manage.add("tile4",tiles);*/


                this->texture->update(tile4,x*64,y*64);


                break;

            case 5:

                /*this->texture->loadFromImage(tile5);
                this->tiles->setTexture(*this->texture);
                this->tiles->setPosition(x*64,y*64);
                manage.add("tile5",tiles);*/


                this->texture->update(tile5,x*64,y*64);

                break;
            default:

                break;


            }
        }
    }



    this->setTexture(*this->texture);

}



 

the reason I use copy is that the "tiles.png" is the tileset, and each tile is supposed to represent the different parts of the tile.

Surely, if the problem is that the file is loaded over and over, it wouldn't happen in this case where the map is rendered only once?
Title: Re: texture.update() problem
Post by: Hapax on May 27, 2015, 09:40:57 pm
Can't work if you've found the solution and I'm not sure which problem you're having but just to make sure you're clear, the x and y values that you pass to texture.update() is the position in the texture that the image goes and the texture in the minimal example has a texture of size zero by zero when you copy into it so it's copying it out of bounds.