1
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 24, 2014, 09:01:31 pm »
J'ai écrit un code qui corrige l'exemple que j'ai donné. Personnellement il me reste toujours un petit soucis pour déterminer quand une texture vient d'un RenderTexture dans mon code qui est un peu plus compliqué que ça. Pour moi il manque un accesseur vers pixelFlipped qui me permettrait de savoir, mais comme il s'agit d'un problème très particulier et très lié a l'implémentation, je pense pas que cet accesseur soit une vraie bonne idée. Une autre idée pour déterminer quand une texture provient d'une RenderTexture?
Voila le code corrigé. L'idée c'est d'afficher à l'envers les textures issues d'un RenderTexture en donnant aux vertex des coordonnées de textures inversées. On voit que comme le shader court circuite le mécanisme des Textures, les coordonnées de textures sont normalisées (entre 0.0 et 1.0) et non en pixels comme l'indique la doc.
Voila le code corrigé. L'idée c'est d'afficher à l'envers les textures issues d'un RenderTexture en donnant aux vertex des coordonnées de textures inversées. On voit que comme le shader court circuite le mécanisme des Textures, les coordonnées de textures sont normalisées (entre 0.0 et 1.0) et non en pixels comme l'indique la doc.
#include <iostream>
#include "SFML/Graphics.hpp"
using namespace std;
int main()
{
sf::Texture tex;
tex.loadFromFile("lena.png");
int s_x = tex.getSize().x;
int s_y = tex.getSize().y;
sf::Shader shader;
shader.loadFromFile("shader.frag",sf::Shader::Fragment);
shader.setParameter("texture", tex);
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);
//1er render: on dessine la texture à l'endroit
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);
sf::RenderTexture renderTexture;
renderTexture.create(s_x,s_y);
renderTexture.clear();
renderTexture.draw(rect, &shader);
renderTexture.display();//L'image se retourne mais pixelFlipped est bien à true (fonctionnement normal de display)
const sf::Texture& tex2 = renderTexture.getTexture();
shader.setParameter("texture", tex2);
//2eme render: on dessine la texture à l'envers (1.0 <-> 0.0 en y)
rect[0].texCoords = sf::Vector2f(0.0,1.0);
rect[1].texCoords = sf::Vector2f(0.0,0.0);
rect[2].texCoords = sf::Vector2f(1.0,0.0);
rect[3].texCoords = sf::Vector2f(1.0,1.0);
sf::RenderTexture renderTexture2;
renderTexture2.create(s_x,s_y);
renderTexture2.clear();
renderTexture2.draw(rect, &shader);
renderTexture2.display();//L'image se retourne 2 fois : une fois à cause des vertex avec les coordonnées de textures à l'envers
//+ une fois à cause du rendu openGl (la texture en entrée du shader n'est pas redressée)
//L'image est bien toujours à l'envers avec pixelFlipped à true
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;
}
#include "SFML/Graphics.hpp"
using namespace std;
int main()
{
sf::Texture tex;
tex.loadFromFile("lena.png");
int s_x = tex.getSize().x;
int s_y = tex.getSize().y;
sf::Shader shader;
shader.loadFromFile("shader.frag",sf::Shader::Fragment);
shader.setParameter("texture", tex);
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);
//1er render: on dessine la texture à l'endroit
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);
sf::RenderTexture renderTexture;
renderTexture.create(s_x,s_y);
renderTexture.clear();
renderTexture.draw(rect, &shader);
renderTexture.display();//L'image se retourne mais pixelFlipped est bien à true (fonctionnement normal de display)
const sf::Texture& tex2 = renderTexture.getTexture();
shader.setParameter("texture", tex2);
//2eme render: on dessine la texture à l'envers (1.0 <-> 0.0 en y)
rect[0].texCoords = sf::Vector2f(0.0,1.0);
rect[1].texCoords = sf::Vector2f(0.0,0.0);
rect[2].texCoords = sf::Vector2f(1.0,0.0);
rect[3].texCoords = sf::Vector2f(1.0,1.0);
sf::RenderTexture renderTexture2;
renderTexture2.create(s_x,s_y);
renderTexture2.clear();
renderTexture2.draw(rect, &shader);
renderTexture2.display();//L'image se retourne 2 fois : une fois à cause des vertex avec les coordonnées de textures à l'envers
//+ une fois à cause du rendu openGl (la texture en entrée du shader n'est pas redressée)
//L'image est bien toujours à l'envers avec pixelFlipped à true
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;
}