[OPENGL] gl_depth_test

gl_depth_test [OPENGL] - Programmation

Marsh Posté le 26-07-2001 à 16:00:22    

Impossible d'utiliser cette option sans que mon image déconne.
Je m'explique:  J'ai une belle sphère tout propre
J'active le depth_test. Je me retrouve avec un sphère toute trouée de partout ! :??:
 
A quoi est-ce du ?

Reply

Marsh Posté le 26-07-2001 à 16:00:22   

Reply

Marsh Posté le 26-07-2001 à 16:26:08    

si tu pouvais être un poil plus spécifique ...
 
enfin si tu ne fais qu'afficher une sphère tu n'as pas besoin de zbuffer :)
 
ça peut venir de la valeur de ton znear à zéro, ou du fait que tu n'effaces pas le zbuffer : glclear(color | depth).

Reply

Marsh Posté le 26-07-2001 à 16:44:28    

Le problème ne vient pas de la sphère puisqu'il se passe exactement la même chose avec de simple surface qui se coupent.
 
voici le code:
**************************************************
**************
#include<gl/glut.h>
#include<math.h>
 
 
int WindowName;  
double a=0;
 
void Reshape(int width, int height)  
{    
 glViewport(0,0,width,height);  
 glMatrixMode(GL_PROJECTION);  
 glLoadIdentity();  
 gluPerspective(45, float(width)/float(height), 0, 100);  
 glMatrixMode(GL_MODELVIEW);  
}
 
 
void Draw()  
{  
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
 glMatrixMode(GL_MODELVIEW);  
 glLoadIdentity();
 gluLookAt(8,8,8,0,0,0,0,1,0);
 
 glRotated(-a,0,1,0);
 a+=0.1;
 
 glBegin(GL_TRIANGLES) ;
 glColor3f(0.0F,0.0F,1.0F) ;
 glVertex3f(1.0F,-1.5F,-0.5F) ;
 glVertex3f(1.5F,1.5F,0.5F) ;
 glVertex3f(-1.1F,-0.2F,0.2F) ;
 glColor3f(0.0F,1.0F,0.0F) ;
 glVertex3f(-1.0F,-1.5F,-0.5F) ;
 glVertex3f(-1.5F,1.5F,0.5F) ;
 glVertex3f(0.5F,-0.5F,0.2F) ;
 glColor3f(1.0F,0.0F,0.0F) ;
 glVertex3f(-1.2F,1.3F,-0.5F) ;
 glVertex3f(1.2F,1.1F,0.5F) ;
 glVertex3f(0.1F,-0.5F,0.3F) ;
 glEnd() ;  
 glutSwapBuffers();
 glutPostRedisplay();
}
 
 
void InitGL()
{
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_COLOR_MATERIAL);
}
 
 
int main (int argc, char *argv[ ], char *envp[ ])
{    
 glutInit(&argc, argv);  
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);  
 glutInitWindowSize(640,480);
 WindowName = glutCreateWindow("test" );  
 glutReshapeFunc(Reshape);
 glutDisplayFunc(Draw);
 InitGL();
 glutMainLoop();
 return 0;  
}
 
****************************************************************
 
 
Si je n'active pas le gl_depth_test, ca fonctionne (mais bon, ça ne ressemble à rien...).
Si je l'active, ca déconne... :(

Reply

Marsh Posté le 26-07-2001 à 16:53:00    

>> gluPerspective(45, float(width)/float(height), 0, 100);  
 
qu'est-ce que je disais sur le znear ....  
 
..., 0.1f, 100); par ex.

Reply

Marsh Posté le 26-07-2001 à 17:02:10    

Mercciiiiii ! :)
 
Euh... Tu pourais pas par la même occasion me dire c'est quoi ce znear ?
Et pourquoi mettre "f" derrière ?  (je suppose que c'est pour indiquer que c'est un float mais pourquoi est-ce nécessaire de l'indiquer là?)
 
 
Ps:  désolé pour ces questions d'un niveau très... "bof"... ;)

Reply

Marsh Posté le 26-07-2001 à 17:16:54    

no pb !
 
quand tu tapes un nombre flottant en C, comme 1.2, 3.1415926, etc ... par défaut il considère que c'est un double. le 'f' précise au compilo qu'il faut traiter le nombre à virgule comme un flottant, c'est tout.
 
float f = 1.6; // affichera un warning genre 'perte de précision'
float f = 1.6f; // ok
 
tu as des commandes (#pragma) pour enlever ce genre de warnings si tu n'as pas envie de taper le 'f' à chaque fois.
 
le znear, c'est le plan qui coupe tes objets quand tu es devant la caméra. tes objets sont transformés dans le repère caméra afin de pouvoir être projetés à l'écran puis rasterisés. maintenant, imagine une face très grande qui traverse la caméra. projeter les points 3d sur le plan 2d de la caméra (situé en z=0) donnera n'importe quoi : les points de la face sont situés de part et d'autre du plan de la caméra.
 
solution : découper les faces avec un plan de clipping, juste avant ce fameux z=0. t'imagines un couteau (le znear) qui coupe ta face juste devant le plan de la caméra. du coup les points de la face coupée sont maintenant situés du même côté de la caméra, on peut donc les projeter. en interne, de nouveaux triangles sont recrées, les coordonnées de mapping sont recalculées, etc ...
 
et le '100' c'est le zfar, le plan de clipping qui fait la même chose mais dès que les objets sont trop loin.
 
pour bien comprendre tout ça, cherche un peu sur le net, la doc de directx est vraiment pas mal aussi.  
 
c'est bon ? :)

Reply

Marsh Posté le 26-07-2001 à 17:18:54    

et, j'oubliais : si ton znear est égal à 0, le renderer essaye lors du calcul d'intersection de diviser par 0. donc, le plantage que tu avais.

Reply

Marsh Posté le 26-07-2001 à 17:41:52    

Détrompe toi, ça ne plantait pas... :)
Ca faisait juste une image trop artistique à mon gout ;)
 
et si je dépasse le point 0.1, ca va de nouveau déconner ???
 
Sinon, pour le zfar, si j'ai bien compris tes propos, ca consiste à poser une limite audelà de laquelle tout ce qui se trouve plus loin est "transformé" en une image de fond, c'est bien ça?

Reply

Marsh Posté le 26-07-2001 à 18:01:36    

:) pour le znear, ça dépend de la taille de ton monde, de la précision souhaitée, etc ... ensuite, il y a d'autres problèmes qui rentrent en jeu, car un znear tout petit devant un zfar très grand va poser des problèmes de précision de zbuffer. là j'ai dit 0.1 car c'est la première valeur flottante > 0 qui m'est venue à l'esprit, en pratique c'est pas ça. tu peux avoir un zfar de 10000 avec un znear de 100, ou encore un zfar de 3 et un znear de 0.3. ça dépend de ton monde ! en fait il faut faire gaffe au rapport zfar/znear.
 
donc si tu dépasses ( < 0.1 ) ça risque de déconner, vi, parce qu'il y aura l'imprécision du zbuffer ET l'imprécision des flottants. en gros t'amuses pas à mettre 0.000000000001f :D fais des tests pour voir ce qui va bien sur le genre de monde que tu crées.
 
pour le zfar, ça ne 'transforme' pas en image de fond, ça fait la même chose que le znear mais pour le ... zfar :) imagine le même couteau qui coupe ton cube, tu ne verras que la partie du cube qui est située entre le znear et le zfar.  
 
en pratique, le zfar sert à gicler les objets qui sont trop loin. il définit également, comme dit plus haut, la précision de ton zbuffer.

Reply

Marsh Posté le 26-07-2001 à 18:12:01    

capich, merci bcp :)
 
Mais dans ce cas, comment faire pour avoir une longue portée de vue tout en étant pas aveugle comme une taupe pour tout ce qui est proche ?
 
=> genre je me balade dans l'esapce, j'aimerais pouvoir voir le solei et la lune à la fois ! ;)
 
Est-ce possible ?

Reply

Marsh Posté le 26-07-2001 à 18:12:01   

Reply

Marsh Posté le 26-07-2001 à 18:20:00    

tu mets le doigt sur un problème épineux. je n'en sais rien. je te laisse chercher !
 
déjà, va bidouiller ton znear et ton zfar avant de vouloir contrôler l'univers :)

Reply

Marsh Posté le 26-07-2001 à 18:25:45    

argh ! :crazy:
 
Pas coooolllll l'opengl ! ;)
 
 
voilà qui m'érite un nouveau post ! ;)
 
 
Quoiqu'il en soit, merci beaucoup pour l'aide que tu m'as apporté Youdoncare :jap:

Reply

Marsh Posté le 26-07-2001 à 18:42:57    

Euh... en fait j'ai toujours un problème avec le gl_depth_test...
 
avec un znear/zfar à 0.1f/100.0f
si je n'active pas le depth_test, ca marche impec
si je l'active, le zfar, bien qu'inchangé dans le code, tombe à 20 :(
 
 
Je ne comprends pas pq...

 

[edtdd]--Message édité par Majca Jalasu--[/edtdd]

Reply

Marsh Posté le 26-07-2001 à 18:52:35    

? c'est quoi qui tombe à 20 ? et tu fais comment pour le mesurer ?

Reply

Marsh Posté le 26-07-2001 à 23:10:54    

tombe à 20 => j'ai fais un compteur qui m'indique la coordonnée z après chaque déplacement.
=> en mettant un surface quelconque en z=0, la surface n'est plus visible dès que je dépase z=20 ou z=-20.
 
Bref, ça se comporte comme si mon zfar était à 20 alors qu'il est à 100.
 
Enfin... la surface ne disparait pas bêtement, en fait, il y a quelques restes qui subsistent jusqu'à ce que je dépasse les z=100 ou z=-100.
 
=> prob quelque part.
 
 
En chipotant, je suis parvenu à arranger le prob il y a de ça 2 minutes, mais je ne comprends pas le pourquoi du comment.
 
 
Je m'explique.
Jusqu'à maitenant, j'activais tout simplement le gl_depth_test et ça déconnait.
Now, j'ai rajouté "glDepthFunc(GL_LEQUAL);" et la, miracle, ça marche.
 
Pourquoi? qu'est ce que ça fait?  Je ne comprends pas... :(

Reply

Marsh Posté le 27-07-2001 à 12:38:52    

>>tombe à 20 => j'ai fais un compteur qui m'indique la coordonnée z après chaque déplacement.  
>>=> en mettant un surface quelconque en z=0, la surface n'est plus visible dès que je dépase z=20 ou z=-20.  
 
hein ? ton compteur marche comment, indique quoi, et surtout dans quel repère ?
 
et oui, il faut que tu précises la fonction de comparaison pour le zbuffer .... *hum* ... normal que ça plante sinon :)

Reply

Marsh Posté le 27-07-2001 à 13:27:20    

Ben je me suis pas cassé la tête pour le compteur...
 
=> Je commence en (0,0,5)  (regard tourné vers (0,0,0))
dès que je presse la touche "flèche arrière", j'incrémente de 1 ma coordonnée en z et j'affiche sa valeur.
 
Le tout me donne un "compteur" m'indiquant à quelle distance je suis de la surface.

Reply

Marsh Posté le 27-07-2001 à 13:35:13    

haaa ok, donc tu ne connais absolument rien en 3d. fallait le dire tout de suite :D
 
va lire une bonne doc sur les repères & co ... cherche sur www.google.com (de préférence en anglais, la recherche, tu trouveras plus de trucs).

Reply

Marsh Posté le 27-07-2001 à 14:12:41    

A ce point là ? :D mdr
J'ai effectivement commencé l'opengl il y a de cela 2 jours ;)
 
 
En fait, ce que je cherche à faire c'est un espace 3d dans lequel je peux me balader.
Je ne sais pas si j'ai choisis la bonne méthode, mais j'ai fais un petit machin qui m'a l'air de plus ou moins fonctionner.
Seulement voilà, je lis partout qu'il faut utiliser les matrices... et moi ben... zéro matrices ;)
Pourtant ça m'a l'air de fonctionner...
 
Si quelqu'un pouvait y jetter un coup d'oeil et me dire si c'est réellement plus simple par matrice, je lui en serais extrèmement reconnaissant :)
 
 
**************************************************
**
 
#include<gl/glut.h>
#include<stdio.h>
#include<math.h>
 
 
int LightPos[4] = {0,0,3,1};
int MatSpec [4] = {1,1,1,1};  
 
 
int WindowName;  
 
double a=0;
const double PI = acos (-1.0);
double rad;
double px=0.0, py=1.0, pz=20.0;
double vx=0.0, vy=0.0, vz=0.0;
double savex=vx, savey=vy;
double angle_x, angle_y;
double sensibilite=1.0;
double vitesse=0.1;
 
 
void Reshape(int width, int height)  
{    
 glViewport(0,0,width,height);  
 glMatrixMode(GL_PROJECTION);  
 glLoadIdentity();  
 gluPerspective(45.1f, float(width)/float(height), 0.1f, 100.0f);
 glMatrixMode(GL_MODELVIEW);
}
 
 
void Draw()  
{  
 glMaterialiv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec);  
 glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,100);
 
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
 glMatrixMode(GL_MODELVIEW);  
 glLoadIdentity();  
 
 gluLookAt(px,py,pz,vx,vy,vz,0,1,0);  
 glRotated(a,0,1,0);  
 
 glLightiv(GL_LIGHT0,GL_POSITION,LightPos);
 
 glRotated(-a,0,1,0);
 glutSolidSphere(1,50,50);
 a +=0.1 ;
 
 glBegin (GL_LINES);
 glVertex3i(0,0,-40); glVertex3i(0,0,40);
 glVertex3i(0,-40,0); glVertex3i(0,40,0);
 glVertex3i(-40,0,0); glVertex3i(40,0,0);
 glEnd();
 
 glutSwapBuffers();
 glutPostRedisplay();
}
 
 
void InitGL()
{
 glEnable(GL_DEPTH_TEST);
 glDepthFunc(GL_LEQUAL);
 glEnable(GL_LINE_SMOOTH);
 glEnable(GL_COLOR_MATERIAL);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 
 rad = sensibilite/180.0 * PI;
 angle_x = 90.0/180.0 * PI;
 angle_y = 90.0/180.0 * PI;
 vx = 10*cos(angle_x);
 vy = 10*cos(angle_y);
}
 
 
double AngleXY()
{
 double res;
 double k = vx-px;
 double m = vz-pz;
 if (k!=0 || m!=0) {  
  res = fabs(k) / sqrt(k*k+m*m);
  if (k<0) {
   if (m<0) res = PI - acos(res);
   else  res = PI + acos(res);
  }
  else if (m<0) res = acos(res);
  else   res = 2*PI - acos(res);
 }
 else {
  if (py == 0) printf("error angleXY\n" );
  else res = acos(1);
 }
 return res;
}
 
 
double AngleXZ()
{
 double res=0;
 double k = vy-py;
 double l = vz-pz;
 if (k!=0 || l!=0) {
  res = fabs(k) / sqrt(k*k+l*l);
  if (k<0) {
   if (l<0) res = PI - acos(res);
   else  res = PI + acos(res);
  }
  else if (l<0) res = acos(res);
  else   res = 2*PI - acos(res);
 }
 else {
  if (pz == 0) printf("error angleXZ\n" );
  else res = acos(1);
 }
 return res;
}
 
 
void GestionSpecialClavier(int key, int x, int y)  
{  
 switch (key) {  
  case GLUT_KEY_LEFT:  {  
         if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
         double angle_xy = AngleXY();
         px -= vitesse*sin(angle_xy);
         vx -= vitesse*sin(angle_xy);
         if (angle_xy != 0) {
          pz -= vitesse*cos(angle_xy);
          vz -= vitesse*cos(angle_xy);
         }
         vitesse = 0.05;
         break;
        }
  case GLUT_KEY_UP:  {  
         if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
         double angle_xy = AngleXY();
         double angle_xz = AngleXZ();
         if (angle_xz != PI/2) {
          py += vitesse*cos(angle_xz);
          vy += vitesse*cos(angle_xz);
         }
         pz += vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
         vz += vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
         if (angle_xy != 0) {    
          px += vitesse*cos(angle_xy)*fabs(sin(angle_xz));
          vx += vitesse*cos(angle_xy)*fabs(sin(angle_xz));
         }
         vitesse = 0.05;
         break;
        }
  case GLUT_KEY_RIGHT: {  
         if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
         double angle_xy = AngleXY();
         px += vitesse*sin(angle_xy);
         vx += vitesse*sin(angle_xy);
         if (angle_xy !=0) {
          pz += vitesse*cos(angle_xy);
          vz += vitesse*cos(angle_xy);
         }
         vitesse = 0.05;
         break;
        }
  case GLUT_KEY_DOWN:  {  
         if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;  
         double angle_xy = AngleXY();
         double angle_xz = AngleXZ();
         if (angle_xz != PI/2) {
          py -= vitesse*cos(angle_xz);
          vy -= vitesse*cos(angle_xz);
         }
         pz -= vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
         vz -= vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
         if (angle_xy != 0) {
          px -= vitesse*cos(angle_xy)*fabs(sin(angle_xz));
          vx -= vitesse*cos(angle_xy)*fabs(sin(angle_xz));
         }
         vitesse = 0.05;
         break;
        }
  case GLUT_KEY_PAGE_UP: {
         sensibilite += 0.1;
         rad = sensibilite/180.0 * PI;
         break;
        }
  case GLUT_KEY_PAGE_DOWN:{
         sensibilite -= 0.1;
         rad = sensibilite/180.0 * PI;
         break;
        }
  case GLUT_KEY_HOME:  {
         vx = 0; vy = 0; vz = 0;
         break;
        }
 }  
}
 
 
void GestionClavier(unsigned char key, int x, int y)  
{  
 if (key=='a') {  
  printf ("angle avec le plan xy: %f\n",AngleXY()/PI * 180.0);
  printf ("angle avec le plan xz: %f\n",AngleXZ()/PI * 180.0);
 }
 if (key=='c') printf("coord: (%f,%f,%f)\n",px,py,pz);
 if (key=='r') {
  px = -px; py = -py; pz = -pz;
  vx = -vx; vy = -vy; vz = -vz;
 }
 if (key=='v') printf("vision: (%f,%f,%f)\n",vx,vy,vz);
 if (key==27) exit(0);    
}  
 
 
void GestionMouvementSouris(int x, int y)
{
 int save;
 if (x < savex)  
 {  
  save = x;
  while (x < savex) {
   angle_x -= rad;
   vx = 10*cos(angle_x) + px;
   vz = 10*sin(angle_x) + pz;
   ++x;
  }
  savex = save;
 }
 else if (x > savex)  
 {  
  save = x;
  while (x > savex) {
   angle_x += rad;
   vx = 10*cos(angle_x) + px;
   vz = 10*sin(angle_x) + pz;
   --x;
  }
  savex = save;
 }
 else if (y < savey)  
 {  
  save = y;
  while (y < savey) {
   angle_y += rad;
   vy = 10*cos(angle_y) + py;
   vz = 10*sin(angle_y) + pz;
   ++y;
  }
  savey = save;
 }
 else  
 {  
  save = y;
  while (y > savey) {
   angle_y -= rad;
   vy = 10*cos(angle_y) + py;
   vz = 10*sin(angle_y) + pz;
   --y;
  }
  savey = save;  
 }
}
 
 
int main (int argc, char *argv[ ], char *envp[ ])
{    
 glutInit(&argc, argv);  
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);  
 glutInitWindowSize(800,600); glutInitWindowPosition (100,100);  
 WindowName = glutCreateWindow("Ma première fenêtre OpenGL !" );  
 glutReshapeFunc(Reshape);
 glutDisplayFunc(Draw);
 InitGL();
 
 glutKeyboardFunc(GestionClavier);
 glutSpecialFunc(GestionSpecialClavier);
 glutPassiveMotionFunc(GestionMouvementSouris);
 
 glutMainLoop();
 
 return 0;  
}
 
 
****************************************************

Reply

Sujets relatifs:

Leave a Replay

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