[OpenGL] [SDL2] problème de z-buffer [RéSOLU]

problème de z-buffer [RéSOLU] [OpenGL] [SDL2] - C - Programmation

Marsh Posté le 29-04-2014 à 12:11:11    

Bonjour à vous.
 
Je m'amuse à apprendre à programmer en opengl (et SDL2) et je bloque un peu.
D'abord, du code:

Code :
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <gl/gl.h>
  4. #include <gl/glu.h>
  5. #include <SDL.h>
  6. #define WIDTH 640
  7. #define HEIGHT 480
  8. SDL_Window* main_window = NULL;
  9. void resize_window(int width, int height)
  10. {
  11.     GLfloat ratio;
  12.     if (height == 0) // évite une division par zéro
  13.     {
  14.         height = 1;
  15.     }
  16.     glViewport(0, 0, width, height);
  17.     ratio = (GLfloat)width / height;
  18.     glMatrixMode(GL_PROJECTION);    // matrice de projection
  19.     glLoadIdentity();               // remise à 0
  20.     gluPerspective(45.0f, ratio, 0.1f, 100.0f);
  21.     glMatrixMode(GL_MODELVIEW); // Choisir la matrice de modélisation
  22.     glLoadIdentity(); // Remettre a zéro la matrice de modélisation
  23. }
  24. void dessine_scene()
  25. {
  26.     // rotation
  27.     static GLfloat rot_triangle;
  28.     // fps
  29.     static GLint t0     = 0;
  30.     static GLint frames = 0;
  31.     // effaçage
  32.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  33.     glLoadIdentity(); // remettre à zéro
  34.     // Bouge de 7.0 unités vers l'exterieur de l'écran
  35.     glTranslatef(0.0f, 0.0f, -7.0f);
  36.     // rotation
  37.     glRotatef(rot_triangle, 0.0f, 1.0f, 0.0f);
  38.     glBegin(GL_TRIANGLES);
  39.         glColor3f(1.0f, 0.0f, 0.0f); // rouge
  40.         glVertex3f(  0.0f,  1.0f,  0.0f);
  41.         glVertex3f( -1.0f, -1.0f,  1.0f);
  42.         glVertex3f(  1.0f, -1.0f,  1.0f);
  43.         glColor3f(0.0f, 1.0f, 0.0f); // vert
  44.         glVertex3f(  0.0f,  1.0f,  0.0f);
  45.         glVertex3f(  1.0f, -1.0f,  1.0f);
  46.         glVertex3f(  1.0f, -1.0f, -1.0f);
  47.         glColor3f(0.0f, 0.0f, 1.0f); // bleu
  48.         glVertex3f(  0.0f,  1.0f,  0.0f);
  49.         glVertex3f(  1.0f, -1.0f, -1.0f);
  50.         glVertex3f( -1.0f, -1.0f, -1.0f);
  51.         glColor3f(1.0f, 0.5f, 0.0f); // orange
  52.         glVertex3f(  0.0f,  1.0f,  0.0f);
  53.         glVertex3f( -1.0f, -1.0f, -1.0f);
  54.         glVertex3f( -1.0f, -1.0f,  1.0f);
  55.     glEnd();
  56.     /* Draw it to the screen */
  57.     SDL_GL_SwapWindow(main_window);
  58.     frames++;
  59.     {
  60.         GLint t = SDL_GetTicks();
  61.         if (t - t0 >= 5000)
  62.         {
  63.             GLfloat seconds = (t - t0) / 1000.0;
  64.             GLfloat fps = frames / seconds;
  65.             printf("%d frames in %g seconds = %g FPS\n", frames, seconds, fps);
  66.             t0 = t;
  67.             frames = 0;
  68.         }
  69.     }
  70.     /* move your body */
  71.     rot_triangle  += 0.9f;
  72. }
  73. int main(int N, char* T[])
  74. {
  75.     bool quitte = false;
  76.     bool visible = true;
  77.     SDL_GLContext glcontexte = NULL;
  78.     SDL_Event event;
  79.     // init SDL
  80.     if (SDL_Init(SDL_INIT_VIDEO != 0))
  81.     {
  82.         fprintf(stderr, "SDL, c'est plus fort que toi !\n" );
  83.         SDL_Quit();
  84.         return -1;
  85.     }
  86.     // init OpenGL
  87.     glShadeModel(GL_SMOOTH); // ombrage
  88.     glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // fond noir
  89.     glClearDepth(1.0f); // tampon de profondeur
  90.     glEnable(GL_DEPTH_TEST); // test de pofondeur
  91.     glDepthFunc(GL_LEQUAL);
  92.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // c'est joli tout plein
  93.     // création fenêtre SDL
  94.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  95.     SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  96.     main_window = SDL_CreateWindow("Hellos world !",
  97.                          SDL_WINDOWPOS_UNDEFINED,
  98.                          SDL_WINDOWPOS_UNDEFINED,
  99.                          WIDTH,
  100.                          HEIGHT,
  101.                          SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
  102.     if (main_window == NULL)
  103.     {
  104.         fprintf(stdout, "Échec de création de fenêtre SDL (%s)\n", SDL_GetError());
  105.         SDL_Quit();
  106.         return -1;
  107.     }
  108.     glcontexte = SDL_GL_CreateContext(main_window);
  109.     if (glcontexte == NULL)
  110.     {
  111.         fprintf(stdout, "Échec de création de contexte OpenGL (%s)\n", SDL_GetError());
  112.         SDL_Quit();
  113.         return -1;
  114.     }
  115.     // sync buffer swap with monitor's vertical refresh rate
  116.     SDL_GL_SetSwapInterval(1);
  117.     /* resize the initial window */
  118.     resize_window(640, 480);
  119.     while (quitte == false)
  120.     {
  121.         while (SDL_PollEvent(&event))
  122.         {
  123.             switch (event.type)
  124.             {
  125.                 case SDL_WINDOWEVENT:
  126.                     switch(event.window.event)
  127.                     {
  128.                         case SDL_WINDOWEVENT_RESIZED:
  129.                             /* handle resize event */
  130.                             resize_window(event.window.data1, event.window.data2);
  131.                             break;
  132.                         case SDL_WINDOWEVENT_HIDDEN:
  133.                             visible = false;
  134.                             break;
  135.                         case SDL_WINDOWEVENT_SHOWN:
  136.                             visible = true;
  137.                             break;
  138.                     }
  139.                     break;
  140.                 case SDL_KEYDOWN:
  141.                     if (event.key.keysym.sym == SDLK_ESCAPE)
  142.                         quitte = true;
  143.                         break;
  144.                 case SDL_QUIT:
  145.                     quitte = true;
  146.                     break;
  147.                 default:
  148.                     break;
  149.             }
  150.         }
  151.         if (visible == true)
  152.         {
  153.             dessine_scene();
  154.         }
  155.     }
  156.     SDL_DestroyWindow(main_window);
  157.     SDL_GL_DeleteContext(glcontexte);
  158.     return 0;
  159.     (void)N; (void)T;
  160. }


 
 
Ça compile sur tous projets incluant SDL2.
 
Et comme vous voyez, la pyramide est bizarre.
J'ai l'impression que les triangles restent à leur plan d'origine, un problème de Z-BUFFER en gros.
Comment régler ça ?
 
 
Merci  :jap:


Message édité par Tangrim le 29-04-2014 à 14:07:38

---------------
Des Bisous et des nounours ! | Internet 2025 | Dungeon-Generator
Reply

Marsh Posté le 29-04-2014 à 12:11:11   

Reply

Marsh Posté le 29-04-2014 à 13:25:17    

j'ai pas vu le résultat, et ce que tu décris est un peu léger.
A tout hasard : es-tu sur de ne pas voir le backface des triangles, pour avoir cette impression ? Parce que pour l'instant, j'ai du mal à imaginer comment tu aurais un souci de z-buffer.


---------------
last.fm
Reply

Marsh Posté le 29-04-2014 à 13:35:13    

La pyramide tourne mais le triangle orange reste toujours au premier plan, le bleu au second plan, le vert au troisième et le rouge au fond.

 

Rouge et vert devraient être au premier plan :
http://hfr-rehost.dev.syn.fr/self/fa5eaa41f3bf45e1ae1fa235e536cb781d06a48c.png

 

Vert et bleu seulement visible, or le orange, qui est derrière, recouvre le bleu.
http://hfr-rehost.dev.syn.fr/self/f503630aaa25ed61ff646a266008623066bbc8af.png

 

Qu'entends tu par backface ?


Message édité par Tangrim le 29-04-2014 à 13:44:03

---------------
Des Bisous et des nounours ! | Internet 2025 | Dungeon-Generator
Reply

Marsh Posté le 29-04-2014 à 13:53:04    

non, effectivement, tu as raison, c'est un problème de z-buffer, il semblerait :o Et effectivement, si la dernière face affichée reste par-dessus toutes les autres, ca semble vouloir dire que ton z-buffer n'est pas actif du tout, même.

 

J'aurais tendance à me demander si le SDL_CreateWindow ne devrait pas être fait avant d'initialiser tes features OpenGL. J'imagine que tu t'es appuyé sur un tutoriel, non ?

 

Le point que tu soulèves (le Z au même niveau pour toutes les faces) pourrait arriver si ton front clip plane et back clip plane sont mal définis. J'oserais espérer que les valeurs par défaut ne te causent pas de souci, mais tu peux toujours regarder de ce côté là aussi. La précision de ton Z-Buffer est définie certes par le nombre de bits que tu as, mais plus tu as une longue distance à couvrir avec tes 24 bits, moins ton z-buffer est précis localement, ca pourrait expliquer que tous tes triangles puissent se trouver tous sur une même valeur de Z.

 


Juste pour info :
Ma théorie sur les backface, c'était que tu afficherais peut-être le mauvais côté de ta pyramide, mais visiblement, tu veux voir les deux côtés dans ton cas.
Le côté visible quand tu n'affiches que l'un est déterminé par la normale à chaque triangle qui, si elle n'est pas donnée, est calculée par OpenGL automatiquement. La normale va être dans un sens ou dans l'autre suivant l'ordre des points que tu donnes. C'est une erreur assez courante de ne pas donner ses points dans le bon ordre quand on ne donne pas la normale à la face.

 


Edit : non, effectivement, la doc SDL indique clairement l'ordre d'initialisation que tu fais ... Tu peux peut-être tester les codes de retour de tes appels à SDL_GL_SetAttribute pour vérifier que tout se passe bien ? Tu dois aussi sans doute pouvoir regarder ce qui est dans ton contexte openGL pour voir si tout a bien été appliqué ?

 

Message cité 1 fois
Message édité par theshockwave le 29-04-2014 à 14:06:41

---------------
last.fm
Reply

Marsh Posté le 29-04-2014 à 14:06:57    

theshockwave a écrit :


J'aurais tendance à me demander si le SDL_CreateWindow ne devrait pas être fait avant d'initialiser tes features OpenGL. J'imagine que tu t'es appuyé sur un tutoriel, non ?


Presque, je suis les tutoriels de Nehe en adaptant à SDL2.
 
C'était presque ça, le SDL_GLContext devait être créé avant l'initialisation openGL, tu m'as mis sur la voie. Merci beaucoup  :jap:


---------------
Des Bisous et des nounours ! | Internet 2025 | Dungeon-Generator
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed