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 :

comment faire le z-sorting ?


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut comment faire le z-sorting ?
    salut

    comment peux-t-on faire un "z-sorting" ou "hierarchical depth buffering" des objects d'une scene opengl ?

    merci

    dav

  2. #2
    Expert confirmé
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Par défaut
    OpenGL n'a pas prévu cette fonctionnalité. Il faut que tu le fasse toi même sur tes structures de données avant de lancer la restitution avec OpenGL. Tu dois prendre un algo générique et l'appliquer à tes structure de données. Une fois trié, tu pourra utilisé OpenGL pour rendre tes objets.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Par défaut
    en fait ce que tu peux faire pour trier tes objets suivant l'axe Z c'est d'utiliser la fonction glGetMatrix(GL_MODELVIEW_MATRIX) pour récupérer le composant Z dans la matrice, qui se trouve à cet endroit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
         [ _, _, _, _,
           _, _, _, _,
           _, _, _, _,
           _, _, Z, _ ];
    en fait tu peux le faire en 2 passes : 1) tu effectue les déplacement (glTranslate, glRotate) sur tous tes objets comme si tu allais les afficher, mais à la place tu récupères la matrice que tu associe avec chaque objet. 2) tu trie suivant le composant Z (z-sorting). 3) tu affiches sans DEPTH_BUFFER suivant l'ordre précédant, en réutilisant la matrice pour positionner l'objet avec glLoadIdentity(); glMultMatrix(mat);

    voici une petite démo qui utilise ce principe, c'est pas du C, mais ça devrait quand même être lisible pour le principe.

    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    open GL
    open Glu
    open Glut
     
    let anglex = ref 0.
    let angley = ref 0.
     
    (* display cubes z-sorting *)
     
    let assoc_color =
      let tbl = Hashtbl.create 30 in
      let get = Hashtbl.find tbl in
      fun i j k ->
      let ndx = (i, j, k) in
      try get ndx
      with Not_found ->
        let r,g,b =
          match Random.int 4 with
          | 0 -> (1.0, 0.0, 0.0)
          | 1 -> (0.1, 0.8, 0.0)
          | 2 -> (0.1, 0.4, 1.0)
          | 3 -> (0.7, 0.0, 0.6)
          | _ -> raise Exit
        in
        Hashtbl.add tbl ndx (r,g,b);
        (r,g,b)
    ;;
     
     
    let mat_get_z = function
        [| [| _; _; _; _ |];
           [| _; _; _; _ |];
           [| _; _; _; _ |];
           [| _; _; z; _ |]; |] -> z
      | _ ->
          invalid_arg "matrix"
    ;;
     
    let mat_get_y = function
        [| [| _; _; _; _ |];
           [| _; _; _; _ |];
           [| _; _; _; _ |];
           [| _; y; _; _ |]; |] -> y
      | _ ->
          invalid_arg "matrix"
    ;;
     
    let assoc_vis, step_vis =
      let tbl = Hashtbl.create 30 in
      let get = Hashtbl.find tbl in
      (fun i j k ->
         let ndx = (i, j, k) in
         try get ndx
         with Not_found ->
           let vis = Random.bool() in
           Hashtbl.add tbl ndx (vis);
           (vis)),
      (fun i j k ->
         if (Random.int 3000) = 0 then
           let ndx = (i, j, k)
           and vis = Random.bool() in
           Hashtbl.replace tbl ndx vis)
    ;;
     
    let gradient_switch = ref true
    let gradient_toggle () =
      if (Random.int 30_000_000) < 100_000 then
        gradient_switch := not(!gradient_switch);
    ;;
     
    let display_cubes_z_sorting n () =
      if !gradient_switch
      then glClearColor 0.3 0.25 0.2  0.0
      else glClearColor 0.4 0.2 0.0  0.0;
     
      glClear [GL_COLOR_BUFFER_BIT];
      glLoadIdentity();
     
      glTranslate 0. 0. (-. 4.0);
     
      glRotate (!angley) 1.0 0.0 0.0;
      glRotate (!anglex) 0.0 1.0 0.0;
     
      glScale 0.5 0.5 0.5;
     
      let prop = ref [] in
     
      let step = 0.8 in
      let half = step *. (float(pred n)) /. 2.0 in
     
      for i=0 to pred n do
        for j=0 to pred n do
          for k=0 to pred n do
            let r,g,b = assoc_color i j k
            and vis = assoc_vis i j k
            and x = ((float i)*. step) -. half
            and y = ((float j)*. step) -. half
            and z = ((float k)*. step) -. half in
     
            step_vis i j k;
     
            prop := (x,y,z, r,g,b, vis) :: !prop;
          done;
        done;
      done;
     
      let item_get_mat (x,y,z, r,g,b, vis) =
        glPushMatrix();
          glTranslate x y z;
          let m = glGetMatrix Get.GL_MODELVIEW_MATRIX in
        glPopMatrix();
        (m, r,g,b, vis)
      in
      let items_prop = List.map (item_get_mat) !prop in
     
      (* sort the items along the Z axis *)
      let z_sort_vert (m1,_,_,_,_) (m2,_,_,_,_) =
        let z1 = mat_get_z m1
        and z2 = mat_get_z m2 in
        if z1 < z2 then -1 else 1
      in
      let sorted_items = List.sort z_sort_vert items_prop in
     
      let gradient (m, r,g,b, vis) =
        let y = mat_get_y m in
        let r = sqrt(half ** 2. *. 3.) *. 0.5 in
        let v = y +. r in
        let v = v /. r /. 2. in
        let v = v *. 1.4 in
        let r = v
        and b = 1.0 -. v
        and g = 0.0 in
        (m, r,g,b, vis)
      in
      let sorted_items =
        if !gradient_switch
        then List.map (gradient) sorted_items
        else sorted_items
      in
      gradient_toggle();
     
      let draw_item (m, r,g,b, vis) =
        if vis then
        begin
          glLoadIdentity();
          glMultMatrix m;
     
          glScale 0.5 0.5 0.5;
          glColor3 0.0 0.0 0.0;
          glutSolidCube 1.0;
     
          glColor3 r g b;
          glutSolidCube 0.89;
          glColor3 1.0 1.0 1.0;
          glutWireCube 0.89;
        end
      in
      List.iter (draw_item) sorted_items;
     
      glutSwapBuffers();
    ;;
     
    (* timers *)
     
    let sleep_ticks = 16 ;;
     
    let rec rot_timer ~value =
      angley := !angley +. 0.2;
      anglex := !anglex +. 0.02;
      glutTimerFunc ~msecs:sleep_ticks ~timer:rot_timer ~value:0;
      glutPostRedisplay();
    ;;
     
    let time = ref 0
     
    let rec time_tracker ~value =
      incr time;
      glutTimerFunc ~msecs:100 ~timer:time_tracker ~value:0;
    ;;
     
    let display = display_cubes_z_sorting 6 ;;
     
    (* reshape *)
     
    let field = 10. ;;
     
    let reshape ~width:w ~height:h =
      glViewport 0 0 w h;
    ;;
     
    let keyboard ~key ~x ~y =
      match key with
      | 'q' | '\027' -> exit 0;
      | _ -> ()
    ;;
     
    let gl_init() =
      glShadeModel GL_FLAT;
      glDisable GL_DEPTH_TEST;
      glClearColor 0.4 0.0 0.0  0.0;
    ;;
     
    (* main *)
    let () =
      Random.self_init();
     
      ignore(glutInit Sys.argv);
     
      glutInitDisplayMode [GLUT_RGB; GLUT_DOUBLE]; (* dont use GLUT_DEPTH *)
      glutInitWindowSize 640 480;
      ignore(glutCreateWindow "demo");
     
      glutFullScreen();
      glutSetCursor GLUT_CURSOR_NONE;
      gl_init();
     
      (* Parameters of perspective projection *)
      glMatrixMode GL_PROJECTION;
      glLoadIdentity();
      gluPerspective ~fovy:60.0 ~aspect:1.0 ~zNear:0.5 ~zFar:100.0;
      glMatrixMode GL_MODELVIEW;
     
      (* callbacks *)
      glutDisplayFunc ~display;
      glutKeyboardFunc ~keyboard;
      glutReshapeFunc ~reshape;
      glutTimerFunc ~msecs:sleep_ticks ~timer:rot_timer ~value:0;
      glutTimerFunc ~msecs:100 ~timer:time_tracker ~value:0;
     
      glutMainLoop();
    ;;

  4. #4
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Par défaut
    Salut
    t'as fais une petite erreur je crois la composante Z de translation dans une matrice affine est dans la derniere colonne.

    [_,_,_,_]
    [_,_,_,_]
    [_,_,_,Z]
    [_,_,_,_]

    Du coup quand on multipli par un vecteur [x,y,z,1] le Z s'ajoute a la composante z du vecteur resultant

    ++

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

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 594
    Par défaut
    Citation Envoyé par goast Voir le message
    la composante Z de translation dans une matrice affine est dans la derniere colonne.
    - en Direct3D les matrices sont "row major" et dans ce cas les composantes de translation sont les 3 premières valeurs de la dernière ligne
    - en OpenGL les matrices sont "column major" donc les composantes de translation sont dans la dernière colonne comme tu le fais remarquer
    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.

  6. #6
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Par défaut
    juste une question pour fgjdfgjdgj
    C'est quoi cette langage? Du Caml?

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 32
    Par défaut
    en fait mon indication donnait la position de la composante Z telle qu'on la récupère dans un tableaux avec la fonction openGL en C, c'est à dire à l'indice 14 si je ne m'abuse :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    GLdouble
    get_modelview_matrix_z(void) {
        GLdouble mat[16];
        glGetDoublev(GL_MODELVIEW_MATRIX, mat);
        return mat[14];
    }

    pour le langage, oui c'est du Caml (l'implémentation OCaml pour être précis)

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/03/2016, 21h22
  2. Comment faire en sorte que le prog se fasse répéter
    Par LeonHONORE dans le forum Pascal
    Réponses: 3
    Dernier message: 20/04/2008, 22h41
  3. sorte de "deroutage" video, comment faire ?
    Par dalmas dans le forum Vidéo
    Réponses: 1
    Dernier message: 20/09/2007, 13h35
  4. Réponses: 3
    Dernier message: 02/08/2007, 18h06
  5. Réponses: 3
    Dernier message: 27/04/2006, 09h03

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