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 :

Lignes indésirables lorsque la scène se redessine


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Par défaut Lignes indésirables lorsque la scène se redessine
    Bonjour à tous.

    Voila je débute avec open gl, j'ai écris un programme en delphi qui dessine une sphère en 3D points par points avec glbegin(GL_POINTS). Lorsque fait bouger la souris, la sphère tourne si le bouton gauche est enfoncé.

    La rotation est fluide mais des lignes horizontales de la même couleur que le fond de la scène apparaissent puis disparaissent lorsque la sphère est redessinée.

    J'ai parcouru les autres sujets et je n'ai rien trouvé qui puisse m'aider, j'utilise le double buffer et la synchronisation verticale est activée. Lorsque je fais un screenshot de la scène et que je le colle sous paint, on ne voit pas les lignes. Je ne saurai donc pas joindre une image du phénomène.

    Voilà le gros du code :

    Création de la fenêtre opengl :
    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
     
    procedure TFrmOpenGL.FormCreate(Sender: TObject);
    begin
          degx:=0;
          degy:=0;
          degz:=0;
          flag_rotation:=false;
         {Initialisation de OpenGL en mode Double tampon}
         InitOpenGL( FrmOpenGL.Canvas.Handle, 16, True );
     
         {Couleur de vidage}
         glClearColor( 0.0, 0.0, 0.0, 0.0 );
         glPointSize(4);
         {Activation du test de profondeur}
         glEnable(GL_DEPTH_TEST);
    Le reste de cette fonction consiste à remplir des tableaux contenant les positions x,y,z et les couleurs r,g,b de chaque point à partir d'un fichier texte.

    La fonction InitOpenGL provient d'un "unit" récupéré sur internet, je ne pense pas que le problème vienne de là. Voici le reste du code:

    Redimensionnement de la fenetre:
    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
     
    procedure TFrmOpenGL.FormResize(Sender: TObject);
    {Objectif :Définission du champs de vision en fonction du contrôle (FrmOPenGL).}
    begin
         {Empêcher les division par ZERO}
         If ClientHeight = 0 Then
            ClientHeight := 1;
     
         {Spécification de l'espace disponible sur le contrôle fenêtré.}
         glViewport( 0, 0, ClientWidth, ClientHeight );
         {Rendre la matrice de project active pour définir un nouveau champs de
         vision}
         glMatrixMode( GL_PROJECTION );
         glLoadIdentity();
     
         {Création d'une nouvelle matrice de projection.}
         gluPerspective( 45, ClientWidth / ClientHeight,0.1 , 800 );
     
         {Rafraîchir le contenu de la fenêtre}
         FrmOpenGL.Invalidate;
    end;
    Dessiner la scène :
    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    procedure TFrmOpenGL.FormPaint(Sender: TObject);
     
    var i:integer;
     
    begin
     
     
         SwapBuffers(Canvas.Handle);
         glClear( GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
     
         {On réénitialise la matrice modélisation-visualisation}
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity;
     
         glPushMatrix;
         glLoadIdentity;
         glTranslated( 0,0, -600.0 );
         glrotated(degx,1,0,0);
         glrotated(degy,0,1,0);
         glrotated(degz,0,0,1);
     
          for i:=0 to (nbre_points-1)  do
          begin
     
     
                    glbegin(gl_points);
                            glColor3f( r[i], g[i], b[i]);
                            glVertex3f( x[i],y[i],z[i] );
                    glend();
     
          end;
     
          glPopMatrix;
          glPushMatrix;
          glLoadIdentity;
          glTranslated( -250,-200, -600.0 );
          glrotated(degx,1,0,0);
          glrotated(degy,0,1,0);
          glrotated(degz,0,0,1);
     
          glbegin(gl_lines);
                    glcolor3f(0,0,1);
                    glvertex3f(0,0,0);
                    glvertex3f(0,0,-100);
          glend();
     
          glbegin(gl_lines);
                    glcolor3f(0,0,1);
                    glvertex3f(0,0,0);
                    glvertex3f(0,100,0);
          glend();
     
         glbegin(gl_lines);
                    glcolor3f(0,0,1);
                    glvertex3f(0,0,0);
                    glvertex3f(100,0,0);
         glend();
     
         glbegin(gl_triangles);
                    glvertex3f(100,0,0);
                    glvertex3f(95,5,0);
                    glvertex3f(95,-5,0);
         glend();
     
         glbegin(gl_triangles);
                    glvertex(0,100,0);
                    glvertex(-5,95,0);
                    glvertex(5,95,0);
         glend();
     
         glbegin(gl_triangles);
                    glvertex(0,0,-100);
                    glvertex(0,-5,-95);
                    glvertex(0,5,-95);
         glend();
     
         glPopMatrix;
     
         glFinish;
     
         SwapBuffers( Canvas.Handle );
    end;
    Et enfin la rotation avec la souris :
    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
     
    procedure TFrmOpenGL.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    var dx,dy:integer;
    begin
            if(flag_rotation=true) then
            begin
                    dx:=Mx-x;
                    dy:=My-y;
                    Mx:=x;
                    My:=y;
                    degx:=degx-dy;
                    degy:=degy-dx;
                    FrmOpenGL.Invalidate;
     
            end;
    end;
    Voilà, si il vous faut plus de renseignements je serai heureux de vous les donner. J'espère avoir été assez clair pour que vous puissiez m'aider.

    J'ai lu que le swapbuffer se faisait par recopie du back_buffer vers le front buffer et comme il y a un nombre assez important de points (environ 100.000), je me dis que c'est peut-être la recopie du buffer qui prend trop de temps et qui crée ce phénomène mais je ne suis pas sur du tout.

    D'avance merci pour votre aide.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    A priori, dans ta fonction de rendu tu as :

    -swapbuffers au debut ET a la fin

    il faut supprimer celui au debut ...


    sinon, le swap n est normalement pas trop couteux : d'ailleurs, en fullscreen , un GPU normalement devrait juste proceder a un changement de l "adresse" de l image afficher (-> immediat)

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    note annexe : sous windows, par ailleurs quand l image est rafraichie (evenement WM_PAINT), le GDI procede dans un premier temps a l effacement de la fentre (evt WM_BACKGROUND ??). Il faut ignorer ce message (qui fera "flashe" l image).

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Par défaut
    Merci pour tes conseils Smashy.
    Je trouvai également bizarre le swapbuffer au début de la fonction mais si je ne le met pas c'est toute la sphère qui disparait puis réaparait chaque fois que je la dessine.

    Par contre si je supprime le swapbuffer à la fin de la fonction, rien ne change.

    Je vais regarder du coté de l'effacement de la fenetre, mais comme je l'ai dit je débute et je n'ai pas très bien compris ce que tu voulais dire.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    ce qui se passe sous windows, c est qu en fonction d un certain nombre d evenements de fenetres des fonctions de callbacks sont appelees. Quand une le reaffichage d une fenetre est necessaire (quand tu appelles Invalidate) , l api windows traite deux messages WM_BACKGROUND (a verifier) et WM_PAINT. Tu peux grace a l API windows intercepte les messages qui t interresse (c est deja a priori le cas pour WM_PAINT) ou laisser windows faire le traitement par defaut.

    Un probleme (peut etre) est que tu laisses windows faire le traitement par defaut pour WM_BACKGROUND. Ce traitement est un effacement de la fenetre par windows lui meme, qui en plus d etre inutile et lent est visible par un utilisateur. Quand WM_PAINT est traite, c est ta callback "FormPaint" qui doit etre appele

    Je ne connais pas l API que tu emploies, mais il faut que tu associes le traitement de WM_BACKGROUND a une callback NULL (de facon similaire a ce que tu as probablement deja fait pour WM_PAINT). Sinon, de memoire, en C quand tu fais InvalideRect() qui invalide une fenetre tu peux aussi specifie si tu veux passer par la callback lie a WM_BACKGROUND.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Par défaut
    Nickel, ca marche. Merci Smashy, le problème venait bien de l'interception du message WM_ERASEBKGND.

    Voilà, la balise résolu s'impose. Encore merci pour ton aide Smashy.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    de rien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ligne grisée lorsqu'une cellule est sélectionnée
    Par NEC14 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 28/10/2011, 10h40
  2. Sélection Ligne,Colonne lorsque non vide
    Par Mairequimby dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 21/12/2009, 14h28
  3. Saut de ligne indésirable après mode
    Par papoose dans le forum Beamer
    Réponses: 4
    Dernier message: 03/03/2009, 18h20
  4. Réponses: 1
    Dernier message: 23/05/2008, 13h13
  5. Passage à la ligne indésirable avec SPOOL
    Par aeled dans le forum Oracle
    Réponses: 5
    Dernier message: 11/08/2006, 13h03

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