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 :

Z buffer


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Fa7
    Fa7 est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Par défaut Z buffer
    Bonjour,
    Je voudrais afficher le Z buffer (en niveaux de gris) d'une scene...
    Pour cela, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      GLfloat * depth = malloc(WIDTH * HEIGHT *sizeof(GL_FLOAT)); 
      glReadPixels (0, 0, WIDTH, HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
      glDrawPixels(WIDTH, HEIGHT, GL_RED, GL_FLOAT, depth);
      glDrawPixels(WIDTH, HEIGHT, GL_GREEN, GL_FLOAT, depth);
      glDrawPixels(WIDTH, HEIGHT, GL_BLUE, GL_FLOAT, depth);
    Mais mon image est toute rouge...

    J'ai bien activé DEPTH_TEST..
    Si j'affiche les valeurs de depth, j'ai plein de 1.000 (normal, c'est le fond), et le reste des valeurs sont tres proches de 1.0 (0.99835 par exemple)..

    Comment faire alors pour afficher le z buffer ?

    Merci d'avance pour votre aide !

  2. #2
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 573
    Par défaut
    essayes de d'abord regarder toutes tes valeurs et de prendre le min et le max pour ensuite l'échelonner avant de l'afficher

    sinon pour ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    glDrawPixels(WIDTH, HEIGHT, GL_RED, GL_FLOAT, depth);
    glDrawPixels(WIDTH, HEIGHT, GL_GREEN, GL_FLOAT, depth);
    glDrawPixels(WIDTH, HEIGHT, GL_BLUE, GL_FLOAT, depth);
    je ne pense pas que cela fonctionne, il faut que tu joues avec le masque de couleur : glColorMask(bool r, bool g, bool b, bool a)

    d'après la doc opengl, glDrawPixels avec un format GL_RED par exemple affichera un point rouge et mettra les autres composantes à 0, donc tu dessines 3 fois le même pixel dans ton cas (je trouve bizarre que le résultat soit rouge et non pas bleu par contre)
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  3. #3
    Fa7
    Fa7 est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Par défaut
    Ok en échelonnant ca marche !! merci !!
    le seul truc c'est que si j'ai un seul objet, qu'il soit tout pres ou loin de la camera, il sera vu pareil...

    en fait ce que je veux faire c'est colorer les objets en fonction de leur distance par rapport a la camera ...
    mon code actuel est le suivant :

    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
     
      // Recuperation de la profondeur
      GLfloat * depth = malloc(WIDTH * HEIGHT *sizeof(GL_FLOAT)); 
      glReadPixels (0, 0, WIDTH, HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
     
      float min, max;
      min = depth[0];
      max = depth[0];
      for (i = 0; i < WIDTH * HEIGHT; i++) {
        if (depth[i] < min)
          min = depth[i];
        if (depth[i] > max)
          max = depth[i];
      }
     
      // Coloration
      GLfloat *rgb = malloc (3 * WIDTH * HEIGHT * sizeof (GL_FLOAT));
      glReadPixels (0, 0, WIDTH, HEIGHT, GL_RGB, GL_FLOAT, rgb);
      for (i = 0; i < WIDTH * HEIGHT; i++) {
        depth[i] = (depth[i] - min) / (max - min);
        if (depth[i] > 0 && depth[i] < 0.5)
          rgb[3 * i] = 1.0;
        if (depth[i] >= 0.5 && depth[i] < 0.8)
          rgb[3 * i + 1] = 1.0;
        if (depth[i] >= 0.8 && depth[i] < 1.)
          rgb[3 * i + 2] = 1.0;
      }
     
      glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_FLOAT, rgb);
    Le seul probleme est que tout cela ne dépend pas de la réelle distance a la camera, mais de la distance relative entre les objets ... (a cause de l'echelonnage justement..)

  4. #4
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 573
    Par défaut
    bon alors 2 choses :

    la première c'est ta réinitialisation de ton depth buffer, il est vidé à 0 ou à 1 ? c'est pour savoir si un objet proche sera noir ou coloré

    la seconde c'est de laisser tomber l'échelonnage pour obtenir ce que tu veux, j'imagine que tu utilises gluPerspective pour initialiser ta projection, auquel cas regardes du côté du znear et du zfar, plus l'intervalle qui les séparent est grand plus grand sera le nombre de profondeurs à coder entre 0 et 1 par opengl

    style tu affiches un cube avec znear = 0.1 et zfar = 10000
    ça fait 100000 valeurs entières à coder mais si ton cube a une taille de 1 bah le dégradé de couelurs sera quasi invisible

    si tu gardes znear à 0.1 mais tu met zfar à 100 tu devrais déjà voir une grosse différence
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  5. #5
    Fa7
    Fa7 est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Par défaut
    mon glClearDepth est à 1..
    Le problème c'est que je vais travailler sur des grandes scènes.. Donc je dois avoir un zFar assez grand pour voir assez loin...
    J'ai trouvé une réponse sur ce sujet sur http://www.opengl.org/resources/faq/...epthbuffer.htm:

    12.080 There is no way that a standard-sized depth buffer will have enough precision for my astronomically large scene. What are my options?

    The typical approach is to use a multipass technique. The application might divide the geometry database into regions that don't interfere with each other in Z. The geometry in each region is then rendered, starting at the furthest region, with a clear of the depth buffer before each region is rendered. This way the precision of the entire depth buffer is made available to each region.
    Je vais chercher dans cette direction...

    un truc étrange, c'est que j'ai essayé de colorer en rouge les pixels proches et en vert les pixels loins (respectivement, depth < 0.5 et depth > 0.5)
    le résultat est surprenant:


    La valeur < 0.5 est vraiment très proche de la camera !

    [edit] : je viens de voir pourquoi sur le meme site...

    Merci pour la reponse en tout cas...

  6. #6
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 573
    Par défaut
    Citation Envoyé par Fa7
    mon glClearDepth est à 1..
    tu peux initialiser ton depthbuffer à 0, il faut que tu chagne le depthtest à GL_GREATER dans ce cas

    un truc étrange, c'est que j'ai essayé de colorer en rouge les pixels proches et en vert les pixels loins (respectivement, depth < 0.5 et depth > 0.5)
    le résultat est surprenant:

    [edit] : je viens de voir pourquoi sur le meme site...
    Tu pourrais nous dire pourquoi ?
    *a la flemme d'aller voir su rle site*
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  7. #7
    Fa7
    Fa7 est déconnecté
    Membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Par défaut
    En fait, l'oeil réagit de la meme facon... raprocher un objet de 10cm ne va pas avoir le meme effet si l'objet est à 20cm ou à 15m de l'oeil... la difference de taille sera bien plus grande pres de l'oeil...
    ici, c'est pareil, plus on s'eloigne de l'oeil et plus la distance doit être grande pour être percue...

    Ca c'est l'explication cognitive..

    Apres, l'explication mathématique ...
    Pendant la phase de la projection ("perspective divide"), toutes les valeurs (XYZ) sont divisées par W, qui représente la distance par rapport à l'oeil... ainsi, plus W augmente, plus 1/W tend vers 0.. C'est pour cela que plus un objet est loin, plus il est petit

    mais comme 1/W n'est pas linéaire (la courbe n'est pas une droite, mais est une courbe qui descend très vite proche de 0, puis qui se rapproche de 0 lentement), une difference de Z de 1 ne sera pas percue de la meme manière si W est pres ou loin de l'oeil...
    Par exemple, une difference de 0.1 en z avec W = 0.1 (donc pres de l'oeil) donne 0.1 / 0.1 = 1
    Alors que si W = 100 (donc loin), on a 0.1/100 = 0.001... On voit donc plus la difference de distance pres que loin...

    Je ne sais pas si je me suis fait comprendre... C'est pas tres facile à expliquer mathématiquement....

    Voila !!

  8. #8
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 573
    Par défaut
    Ok pour les explications, j'ai bien compris le principe qui se cache derrière la phase de projection comme cela

    Merci beaucoup d'avoir éclairé ma lanterne, tes explications ont été très claires
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  9. #9
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2003
    Messages : 2 574
    Par défaut
    rhaaa merci... je sait enfin l'explication mathematique de pourquoi le ZBuffer n'est pas "mappé" lineairement...
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

Discussions similaires

  1. stencil buffer
    Par patapetz dans le forum OpenGL
    Réponses: 6
    Dernier message: 26/02/2004, 17h23
  2. A propos depth buffer
    Par j.yves dans le forum DirectX
    Réponses: 1
    Dernier message: 03/12/2002, 00h41
  3. Vider le buffer du clavier
    Par flavien tetart dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 12/07/2002, 08h35
  4. Affichage en passant par un buffer...
    Par Sirotilc dans le forum MFC
    Réponses: 5
    Dernier message: 27/05/2002, 21h00
  5. Alpha blending et Z-buffer directx 8
    Par Cesar4 dans le forum DirectX
    Réponses: 1
    Dernier message: 23/05/2002, 12h58

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