OpenGL: Cómo determinar si un (prestado) de puntos 3D se ocluye por otras primitivas 3D (prestados) delante de él?

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

  •  19-09-2019
  •  | 
  •  

Pregunta

En mi programa de OpenGL, estoy haciendo lo siguiente en secuencia:

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

Para la visualización de la información del punto (digamos un punto identificador / número), puedo convertir las coordenadas 3D del punto a la ventana de coordenadas 2D usando gluProject (). Escribo el identificador de punto en el que la ubicación de la ventana 2D utilizando glRasterPos () y 2D carácter de código de representación.

Cuando un punto prestados se ocluye por otro primitivo, es automáticamente no aparece debido a la prueba de oclusión automática y prueba profundidad que sucede en la tubería OpenGL. Sin embargo, mi punto de texto identificador aparece fuera de lugar, incluso cuando se ocluye ya que no entiendo esta información oclusión.

Cómo determinar si un (prestado) de puntos 3D se ocluye por otras primitivas 3D (prestados) delante de él? ¿O hay una mejor manera de mostrar el texto de la información de puntos junto a él solamente cuando no se ocluye?

Nota: Soy consciente de los métodos que requieren un pase prestación adicional. Siento que esos son caros para mi propósito.

¿Fue útil?

Solución

Si usted no está dispuesto a utilizar una consulta de la oclusión segundo paso se puede tratar el muestreo de la Z-buffer para comparar en contra de su punto de prueba.

Desde que está añadiendo el texto al lado de un punto, obtenemos el valor del buffer Z normalizada (digamos usando gluProject) del punto, y luego comparar ese valor a la Z-buffer de muestra (usando glReadPixels) valor en ese punto. Si el punto está detrás (mayor que) el valor de profundidad se muestra, el punto debe ser ocluido y se puede renunciar a la elaboración del texto.

Por supuesto, esto requiere que se le presten toda su geometría antes del texto, pero eso no debería ser un problema.

Código de ejemplo:

// 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

Otros consejos

La lectura de la memoria intermedia z puede ser muy lento en el hardware moderno. Es por eso que la oclusión consulta fue inventado. Busque la extensión ARB-oclusión en consultas. Tiene un par de cuadros de retraso antes de poder obtener los resultados, pero no llegará a su rendimiento.

Si la oclusión consulta no va a trabajar por cualquier razón, la siguiente opción de reserva es hacer una operación de software de rayos-se cruzan en el mundo usando un BSP-árbol (que no utiliza en absoluto GL).

con la respuesta de Alan, usted podría probar matemáticamente para la oclusión mediante la proyección de un rayo desde su posición de la cámara a su punto, y determinar si se cruza cualquiera de su geometría. Hay un montón de referencias en Internet para hacer las pruebas de intersección rayo-objeto (véase, por ejemplo, el Objeto / Objeto Intersección Página ). Si usted tiene un montón de geometría entonces puede que desee para acelerar las cosas usando volúmenes que limitan o un árbol BSP.

Como beneficio adicional, el código de la oclusión debe ser mucho más fácil de probar la unidad, ya que no se basa en la extracción de los valores de OpenGL.

Respuesta de Ashwin Nanjappa fue muy útil. No soy un experto OpenGL, por lo que me tomó un tiempo para averiguar cómo obtener matrices de MVP. Estoy compartiendo el código aquí para complementar su mensaje:

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top