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

Author Topic: Slicing/extracting tiles from a grid of tiles  (Read 6996 times)

0 Members and 1 Guest are viewing this topic.

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Slicing/extracting tiles from a grid of tiles
« on: August 11, 2012, 11:22:40 am »
Hey everyone,

I'm trying to copy a 25x25 pixel area from a master textures file and when I try and run my game this error appears in the output:


This is the code that I'm using:
  sf::Image tiles;
  tiles.loadFromFile("Resources/tiles.tga");

  sf::Image img;
  img.copy(tiles, 0, 0, sf::IntRect(0, 0, 25, 25)); // extracts the first 25x25 tile from "tiles"
 
  sf::Texture tex;
  tex.loadFromImage(img); // loads the texture from "img" which is just the first 25x25 tile

Is there any reason that I'm not seeing that is causing this?

Thanks,
Andrew

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #1 on: August 11, 2012, 11:56:53 am »
http://sfml-dev.org/features.php
Quote
Can load standard font file formats : ttf, cff, pcf, fnt, bdf, pfr, sfnt, type 1, type 42

Have you tried loading a *.png file?
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #2 on: August 11, 2012, 12:05:20 pm »
Quote
The supported image formats are bmp, png, tga, jpg, gif, psd, hdr and pic. Some format options are not supported, like progressive jpeg. If this function fails, the image is left unchanged.

http://www.sfml-dev.org/documentation/2.0/classsf_1_1Image.php#a9e4f2aa8e36d0cabde5ed5a4ef80290b

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #3 on: August 11, 2012, 12:36:58 pm »
Problem solved for now - I've cut out the second img and just loaded the texture using sf::Texture.loadFromImage(src, area);

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #4 on: August 11, 2012, 03:04:22 pm »
You'll be having same pixels in memory few times if you do what you did in first post, sprites have subRects you can set to make them use just part of texture.
Back to C++ gamedev with SFML in May 2023

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #5 on: August 11, 2012, 03:11:42 pm »
You'll be having same pixels in memory few times if you do what you did in first post, sprites have subRects you can set to make them use just part of texture.

See: http://en.sfml-dev.org/forums/index.php?topic=8844.msg59455#msg59455

Is that what you meant?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #6 on: August 11, 2012, 05:05:57 pm »
Before copying "tiles" to "img", "img" must be created (with a valid size). You can't copy an image to an empty one, it doesn't expand automatically.
Laurent Gomila - SFML developer

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #7 on: August 11, 2012, 05:20:27 pm »
Before copying "tiles" to "img", "img" must be created (with a valid size). You can't copy an image to an empty one, it doesn't expand automatically.

Thanks Laurent.

I have changed the way I load the textures, removing the need for the new sf::Image.
void loadTextures(std::vector<sf::Texture>& texture_list) {
  sf::Image master;
  master.loadFromFile("Resources/tiles.tga");

  for (int x = 0; x < ps::ktexture_grid_size; x++) {
    for (int y = 0; y < ps::ktexture_grid_size; y++) {
      sf::Texture temp_texture;
      temp_texture.loadFromImage(master, sf::IntRect(x * ps::ktexture_size, y * ps::ktexture_size, ps::ktexture_size, ps::ktexture_size));
      texture_list.push_back(temp_texture);
    }; // for y
  }; // for x
} // void loadtextures

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #8 on: August 11, 2012, 05:24:18 pm »
Instead of:
sf::Image tiles;
  tiles.loadFromFile("Resources/tiles.tga");
  sf::Image img;
  img.create(25,25);
  img.copy(tiles, 0, 0, sf::IntRect(0, 0, 25, 25));
  sf::Texture tex;
  tex.loadFromImage(img);
  sf::Sprite spr(tex);
You can do:
  sf::Texture tiles;
  tiles.loadFromFile("Resources/tiles.tga");
  sf::Sprite spr(tiles);
  spr.setTextureRect(sf::IntRect(0,0,25,25));

Why do you 'extract' tiles from tilesheet anyway?
Back to C++ gamedev with SFML in May 2023

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #9 on: August 11, 2012, 05:27:31 pm »
Instead of:
sf::Image tiles;
  tiles.loadFromFile("Resources/tiles.tga");
  sf::Image img;
  img.create(25,25);
  img.copy(tiles, 0, 0, sf::IntRect(0, 0, 25, 25));
  sf::Texture tex;
  tex.loadFromImage(img);
  sf::Sprite spr(tex);
You can do:
  sf::Texture tiles;
  tiles.loadFromFile("Resources/tiles.tga");
  sf::Sprite spr(tiles);
  spr.setTextureRect(sf::IntRect(0,0,25,25));

Why do you 'extract' tiles from tilesheet anyway?

That's the method that I'm using now (see above post).

I'm want to keep the tiles in a single image so it's easier to update/change any of the tiles while developing and post-release. Plus it keeps my resources file clean.

Edit: Oh no, I just re-read what you posted. Would that method not keep the entire tiles.tga file loaded for every texture though?
« Last Edit: August 11, 2012, 05:29:18 pm by AndrewB »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #10 on: August 11, 2012, 05:30:25 pm »
That's great and that's why tilesheets are good but why do you 'extract' them into single texture each at runtime instead of using sf::VertexArray or sf::Sprite::setTextureRect ?
Load your texture once and then make every sprite/your one huge vertex array use this texture with proper rectangle/coords.
« Last Edit: August 11, 2012, 05:32:47 pm by FRex »
Back to C++ gamedev with SFML in May 2023

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #11 on: August 11, 2012, 05:42:14 pm »
That's great and that's why tilesheets are good but why do you 'extract' them into single texture each at runtime instead of using sf::VertexArray or sf::Sprite::setTextureRect ?
Load your texture once and then make every sprite/your one huge vertex array use this texture with proper rectangle/coords.

void loadTextures(std::vector<sf::Texture>& texture_list) {
  sf::Image master;
  master.loadFromFile("Resources/tiles.tga");

  for (int x = 0; x < ps::ktexture_grid_size; x++) {
    for (int y = 0; y < ps::ktexture_grid_size; y++) {
      sf::Texture temp_texture;
      temp_texture.loadFromImage(master, sf::IntRect(x * ps::ktexture_size, y * ps::ktexture_size, ps::ktexture_size, ps::ktexture_size));
      texture_list.push_back(temp_texture);
    }; // for y
  }; // for x
} // void loadtextures

The tiles.tga file is loaded into memory, each texture is then created and stored on the gpu and then the image storing tiles.tga is freed.

From the definition of setTextureRect on the sfml documentation, EVERY texture would have to store the WHOLE tiles.tga image on the GPU (using 225 times more gpu memory than loading the textures individually). setTextureRect just modifies which part of the texture that will be drawn, it still keeps the whole texture in memory.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #12 on: August 11, 2012, 05:47:31 pm »
What? :o
Where is that stated?
Back to C++ gamedev with SFML in May 2023

AndrewB

  • Newbie
  • *
  • Posts: 33
    • View Profile
Re: Slicing/extracting tiles from a grid of tiles
« Reply #13 on: August 11, 2012, 05:52:35 pm »
What? :o
Where is that stated?

http://www.sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php#a3fefec419a4e6a90c0fd54c793d82ec2
Quote
Set the sub-rectangle of the texture that the sprite will display.

The texture rect is useful when you don't want to display the whole texture, but rather a part of it. By default, the texture rect covers the entire texture.

That wording suggests that it's only changing what is going to be displayed.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Slicing/extracting tiles from a grid of tiles
« Reply #14 on: August 11, 2012, 05:56:58 pm »
You can have ONE and only ONE sf::Texture and assign it to each of 225 sf::Sprite s and then set each Sprite's rectangle.
Back to C++ gamedev with SFML in May 2023