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

Auteur Sujet: [Résolu][SFML 2.0] Souci de FBO avec sf::style::Default  (Lu 2273 fois)

0 Membres et 1 Invité sur ce sujet

Dragonic

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
[Résolu][SFML 2.0] Souci de FBO avec sf::style::Default
« le: Février 12, 2014, 11:57:52 am »
Bonjour,

J'essayais de rechercher une erreur équivalente mais sans succès, c'est pour cela que j'ouvre ce topic !

J'ai un programme assez costaud OpenGL+SFML (+ quelques tonnes d'autres libs ^^) auquel je devais implémenter récemment une fonctionnalité qui me demandait d'utiliser un FBO (1ère fois que j'en utilise,  et je sais que je vais dans le futur m'en servir pour bcp d'autres choses ^^) ! Je fais donc quelques rendus dans le FBO, que j'utilise ensuite pour faire un rendu à l'écran !

Enfin bref, tout se passe bien en sf::style::Fullscreen, mais avec sf::style::Default pour me retrouver en mode fenêtré impossible de mettre à jour le contenu de mon FBO, ce dernier reste vide ! C'est la seule chose que j'ai changé, et ça me produit donc un bel écran noir !
Pour info, si je fais un rendu directement à l'écran plutôt que dans le FBO tout fonctionne bien, en Fullscreen comme en Default !

Je vais m'arrêter là pour ce 1er post, si ça se trouve ces premières informations seront suffisantes pour comprendre le problème (problème connu de 2.0 et corrigé en 2.1 ? Je n'ai pas d'autres pistes)  !

Sinon je peux essayer d'écrire un code minimal en cas de besoin ! Il suffit de me demander (se basera sur SFML 2.0 avec utilisation de GLEW par contre) !
« Modifié: Février 13, 2014, 02:43:46 pm par Dragonic »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Souci de FBO avec sf::style::Default
« Réponse #1 le: Février 12, 2014, 12:29:06 pm »
Ce n'est pas un bug connu, il faudrait donc un exemple complet minimal.

Quelque chose qui a souvent rapport avec les problèmes FBOs : contrairement au reste, ceux-ci ne sont pas partagés entre les différents contextes OpenGL. Je te laisse voir si ça t'aide ;)
Laurent Gomila - SFML developer

Dragonic

  • Newbie
  • *
  • Messages: 46
    • Voir le profil
Re : [RESOLU][SFML 2.0] Souci de FBO avec sf::style::Default
« Réponse #2 le: Février 12, 2014, 05:18:44 pm »
Bon, finalement c'était un petit problème de configuration du FBO qui venait poser souci ^^ ! Un "glDrawBuffers(1, gl_draw_buffers);" de trop ! C'est en écrivant le code minimal que je me suis rendu compte que j'avais même plus le FBO en Fullscreen ><, et que je suis remonté petit à petit à cette ligne problématique !

Néanmoins il me reste une bizarrerie !

Je donne le code minimal suivant (utilise SFML 2.0 et GLEW 1.9.0)

#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

GLuint sizeX=800;
GLuint sizeY=600;

GLuint oculusFBO;
GLuint oculusFBODepth;
GLuint oculusFBOTexture;

typedef unsigned char UINT8;

GLint setupFBO();

int main()
{
    sf::RenderWindow window;
    window.create(sf::VideoMode(sizeX, sizeY), "testFBO", sf::Style::Default, sf::ContextSettings(32));
    window.setVerticalSyncEnabled(true);

    GLenum initialisationGLEW( glewInit() );
    if(initialisationGLEW != GLEW_OK)
    {
        std::cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << std::endl;
        return 1;
    }

        glDisable(GL_DEPTH_TEST);
        glDisable(GL_CULL_FACE);

    if(setupFBO() != 0)//erreur
    {
        return 2;
    }

        sf::CircleShape shape(50);
        shape.setFillColor(sf::Color(100, 250, 50));

        bool running = true;
    while (running)
    {
        // gestion des évènements
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // on stoppe le programme
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // on ajuste le viewport lorsque la fenêtre est redimensionnée
                glViewport(0, 0, event.size.width, event.size.height);
            }
            else if (event.type == sf::Event::KeyPressed)
            {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                {
                        running = false;
                }
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::F))//permet d'enregistrer le contenu du FBO (pour debug)
                {
                    std::vector<UINT8> pixels(sizeX*sizeY*4);

                                        glBindFramebuffer(GL_FRAMEBUFFER, oculusFBO);
                                        glReadBuffer(GL_COLOR_ATTACHMENT0);
                                        glReadPixels(0, 0, GLsizei(sizeX), GLsizei(sizeY), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
                                        glBindFramebuffer(GL_FRAMEBUFFER, 0);

                                        sf::Texture texture;
                                        texture.create(sizeX, sizeY);
                                        texture.update(&pixels[0]);
                                        texture.copyToImage().saveToFile("testFBO.jpg");
                }
            }
        }

        //rendu dans le FBO
        glBindFramebuffer(GL_FRAMEBUFFER, oculusFBO);

                glViewport(0,0, sizeX, sizeY);

                glClearColor(0,0,0,0);
                glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

                //un rond SFML
        window.pushGLStates();
        window.draw(shape);
                window.popGLStates();

                //et un triangle OpenGL
                glBegin(GL_TRIANGLES);
        glColor3f(1, 0, 0);
        glVertex3f(0, 0, 0);
        glVertex3f(1, 0, 0);
        glVertex3f(0, 1, 0);
        glEnd();

                glBindFramebuffer(GL_FRAMEBUFFER, 0);

                //maintenant on va afficher le FBO à l'écran

        // effacement les tampons de couleur/profondeur
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, oculusFBOTexture);

                float quad[][5]=
                {
                        {-1, -1, -1,  0,  0},
                        { 1, -1, -1,  1,  0},
                        { 1,  1, -1,  1,  1},
                        {-1,  1, -1,  0,  1},
                };
                unsigned int faces[]=
                {
                        0, 1, 2, 3
                };

                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);

                glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &quad[0][0]);
                glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &quad[0][3]);

                glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, faces);

                glDisableClientState(GL_VERTEX_ARRAY);
                glDisableClientState(GL_TEXTURE_COORD_ARRAY);

                glBindTexture(GL_TEXTURE_2D, 0);
                glDisable(GL_TEXTURE_2D);

        // termine la trame courante (en interne, échange les deux tampons de rendu)
        window.display();
    }

    // libération des ressources...
    // mais je suis un gros flemmard :p

}

GLint setupFBO()
{
        glGenFramebuffers(1, &oculusFBO);
    glGenTextures(1, &oculusFBOTexture);
    glGenRenderbuffers(1, &oculusFBODepth);

    glBindFramebuffer(GL_FRAMEBUFFER, oculusFBO);

    glBindTexture(GL_TEXTURE_2D, oculusFBOTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sizeX, sizeY, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, oculusFBOTexture, 0);

    glBindRenderbuffer(GL_RENDERBUFFER, oculusFBODepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, sizeX, sizeY);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, oculusFBODepth);

    //glDrawBuffers(1, gl_draw_buffers);

        if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
                std::cout<<"[FRAMEBUFFER] error."<<std::endl;
                return 1;
    }

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

    return 0;
}


Ce code va donc faire le rendu d'un rond vert SFML et d'un triangle rouge OpenGL dans le FBO, et ensuite on affichera le FBO à l'écran ! Voici le contenu du FBO (lu via la petite partie de code dispo en appuyant sur F) :



Mais voici le résultat une fois l'affichage du FBO à l'écran :



Je sais pas d'où me viens cette transformation du rond vert en marron xD ! (l'inversion est normale par contre)

Bon, je peux aucunement mettre en cause je pense un problème avec la SFML puisque le contenu du FBO est correct ^^ ! Ça doit venir d'un paramètre OpenGL manquant je suppose !

Enfin bref, je passe ça en Résolu !
« Modifié: Février 12, 2014, 05:21:24 pm par Dragonic »