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

Author Topic: Why shapes does strech texture (and not sprite) ?  (Read 7987 times)

0 Members and 2 Guests are viewing this topic.

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Why shapes does strech texture (and not sprite) ?
« on: April 28, 2013, 02:54:23 pm »
Hi there,

I've a problem : I need a giant circle to have a texture that is repeated inside of it. Let say the circle radius is 1024px, my texture is 512x512px. The problem is the texture does not repeat itself (with texture.setRepeated(true)) and is stretched to fit the circle size (so the texture is "zoomed").
I do not have this problem with a sprite of 1024x1024, the texture is well repeated.
I do not understand because sf::Sprite and sf::Shape both inherit from sf::Transformable

Minimal code :

int main()
{
    sf::RenderWindow window(sf::VideoMode(2048, 1024), "Ant");


    sf::Texture ground; // ground is 512x512
    ground.setSmooth(true);
    ground.setRepeated(true);
    ground.loadFromFile("ground.png");

    float radius = 1024;
    sf::CircleShape planet;
    planet.setOrigin(radius, radius);
    planet.setTexture(&ground);
    planet.setRadius(radius);
    planet.setPointCount(radius*180);
    planet.setPosition(1024, 512);
   
    // It works with a sprite
    /*sf::Sprite spr;
    spr.setTextureRect(sf::IntRect(0,0,2048,2048));
    spr.setTexture(ground);*/


    // on fait tourner le programme jusqu'à ce que la fenêtre soit fermée
    while (window.isOpen())
    {
        // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
        sf::Event event;
        while (window.pollEvent(event))
        {
            // évènement "fermeture demandée" : on ferme la fenêtre
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();

        window.draw(planet);
        //window.draw(spr);

        window.display();
    }

    return 0;
}

Any ideas, remarks, insults ?

Edit and Note : I've tried many different things such as add a planet.setTextureRect(), but nothing makes it

[attachment deleted by admin]
« Last Edit: April 28, 2013, 02:56:55 pm by Lo-X »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #1 on: April 28, 2013, 04:01:00 pm »
You're right, Sprite and Shape behave the same way, so using setTextureRect with a rect bigger than the texture should do the trick.
Laurent Gomila - SFML developer

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #2 on: April 28, 2013, 04:08:40 pm »
You're right, Sprite and Shape behave the same way, so using setTextureRect with a rect bigger than the texture should do the trick.

Yes but it does not :/

    float radius = 1024;
    sf::CircleShape planet;
    planet.setTextureRect(sf::IntRect(0,0,2048,2048));
    planet.setOrigin(radius, radius);
    planet.setTexture(&ground);
    planet.setRadius(radius);
    planet.setPointCount(radius*180);
    planet.setPosition(1024, 512);

The texture is zoomed in with any sf::Shape. Even if I set the Shape size before or after the TextureRect size.

I'll look at the sfml implementation, perhaps I miss something
« Last Edit: April 28, 2013, 04:16:55 pm by Lo-X »

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #3 on: April 28, 2013, 04:40:11 pm »
Ok, I think I found something in sf::Shape :

void Shape::updateTexCoords()
{
    for (unsigned int i = 0; i < m_vertices.getVertexCount(); ++i)
    {
        float xratio = (m_vertices[i].position.x - m_insideBounds.left) / m_insideBounds.width;
        float yratio = (m_vertices[i].position.y - m_insideBounds.top) / m_insideBounds.height;
        m_vertices[i].texCoords.x = m_textureRect.left + m_textureRect.width * xratio;
        m_vertices[i].texCoords.y = m_textureRect.top + m_textureRect.height * yratio;
    }
}

I've to admit I'm not extremely sure of what I'll say just below :

Doesnt that code strectch the texture by making it cover the full shape instead of making it cover what it can cover and letting openGL do the repeat thing ?

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #4 on: April 28, 2013, 05:43:20 pm »
I fixed it by modifying the sf::Shape::updateTextCoord() method.

I put the ratio relative to the texture dimensions (instead of the vextexArray dimension) :

void Shape::updateTexCoords()
{
    for (unsigned int i = 0; i < m_vertices.getVertexCount(); ++i)
    {
        float xratio = (m_vertices[i].position.x - m_insideBounds.left) / m_textureRect.width;
        float yratio = (m_vertices[i].position.y - m_insideBounds.top) / m_textureRect.height;
        m_vertices[i].texCoords.x = m_textureRect.left + m_textureRect.width * xratio;
        m_vertices[i].texCoords.y = m_textureRect.top + m_textureRect.height * yratio;
    }
}


The texture is now well repeated inside the sf::Shape.

I tested the result with sf::CircleShape and sf::RectangleShape. Rotation still works.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #5 on: April 28, 2013, 06:40:32 pm »
Quote
Doesnt that code strectch the texture by making it cover the full shape instead of making it cover what it can cover and letting openGL do the repeat thing ?
Hum no, it stretches the textureRect to cover the whole shape. Replace variables with real numbers, you'll see that it gives the expected result: textureRect.left is on the left side of the shape, textureRect.right is on the right side.
I have no idea why it doesn't work, and why your code works while it seems incorrect. I have to do some tests.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #6 on: April 28, 2013, 07:15:42 pm »
It works perfectly for me without your modification.

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(512, 512), "Test");

    sf::Image image;
    image.create(128, 128, sf::Color::Red);
    for (unsigned int x = 0; x < 64; ++x)
        for (unsigned int y = 0; y < 64; ++y)
        {
            image.setPixel(x, y, sf::Color::Green);
            image.setPixel(x + 64, y + 64, sf::Color::Green);
        }

    sf::Texture texture;
    texture.setRepeated(true);
    texture.loadFromImage(image);

    sf::CircleShape circle;
    circle.setTexture(&texture);
    circle.setTextureRect(sf::IntRect(0, 0, 512, 512));
    circle.setRadius(256);

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

        window.clear();
        window.draw(circle);
        window.display();
    }

    return 0;
}


[attachment deleted by admin]
Laurent Gomila - SFML developer

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #7 on: April 28, 2013, 07:47:42 pm »
Ok, I found what was wrong :

I applied setTextureRect before applying the texture itself, by switching order it also solve the problem.

Thank you !

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #8 on: April 28, 2013, 08:55:48 pm »
It should work also with the initial order, because the second argument of setTexture, resetRect, is false by default.
Laurent Gomila - SFML developer

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #9 on: April 29, 2013, 06:46:09 pm »
It should work also with the initial order, because the second argument of setTexture, resetRect, is false by default.

It does not, even with your example (I just inverted the two lines)

OS: Linux kernel 3.8 Ubuntu Gnome 3.6
GPU: NVidia GEFORCE GT 555M and Intel Sandybridge Mobile

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #10 on: April 29, 2013, 06:56:57 pm »
Ok, I'll test it and see if I can reproduce the problem.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #11 on: May 01, 2013, 09:41:51 am »
You're right, there's something wrong when the rextureRect is set before the texture. I'll investigate this.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why shapes does strech texture (and not sprite) ?
« Reply #12 on: May 01, 2013, 09:49:39 am »
It's fixed :)
Laurent Gomila - SFML developer

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
Re: Why shapes does strech texture (and not sprite) ?
« Reply #13 on: May 01, 2013, 11:20:58 am »
It's fixed :)

That was fast ! Thanks =)