SFML renderTexture: flip output

I use SFML to render effects using shaders. I use sf :: RenderTexture objects to render my effect, and then use RenderWindow to render it.

When I endure 2 effects using the output of the first as the input of the second, the displayed image is upside down.

For example, the code below displays the input image up, and I don't understand why. I am using the shader file specified in the SFML documentation here (which I also copied at the end of the question).

If you replace l.33 with l.34 (which is commented) or l.42 with l.43, the result will be normal. Copying the output texture seems to solve the problem.

Why does copying the renderTexture output texture solve the problem? Also, I would like to avoid copying textures, is there any other solution?

main.cpp

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

using namespace std;

int main()
{
    //Loading image
    sf::Texture tex;
    tex.loadFromFile("lena.png");
    int s_x = tex.getSize().x;
    int s_y = tex.getSize().y;

    //loading shader;
    sf::Shader shader;
    shader.loadFromFile("shader.frag",sf::Shader::Fragment);

    //Creating drawable object (rectangle) to be drawn by renderTextures
    sf::VertexArray rect(sf::Quads,4);
    rect[0].position = sf::Vector2f(0,0);
    rect[1].position = sf::Vector2f(0,s_y);
    rect[2].position = sf::Vector2f(s_x,s_y);
    rect[3].position = sf::Vector2f(s_x,0);
    rect[0].texCoords = sf::Vector2f(0.0,0.0);
    rect[1].texCoords = sf::Vector2f(0.0,1.0);
    rect[2].texCoords = sf::Vector2f(1.0,1.0);
    rect[3].texCoords = sf::Vector2f(1.0,0.0);

    //Render with the loaded image
    shader.setParameter("texture", tex);
    sf::RenderTexture renderTexture;
    renderTexture.create(s_x,s_y);
    renderTexture.clear();
    renderTexture.draw(rect, &shader);
    renderTexture.display();

    //Rendering with the output from the first render
    const sf::Texture& tex2 = renderTexture.getTexture();
    //switching those lines displays a correct image
    //sf::Texture tex2 = renderTexture.getTexture();
    shader.setParameter("texture", tex2);
    sf::RenderTexture renderTexture2;
    renderTexture2.create(s_x,s_y);
    renderTexture2.clear();
    renderTexture2.draw(rect, &shader);
    renderTexture2.display();

    //displaying
    const sf::Texture& tex3 = renderTexture2.getTexture();
    //switching those lines displays a correct image
    //sf::Texture tex3 = renderTexture2.getTexture();
    sf::Sprite sprite(tex3);
    sf::RenderWindow window(sf::VideoMode(s_x,s_y), "");
    window.clear();
    window.draw(sprite);
    window.display();

    char c;
    std::cin>>c;

    return 0;
}

shader.frag

uniform sampler2D texture;

void main()
{
    // lookup the pixel in the texture
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);

    // multiply it by the color
    gl_FragColor = gl_Color * pixel;
}
+4
source share
1 answer

I had the same problem when using shaders some time ago: http://en.sfml-dev.org/forums/index.php?topic=11178.msg77236

Texture coordinates are inverted because the texture created by sf :: RenderTexture is inverted (due to FBO).

The behavior is consistent, so you can get around it and consider the inverse coordinates when working with RenderTextures.

0
source

Source: https://habr.com/ru/post/1531917/


All Articles