Saltear al contenido principal

OpenGL: Primitivas, Proyección e Iluminación de objetos 3D

Gráficos 2D-3D en Android: OpenGL (II)
1. Uso de OpenGL ES en Android
2. OpenGL: Primitivas, Proyección e Iluminación de objetos 3D
3. Proyecto Android con OpenGL: iluminación e interacción con objetos 3D
4. Videotutorial: ejemplo práctico con Android y OpenGL ES

Tipos de Primitivas de OpenGL

Comentamos los tipos de primitivas existentes en OpenGL ES y visualizaremos un cubo utilizando cada una de ellas.

Primitiva Descripción
GL_POINTS Dibuja los vértices como puntos individuales.
GL_LINES Cada par de vértices formaría una línea individual.
GL_LINE_STRIP Cada vértice está unido con el anterior formando segmentos conectados.
GL_LINE_LOOP Al igual que GL_LINE_STRIP, pero implementando un segmento más entre el primer y último vértice.
GL_TRIANGLES Tres vértices son interpretados como tres triángulos
GL_TRIANGLE_STRIP Cada vértice se une con los dos anteriores para formar un triángulo.
GL_TRIANGLE_FAN Cada vértice se une con los dos primeros para formar un triángulo.

 

Resultado de las primitivas utilizadas para un cubo.

Resultados primitivas OpenGL para un cubo

La proyección: Objetos 3D en superficie 2D.

La proyección de una escena, es aquella que permite representar objetos definidos en 3D en una superficie 2D. Esta proyección, se consigue trazando líneas imaginarias, desde un punto fijo llamado foco, a cada uno de los puntos del objetos 3D que se representa.

Proyección objeto 2D a 3D

Tipos de proyección:

  • Paralela: El foco se sitúa en el infinito, siendo las líneas de proyección trazadas paralelas. Si el plano de proyección se sitúa perpendicular a las líneas de proyección se denomina proyección ortogonal.
  • Perspectiva: El foco se sitúa en un punto concreto, por lo que las líneas de proyección trazadas no serán paralelas. Si el objeto está cercano al foco se representará más grande, dando una sensación de profundidad. Esta opción es una de las más usadas en gráficos 3D.

OpenGL se encarga de realizar todos los cálculos necesarios para la realización de dicha proyección, con lo que nos evita realizarla manualmente.

Iluminación en objetos 3D

En el siguiente punto, nos centraremos en entender como iluminar una escena, estableciendo un foco, para reflejar luz sobre un objeto 3D, mostrando los diferentes efectos de sombra.

En cualquier objeto 3D representado, lo habitual es que alguna de las caras que forman el objeto, queden a la sombra, y por lo tanto se vean más oscuras. Para ello OpenGL divide el proceso de iluminación en tres partes bien diferenciadas, para dar mucho más realismos a las formas construidas:

  • Definir los vectores normales de cada cara: En este punto será necesario calcular la luz reflejada con respecto al ángulo que se forme con el foco de luz. Para ello es necesario definir un vector normal (perpendicular a la superficie apuntando hacia fuera de la parte visible) por cada uno de los vértices de nuestra representación. Por lo tanto es necesarios definir 6 vectores normales por cada una de las caras de un cubo.
    Vectores normales a caras de un cubo
  • Situar las luces: Para iluminar una escena será necesario situar las luces. OpenGL maneja dos tipos de iluminación:
    • Luz ambiental: ilumina toda la escena por igual, ya que esta no proviene de una dirección predeterminada.
    • Luz difusa: Viene de una dirección específica, y depende de su ángulo de incidencia para iluminar una superficie en mayor o menor medida.
  • Definiendo materiales: OpenGL permite controlar la forma en que la luz se refleja sobre nuestros objetos, que es lo que se conoce como definición de materiales.

Implementación de luz difusa

En nuestra clase encargada de construir la vista (implementa la interfaz GLSurfaceView.Renderer), dentro del método onSurfaceCreated(GL10 gl, EGLConfig config)se deben añadir las siguientes instrucciones:

  • En primer lugar habilitamos la iluminación:
    gl.glEnable(GL10.GL_LIGHTING);
  • Y habilitamos la primera luz individualmente: gl.glEnable(GL10.GL_LIGHT0);
  • Con el método glLightfv(int luz,int propiedad,float[] parámetros,int inicio), nos permite introducir las características de la luz, a través de las coordenadas indicadas en los tres primeros parámetros recibidos:
  • Y por último se especifica el modo en que OpenGL realizará el sombreado sobre el objeto:
    gl.glShadeModel(GL10.GL_SMOOTH);

 Implementación de materiales

En nuestra clase encargada de definir los parámetros de representación del objeto, dentro del método draw(GL10 gl) se deben añadir las siguientes instrucciones:

  • En primer lugar habilitamos la definición de materiales: gl.glEnable(GL10.GL_COLOR_MATERIAL);
  • Y posteriormente, mediante el método glMaterialfv(int face,int pname, float[] params,int offset) definimos las propiedades de los materiales (estos cambios afectarán al resto de operaciones que estén definidas):

Aquí puedes consultar la documentación oficial de la interfaz GL10

Continuaremos en el siguiente tutorial desarrollando un proyecto ejemplo para mostrar como iluminar objetos 3D e implementar eventos de interacción como pantalla táctil o acelerómetro.


Contenidos elaborados por Academia Android – José Antonio Gázquez

Volver arriba