I) Objetivo
Introducción a OpenGL En OpenGL se proporciona una biblioteca básica de funciones para especificar primitivas gráficas, atributos, transformaciones geométricas, transformaciones de visualización y muchas otras operaciones. Está diseñada para ser independiente del hardware, por tanto, muchas operaciones, tales como las subrutinas de entrada y salida, no están incluidas en la biblioteca básica. Sin embargo, las subrutinas de entrada y salida y muchas funciones adicionales están disponibles en bibliotecas auxiliares que se han desarrollado para programas OpenGL. Sintaxis básica de OpenGL Los nombres de las funciones de la biblioteca básica de OpenGL utiliza como prefijo gl. glBegin, glClear, glCopyPixels, glPolygonMode Todas las constantes comienzan con las letras GL en mayúsculas. GL_2D, GL_RGB, GL_CCW, GWOLYGON, GL_AMB I ENT_AND_D IFFUSE Las funciones de OpenGL también esperan tipos de datos específicos. Por ejemplo, GLbyte, GLshort, GLint, GLfloat, GLdouble, GLboolean. A algunos argumentos de funciones de OpenGL se les puede asignar valores empleando una matriz que enumera un conjunto de valores de datos. Esta opción se utiliza para especificar una lista de valores como un puntero a una matriz, en lugar de especificar cada elemento de la lista explícitamente como un argumento. Un ejemplo típico del uso de esta opción es la especificación de los valores de las coordenadas xyz. Bibliotecas relacionadas Existe un gran número de bibliotecas relacionadas para la realización de operaciones especiales, además de la biblioteca básica de OpenGL. La utilidad GLU (OpenGL Utility) proporciona subrutinas para la configuración de las matrices de visualización y proyección, descripción de objetos complejos mediante líneas y aproximaciones poligonales, visualización de cuádricas y splines B empleando aproximaciones lineales, procesamiento de operaciones de representación de superficies y otras tareas complejas. Toda implementación de OpenGL incluye la biblioteca GLU. Todos los nombres de las funciones de GLU comienzan con el prefijo glu. También existe un conjunto de herramientas orientadas a objetos basado en OpenGL, llamado Open Inventor que proporciona subrutinas y formas de objetos predefinidos para su uso en aplicaciones tridimensionales interactivas. Para crear gráficos utilizando OpenGL, necesitamos en primer lugar configurar una ventana de visualización en nuestra pantalla de vídeo. Se trata simplemente de la zona rectangular de la pantalla en la que nuestra imagen se mostrará. No podemos crear directamente la ventana de visualización con las funciones de OpenGL básicas, ya que esta biblioteca contiene únicamente funciones gráficas independientes del dispositivo, y las operaciones de gestión de ventanas dependen de la computadora que estemos utilizando. Sin embargo, existen varias bibliotecas de sistema de ventanas que soportan las funciones de OpenGL en una gran variedad de máquinas. El kit de herramientas GLUT (OpenGL Utility Toolkit) proporciona una biblioteca de funciones para interactuar con cualquier sistema de ventanas. Las funciones de la biblioteca GLUT utilizan como prefijo glut. Esta biblioteca también contiene métodos para describir y representar superficies y curvas cuádricas. Programación OpenGL en Java OpenGL es compatible con principales sistemas operativos, funciona con cualquier sistema de ventanas, y se puede utilizar desde muchos lenguajes de programación. Ofrece total independencia de los protocolos de red y topologías. En java existen APIs variadas que permite la escritura de aplicaciones OpenGL en java, por ejemplo las siguientes:
III) Prácticas 1) Configuración inicial de JOGL en Netbeans Esta práctica está destinado a practicar la implementación JOGL desde sus inicios. Ayuda a configurar una instalación reciente JOGL en Netbeans en Windows.
En primer lugar se necesita descargar JOGL. se puede descargar los últimos binarios JOGL de http://schabby.de/jogl-download/. Para esta práctica se utilizó los binarios:
Descargados estos archivos, debemos descomprimirlos y luego añadir a la librería de nuestra aplicación en java los paquetes de clases Jar siguientes:
Una vez cargados estos Jar en la librería crear las Renderer y Ventana como se muestra en la figura: Clase Ventana
Clase Renderer_Punto
Resultado: IV) Tarea 1) En base a la aplicación de la práctica modifique la aplicación cambiar el color de la ventana a blanco. 2) Modificar el programa de la práctica para dibujar puntos aleatorios en la ventana. 3) Modificar el programa de la práctica para que el programa pueda solicitar al usuario coordenadas de puntos para que se dibujen en la ventana. V) Referencias
Ejercicio 2: Modificar el programa de la práctica para dibujar puntos aleatorios en la ventana. La Clase Ventana no varia, solo se cambiar el Renderer_Punto utilizado en anteriores programas, por esta nueva clase Renderer_Punto_Aleatorios. El método Display es la que hace los dibujos en este caso dibuja puntos, se ha añadido un bucle for donde se genera puntos aleatorios con la el Math.Random y luego de ello se llama a un método que dibujo un punto, de esta manera obtenemos el dibujo de puntos. package geometrias.puntos;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GL
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
/**
*
* @author hernan
*/
public class Renderer_Punto_Aleatorios implements GLEventListener {
static final Logger logger = Logger.getLogger("BasicLoggingExample");
//
protected GL2 gl;
@Override
public void init(GLAutoDrawable gLDrawable) {
logger.log(Level.INFO, "método - init");
// Provee un objeto que enlaza las APIs del OpenGL
// Que se encargara de realizar las instrucciones de dibujos
gl = gLDrawable.getGL().getGL2();
// 6. Especificar el color del dibujo: Rojo
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glDrawBuffer(GL2.GL_FRONT_AND_BACK);
}
@Override
public void reshape(GLAutoDrawable glad, int x, int y, int width,
int height) {
logger.log(Level.INFO, "Reshape");
// 7. Especificar el área de dibujo (frame) utilizamos coordenadas
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(0, width, 0, height, -1.0, 1.0);
}
@Override
public void display(GLAutoDrawable drawable) {
for (int i = 1; i <= 20; i++) {
// 7. Generar un punto de coordenadas aleatorias
double x = Math.random() * 400;
double y = Math.random() * 400;
// Especificar aleatoriamente el color de dibujo
gl.glColor3d(Math.random(), Math.random(), Math.random());
gl.glPointSize(5);
// Dibujar un punto
dibujarPunto(x, y);
}
}
protected void dibujarPunto(double x, double y) {
gl.glBegin(GL.GL_POINTS);
gl.glVertex2d(x, y);
gl.glEnd();
}
@Override
public void dispose(GLAutoDrawable glad) {
// throw new UnsupportedOperationException("Not supported yet.");
}
} Resultado: Ejercicio 3) Modificar el programa de la práctica para añadir un panel de ingreso de valores de coordenadas x, y de un punto por el usuario, y en base a ello dibujar el punto correspondiente en la ventana. Para dar solución a este problema vamos a generar una nueva ventana la cual lleva el siguiente diseño de la figura. Se requiere, dos paneles para visualizar el gráfico de OpenGL y un panel de ingreso de datos. El diseño lo desarrollamos en la siguiente clase: Ventana_Entrada package geometrias.frontend;
import geometrias.puntos.Renderer_Punto_Entrada;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
public class Ventana_Entrada extends JFrame implements ActionListener {
// Atributos de Clase
// objetos de swing
private JPanel pOpenGL;
private JPanel pEntrada;
private JButton btnDibujar;
private JTextField txtX;
private JTextField txtY;
// objetos de libreria JOGL
private GLCanvas glCanvas;
// Objeto graficador de un punto
private Renderer_Punto_Entrada render_punto;
public Ventana_Entrada() {
inicializarVentana();
}
// Inicializar la ventana
private void inicializarVentana() {
// habilita el botón cerrar de la ventana
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Crear un panel para ubicar el graficador Opengl
pOpenGL = new JPanel(new BorderLayout());
pOpenGL.setBorder(new TitledBorder(
new EtchedBorder(), // Tipo de Borde
"OpenGL")); // Título del borde
// Añadir el graficador al panel de OpenGL
// 1. Configuración de OpenGL Version 2
GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities capabilities = new GLCapabilities(profile);
// 2. Canvas es el aplicativo gráfico que se empotra en un JFrame - Ventana
glCanvas = new GLCanvas(capabilities);
render_punto = new Renderer_Punto_Entrada();
glCanvas.addGLEventListener(render_punto);
pOpenGL.add(glCanvas); // Se añade el graficador OpenGL al panel
glCanvas.setSize(500,500);
// Crear el panel de entrada de datos
pEntrada = new JPanel();
pEntrada.setBorder(new TitledBorder(
new EtchedBorder(), // Tipo de Borde
"Datos de gráfico"));
// Añadir controles
JLabel lblX = new JLabel("X: ");
txtX = new JTextField(5);
JLabel lblY = new JLabel("Y: ");
txtY = new JTextField(5);
btnDibujar = new JButton("Dibujar");
// Añadir los controles al panel de entrada de datos
pEntrada.add(lblX);
pEntrada.add(txtY);
pEntrada.add(lblY);
pEntrada.add(txtX);
pEntrada.add(btnDibujar);
// hacer que el botón capte eventos cuando se hace click sobre él.
btnDibujar.addActionListener(this);
// Añadir los paneles en la ventana
// Obtener el contenedor de componentes
Container content = getContentPane();
content.add(pOpenGL, BorderLayout.CENTER);
content.add(pEntrada, BorderLayout.SOUTH);
// Mostrar ventana
pack();
setVisible(true);
}
/*
* Método para tratar eventos en el formulario.
*/
@Override
public void actionPerformed(ActionEvent e) {
// Identificar el objeto o control donde se genero el evento
Object source = e.getSource();
if (source == btnDibujar) { // si hay evento click en el botón
// ubicar las nuevas coordenadas del punto
int x = Integer.parseInt(txtX.getText());
int y = Integer.parseInt(txtY.getText());
// actualizar los valores de los puntos en el dibujador
render_punto.setX(x);
render_punto.setY(y);
// repintar el nuevo punto
glCanvas.repaint();
}
}
public static void main(String args[]) {
// iniciar la ventana
Ventana_Entrada ventana;
ventana = new Ventana_Entrada();
}
} La siguiente clase denominada Renderer_Punto_Entrada, se añade dos atributos x,y que representan las coordenadas el punto, estos valores son utilizados para dibujar el punto. package geometrias.puntos;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
/**
*
* @author hernan
*/
public class Renderer_Punto_Entrada implements GLEventListener {
static final Logger logger = Logger.getLogger("BasicLoggingExample");
//
protected GL2 gl;
private int x;
private int y;
public Renderer_Punto_Entrada() {
this.x = 0;
this.y = 0;
}
public Renderer_Punto_Entrada(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public void reshape(GLAutoDrawable glad, int x, int y, int width,
int height) {
logger.log(Level.INFO, "Reshape");
// 7. Especificar el área de dibujo (frame) utilizamos coordenadas
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(0, width, 0, height, -1.0, 1.0);
}
@Override
public void display(GLAutoDrawable drawable) {
gl.glClear(GL2.GL_COLOR_BUFFER_BIT);
// Especificar aleatoriamente el color de dibujo
gl.glColor3d(Math.random(), Math.random(), Math.random());
gl.glPointSize(10);
// Dibujar un punto
dibujarPunto(this.x, this.y);
}
protected void dibujarPunto(double x, double y) {
gl.glBegin(GL.GL_POINTS);
gl.glVertex2d(x, y);
gl.glEnd();
}
@Override
public void init(GLAutoDrawable glad) {
logger.log(Level.INFO, "método - init");
// Provee un objeto que enlaza las APIs del OpenGL
// Que se encargara de realizar las instrucciones de dibujos
gl = glad.getGL().getGL2();
// 6. Especificar el color del dibujo: Rojo
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glDrawBuffer(GL2.GL_FRONT_AND_BACK);
}
@Override
public void dispose(GLAutoDrawable glad) {
}
} Resultado: |