OpenGL: Comment déterminer si un primitives devant le point est obturée par d'autres 3D (rendus) 3D (rendu) elle?

StackOverflow https://stackoverflow.com/questions/1311869

  •  19-09-2019
  •  | 
  •  

Question

Dans mon programme OpenGL, je fais ce qui suit dans l'ordre:

// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it

Pour l'affichage de l'information de point (par exemple un identifiant Point / numéro), je convertir les coordonnées 3D du point de coordonnées 2D en utilisant la fenêtre gluProject (). J'écrire l'identificateur de point à l'emplacement de la fenêtre 2D en utilisant glRastePos () et le caractère 2D code de rendu.

Lorsqu'un point rendu est obturée par une autre primitive, il est automatiquement pas affiché en raison de test d'occlusion automatique et test de profondeur qui se produit dans le pipeline OpenGL. Cependant, mon point texte d'identification est affiché à côté du point, même quand il est obturée depuis que je ne comprends pas cette information d'occlusion.

Comment déterminer si un primitives devant le point est obturée par d'autres 3D (rendus) 3D (rendu) elle? Ou est-il une meilleure façon d'afficher le texte d'information point à côté que quand il n'occlus?

Note: Je suis au courant des méthodes qui nécessitent un laissez-passer de rendu supplémentaire. Je pense que ce sont cher pour mon but.

Était-ce utile?

La solution

Si vous n'êtes pas prêt à utiliser une requête d'occlusion secondes vous pouvez passer essayer d'échantillonnage Z-tampon pour comparer contre votre point de test.

Puisque vous ajoutez le texte suivant à un point, saisir la valeur tampon Z normalisée (dire en utilisant gluProject) du point, puis de comparer cette valeur à la Z-buffer échantillonné (en utilisant glReadPixels) valeur à ce moment-là. Si votre point est derrière (plus) la valeur de profondeur que vous avez échantillonnés, votre point doit être obturée et vous pouvez choisir de ne pas dessiner le texte.

Bien sûr, cela exige que vous lui fournir toute la géométrie avant que le texte, mais cela ne devrait pas être un problème.

Exemple de code:

// Assumed to already hold 3D coordinates of point
GLdouble point3DX, point3DY, point3DZ;

// Project 3D point coordinates to 2D
GLdouble point2DX, point2DY, point2DZ;  // 2D coordinates of point
gluProject( point3DX, point3DY, point3DZ,
            mMatrix, pMatrix, vMatrix,      // MVP matrices
            &point2DX, &point2DY, &point2DZ);

// Read depth buffer at 2D coordinates obtained from above
GLfloat bufDepth = 0.0;
glReadPixels(   static_cast<GLint>( point2DX ), static_cast<GLint>( point2DY ),     // Cast 2D coordinates to GLint
                1, 1,                                                               // Reading one pixel
                GL_DEPTH_COMPONENT, GL_FLOAT,
                &bufDepth);

// Compare depth from buffer to 2D coordinate "depth"
GLdouble EPSILON = 0.0001;  // Define your own epsilon
if (fabs(bufDepth - point2DZ) < EPSILON)
    // 3D point is not occluded
else
    // 3D point is occluded by something

Autres conseils

Lecture du z-buffer peut être très lent sur le matériel moderne. Voilà pourquoi la requête d'occlusion a été inventée. Recherchez l'extension ARB-occlusion requête. Il a deux cadres de retard avant de pouvoir obtenir les résultats, mais il ne sera pas touché votre performance.

Si la requête d'occlusion ne va pas travailler pour une raison quelconque, la prochaine option de repli est de faire une opération logiciel ray-Intersection monde en utilisant un BSP-arbre (qui n'utilise pas GL du tout).

Suite à la réponse d'Alan, vous pouvez tester l'occlusion mathématiquement en projetant un rayon de votre position de la caméra à votre point et déterminer si elle croise une de la géométrie. Il y a beaucoup de références sur Internet pour faire des tests d'intersection ray-objet (voir, par exemple, Objet / objet intersection ). Si vous avez beaucoup de géométrie alors vous pourriez vouloir accélérer les choses en utilisant des volumes EXpLoRATIoN ou un arbre BSP.

En prime, votre code d'occlusion devrait être beaucoup plus facile à tester l'unité, car il ne repose pas sur l'extraction des valeurs d'OpenGL.

Réponse de Ashwin Nanjappa a été très utile. Je ne suis pas un expert en OpenGL, donc il m'a fallu un certain temps pour savoir comment obtenir des matrices MVP. Je partage le code ici pour compléter son poste:

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top