Read the book: «Gráficos por computadora usando JOGL»

Font:

Gráficos por Computadora Usando JOGL


UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO

Dr. Enrique Luis Graue Wiechers

Rector

Dr. Leonardo Lomelí Vanegas

Secretario General

FACULTAD DE ESTUDIOS SUPERIORES ACATLÁN

Dr. Manuel Martínez Justo

Director

Mtra. Nora del Consuelo Goris Mayans

Secretaria General

Mtro. Carlos Nandayapa Hernández

Secretario de Estudios Profesionales

Dra. Laura Páez Díaz de León

Secretaria de Posgrado e Investigación

Mtro. Fernando Martínez Ramírez

Coordinador de Servicios Académicos

Act. Luz María Lavín Alanís

Jefa de la División de Matemáticas e Ingeniería

D.G. Norma Guadalupe Rojas Borja

Jefa de la Unidad de Servicios Editoriales


Catalogación en la publicación UNAM. Dirección General de Bibliotecas y Servicios Digitales de Información

Nombres: Caballero Martínez, Oscar Gabriel, autor.

Título: Gráficos por computadora usando JOGL / Oscar Gabriel Caballero Martínez.

Descripción: Primera edición. | México: Universidad Nacional Autónoma de México, Facultad de Estudios Superiores Acatlán, 2021.

Identificadores: LIBRUNAM 2112231 (libro electrónico) | ISBN 9786073050302 (libro electrónico).

Temas: Gráficas por computadora. | OpenGL. | Java (Lenguaje de programación para computadora). | Imágenes tridimensionales.

Clasificación: LCC T386.O64 (libro electrónico) | DDC 006.6—dc23

Primera edición digital: 2021

D.R. © UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO

Ciudad Universitaria, Alcaldía Coyoacán,

C.P. 04510, Ciudad de México, México.

FACULTAD DE ESTUDIOS SUPERIORES ACATLÁN

Av. Alcanfores y San Juan Totoltepec s/n

C.P. 53150, Naucalpan de Juárez, Estado de México.

Unidad de Servicios Editoriales.

Esta edición y sus características son propiedad de la Universidad Nacional Autónoma de México.

Prohibida la reproducción total o parcial por cualquier medio sin la autorización escrita del titular de los derechos patrimoniales.

ISBN: 978-607-30-5030-2

Hecho en México

Made in Mexico

Índice

Introducción

Capítulo 1 Principios de gráficos por computadora

Capítulo 2 Programación con Java Open Graphics Library 2. (JOGL2)

Capítulo 3 Primitivas Gráficas

Capítulo 4 Algoritmos para generar líneas

Capítulo 5 Transformaciones afines en 2D: traslación, escalamiento, rotación

Capítulo 6 Gráficas en 3D

Capítulo 7 Aplicación de los modos de vista

Capítulo 8 Gráficas de curvas y superficies

Capítulo 9 Técnicas de barrido e iluminación

Capítulo 10 Animación y juegos

Referencias

Apéndice A

Apéndice B

Introducción

Este documento está dirigido a personas interesadas en la generación de gráficos por computadora con el lenguaje de programación Java.

A lo largo del texto se descubrirá que la mayoría de los trabajos que existen para la generación de gráficos por computadora están basados en el uso de las librerías conocidas como OpenGL. Las referencias más accesibles están trabajadas con el lenguaje de programación C, lenguaje principal en el que se han creado las funciones de la librería.

El reto consiste en presentar el uso de estas librerías con el lenguaje de programación Java, de ahí las siglas JOGL (Java Open Graphics Library o Java OpenGL).

La importancia del presente trabajo radica en mostrar la facilidad con la cual los programas que se encuentran en las referencias del presente documento también pueden ser escritos en el lenguaje Java, y así poseer un panorama más amplio que ayude a la profundización del conocimiento para la creación de las gráficas por computadora.

El estudio de las librerías de OpenGL permite, a quienes las trabajan, entender mejor la terminología y funciones que se utilizan en la generación de gráficos por computadora por medio de diferentes paquetes que existen en el mercado, como Maya y 3D Studio Max, entre otros, y comprender los rudimentos del manejo de lenguajes como WebGL.

El trabajo presenta una breve cronología de las máquinas y eventos que han generado el estudio de esta disciplina. También trata sobre las principales funciones para facilitar la creación de figuras básicas relacionadas con el desarrollo de proyectos referidos a las gráficas computacionales, los efectos que pueden aplicarse con los objetos creados para una escena y las maneras en que se manipulan los elementos que intervienen en tales escenas, como es la iluminación, la animación y el sombreado.

Es importante destacar que el trabajo está enfocado a personas que ya han programado con el lenguaje Java, ya que el estudio no se detiene a verificar cuestiones relacionadas con el lenguaje, al igual que al manejo de la APl NetBeans.

Sin más preámbulos, se invita al lector a realizar un recorrido por el maravilloso y fascinante mundo de la generación de gráficos por computadora mediante las librerías JOGL.

Capítulo 1
Principios de gráficos por computadora

Para tener un panorama más amplio sobre la historia de los gráficos por computadora a continuación se enlistan algunas fechas y eventos importantes en el desarrollo cronológico de la evolución de esta actividad.

1.1 Desarrollo cronológico

Durante la Segunda Guerra Mundial se realizó un proyecto de simulación de vuelo para entrenar pilotos. Se llevó a cabo en el MIT y estuvo a cargo de Jay Forrester [Benstead, 2009]. Se concluyó hasta 1951. Llevó el nombre de Whirl-wind.


Figura 1.1 Computadora Whirl-wind

Fuente: https://en.wikipedia.org/wiki/Whirlwind_I

En 1959, IBM y General Motors lograron modelar autos en 3D. Para 1962 Ivan Sutherland creó el Sketchpad, programa informático que permitía la manipulación directa de objetos gráficos: fue el primer programa de dibujo por computadora.

En 1963 Doug Englebart inventó el “ratón”, herramienta importante para la manipulación de gráficos en una computadora, además de que ayuda a dibujar objetos con mayor facilidad. Para 1969 nace SIGGRAPH (Special Interest Group for Graphics), organismo que se encarga de estandarizar las técnicas para graficar en dispositivos electrónicos.

En el año de 1972 la Universidad de Utha desarrolla algoritmos y técnicas, como el sombreado de Goraud y Phong, el algoritmo del pintor y el algoritmo z-buffer, que son actualmente estudiados en los niveles básicos para el desarrollo de efectos visuales [Villar, 2009].

A princípios de los 80’s salen a la venta las computadoras Apollo, Macintosh e IRIS.


Figura 1.2 Macintosh y Silicongraphics

Fuente: Macintosh.org & silicongraphics.org

En 1985 se crea un API estándar: GKS-> PHIGS

En el año de 1986 se realiza el primer cortometraje por computadora: Luxo Jr.


Figura 1.3 Luxo Jr.

Fuente: pixar.org.

Para1990 aparece el primer producto de animación: Studio 3D de Autodesk.


Figura 1.4 3D Studio Max.

Fuente: www.fiuxi.net/autodesk-3d-studio-max-8-full-medicina.html

En 1995 se realiza la primera película animada por computadora: Toy Story.


Figura 1.5 Woody y Buzz

Fuente: www.mundodisney.net/juegos/toy/009/

Para generar una escena es importante seguir una serie de pasos para tener una mejor presentación.

1.2 principios generales

Modelado: Estudia los diversos tipos de modelos matemáticos usados para representar la forma de los objetos que se utilizan en una escena [Shreiner, 2013; Villar, 2009].


Figura 1.6 Modelado Geométrico

Fuente: Apuntes Villar Patiño.

Render: Es el proceso en el que se usan cálculos y algoritmos computacionales para dibujar un objeto tridimensional de manera realista aplicando color, texturas y efectos de iluminación.

Para generar un rendereo primero se coloca el color a la imagen y posteriormente la iluminación.

La totalidad del proceso de render se presenta en la figura 1.7. A partir de figuras geométricas o una imagen se aplican los comandos para cada uno de los pixeles y por medio de las texturas permite una mejor representación de la figura, ya que al aplicarle a cada fragmento las operaciones pertinentes, podemos enviar al frame la figura para que sea dibujada [Hearn, 2006; Villar, 2009].


Figura 1.7 Pasos a seguir para el rendereo.

Fuente: Apuntes Villar Patiño.

Animación: Es el control computacional de una secuencia de imágenes u objetos a lo largo del tiempo


Figura 1.8 Maya Autodesk y Valiente de Pixar

Fuente: ielp1990blogspot.mx/2012/12/maya.html y pixar.org

Interacción: Estudia lo relativo a la creación, en hardware y software, de interfases de usuario.

– Para el hardware, se identifican los dispositivos que deben contener las computadoras para un mejor manejo.

• Adaptador gráfico.

• Monitores.

• Dispositivos de entrada y salida.

– Para el software, se tienen las siguientes identificaciones que permiten manejar la interacción de una mejor forma.

• GUI: Interfaz Gráfica del Usuario, por sus siglas en inglés.

• API: Conjunto de funciones y procedimientos que pueden ser usados por un programa para un fin específico.

Capítulo 2
Programación con Java Open Graphics Library 2. (JOGL2)

Para poder programar en JOGL2 [jogamp, 2016] es necesario tener las librerías que utiliza para su programación en Java (ver Apéndice A) y a su vez, configurar NetBeans para ligar las librerías a los proyectos que se crean (ver Apéndice B).

Lo primero que debe hacerse es generar, a partir del proyecto de trabajo, un archivo tipo class para transcribir el programa; para ello, dentro de NetBeans hacemos lo siguiente: con el botón derecho del mouse abrimos el menú en el proyecto y en la opción de Java Class podremos construir el programa. Ver figura 2.1


Figura 2.1 Ventana de NetBeans para crear un Java Class.

Fuente: Elaboración propia

Al hacer lo anterior se pone el nombre de la clase en la ventana, como se muestra en la figura 2.2. Hay que recordar que los nombres de las clases en Java deben comenzar con una letra mayúscula; si el nombre que se desea transcribir es de dos o más palabras, cada nueva palabra comienza con Mayúsculas.


Figura 2.2 Poner nombre a una clase.

Fuente: Elaboración propia

Al oprimir el botón de finalizar (Finish) se tendrá abierto el editor para transcribir programas en Java que genera un archivo *.class. Para ver cómo se trabaja con JOGL se transcribirá el siguiente código [jogamp, 2016].

1. package Graficacion;

2.

3. import com.jogamp.opengl.GLAutoDrawable;

4. import com.jogamp.opengl.GLEventListener;

5. import com.jogamp.opengl.awt.GLCanvas;

6. import com.jogamp.opengl.util.Animator;

7. import java.awt.Frame;

8. import java.awt.event.WindowAdapter;

9. import java.awt.event.WindowEvent;

10. /**

11. *

12. * @author Caballero Martínez Oscar Gabriel

13. * Caballero Jiménez Oscar Emilio

14. * Caballero Jiménez Mariana

15. * Jiménez Jacinto Verónica

16. *

17. * @Group 2803

18. *

19. * @Fecha 10/febrero/2016

20. *

21. * @Materia Graficación por Computadora

22. *

23. */

24. public class Ventana implements GLEventListener {

25. public static void main(String[] args) {

26. Frame frame = new Frame("Ventana.java");

27. GLCanvas canvas = new GLCanvas();

28. canvas.addGLEventListener(new Ventana());

29. frame.add(canvas);

30. frame.setSize(640, 480);

31. final Animator animator = new Animator(canvas);

32. frame.addWindowListener(new WindowAdapter() {

33. @Override

34. public void windowClosing(WindowEvent e) {

35. // Run this on another thread than the AWT event queue to

36. // make sure the call to Animator.stop() completes before

37. // exiting

38. new Thread(new Runnable() {

39. public void run() {

40. animator.stop();

41. System.exit(0);

42. }

43. }).start();

44. }

45. });

46. // Center frame

47. frame.setLocationRelativeTo(null);

48. frame.setVisible(true);

49. animator.start();

50. }

51. @Override

52. public void init(GLAutoDrawable glad) {

53. }

54. @Override

55. public void dispose(GLAutoDrawable glad) {

56. }

57. @Override

58. public void display(GLAutoDrawable glad) {

59. }

60. @Override

61. public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3){

62. }

63. }

Código 2.1 Ventana.java

Al ejecutar el programa anterior tendremos la siguiente salida.


Figura 2.3 Programa “Ventana”. Fuente: Elaboración propia.

Como siempre se trabajará con el mismo código, se escribirá en la plantilla original de los archivos class que crea NetBeans el código anterior pero con generalidades. Para ello es necesario abrir la plantilla.


Figura 2.4 Menú para modificar la plantilla de los class.

Fuente: Elaboración propia.

Posteriormente, en las plantillas asociadas a Java se abre la referente a los archivos class con el editor.


Figura 2.5 Abrir con el editor los class

Fuente: Elaboración propia.

Y se escriben las siguientes líneas:

1. import com.jogamp.opengl.GLAutoDrawable;

2. import com.jogamp.opengl.GLEventListener;

3. import com.jogamp.opengl.awt.GLCanvas;

4. import com.jogamp.opengl.util.Animator;

5. import java.awt.Frame;

6. import java.awt.event.WindowAdapter;

7. import java.awt.event.WindowEvent;

8. </#if>

9. /**

10. *

11. * @authors Caballero Jiménez Mariana

12. * Caballero Jiménez Oscar Emilio

13. * Caballero Martínez Oscar Gabriel

14. * Jiménez Jacinto Verónica

15. *

16. * @Tema: Libro

17. *

18. * @Fecha ${date}

19. *

20. */

21. public class ${name} implements GLEventListener {

22. public static void main(String[] args) {

23. Frame frame = new Frame("${name}.java");

24. GLCanvas canvas = new GLCanvas();

25. canvas.addGLEventListener(new ${name}());

26. frame.add(canvas);

27. frame.setSize(640, 480);

28. final Animator animator = new Animator(canvas);

29. public void windowClosing(WindowEvent e) {

30. // Run this on another thread than the AWT event queue to

31. // make sure the call to Animator.stop() completes before

32. // exiting

33. new Thread(new Runnable() {

34. public void run() {

35. animator.stop();

36. System.exit(0);

37. }

38. }).start();

39. }

40. });

41. // Center frame

42. frame.setLocationRelativeTo(null);

43. frame.setVisible(true);

44. animator.start();

45. }

46. @Override

47. public void init(GLAutoDrawable glad) {

48. }

49. @Override

50. public void dispose(GLAutoDrawable glad) {

51. }

52. @Override

53. public void display(GLAutoDrawable glad) {

54. }

55. @Override

56. public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3){

57. }

58. }

Código 2.2 Plantilla para las clases

El ${name} de la línea 21 y el ${date} de la línea 18 son variables del sistema que toma la plantilla para colocarlos en el lugar correspondiente. ${name} es el nombre del programa y ${date} es la fecha actual de la máquina local.

Nota: Esto va a quedar estipulado siempre en todos los programas que se hagan durante el trabajo, si se hace alguna modificación a esto en cada programa se especificarán únicamente las funciones que se modificarán.

De la línea 1 a la línea 7 se importan paquetes que se van a utilizar todo el tiempo, especificados para lo siguiente:

1. com.jogamp.opengl.GLAutoDrawable es la clase con la que se trabajan los objetos que permiten dibujar en el lienzo.

2. import com.jogamp.opengl.GLEventListener es la clase que ayuda a escuchar los eventos que ocurren en el lienzo.

3. import com.jogamp.opengl.awt.GLCanvas es la clase que permite colocar el lienzo para dibujar en el Frame.

4. com.jogamp.opengl.util.Animator Es la clase que permite se esté animando la ejecución del programa, y así permitir que el dibujo pueda ser manipulado. Nota: para algunos programas no se necesita que esté redibujándose el dibujo, así que se eliminará. Se especificará dónde se hace.

5. import java.awt.Frame es la clase que permite colocar el lienzo (GLCanvas) para poder dibujar.

6. import java.awt.event.WindowAdapter Clase que permite colocar al Frame en cualquier parte de la pantalla y a su vez permite adaptar las acciones que se realizarán en el momento de cerrar la ventana. Dichas instrucciones se componen de la línea 29 a la 40, donde por medio de hilos se ligan las acciones a seguir.

7. java.awt.event.WindowEvent Clase que se dispara en el momento que ha ocurrido algo en la ventana que contiene al Frame y a su vez, al Canvas.

Las funciones con las que trabaja JOGL2 [jogamp, 2016] en cada programa son:

void display(GLAutoDrawable glad) (línea 53): es llamado por el objeto de interfaz de GLAutoDrawable para iniciar la representación de OpenGL por el cliente; es decir, este método contiene la lógica utilizada para dibujar los elementos gráficos que utilizan las API de OpenGL

void dispose(GLAutoDrawable glad) (línea 50): este método activa al listener para llevar a cabo la liberación de todos los recursos de OpenGL por cada GLContext , tales como buffers de memoria y programas GLSL.

void init(GLAutoDrawable glad) (línea 47): Es llamada por la interfaz de GLAutoDrawable inmediatamente después de inicializar el contexto de OpenGL.

void reshape(GLAutoDrwawble drawable, int i, int i1, int i2, int i3) (línea 56): Es llamada por la interfaz de GLAutoDrawable durante el primer repintado después de que el componente ha sido redimensionado. También se llama cuando la posición del componente en la ventana se cambia.

A continuación un ejemplo: crearemos un nuevo class llamado HolaMundo.

1. import com.jogamp.opengl.GL2;

2. import com.jogamp.opengl.GLAutoDrawable;

3. import com.jogamp.opengl.GLEventListener;

4. import com.jogamp.opengl.awt.GLCanvas;

5. import com.jogamp.opengl.glu.GLU;

6. import com.jogamp.opengl.util.Animator;

7. import com.jogamp.opengl.util.gl2.GLUT;

8. import java.awt.Frame;

9. import java.awt.event.WindowAdapter;

10. import java.awt.event.WindowEvent;

En comparación con el código anterior, se han importado 3 nuevas clases: la de la línea 1, la línea 5 y la línea 7. En la línea 1 se importa la clase GL2 donde están todos los métodos que se utilizan para trabajar con GraphicsLibreries versión 2. En la línea 5 se utiliza la clase GLU que contiene los métodos relacionados con la OpenGL Utility. Y la línea 7 la clase GLUT que le corresponden a la clase OpenGL Utilities Tools.

Las funciones que se modifican con respecto al código anterior son:

1. @Override

2. public void init(GLAutoDrawable glad) {

3. final GL2 gl = glad.getGL().getGL2();

4. final GLU glu = new GLU();

5. gl.glMatrixMode (GL2.GL_PROJECTION);

6. gl.glClearColor (1.0f, 1.0f, 1.0f, 0.0f);

7. glu.gluOrtho2D (0.0, 200.0, 0.0, 150.0);

8. }

9.

10. @Override

11. public void display(GLAutoDrawable glad) {

12. GL2 gl = glad.getGL().getGL2();

13. GLUT glut = new GLUT();

14. gl.glClear (GL2.GL_COLOR_BUFFER_BIT);

15. gl.glColor3f (0.0f, 0.0f, 0.0f);

16. gl.glMatrixMode (GL2.GL_MODELVIEW);

17. gl.glLoadIdentity();

18. gl.glRasterPos2i(10, 15);

19. glut.glutBitmapString(GLUT.BITMAP_HELVETICA_10 , "Hola Mundo");

20. }

Código 2.3 HolaMundo.java

Todas las funciones que le corresponden al objeto gl que está definido en las líneas 3 y 12 se enfocan en su análisis a lo largo del texto y posteriormente van a ser analizadas [TutorialOpenGL, 2016]. Para el objeto glu definido en la línea 4, la función gluOrtho2D que se usa es para generar un espacio ortogonal de dimensión 2 (línea 7) para para poder dibujar. Para el objeto glut definido en la línea 13 la función que se utiliza es glutBitmapString: define el tipo de letra con la característica GLUT.BITMAP_HELVETICA_10 para dibujar la cadena “Hola Mundo”.

En la función init que comienza en la línea 2, su primera línea de código se define un objeto de tipo GL cuyos métodos y características son extraídos del objeto que llega como parámetro a la función.

Para poder realizar todas las características de una escena se realizan operaciones entre matrices, así que la primera matriz para multiplicar será la del modo, y la que se define es de tipo proyección con la característica GL2.GL_PROJECTION. En la línea 6 se limpia el color. La función glColorClear recibe como parámetros 4 valores de tipo flotante, que en orden son las intensidades del rojo, verde y azul; el útimo parámetro le corresponde a la transparencia y es el color del fondo.

Para la función display en la línea 14 se limpia el buffer de color con la característica GL2.GL_COLOR_BUFFER_BIT, después, en la línea 15, se define el color con el que se va a pintar, seguido del tipo de matriz a operar que se define con la característica GL2.GL_MODELVIEW (línea 16). Se establece la matriz identidad para realizar todas las operaciones (línea 17) y posteriormente se define la posición donde va a comenzar a dibujar el gl. Por último, se escribe el mensaje (línea 18).

¿Por qué aparece ahí el mensaje?


Figura 2.6 Salida de HolaMundo. Fuente: Elaboración propia.

Con esto se concluye con los principios fundamentales para la programación con OpenGL 2 para java. Continuaremos con las primitivas gráficas.

The free excerpt has ended.