Bonjour a tous
J'ai un petit problème avec les Shaders et RenderTexture qui produisent une image retournée. J'ai cherché, et je suis tombé sur des oublis de display(), mais c'est pas mon cas.
Mon problème à moi, il se produit quand on utilise la texture retournée par RenderTexture::getTexture() comme paramètre d'un shader.
Chose étrange, copier la texture avec le constructeur par recopie (ce qui n'est pas vraiment optimal) semble résoudre le problème.
Mon intuition c'est que Shader::setParameter() ne s'en sort pas bien avec les Textures dont le flag pixelFlipped est a true (ce qui arrive seulement dans les textures contenues dans les RenderTexture si je ne m'abuse).
Une idée de comment remédier a ce problème proprement? Pour l'instant dans mon vrai code, j'ai affiché mon image à l'envers et je n'ai pas appelé display(). Ça semble résoudre le problème mais je n'aime pas trop le caractère "undefined behaviour" de ce hack... En plus j'imagine que le glFlush qui est fait à l'update doit avoir son importance.
Voila un petit code qui montre mon problème:
main.cpp
#include <iostream>
#include "SFML/Graphics.hpp"
using namespace std;
int main()
{
//Chargement de l'image
sf::Texture tex;
tex.loadFromFile("lena.png");
int s_x = tex.getSize().x;
int s_y = tex.getSize().y;
//Chargement du shader
sf::Shader shader;
shader.loadFromFile("shader.frag",sf::Shader::Fragment);
//Création d'un rectangle pour dessiner
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);
//Rendu avec la texture chargée en paramètre du shader
shader.setParameter("texture", tex);
sf::RenderTexture renderTexture;
renderTexture.create(s_x,s_y);
renderTexture.clear();
renderTexture.draw(rect, &shader);
renderTexture.display();
//Rendu avec la texture de RenderTexture en paramètre du shader
const sf::Texture& tex2 = renderTexture.getTexture();
//sf::Texture tex2 = renderTexture.getTexture(); //--->En mettant ca à la place ca fonctionne
shader.setParameter("texture", tex2);
sf::RenderTexture renderTexture2;
renderTexture2.create(s_x,s_y);
renderTexture2.clear();
renderTexture2.draw(rect, &shader);
renderTexture2.display();
//affichage
const 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;
}
vertex.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;
}