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

Bibliothèques, systèmes et outils C Discussion :

[OpenGL] La caméra tremble


Sujet :

Bibliothèques, systèmes et outils C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Par défaut [OpenGL] La caméra tremble
    Bonsoir à tous, je me permets de vous faire part d'un problème qui ne m'était jamais apparu auparavant : La caméra tremble.
    Je code un petit jeu en OpenGL où l'on conduit un TGV, j'utilise l'axe des Z comme axe vertical et le train est initialement orienté dans la direction de X, ainsi que la caméra. Lorsque l'on active la vue en cabine, le calcul de la position de la caméra connaissant celle du train ainsi que l'orientation de ce dernier se fait de cette façon :

    A = xTrain + 7 * cos(angleTrain)
    B = yTrain + 7 * sin(angleTrain)

    xCam = A - 0.5*sin(angleTrain)
    yCam = B + 0.5*cos(angleTrain)

    Voici un schéma explicatif :

    Nom : Image1.jpg
Affichages : 315
Taille : 32,8 Ko

    Pour calculer la position de la cible de la caméra, je prends comme distance 900 (Par exemple) et je procède ainsi :

    xCible = xCam + 900 * cos(angleCam + angleTrain)
    yCible = yCam + 900 * sin(angleCam + angleTrain)

    Un autre schéma pour expliquer :

    Nom : Image2.jpg
Affichages : 318
Taille : 35,3 Ko

    Lorsque je teste, je me rends compte que la caméra tremble dès que la somme (angleCam + angleTrain) a une valeur différente de 0, 90, 180 ou 270° ! J'ai toujours géré la caméra de cette façon et je n'ai jamais eu ce problème.

    Voici le code résumé du main:

    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
    int main(int argc,char *argv[])
    {
        SDL_Surface *ecran;
        SDL_Event evenement;
     
        if(SDL_Init(SDL_INIT_VIDEO)!=0)		//Initialisation mode vidéo SDL
            return -1;
     
        SDL_WM_SetCaption("TGV Driving",NULL);
        putenv("SDL_VIDEO_CENTERED=1");
     
        ecran=SDL_SetVideoMode(800,600,32,SDL_OPENGL);	//Fenêtre SDL
     
        glMatrixMode(GL_PROJECTION);	//Appel matrice de projection
        glLoadIdentity();
        gluPerspective(70,4.0/3,0.1,1000);
     
        glEnable(GL_TEXTURE_2D);	//Initialisations texturing et Z-buffer
        glEnable(GL_DEPTH_TEST);
     
        //Chargement textures et initialisations paramètres
     
        while(1)    //BOUCLE PRINCIPALE
        {
            SDL_PollEvent(&evenement);
            if(evenement.type==SDL_QUIT)
                break;
            if(evenement.type==SDL_KEYDOWN)
            {
                ...
            }
     
            CommandeTrain(&infos);		//Mouvement du train
            gestionCam(&infos,evenementCam);	//Gestion de la caméra
            Dessiner(&infos);		//Dessin 3D
     
            glFlush();
            SDL_GL_SwapBuffers();
        }
     
        SDL_Quit();
        return 0;
    }
    Et celui de la fonction gestionCam() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void gestionCam(Principale *ptr)
    {
        ptr->vuesCam[1].xRepere1=ptr->convoi[ptr->numTrain].voitures[0].x+7*cos(ptr->convoi[ptr->numTrain].voitures[0].angle*M_PI/180);	//Calcul A et B
        ptr->vuesCam[1].yRepere1=ptr->convoi[ptr->numTrain].voitures[0].y+7*sin(ptr->convoi[ptr->numTrain].voitures[0].angle*M_PI/180);
     
        ptr->vuesCam[1].x=ptr->vuesCam[1].xRepere1-0.5*sin(ptr->convoi[ptr->numTrain].voitures[0].angle*M_PI/180);		//Calcul xCam et yCam
        ptr->vuesCam[1].y=ptr->vuesCam[1].yRepere1+0.5*cos(ptr->convoi[ptr->numTrain].voitures[0].angle*M_PI/180);
     
        ptr->vuesCam[1].xCible=ptr->vuesCam[1].x+900*cos((ptr->convoi[ptr->numTrain].voitures[0].angle+ptr->vuesCam[1].angle)*M_PI/180);	//Calcul xCible et yCible
        ptr->vuesCam[1].yCible=ptr->vuesCam[1].y+900*sin((ptr->convoi[ptr->numTrain].voitures[0].angle+ptr->vuesCam[1].angle)*M_PI/180);
    }
    ptr est un pointeur sur une structure contenant les différents paramètres, vuesCam[] est un tableau de structures qui contiennent les coordonnées de A et B (xRepere1 et yRepere1) ainsi que celles de la caméra (x et y) et celles de la cible de la caméra (xCible et yCible), ainsi que l'orientation de la caméra par rapport au train (angle). convoi[] est un tableau de structures représentant les différents trains, chaque case de ce tableau contient un tableau de structures appelé voitures[] (La motrice et les wagons) contenant entre autres l'orientation de la voiture de train).

    Je n'arrive pas au bout de ce problème, j'y ai passé tout l'après-midi, auriez-vous une solution svp ??
    Images attachées Images attachées  

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Bonsoir,

    Le projet a l'air intéressant : est-il possible d'avoir accès à la totalité du code source ? Ce serait bien de pouvoir le compiler et de constater par nous mêmes les effets que tu constates.

    En tout état de cause, la seule fois où j'ai été confronté à un problème similaire, il y a 25 ans lorsque j'essayais de faire défiler de manière fluide un texte sur mon écran de droite à gauche avec mon 8 bits, et qu'il fallait pour cela attendre le retour du raster en haut de l'écran (Bit 7 de &HE7E7 sur TO8D, l'équivalent de WAIT &H3DA,8 sur les PC de l'époque).

    J'obtenais un gros tremblement parce que j'attendais deux VBL au lieu d'une, alternant ainsi phases de mouvement et phases statiques, ce qui était très perturbant pour l'œil.

    Il est tout-à-fait possible que le mélange d'OpenGL et de la SDL provoque des conflits, notamment au niveau de glFlush() et SDL_GL_SwapBuffers(). Il est possible que l'un des deux implique déjà l'autre. Fais un test en désactivant celui de ton choix.

  3. #3
    Membre éclairé
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Par défaut
    Citation Envoyé par nanosoft Voir le message
    Bonjour,

    Est-ce que le mouvement de la caméra est associé aux évènements (comme SDL_KEYDOWN) ?

    Parceque la gestion des évènements ici n'est pas correcte (ligne 25) :
    Il faut tester le retour de SDL_PollEvent() pour associer la condition à UN évènement.
    Sinon on éxecute plusieurs fois au rythme de la boucle principale la condition du dernier évènement.

    Classiquement, on teste dans un boucle while{} pour dépiler tous les évènements avant de reprendre la boucle principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while(SDL_PollEvent(&event))
    {
       switch(event.type)
       {
     
     
     
       } 
     
     
    }

    Effectivement, je devrais de préférence tester la valeur de retour de SDL_PollEvent().
    Les événements SDL permettent juste de faire pivoter la caméra ou de la déplacer, mais en vue cabine elle reste à un position fixe, et ce sont les touches fléchées latérales qui permettent de faire pivoter la caméra en agissant sur son angle. L'angle du train quant à lui est géré par une fonction Orientation() qui détecte sur quelle voie ou quel virage se trouve le convoi et modifie l'angle en fonction.

    Citation Envoyé par Obsidian Voir le message
    Il est tout-à-fait possible que le mélange d'OpenGL et de la SDL provoque des conflits, notamment au niveau de glFlush() et SDL_GL_SwapBuffers(). Il est possible que l'un des deux implique déjà l'autre. Fais un test en désactivant celui de ton choix.
    La désactivation de glFlush() ou SDL_GL_SwapBuffers() ne change rien malheureusement.

    Citation Envoyé par Obsidian Voir le message
    Bonsoir,

    Le projet a l'air intéressant : est-il possible d'avoir accès à la totalité du code source ? Ce serait bien de pouvoir le compiler et de constater par nous mêmes les effets que tu constates.
    Je voudrais bien mais le code est réparti sur une vingtaine de fichiers, et il y également les textures, dll et divers fichiers.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par KevinduC Voir le message
    Je voudrais bien mais le code est réparti sur une vingtaine de fichiers, et il y également les textures, dll et divers fichiers.
    Dans ce cas, tu peux faire un gros *.zip et le présenter ici en pièce jointe.
    Si tu comptes ouvrir ton projet à la collaboration publique, tu peux également ouvrir un compte github pour cela, voire même le faire héberger ici si tu comptes travailler dessus un petit moment.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    OK,

    une autre piste : des arrondis de calcul qui ne conduisent pas toujours au même résultat.
    Car apparemment la position caméra est calculée à chaque fois dans gestionCam() , non ?

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Primo, +1 pour avoir présenté ta requête de façon claire en introduisant le contexte clairement et avec des schémas explicatifs.


    Secundo, concernant le comportement dont tu es témoin : comme ça tout de go je lis « train » donc « grandes valeurs de distance » et je suppute un souci de précision dû au fait que tu stockes de « grandes » coordonnées dans des variables à virgule flottante. Tu n'as pas précisé si tu utilisais des float ou des double. Il faut savoir qu'en simple précision (float) ce genre de comportement peut apparaître dès ~1000.0f (je parle d'expérience).

    Si tu es en float, passe en double pour confirmer ou infirmer cette hypothèse. Si c'est bien la cause tu as deux solutions : rester définitivement en double avec les contraintes techniques qui vont avec, ou t'arranger pour effectuer les calculs dans un repère ou les valeurs de coordonnées sont faibles (idéalement inférieures à 100.0f).


    Terzio, pourquoi as-tu besoin d'avoir la target de caméra à 900 mètres de l'oeil ? Un vecteur unitaire suffit.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut PollEvent
    Bonjour,

    Est-ce que le mouvement de la caméra est associé aux évènements (comme SDL_KEYDOWN) ?

    Parceque la gestion des évènements ici n'est pas correcte (ligne 25) :
    Il faut tester le retour de SDL_PollEvent() pour associer la condition à UN évènement.
    Sinon on éxecute plusieurs fois au rythme de la boucle principale la condition du dernier évènement.

    Classiquement, on teste dans un boucle while{} pour dépiler tous les évènements avant de reprendre la boucle principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    while(SDL_PollEvent(&event))
    {
       switch(event.type)
       {
     
     
     
       } 
     
     
    }

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

Discussions similaires

  1. OpenGL et Caméra
    Par Boubou01 dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 10/02/2011, 18h13
  2. Windows mobile : capture caméra et openGL ES
    Par toukito dans le forum DirectX
    Réponses: 1
    Dernier message: 28/03/2009, 14h01
  3. Réponses: 2
    Dernier message: 04/11/2007, 13h10
  4. [OpenGL][Debutant]bouger la caméra
    Par luckyvae dans le forum OpenGL
    Réponses: 7
    Dernier message: 01/05/2007, 11h01
  5. Problème de caméra/OpenGL
    Par nicl75 dans le forum 3D
    Réponses: 2
    Dernier message: 10/03/2007, 17h40

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