El z-buffering
“Los objetos cercanos ocultan a los más lejanos”
El z-buffering, o el buffer de profundidad es la parte de la memoria de nuestra tarjeta gráfica encargada de la visibilidad de nuestros gráficos 3D según las coordenadas de sus pixeles, con lo que se puede gestionar qué elementos de una escena renderizada son visibles y cuales permanecerán ocultos según sus posiciones en el eje Z ( distancia a cámara ).
Cuando dibujamos un objeto, la profundidad de sus pixeles se guardan en este buffer. Si utilizamos dichos pixeles en pantalla para dibujar otro objeto, se producirá la comparación de las profundidades de dichos pixeles. Si la profundidad del último es mayor que la nueva (está más lejos) el pixel nuevo no se pinta, mientras que si está más cerca (la profundidad es menor), se dibuja el pixel y se guarda la nueva profundidad en el z-buffering. En definitiva lo que se hace es comparar las profundidades de ambos gráficos para representar el objeto más cercano al observador. La profundidad elegida se guardará en el z-buffering reemplazando a la anterior.
Un Ejemplo:
Nada mejor que verlo con un ejemplo. Vamos a proceder a pintar un triángulo en primer lugar y cercano a nosotros (coordenada 0 del eje Z) y un rectángulo en segundo lugar y más alejado de nosotros (coordenada -50 en el eje Z).
Dependiendo de si hemos habilitado o no el soporte de profundidad en OpenGL los resultados pueden ser los que se ven en la siguientes imágenes:
- Con el buffer habilitado
- Con el buffer deshabilitado
Como podemos ver, al habilitar el buffer de profundidad, el primer objeto que veremos será el triángulo rojo, ya que se encuentra más cercano a nosotros. Al deshabilitar el buffer, el rectángulo azul, pintado más tarde y más lejano a nosotros, sobreescribe la profundidad del triángulo por lo que lo vemos visible por encima del triángulo.
Para habilitar o deshabilitar el buffer de profundidad nos tendremos que valer de las siguientes funciones:
glEnable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST); |
El código utilizado para dibujar las anteriores primitivas es el siguiente:
//dibujamos un triángulo rojo glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.0f,50.0f,0.0f); glVertex3f(50.0f,0.0f,0.0f); glEnd(); //dibujamos un rectángulo azul más lejano glColor3f(0.0f, 0.0f, 1.0f); glBegin(GL_QUADS); glVertex3f(0.0f,0.0f,-50.0f); glVertex3f(0.0f,50.0f,-50.0f); glVertex3f(20.0f,50.0f,-50.0f); glVertex3f(20.0f,0.0f,-50.0f); glEnd(); |
Para habilitar el uso de la función glEnable(GL_DEPTH_TEST) tendremos que haber inicializado el sistema con el Buffer de Profundidad:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); |
El buffer de profundidad se puede limpiar utilizando la siguiente función:
glClear( GL_DEPTH_BUFFER_BIT ); |