Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Blending pas fais avec les textures des FBO.  (Lu 2584 fois)

0 Membres et 1 Invité sur ce sujet

nagimar

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Blending pas fais avec les textures des FBO.
« le: Mars 11, 2020, 04:44:51 pm »
Salut, j'ai fais un code minimal pour reproduire le bug, j'essaie d'afficher un rectangle rouge sur la texture d'un FBO et un rectangle vert et un rectangle bleu sur une autre texture de FBO, mais, le blending alpha ne e faire pas et le rectangle rouge n'est pas affiché et pas de blending non plus à l'intersection du rectangle vert et bleu.

Voici le code :

int main(int argc, char* argv[])
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "test blending", sf::Style::Default,
    sf::ContextSettings(0, 0, 0, 3, 0));
    sf::RenderTexture rt1, rt2;
    rt1.create(800, 600, sf::ContextSettings(0, 0, 0, 3, 0));
    rt2.create(800, 600, sf::ContextSettings(0, 0, 0, 3, 0));
    sf::RectangleShape tile1 (sf::Vector2f(100, 50));
    tile1.setFillColor(sf::Color(255, 0, 0, 50));
    sf::RectangleShape tile2 (sf::Vector2f(100, 50));
    tile2.setPosition(50, 25);
    tile2.setFillColor(sf::Color(0, 255, 0, 50));
    sf::RectangleShape tile3 (sf::Vector2f(100, 50));
    tile3.setPosition(-50, 25);
    tile3.setFillColor(sf::Color(0, 0, 255, 50));
    sf::Sprite trt1(rt1.getTexture());
    sf::Sprite trt2(rt2.getTexture());
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }
        window.clear();
        rt1.clear();
        rt2.clear();
        rt1.draw(tile1);
        rt1.display();
        rt2.draw(tile2);
        rt2.draw(tile3);
        rt2.display();
        window.draw(trt1);
        window.draw(trt2);
        window.display();
    }
    return 0;
}
 

Je suis sur windows 10 et ma carte graphique c'est une nvidia.
Lorsque j'essaie sur mon portable avec linux et une carte graphique amd ça marche.
Quelqu'un m'a dit qu'il fallait utiliser des autres paramètres pour le blending avec des FBO mais je ne sais pas lesquels.
« Modifié: Mars 11, 2020, 04:49:45 pm par nagimar »

nagimar

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Re: Blending pas fais avec les textures des FBO.
« Réponse #1 le: Avril 08, 2020, 10:19:49 pm »
Bon il semblerait que le problème vienne de la SFML, j'ai essayé d'utiliser opengl en dehors de la SFML pour dessiner presque la même chose avec deux FBO et là le blending alpha se fait bien.

int main(int argc, char* argv[])
{  
    sf::Window window(sf::VideoMode(800, 600), "test", sf::Style::Default, sf::ContextSettings(0, 0, 4, 3, 0));
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
      /* Problem: glewInit failed, something is seriously wrong. */
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err));

    }
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    float verticesFBO1[] = {-1.f, -1.f,
                        1.f, 0, 0, 0.5f,
                        -0.90f, -1.f,
                        1.f, 0, 0, 0.5f,
                        -0.90f, -0.90f,
                        1.f, 0, 0, 0.5f,
                        -1.f, -0.90f,
                        1.f, 0, 0, 0.5f};
    float verticesFBO2[] = {-0.95f, -0.95f,
                        0, 1.f, 0, 0.5f,
                        -0.85f, -0.95f,
                        0, 1.f, 0, 0.5f,
                        -0.85f, -0.85f,
                        0, 1.f, 0, 0.5f,
                        -0.95f, -0.85f,
                        0, 1.f, 0, 0.5f};
    float fullScreenQuad[] = {-1.f, -1.f,
                              1.f, 1.f, 1.f, 1.f,
                              0.f, 0.f,
                              -1.f, 1.f,
                              1.f, 1.f, 1.f, 1.f,
                              1.f, 0.f,
                              1.f, 1.f,
                              1.f, 1.f, 1.f, 1.f,
                              1.f, 1.f,
                              1.f, -1.f,
                              1.f, 1.f, 1.f, 1.f,
                              0.f, 1.f};

    GLuint textureFBO1;
    glGenTextures(1, &textureFBO1);
    glBindTexture(GL_TEXTURE_2D, textureFBO1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    GLuint textureFBO2;
    glCheck(glGenTextures(1, &textureFBO2));
    glBindTexture(GL_TEXTURE_2D, textureFBO2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    const char* data = reinterpret_cast<const char*>(fullScreenQuad);
    glVertexPointer(2, GL_FLOAT, 32, data + 0 );
    glColorPointer(4, GL_FLOAT, 32, data + 8);
    glTexCoordPointer(2, GL_FLOAT, 32, data + 24);

    sf::Context contextFBO1(sf::ContextSettings(0, 0, 4, 3, 0),800, 600);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    const char* data2 = reinterpret_cast<const char*>(verticesFBO1);
    glVertexPointer(2, GL_FLOAT, 24, data2 + 0 );
    glColorPointer(4, GL_FLOAT, 24, data2 + 8);
    GLuint framebuffer1;
    glGenFramebuffers(1, &framebuffer1);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFBO1, 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::cerr<<"failed to create frame buffer 1";
    }

    sf::Context contextFBO2(sf::ContextSettings(0, 0, 4, 3, 0),800, 600);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    const char* data3 = reinterpret_cast<const char*>(verticesFBO2);
    glVertexPointer(2, GL_FLOAT, 24, data3 + 0 );
    glColorPointer(4, GL_FLOAT, 24, data3 + 8);
    GLuint framebuffer2;
    glGenFramebuffers(1, &framebuffer2);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFBO2, 0);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        std::cerr<<"failed to create frame buffer 2";
    }
    fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }
        contextFBO1.setActive(true);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_QUADS, 0, 4);
        glFlush();
        contextFBO2.setActive(true);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_QUADS, 0, 4);
        glFlush();
        window.setActive(true);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D, textureFBO1);
        glDrawArrays(GL_QUADS, 0, 4);
        glBindTexture(GL_TEXTURE_2D, textureFBO2);
        glDrawArrays(GL_QUADS, 0, 4);
        window.display();
    }
    return 0;
}
 

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re: Blending pas fais avec les textures des FBO.
« Réponse #2 le: Avril 09, 2020, 04:33:39 am »
le blending alpha ne e faire pas et le rectangle rouge n'est pas affiché et pas de blending non plus à l'intersection du rectangle vert et bleu.
Alors premièrement, si tu as un rectangle bleu de 100 de largeur qui commence en -50, et un rectangle vert qui commence en 50, tu n'as PAS d'intersection entre le vert et le bleu donc il risque pas d'y avoir un quelconque blending entre eux s'ils se superposent pas.

Ensuite, quand tu clear une RenderTarget sans préciser de couleur ça utilise du noir opaque. Donc t'as rt1 et rt2, 2 textures toutes noires avec 1 rectangle rouge sur l'une et des rect verts et bleu sur l'autre, et quand tu draw rt2 par dessus rt1 bah forcément tu vois plus du tout rt1.
Utilise sf::Color::Transparent dans ton clear de rt et tu devrais apercevoir ton rectangle rouge.

nagimar

  • Newbie
  • *
  • Messages: 36
    • Voir le profil
Re: Blending pas fais avec les textures des FBO.
« Réponse #3 le: Avril 09, 2020, 07:06:46 pm »
C'est bon j'ai trouvé le problème, merci!