IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Double buffer + resize = flicker!


Sujet :

OpenGL

  1. #1
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut Double buffer + resize = flicker!
    Bonjour a tous,

    Je butte sur un problème dans mon application.
    Je dispose d'un main thread avec un fenêtre win32 basique.
    Un autre thread fait le rendu.

    Je dispose de 4 viewport (glViewport + glScissor ).
    A chaque boucle de rendu je fais

    1 - Pour chaque viewport
    - glViewport
    - glScissor
    - glClear(GL_COLOR_BUFFER_BIT)
    - glFinish

    2 - SwapBuffers(HDC)

    Je me retrouve avec dans mon exemple un viewport rouge et les autre tout noir.

    Lorsque je resize la fenêtre Windows, de temps en temps, j'ai un flicker des viewport. Je vais décrire au mieux les choses mais n'hésiter pas à me demander plus de renseignement si nécessaire.
    Donc, le flicker correspond en fait ( je pense ) au fait que je suis en double buffering. les viewports sont resize sur l'event WM_EXITSIZEMOVE, lorsque je le catch et je calcule la nouvelle taille des viewports, je n'effectue pas ici de glViewport ou glScissor, je ne fais que set des variables (x,y,height,width).

    Je me retrouve en diminuant la fenêtre, avec un buffer qui affiche la bonne taille puis la frame d'après le buffer contient la taille d'avant la fin du resize. Je me retrouve donc avec un viewport rouge qui est une frame sur deux d'une taille différente. pourtant glViewport et glScissor est appeler pour chaque viewport à chaque frame.

    J'avoue ne pas comprendre. Je ne sais pas si le problème vient de ma gestion de l'API win32 ou de OpenGL.

    Merci

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Je rajoute également que le problème se fixe dès que je refait un resize ne serait-ce que d'un pixel.

    Voici ma procédure windows:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    LRESULT clWindow::ProcessWindow(HWND _hWnd, UINT _message, WPARAM _wParam, LPARAM _lParam)
    {
    	switch(_message)
    	{
    	case WM_CLOSE:
    		{
    			//We destroy the windows
    			Destroy();
     
    			//We delete the window from the engine, 
    			// if window count is 0 so we destroy the engine and exit the run loop
    			m_engine.DestroyWindow(this);
    		}
    		break;
    	case WM_ENTERSIZEMOVE:
    		{
    		}
    		break;
    	case WM_EXITSIZEMOVE:
    		{
    			if(m_renderSystem->RenderWindowRelative())
    			{
    				RECT rect;
    				GetClientScreenRect(&rect);
    				int newHeight = static_cast<int>(rect.bottom - rect.top);
    				int newWidth = static_cast<int>(rect.right - rect.left);
    				if(static_cast<int>(m_clientSize.m_height) != newHeight ||
    				   static_cast<int>(m_clientSize.m_width) !=  newWidth)
    				{
    					m_renderSystem->ResizeRelative(static_cast<int>(m_clientSize.m_height),static_cast<int>(m_clientSize.m_width),newHeight,newWidth);
    					SaveClientSize();
    				}
    			}
    		}
    		break;
    	case WM_SETCURSOR:
    		{
    			if(m_cursor.IsVisible())
    				m_cursor.Visible(clTrue);
    			else
    				m_cursor.Visible(clFalse);
    		}
    		break;
    	}
    	return DefWindowProc(_hWnd, _message, _wParam, _lParam);
    }
    Il me manque sans doute quelque chose car lorsque je resize si je dis pas de bétise, les events WM_ENTERSIZEMOVE WM_SIZE et WM_EXITSIZEMOVE sont générer. Hors le bug se fixe avant même l'event WM_EXITSIZEMOVE .

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 157
    Billets dans le blog
    151
    Par défaut
    Bonjour,

    Pourquoi la taille des viewport n'est pas modifiée lors du "enter" ? car c'est à partir de là, que la taille de la fenêtre est vraiment modifiée.
    Une autre triche serait de geler le rendu, tant qu'un redimensionnement est fait.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Salut!

    Qu'appelles tu "Enter"? le enter frame?
    Car je fais appelle a glViewport et glScissor en debut de frame.
    J'ai pensé et tester le blocage du Thread de rendu lors du redimensionnement et je l'ai tester mais je garde le même problème.

    Un comportement similaire.
    ma fenêtre ressemble à ça:
    Avant resize:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ________________________
    |                       |
    |                       |
    |                       |
    |xxxxxxxxxxxx           |
    |xxxxxxxxxxxx           |
    |xxxxxxxxxxxx___________|
    Désiré après resize:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ________________________
    |                      |
    |                      |
    |oooooooo              |
    |oooooooo              |
    |oooooooo              |
    |oooooooo______________|
    Mais j'obtiens les deux en même temps!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ________________________
    |                       |
    |                       |
    |oooooooo               |
    |xxxxxxxxxxxx           |
    |xxxxxxxxxxxx           |
    |xxxxxxxxxxxx___________|
    Si je resize un peu, dès que je bouge la souris je me retrouve avec le bon dessin!

    J'ai l'impression que les buffers sont pourris lors du resize et que window les clean au moindre resize mais impossible de savoir comment regler ca.

  5. #5
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 157
    Billets dans le blog
    151
    Par défaut
    Je parlais du entersizemove.

    Il se peut qu'il ne les clean pas, mais qu'il les reconstruise (cas lorsque l'on minimise )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  6. #6
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    J'ai le même problème dans le enter. Par contre, dès que je resize l'affichage se corrige et se met correctement. Mais dès que je relâche il ne me met pas la bonne taille. Je dois resize pour la voir s'afficher correctement. Comme si le message WM_SIZE fesait un clean ou je sais pas quoi.

    Par contre ça ne flicker plus. Ça n'affiche juste pas correctement les viewports.

  7. #7
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Bon après beaucoup de réflexion je viens de trouver le souci.
    Le fait d'utiliser glScissor avec un resize n'est pas génial.
    En effet, glScissor veut tout simplement dire que l'on redessine une zone et bien entendu le reste n'est pas toucher, même pas effacé et donc mon problème vient de là!
    Resize avec un double buffer avec glScissor. Sur le back buffer il va dessiner la bonne taille avec le bon scissor, mais au swap, ce qui est en dehors du nouveau scissor reste...,donc ce qui est en dehors n'est pas effacé.

    Donc il n'y a pas de bug en soit, c'est juste que en dehors du glScissor, opengl n'y touche pas donc on ce retrouve avec des vieux restes

  8. #8
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Existe-t-il une façon élégante de glClear le front et le back buffer pour éviter les bugs du genre?

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 157
    Billets dans le blog
    151
    Par défaut
    Faire le clear avant d'activer le glScissor, ça ne donnerait pas mieux ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #10
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Et bien vu que mon context est dans un thread de rendu, je n'ai pas le contrôle de quand glScissor est activer et désactiver.
    Je dois mettre en pause le thread.
    Déactiver glScissor,
    Clear le buffer,
    Swap les buffers,
    Clear le buffer
    Reprendre le rendu.
    C'est Lourd mais je ne vois que ça vu que ce n'est pas synchrone.
    Mais je ne peux pas clear avant glScissor car pour un multiviewport je ne veux pas effacer les autres viewport si ceux ci sont déjà dessiné

  11. #11
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 050
    Par défaut
    Après un premier essai c'est plutôt concluant.
    Voici ce que je fais:
    sur WM_ENTERSIZEMOVE je stop mon thread de rendu.
    sur WM_EXITSIZEMOVE je recalcule la taille de viewport puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    glDisable(GL_SCISSOR_TEST);
    	glClearColor(0.0f,0.0f,0.0f,1.0f);
    	glClear(GL_COLOR_BUFFER_BIT);
    	SwapBuffers();
    	glClear(GL_COLOR_BUFFER_BIT);
    Ensuite je relance le thread de rendu.

    Alors je pourrais améliorer tout ça en utilisant une critical_section pour stopper le thread le temps du WM_EXITSIZEMOVE ce qui evitera de stoper et de relancer le thread!

    Je vous tiens au courant.
    En tout cas merci Little White

  12. #12
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 035
    Billets dans le blog
    12
    Par défaut
    Tu utilises le multiviewport, pourquoi pas passer par des FBO à la place ?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

Discussions similaires

  1. [GDI+] Double buffer
    Par sebbb dans le forum MFC
    Réponses: 3
    Dernier message: 24/05/2005, 15h19
  2. [MFC] Scinttillement vs Double buffering
    Par DamessS dans le forum MFC
    Réponses: 9
    Dernier message: 07/04/2005, 09h01
  3. Réponses: 1
    Dernier message: 04/04/2005, 11h19
  4. Réponses: 7
    Dernier message: 03/08/2004, 16h33
  5. [Exception]Double buffering & NullPointerException
    Par Seiya dans le forum API standards et tierces
    Réponses: 25
    Dernier message: 09/07/2004, 18h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo