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 :

OpenGL, GLSL, incohérence


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 5
    Par défaut OpenGL, GLSL, incohérence
    Bonjour à tous,
    je me permet de poster ici car je rencontre un petit problème avec GLSL (je suis débutant).
    Dans mon appli OpenGL, en ayant effectué aucune modification sur la matrice ModelView, je la récupère avec glGet et j'obtient bien la matrice identitée. Dans mon fragment shader, je compare la matrice gl_ModelView à la matrice identitée, mais la comparaison me renvoit false =X (je le constate en modifiant la couleur des fragments en fonction du test).

    Voici les différentes parties de code :

    code C :
    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
     
    [... chargement des shader et ouverture fenetre) ]
      glEnable(GL_DEPTH_TEST);
     
      glEnable(GL_CULL_FACE); // me permet de voir l'interieur de la sphere que je dessine plus bas
      glCullFace(GL_FRONT);
     
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(70, (double) 800 / 600, 1., 1000.);
     
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
     
      double mat[16];
      glGetDoublev(GL_MODELVIEW_MATRIX, mat);
      for(int i = 0; i < 16; i++) {
        cout << mat[i] << ", "; // Ici la matrice idéntitée est bien affichée
      }
      cout << endl;
     
      bool loop = true;
      while(loop) {
        SDL_Event e;
        if(SDL_PollEvent(&e)) {
          switch(e.type) {
            case SDL_QUIT :
              loop = false;
              break;
          }
        }
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
        drawSphere(40, 40, 3.); // Fonction que j'ai écrite qui ne modifie pas la matrice MV
     
        glFlush();
        SDL_GL_SwapBuffers();
      }
    [...]
    vertex shader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #version 140
     
    void main() {
      gl_Position = ftransform();
    }
    fragment shader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #version 140
     
    void main() {
      if(gl_ModelViewMatrix == mat4(vec4(1., 0., 0., 0.), vec4(0., 1., 0., 0.), vec4(0., 0., 1., 0.), vec4(0., 0., 0., 1.))) {
        gl_FragColor = vec4(1., 1., 1., 1.);
      } else {
        gl_FragColor = vec4(1., 0., 0., 1.);
      }
    }
    Donc voila, l'interieur de ma sphere est affichée en rouge, ce qui n'est pas cohérent avec le resultat renvoyé par OpenGL dans mon code C :/

    J'espere que quelqun pourra m'aider à comprendre. Merci d'avance ^^

  2. #2
    Membre extrêmement actif

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 408
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 408
    Par défaut
    en général, ne jamais comparer des flottants avec ==, ceci peut conduire à un test faux à cause de la représentation des flottants en mémoire.

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 142
    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 142
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    La réponse de stardeath est très bonne. J'ai déjà rencontré ce problème, et l'utilisation d'un epsilon serai judicieux.
    L'epsilon à utiliser pour être vraiment précis, peut être retrouvé dans le documentation d'OpenGL (la norme).
    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 à l'essai
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 5
    Par défaut
    Mmmh, effectivement le problème pourrait venir de la perte de précision de
    l'arithmétique sur les flottants. En réalité mon problème n'est pas vraiment la :/ si j'ai décidé de faire ce test c'est à cause d'un autre problème. J'essaye de realiser un petit ToonShader en suivant le tutoriel du site lighthouse3d. Pour l'effet Toon pas de soucis, c'est le positionnement de la lumière qui pose problème.

    Voici mon code C :
    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
     
    [... ouverture fenetre + chargement shaders]
      glEnable(GL_DEPTH_TEST);
     
      float direction[4] = {1 / sqrt(3), 1 / sqrt(3), 1 / sqrt(3), 0.};
      glLightfv(GL_LIGHT0, GL_POSITION, direction); // Placement lumiere directionelle : direction (1, 1, 1) et longueur 1
     
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(70, (double) 800 / 600, 1., 1000.);
     
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      gluLookAt(3, 4, 2, 0, 0, 0, 0, 1, 0);
     
      bool loop = true;
      while(loop) {
        SDL_Event e;
        if(SDL_PollEvent(&e)) {
          switch(e.type) {
            case SDL_QUIT :
              loop = false;
              break;
          }
        }
     
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
        drawSphere(40, 40, 1.); // dessin sphere de rayon 1
        drawCoordinateSystem(2.); // dessin systeme de coordonnée
        glBegin(GL_LINES); // dessin d'une ligne representant le rayon de lumiere
          glVertex3d(0., 0., 0.);
          glVertex3d(1., 1., 1.);
        glEnd();
     
        glFlush();
        SDL_GL_SwapBuffers();
      }
    Je place une lumiere directionelle selon la direction (1, 1, 1) avec glLight. Selon la doc OpenGL, la lumiere est placée dans l'espace view (donc multiplié par la matrice ModelView automatiquement). En consequence, voici le code de mon vertex shader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #version 140
     
    out float intensity;
     
    void main() {
      intensity = dot(gl_NormalMatrix * gl_Normal, vec3(gl_LightSource[0].position));
      gl_Position = ftransform();
    }
    Je multiplie la normale associée au sommet par la matrice gl_NormalMatrix afin de la passer dans l'espace view. Problème, voici le resultat :



    On voit que la lumiere ne suit pas le vecteur (1, 1, 1) mais plutot le vecteur (1, 1, -1) (on voit un petit bout de la ligne representant (1, 1, 1)).
    En fait, j'arrive à obtenir le bon resultat quand je ne multiplie pas gl_Normal par gl_NormalMatrix :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #version 140
     
    out float intensity;
     
    void main() {
      intensity = dot(gl_Normal, vec3(gl_LightSource[0].position));
      gl_Position = ftransform();
    }
    et le resultat :
    [IMG=http://img822.imageshack.us/img822/9939/capturesansglnormals.th.png][/IMG]

    Voila je trouve ça illogique =/ je devrais avoir le second resultat lorsque j'applique le premiere shader. Si quelqun pouvait me montrer où je me trompe, je lui en serais reconnaissant ^^ Merci d'avance

Discussions similaires

  1. openGL/GLSL Projection matrix
    Par matador1mas dans le forum OpenGL
    Réponses: 0
    Dernier message: 15/02/2010, 17h04
  2. [OpenGL/GLSL] Utilisation Normal Map
    Par AuraHxC dans le forum OpenGL
    Réponses: 3
    Dernier message: 31/01/2010, 11h45
  3. [OpenGL/GLSL] Texture - Transparence non voulu
    Par AuraHxC dans le forum OpenGL
    Réponses: 19
    Dernier message: 25/01/2010, 16h42
  4. OpenGL/GLSL tout ce qui touche aux transformations
    Par AuraHxC dans le forum OpenGL
    Réponses: 13
    Dernier message: 15/12/2009, 14h55

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