Comment configurer correctement la scène OpenGL pour visualiser des objets uniques


2

Je dois écrire un visualiseur simple pour ma boîte à outils maillée. Les objets avec lesquels je travaille sont toujours situés dans la boîte [-1,1]^3 (inclus), donc je dois m'assurer que l'objet sera entièrement visible par l'utilisateur. Je veux aussi avoir la possibilité de faire tourner une caméra autour d'un objet comme si l'utilisateur "volait" autour d'un objet.

Voilà comment je fais ceci:

static void Reshape(int w, int h) 
{ 
    glViewport(0,0,(GLsizei) w, (GLsizei) h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    float maxDistance = sqrt(2); 
    if (w <= h) 
    { 
     glOrtho(-maxDistance, maxDistance, -maxDistance * (GLfloat)h/(GLfloat)w, 
      maxDistance * (GLfloat)h/(GLfloat)w, -6.0, 6.0); 
    } 
    else 
    { 
     glOrtho(-maxDistance * (GLfloat)w/(GLfloat)h, maxDistance * (GLfloat)w/(GLfloat)h, 
      -maxDistance, maxDistance, -6.0, 6.0); 
    } 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

static void PolarView(GLdouble distance, GLdouble twist, GLdouble elevation) 
{ 
    double centerx, centery, centerz; 
    double eyex, eyey, eyez; 

    eyex = distance * cos(-twist) * cos(elevation); 
    eyey = distance * sin(-twist) * cos(elevation); 
    eyez = distance * sin(elevation); 
    centerx = centery = centerz = 0; 

    gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1); 
} 

La fonction Reshape est appelée lors de l'installation initiale et après chaque Redimensionnement du contrôle Visualiseur, la fonction PolarView est appelée à chaque redessiner avec des angles et une plus grande distance que la racine carrée de 3 (est-ce vraiment important?). Ce code fonctionne bien avec des objets convexes comme le cube ou la sphère, mais il a quelques problèmes avec l'objet torus (certains des visages sont vus par d'autres), donc je crois que c'est quelque chose sur les tests de profondeur. Quel est le problème avec ma configuration? Capture d'écran:
Bad torus http://s5.tinypic.com/1039b1y.jpg
Bad torus filled http://s5.tinypic.com/2h54paf.jpg
J'ai fait une recherche sur Internet et a constaté que ce problème peut se produire dans le cas où il y a quelque chose de mal avec mes paramètres d'avion près et de loin. Quelles sont les valeurs correctes pour ceux-ci dans mon cas? Ma procédure de dessin ressemble:

glEnable(GL_DEPTH_TEST); 
glClearDepth(1); 
glPolygonMode(GL_FRONT, GL_LINE); // Changing of GL_LINE to GL_FILL doesn't fixing my problem, it just changing the appearance of the model. 
glClearColor(BackColor.R/255.0f, BackColor.G/255.0f, BackColor.B/255.0f, 1); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
PolarView(sqrt(3), _phi, _theta); 
// .. only draws 

Mon PIXELFORMATDESCRIPTOR:

 PIXELFORMATDESCRIPTOR pfd = 
    { 
     sizeof(PIXELFORMATDESCRIPTOR), 
     1, 
     PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
     PFD_TYPE_RGBA, 
     24, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     32, // Depth buffer size 
     0, 
     0, 
     PFD_MAIN_PLANE, 
     0, 
     0, 
     0, 
     0 
    }; 

J'ai trouvé des façons de contourner ce:

  • valeurs Swap pour mon proche et lointain avions
  • définir glDepthFunc à GL_GREATER et g OK, mon code fonctionnera correctement s'il y a un nombre pair d'erreurs. Mais où est la première erreur?
  0

Vous devez donner plus de détails sur exactement quel est le problème. c'est difficile à comprendre. Peut-être même une capture d'écran? 22 févr.. 092009-02-22 14:54:03

0

« 8.070 Comment puis-je calculer automatiquement une vue qui affiche l'ensemble de mon modèle? (Je sais que la sphère de délimitation et en vecteur.) » Entrée à OpenGL FAQ 8 répond à ma question. Cependant, ma configuration est légèrement différente, voici mes fonctions PolarView et Reshape réécrites:

static void Reshape(int w, int h) 
{ 
    float diameter = sqrt(3); 
    glViewport(0, 0, (GLsizei)w, (GLsizei)h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    GLdouble zNear = 1; 
    GLdouble zFar = zNear + diameter * 2; 
    GLdouble left = -diameter; 
    GLdouble right = diameter; 
    GLdouble top = -diameter; 
    GLdouble bottom = diameter; 
    double aspect = (double)w/(double)h; 
    if (aspect < 1) 
    { 
     bottom /= aspect; 
     top /= aspect; 
    } 
    else 
    { 
     left *= aspect; 
     right *= aspect; 
    } 
    glOrtho(left, right, bottom, top, zNear, zFar); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

static void PolarView(GLdouble twist, GLdouble elevation) 
{ 
    float diameter = sqrt(3); 
    double distance = diameter * 2; 
    double centerx, centery, centerz; 
    double eyex, eyey, eyez; 

    eyex = distance * cos(twist) * cos(elevation); 
    eyey = distance * sin(twist) * cos(elevation); 
    eyez = distance * sin(elevation); 
    centerx = centery = centerz = 0; 
    gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1); 
} 

2

Avez-vous lu OpenGL FAQ 12?

La seule chose qui vous semble suspecte à propos de votre code est le plan proche négatif. Les valeurs Z négatives sont derrière la caméra, ce qui est généralement une erreur lors du rendu d'une scène 3D. Cependant, cela en soi ne devrait pas causer le problème que vous voyez, et la gamme [-6,6] pour Z devrait fournir beaucoup de précision pour ce genre de scène. Avez-vous appelé glEnable(GL_DEPTH_TEST)? Passez-vous GL_DEPTH_BUFFER_BIT à glClear chaque image?

Mise à jour: vous appelez glPolygonMode(GL_FRONT, GL_LINE). Cela signifie que les triangles orientés vers l'avant ne sont dessinés qu'en contour, ce qui signifie que si le triangle A faisant face à l'avant chevauche un autre triangle B face à l'avant, vous pouvez voir A jusqu'aux bords de B. Avec un corps convexe cela ne peut pas arriver , donc vous ne remarquez pas le problème.

Si vous voulez que les triangles cachent les triangles derrière eux, vous devrez les remplir en utilisant le mode GL_FILL.Pour obtenir un chiffre wireframe, vous devez dessiner le modèle avec remplissage blanc, puis dessiner à nouveau le modèle avec contour noir, comme ceci:

 
glDepthFunc(GL_LEQUAL); 
glPolygonMode(GL_FRONT, GL_FILL); 
/* draw the model in white */ 
glDepthFunc(GL_EQUAL); 
glPolygonMode(GL_FRONT, GL_LINE); 
/* draw the model again in black */ 

L'idée est que le deuxième passage sur le modèle, nous voulons seulement dessiner les contours qui ne sont pas obscurcis par un triangle dessiné dans le premier passage qui est plus proche de la caméra (c'est-à-dire avec un Z inférieur).

Une autre idée: je pense que votre appareil photo peut pointer dans le mauvais sens. Cela expliquerait pourquoi la scène est mal dessinée avec la perspective GlOrtho, et pas du tout avec la perspective GlFrust. Dans le cas de GlOrtho, toute la scène est dessinée derrière la caméra; C'est pourquoi il est dessiné avec l'ordre Z à l'envers. Lorsque vous placez le plan de proximité à un nombre positif, la scène entière est triée.

  0

Ce lien ne m'a pas aidé. J'ai ajouté plus de code dans ma question. 22 févr.. 092009-02-22 17:24:34

  0

Peu importe comment je dessine mes polygones (GL_LINE ou GL_FILL), le problème est toujours là. Existe-t-il des preuves que le rendu avec GL_LINE ne doit pas utiliser le buffer de profondeur? 22 févr.. 092009-02-22 18:03:36

  0

Pouvez-vous prendre une capture d'écran du modèle dessiné comme je le recommande ci-dessus? 22 févr.. 092009-02-22 18:12:56

  0

Téléchargement d'un nouveau modèle de rendu avec des faces pleines. 22 févr.. 092009-02-22 18:26:03

  0

Vous utilisez glOrtho ce qui rend un peu difficile à dire (voir) quels triangles sont proches/lointains. Si vous avez un problème pour générer les maillages, les triangles doivent être générés dans un certain ordre. Voir http://home.comcast.net/~fbui/glCullFace.html 22 févr.. 092009-02-22 18:31:07

  0

Voir aussi http://home.comcast.net/~fbui/glFrontFace.html 22 févr.. 092009-02-22 18:32:06

  0

Je pense qu'il est clair que l'abattage fonctionne correctement - nous pouvons ne voir que des triangles orientés vers l'avant. C'est le tampon de profondeur qui ne fonctionne pas. Êtes-vous sûr d'appeler glDepthFunc (GL_LEQUAL)? 22 févr.. 092009-02-22 18:39:00

  0

La valeur par défaut de glDepthFunc est GL_LESS, ce qui devrait être bon, ce n'est probablement pas le problème. 22 févr.. 092009-02-22 18:47:55

  0

A quoi ressemble la scène si vous essayez glFrustum au lieu de glOrtho? (assurez-vous d'utiliser un plan proche positif) 22 févr.. 092009-02-22 18:48:45

  0

Si j'utilise glFrustum (-maxDistance, maxDistance, -MaxDistance, maxDistance, 0,1, 10) alors la zone de rendu sera vide. 23 févr.. 092009-02-23 01:33:50

  0

J'ai trouvé comment contourner ce problème. Mais comment puis-je régler correctement mon appareil photo? Je dois m'assurer que je regarde le centre de mon modèle à partir d'une distance constante. Quel est le problème avec ma fonction PolarView? 23 févr.. 092009-02-23 03:26:04