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

API, COM et SDKs Delphi Discussion :

Graphisme Temps réel


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut Graphisme Temps réel
    Bonjour je vous expose mon projet afin d'obtenir des pistes de solutions ....

    Voilà, je dois afficher sur un écran secondaire (Deuxième écran sur sortie hdmi, ...) un point (genre spot lumineux de petite taille) qui effectue des mouvements sinusoïdaux horizontaux et verticaux. la contrainte la plus importante est la "fluidité" et la "netteté" de ces mouvements et non la complexité de l'image celle-ci étant simplement ce point lumineux sur fond noir. (docnc très simple).

    j'ai déjà expérimenté : (sous Delphi Xe)

    - D2D + SVATimer (sous Windows 7),
    - AsphyreSphinx110 (Directx9 ou OpenGl).

    mais à chaque fois des 'saccades' et 'pauses' dans le mouvement apparait alors que le processeur est sous les 20% d'utilisation.

    Merci pour vos idées et conseils ...

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    Sinon FMX sur XE2
    FMX gère DX et OpenGL, je ne connais pas tous les détails à ce sujet
    FMX contient déjà un système d'Animation : Effets d'animation FireMonkey \ Utilisation des effets d'animation FireMonkey

    Ton programme monte à combien en FPS ?
    J'espère qu'il atteint au moins les 60 !

    Comment l'as-tu programmé ? Pas de Timer j'espère ?
    J'espère que tu es parti si un Thread + Triple Buffered

    le V-Sync n'est-il pas un moyen pour générer juste le nombre précis d'image et éviter de "sauter" des images lors de l'utilisation d'un Buffer ?

    Cela ma rappelle ce sujet
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    pourquoi diable passer par DirectX ou 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
    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
     
    var
      P: TPoint;
      W: Integer;
      H: Integer;
      B: TBitmap;
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      m: Integer;
    begin
      m := 0;
      if Screen.MonitorCount > 0 then
        m := 1;
     
      BorderStyle := bsNone;
      Color := clBlack;
     
      B := TBitmap.Create;
     
      with Screen.Monitors[m] do
      begin
        SetBounds(Left, Top, Width, Height);
        W := Width div 2;
        H := Height div 2;
        B.Width := Width;
        B.Height := Height;
      end;
     
      with B.Canvas do
      begin
        Brush.Color := clBlack;
        Rectangle(0, 0, B.Width, B.Height);
      end;
    end;
     
    procedure TForm1.FormPaint(Sender: TObject);
    var
      T: Single;
      N: TPoint;
    begin
      T := GetTickCount/1000;
     
      N.X := W + Round(W * Cos(T) * Sin(T));
      N.Y := H + Round(H * Sin(T) * Sin(2*T));
     
      with B.Canvas do
      begin
        Brush.Color := clWhite;
        Pen.Color := clWhite;
        Rectangle(N.X - 5, N.Y - 5, N.X + 5, N.Y + 5);
      end;
     
      Canvas.Draw(0, 0, B);
     
      with B.Canvas do
      begin
        Brush.Color := clBlack;
        Pen.Color := clBlack;
        Rectangle(P.X - 5, P.Y - 5, P.X + 5, P.Y + 5);
      end;
     
      P := N;
     
      InvalidateRect(Handle, nil, False);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Bonjour,

    mais à chaque fois des 'saccades' et 'pauses' dans le mouvement apparait alors que le processeur est sous les 20% d'utilisation.
    ... Bizarre : j'ai testé (avec with Screen.Monitors[0] car je n'ai qu'un seul moniteur de branché) et il n'y a ni "saccades" ni "pauses" ... sauf que le "point" est en fait un petit carré.

    A+.

    EDIT : Autre test : avec ou sans DoubleBuffered:=true c'est kif-kif.
    Oups : ces tests ont été effectués avec le code Paul TOTH, mais ça confirme au moins qu'il marche!!!
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  5. #5
    Membre très actif
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Par défaut
    Salut,

    Et si l'on considère que la simplicité est une vertu en programmation, on peut même aller plus loin que ce que propose Paul.
    - Le rôle du fond noir est joué par une fiche de couleur noire.
    - Le rôle du spot par un TShape stCircle de couleur et de taille adéquates.
    - Le tout étant mis en scène à l'aide des Top et Left du TShape.

    Je n'ai pas testé, mais ce n'est pas très compliqué à mettre en oeuvre et ça doit répondre aux exigences de fluidité.

  6. #6
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut
    Re-bonjour,

    merci pour toutes ces réponses ...

    FPS : avec AsphyreSphinx110 cela monte très haut si l'on n'active pas le V-Sync sinon cela se fixe à 60 ce qui est normal et plus que suffisant,

    En fait les différentes solutions que j'ai testées fonctionne bien ... mais toutes les 2/3 secondes il y a des à coups et donc la fluidité du mouvement est mauvaise ... (l'oeil doit suivre ce point ).

    De plus ce n'est pas tout ce que fait mon application. Avec le V-Sync tous les autres processus (Timer, Thread) sont complètement ralenti.

    Je vais vite implémenter la solution de Paul Toth si j'ai bien compris, la fréquence d'affichage sera "au maximum" ...

  7. #7
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut
    je pense qu'il y a une petite erreur (ou alors un effet visuel supplémentaire ):

    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
     
    with B.Canvas do
      begin
        Brush.Color := clWhite;
        Pen.Color := clWhite;
        Rectangle(N.X - 5, N.Y - 5, N.X + 5, N.Y + 5);
      end;
     
      Canvas.Draw(0, 0, B);
     
      with B.Canvas do
      begin
        Brush.Color := clBlack;
        Pen.Color := clBlack;
        Rectangle(P.X - 5, P.Y - 5, P.X + 5, P.Y + 5);
      end;
     
      P := N;
    Lorsque l'on affiche le BitMap il contient 2 points (rectangle) pourquoi mémoriser la position (P:=N) et effacer au prochain onPaint.

    j'ai mis ceci :
    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
    with B.Canvas do
      begin
        Brush.Color := clWhite;
        Pen.Color := clWhite;
        Rectangle(N.X - 5, N.Y - 5, N.X + 5, N.Y + 5);
      end;
    
      Canvas.Draw(0, 0, B);
     
      with B.Canvas do
      begin
        Brush.Color := clBlack;
        Pen.Color := clBlack;
        Rectangle(N.X - 5, N.Y - 5, N.X + 5, N.Y + 5);
      end;
    Maintenant j'ai calculé le FPS (le nombre de OnPaint par secondes) ;
    Sans le "DoubleBuffer" : 170
    Avec le "DoubleBuffer" : 80

    J'ai également changé les equations de mouvement pour revenir a un sinus horizontal simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     N.X := W + Round(W * Sin(T) );
     N.Y := H ;
    et là on voit plus les "saccades" et "micro-pause", mais c'est tout aussi fluide qu'avec une "grosse artillerie" (AsphyreSphinx).

    Comment contrôler la priorité du OnPaint de la form, par rapport au autres évènement de l'application ?

  8. #8
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    Citation Envoyé par steph1969 Voir le message
    et là on voit plus les "saccades" et "micro-pause", mais c'est tout aussi fluide qu'avec une "grosse artillerie" (AsphyreSphinx).
    Ah oui, tu ne voulais vraiment aucun effet, je pensais que si tu partais sur OpenGL, tu voulais avoir d'autres effet sur le ce fameux point par la suite comme rémanence du tracé par effet de transparence !

    Tu n'avais pas testé le mode TPaintBox avant de te lancer dans un truc si compliqué ? Si c'est pas mettre la Charrue avant les Bœufs ça !

    Citation Envoyé par steph1969 Voir le message
    Comment contrôler la priorité du OnPaint de la form, par rapport au autres évènement de l'application ?
    Tu n'y pourras pas grand chose, c'est la file d'Attente des messages de Windows, un ShowModal, un PopupMenu, un Synchronize, un excité du clavier ou de la souris sur le Monitor 0 et tu verras ton point ralentir sur le Monitor 1

    Tout dépend ce que ton application (et les autres) fait pendant ton dessin !
    En fait tu veux juste faire un oscilloscope ? il n'y avait pas une démo Delphi sur ça ?

    C'est surement pour cela que tu as un si mauvais FPS, 180 pour un pauvre point ! c'est parce que InvalidateRect ou Application.Run() prend son temps pour envoyer ou recevoir WM_PAINT
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    @Caribensila, oui ça fonctionnerait avec un TShape, mais l'avantage du Bitmap est qu'il évite tout scintillement...et activer le DoubleBuffer revient à créer un bitmap à chaque affichage...je préfère en avoir un alloué une fois pour toute

    @steph1969, P et N sont un reste de mon premier test en mode XOR...en effet, dans la solution que je propose P suffit

    dernier point, il est tout à fait possible de dessiner le bitmap en dehors du Paint (sur un OnIdle par exemple), mais je ne suis pas certain que ce soit plus efficace que ce que j'ai proposé.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  10. #10
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Tu n'avais pas testé le mode TPaintBox avant de te lancer dans un truc si compliqué ? Si c'est pas mettre la Charrue avant les Bœufs ça !
    j'avais essayé avec un TD2DCanvas sur un PaintBox, mon idée était que le TPaintBox seul n'utiliserai pas les capacités du GPU présent. De plus les démo (directX, ...) fournies avec certaines librairies sont toujours "bluffantes" mais paradoxalement plus la scène est "chargée" moins on perçoit ces fameuses micro poses ...

    Citation Envoyé par ShaiLeTroll Voir le message
    Tout dépend ce que ton application (et les autres) fait pendant ton dessin !
    En fait tu veux juste faire un oscilloscope ? il n'y avait pas une démo Delphi sur ça ?
    Mon application fait beaucoup d'autres choses (capture video, analyse position de l'oeil, sauvegarde ...) cette partie doit remplacer un laser projetant sur un mur ces mouvements. Associé à un video projecteur la différence de fluidité entre le mouvement du laser et celui de mon point est trop importante ... En plus je doit également réalisé un "panorama" tournant.

    Citation Envoyé par ShaiLeTroll Voir le message
    C'est surement pour cela que tu as un si mauvais FPS, 180 pour un pauvre point ! c'est parce que InvalidateRect ou Application.Run() prend son temps pour envoyer ou recevoir WM_PAINT
    Je vais tenter la solution TPaintbox + Bitmap de Paul mais je vais introduire un Timer (SVATimer) à 30-60FPS basé sur un thread pour contrôler le "Invalidate"

    J'ai également remarqué que les performances sont meilleures si je crée deux applications :

    - Application principale
    - Application "Laser" + Communication via TCP en local host

    par rapport à une seule application ! pas très logique.

  11. #11
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 935
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 935
    Par défaut
    Il faudrait vraiment déporter le traitement (calcul) dans un thread secondaire et garder le principal uniquement pour la boucle d'affichage.
    Définir Rect sur InvalidateRect devrait aussi permettre d'optimiser le rafraîchissement.

  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Par défaut
    Bonjour,

    J'ai également changé les equations de mouvement pour revenir a un sinus horizontal simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     N.X := W + Round(W * Sin(T) );
     N.Y := H ;
    ... avec ça le point reste sur une ligne horizontale même s'il bouge.

    Faudrait au moins qu'en plus N.Y soit de la forme N.Y= round((K*(T-T0)));
    suivi de if N.Y>2*H then T0:=T;
    (avec K = 50 à 100 par exemple et avec T0 := GetTickCount/1000 déterminé dans FormCreate).

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Membre très actif
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Par défaut Hors sujet :
    @steph1969
    Si j'ai bien compris ton explication, une petite remarque hors sujet mais qui peut avoir de l'importance :

    Citation Envoyé par steph1969 Voir le message
    Mon application fait beaucoup d'autres choses (capture video, analyse position de l'oeil, sauvegarde ...) cette partie doit remplacer un laser projetant sur un mur ces mouvements. Associé à un video projecteur la différence de fluidité entre le mouvement du laser et celui de mon point est trop importante ...
    Attention aux risques d'interférences entre les micro-saccades physiologiques de l'oeil et le FPS qui sont du même ordre de grandeur !

    Le spot du laser est animé d'un mouvement uniforme. En revanche, le spot du dispositif que tu comptes mettre en place sera animé d'un mouvement saccadé (env. 60 Hz).
    En remplaçant le laser par ce système, tu discrétises l'espace et tu risques d'avoir des difficultés à distinguer la mesure d'une micro-saccade de l'oeil dû à sa physiologie de celle provoquée par le système de projection.

  14. #14
    Membre averti
    Profil pro
    Delphi 10.4
    Inscrit en
    Août 2007
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Delphi 10.4

    Informations forums :
    Inscription : Août 2007
    Messages : 51
    Par défaut
    Citation Envoyé par Caribensila Voir le message
    @steph1969
    Le spot du laser est animé d'un mouvement uniforme. En revanche, le spot du dispositif que tu comptes mettre en place sera animé d'un mouvement saccadé (env. 60 Hz).
    En remplaçant le laser par ce système, tu discrétises l'espace et tu risques d'avoir des difficultés à distinguer la mesure d'une micro-saccade de l'oeil dû à sa physiologie de celle provoquée par le système de projection.
    Ta remarque est juste dans l'absolu, mais en pratique j'en suis au stage ou j'ai un mouvement satisfaisant durant 2/3 secondes puis des saccades dans le mouvement ...puis quelques secondes de mouvement satisfaisant ....

    La capture des mouvement de l'oeil est de toute façon encore plus "discrète" (au sens mathématique) vu qu'il s'agit de camera.

Discussions similaires

  1. Mise à jour en temps réel de la base de données
    Par Clotilde dans le forum Bases de données
    Réponses: 2
    Dernier message: 11/06/2004, 22h09
  2. [MFC] graphique temps réel
    Par _Thomas_ dans le forum MFC
    Réponses: 10
    Dernier message: 01/06/2004, 11h56
  3. Voir requête éxécuté en temps réel ?
    Par [DreaMs] dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 08/01/2004, 14h52
  4. cubes temps réel en ROLAP
    Par Guizz dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 09/07/2003, 16h36
  5. Durée d'un traitement temps réel
    Par Almex dans le forum C
    Réponses: 5
    Dernier message: 29/03/2003, 14h15

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