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

Author Topic: Convert Vertices into Image  (Read 2805 times)

0 Members and 1 Guest are viewing this topic.

Mlikaon

  • Newbie
  • *
  • Posts: 17
    • View Profile
Convert Vertices into Image
« on: December 09, 2013, 11:02:34 am »
Hello everybody,

I'd like to use the TileMaping Tutorial from SFML, and save the result in an Image class.
But I don't find any way to convert this, can anyone help me a bit please?

Here is the code of the tutorial :


class TileMap : public sf::Drawable, public sf::Transformable
{
public:

    bool load(const std::string& tileset, sf::Vector2u tileSize, const int* tiles, unsigned int width, unsigned int height)
    {
        // load the tileset texture
        if (!m_tileset.loadFromFile(tileset))
            return false;

        // resize the vertex array to fit the level size
        m_vertices.setPrimitiveType(sf::Quads);
        m_vertices.resize(width * height * 4);

        // populate the vertex array, with one quad per tile
        for (unsigned int i = 0; i < width; ++i)
            for (unsigned int j = 0; j < height; ++j)
            {
                // get the current tile number
                int tileNumber = tiles[i + j * width];

                // find its position in the tileset texture
                int tu = tileNumber % (m_tileset.getSize().x / tileSize.x);
                int tv = tileNumber / (m_tileset.getSize().x / tileSize.x);

                // get a pointer to the current tile's quad
                sf::Vertex* quad = &m_vertices[(i + j * width) * 4];

                // define its 4 corners
                quad[0].position = sf::Vector2f(i * tileSize.x, j * tileSize.y);
                quad[1].position = sf::Vector2f((i + 1) * tileSize.x, j * tileSize.y);
                quad[2].position = sf::Vector2f((i + 1) * tileSize.x, (j + 1) * tileSize.y);
                quad[3].position = sf::Vector2f(i * tileSize.x, (j + 1) * tileSize.y);

                // define its 4 texture coordinates
                quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.x, tv * tileSize.y);
                quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.x, (tv + 1) * tileSize.y);
                quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv + 1) * tileSize.y);
            }

        return true;
    }

private:

    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
    {
        // apply the transform
        states.transform *= getTransform();

        // apply the tileset texture
        states.texture = &m_tileset;

        // draw the vertex array
        target.draw(m_vertices, states);
    }

    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
};

I need the Image class to call all the Image functions (GetPixel, SaveToFile etc.).

Thank you!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
Re: Convert Vertices into Image
« Reply #1 on: December 09, 2013, 11:11:38 am »
You can save any scene quite easily by drawing the scene to a render texture, then extract the texture, convert it to an sf::Image by calling copyToImage and then save to the disk.
Keep in mind that this can introduce a small lag, due to the amount of data that needs to be transferred from the GPU memory to the CPU memory to the disk. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Mlikaon

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Convert Vertices into Image
« Reply #2 on: December 09, 2013, 11:24:55 am »
That sounds really good =)
Thank you mate, you made my day =D

Mlikaon

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Convert Vertices into Image
« Reply #3 on: December 09, 2013, 11:40:16 am »
TileMap map;

//Initialisation of the tilemap
//...

RenderTexture rt;
rt.create(6000,6000);
rt.draw(map);
Image background_image;
background_image = rt.getTexture().copyToImage();

Texture bg_texture;
bg_texture.loadFromImage(background_image);
 


It works, but it's very laggy, and my tiles are inverted vertically (and maybe horizontally, i'm not sure)!
« Last Edit: December 09, 2013, 11:57:07 am by Mlikaon »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
Re: Convert Vertices into Image
« Reply #4 on: December 09, 2013, 12:13:01 pm »
As I said the transfer from GPU to CPU memory is a very expensive operation, especially for a 6000x6000 texture...

Read the docs again, the render texture is like a window, you need call clear(), draw(), display().
I really wonder why so many people just don't call display... ::)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Mlikaon

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Convert Vertices into Image
« Reply #5 on: December 09, 2013, 01:11:56 pm »
Shouldn't my lag disappear after using the Image class?
I mean, the operation from GPU to CPU is slow, but then, i have an image which i can use without lag, am i wrong?

I still wonder why is my texture inverted :/


Quote
I really wonder why so many people just don't call display...
->I just wanted to create a random tilemap and the collision tilemap associated.
For my collision tilemap, i need to call the GetPixel function, which is relative to the Image class.
That's why i'm trying to convert VerticesArray into an Image.

Anyway, thank you for helping, it's really kind and i appreciate.


Edit : The texture is no more rotated, after calling the Display() function once.
« Last Edit: December 09, 2013, 01:36:33 pm by Mlikaon »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10998
    • View Profile
    • development blog
    • Email
Re: Convert Vertices into Image
« Reply #6 on: December 09, 2013, 01:37:44 pm »
Shouldn't my lag disappear after using the Image class?
I mean, the operation from GPU to CPU is slow, but then, i have an image which i can use without lag, am i wrong?
If you only do image manipulations and don't copy it back and forth from one source to the other (GPU memory, CPU memory, disk) then you shouldn't notice anything.
If you push the changes back to the GPU, it will have to go through the same slow process as when you retrieved it.

Don't forget that writing to disk is also not the fastest process and a 6000x6000 image takes up quite a few megabytes.

I still wonder why is my texture inverted :/
Maybe if I set it in bold: You need to call rt.display() for every scene you draw to the render texture - read the documentation and tutorial!
Got it? ;D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Mlikaon

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Convert Vertices into Image
« Reply #7 on: December 09, 2013, 01:59:59 pm »
Yeah, i noticed a bit too late =)

Thank you for your help!