Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - arnodu

Pages: [1]
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.
#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;
}
 

2
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 24, 2014, 08:28:14 pm »
Je comprends que ça pose problème, surtout avec les différence de matériel qu'il peut y avoir entre les machines qui utilisent SFML.
Copier la texture est une solution à mon problème, vu que ça remet la texture à l'endroit durant la copie. Mais c'est vrai que ce n'est pas du tout une solution optimale et qu'il vaut mieux travailler en remettant la texture à l'endroit "à la main".
Je posterais la solution que j'ai retenu pour éviter ce problème, au cas ou quelqu'un aurait le même.

3
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 24, 2014, 06:32:09 pm »
Mon idée c’était plutôt d'utiliser le code qui est à l’intérieur de RenderTexture pour copier la texture, mais dans l'idée c'est ça.
Enfin je sais pas ce qu'il y a exactement dans le Sprite, mais je vais supposer que ça ne copie pas la texture.

Mon argument c'est juste que si RenderTexture peut copier une texture sans passer par la mémoire centrale, le constructeur de copie de texture doit aussi pouvoir le faire. C'est aussi ce que fait mon premier code: il copie 2 fois les textures sans passer par la mémoire centrale (mais il se trouve que ça merde un peu alors...).

J'ai pas vraiment le temps en ce moment, mais je peux mieux étudier la question et proposer une pull request quand j'aurais le temps.

4
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 24, 2014, 12:11:04 pm »
Utiliser draw sur un sprite avec une texture ne revient pas a copier la texture vers la texture interne au rendertexture sans passer par la mémoire centrale?

Il y a un moyen de tester que FBO est bien disponible? Histoire que je puisse donner un petit message de Warning a mon utilisateur si ce n'est pas le cas?

5
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 23, 2014, 10:02:57 pm »
Vu que je fais draw avec des vertex, je peux juste changer les coordonnées des textures sur les vertex pour retourner l'image. Le vrai problème est de savoir quand il faut les retourner.

D'ailleurs si c'est possible de retourner une image comme ça, la copie de Textures devrait pas être plus couteuse et donc j'imagine que le constructeur par recopie de Texture doit pas être vraiment optimal. Enfin je dis j'imagine, mais j'ai été regarder le code et je suis sûr qu'il y a pas besoin de faire passer la texture par la mémoire centrale par le biais d'une Image. Enfin je dis ça, je pense que tu doit très bien être au courant de tout ça  ;)

Pour en finir avec ce problème: est ce que tu penses que c'est safe de ne pas appeler display pour éviter que ce flag soit mis à vrai? (tout aurait été tellement plus simple si il y avait une méthode flipTexture() )
Je pense surtout aux problèmes que ça pourrait causer quand l'implémentation "FBO" n'est pas disponible. Déjà est ce que c'est possible que ça ne soit pas dispo avec une version 2.1 de SFML? C'est lié au matériel?

6
Graphique / Re : RenderTexture, shaders et image retournée
« le: Mars 23, 2014, 09:13:00 pm »
Mon cas est plus compliqué: les shaders qui sont utilisés pour le rendu sont quelconques et peuvent avoir plusieurs textures en entrée.

Retourner moi même la texture ne me semble pas non plus possible: il faudrait que je la retourne seulement si son état interne pixelFlipped est true, et je n'ait pas accès a cet attribut... Retourner l'image quand pixelFlipped=true c'est ce que fait le constructeur par recopie si je ne me trompe pas. Il n'y aurait donc pas d'autre solution que de copier la texture tout entière?

Dans tous les cas, ce petit problème mériterait d'être documenté quelque part

7
Graphique / RenderTexture, shaders et image retournée
« le: Mars 23, 2014, 07:15:28 pm »
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;
}
 

Pages: [1]
anything