Java OpenGL (JOGL) es una biblioteca que permite acceder a OpenGL mediante programación en Java. Actualmente está siendo desarrollado por el Game Technology Group de Sun Microsystems, y es la implementación de referencia para JSR-231 (Java Bindigs for OpenGL).

JOGL (JSR-231)
Información general
Tipo de programa Gráficos 3D por computadora (biblioteca/API)
Autor
  • Kenneth Bradley Russell
  • Christopher John Kline
Desarrollador Sun Microsystems Game Technology Group
Licencia BSD
Información técnica
Programado en Java
Plataformas admitidas máquina virtual Java
Versiones
Última versión estable 2.3.1 ( 27 de marzo de 2015)
Última versión en pruebas 2.3.1 ( 27 de marzo de 2015)
Enlaces

JOGL permite acceder a la mayoría de características disponibles para los programadores de C, con la excepción de las llamadas a ventanas realizadas en GLUT (ya que Java contiene sus propios sistemas de ventanas, AWT y Swing), y algunas extensiones de OpenGL.

Diseño

editar

La API OpenGL, escrita en C, es llamada por JOGL gracias a la Java Native Interface (JNI). Por tanto, el sistema en el que se está programando debe tener soporte para OpenGL para que pueda funcionar JOGL correctamente.

JOGL se diferencia de otras bibliotecas Java para OpenGL en que simplemente expone las funciones de la OpenGL, basadas en un lenguaje procedural (lenguaje C), por medio de métodos contenidos en unas pocas clases, en lugar de intentar realizar un mapeo completo del código OpenGL para transformarlo y adaptarlo al paradigma de orientación a objetos. De hecho, la mayoría del código de JOGL está en realidad autogenerado a partir de las cabeceras de las bibliotecas C de OpenGL, mediante una herramienta llamada Gluegen, que fue programada específicamente para dicho propósito.

Esta decisión en el diseño tiene sus ventajas y sus desventajas. La naturaleza procedural y de máquina de estados de OpenGL es inconsistente con la forma habitual de programar en Java, lo cual puede dejar perplejos a muchos programadores. Sin embargo, la conversión directa realizada de las funciones OpenGL a métodos Java, permite la conversión del código de aplicaciones C ya existentes mucho más simple. La fina capa de abstracción proporcionada por JOGL hace que la ejecución sea muy eficiente, aunque resulta mucho más difícil de programar que otras bibliotecas de mucho más alto nivel como Java3D. Dado que la mayoría del código está autogenerado, los cambios que se produzcan en OpenGL son rápidamente adaptados a JOGL.

Estado y estandarización

editar

En 2007, JOGL proporciona acceso completa a la especificación 2.0 de OpenGL.

Es la implementación de referencia para la especificación JSR-231 (Java Bindings for OpenGL).

Interoperatibilidad Java2D / OpenGL

editar

Dado que en la versión Java SE 6 de Java, la API Java2D (que permite crear gráficos de dos dimensiones en Java) y JOGL son interoperables, esto permite que:

  • Se puedan sobreescribir componentes Swing mediante renderizado en OpenGL.
  • Se puede dibujar gráficos 3D mediante OpenGL sobre Java2D (hay un ejemplo aquí en el que se crea un botón mediante OpenGL).

Ejemplo de la programación de una Pirámide 3D

editar

Este programa dibuja una pirámide 3D mediante JOGL.

JavaRenderer class — Esta clase usa GLAutoDrawable para generar la escena.

 import javax.media.opengl.GL;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLAutoDrawable;
 import javax.media.opengl.glu.GLU;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 
 public class JavaRenderer implements GLEventListener, KeyListener {
    private float rotateT = 0.0f;
    private static final GLU glu = new GLU();
 
    public void display(GLAutoDrawable gLDrawable) {
        final GL gl = gLDrawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        gl.glTranslatef(0.0f, 0.0f, -5.0f);
 
        gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
        gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
        gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
 
        gl.glBegin(GL.GL_TRIANGLES);
 
        // Front
        gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
 
        // Right Side Facing Front
        gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
 
        // Left Side Facing Front
        gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
        gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
        gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
 
        // Bottom
        gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.1f, 0.1f, 0.1f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
        gl.glColor3f(0.2f, 0.2f, 0.2f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
 
        gl.glEnd();
 
        rotateT += 0.2f;
    }
 
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
    }
 
    public void init(GLAutoDrawable gLDrawable) {
        final GL gl = gLDrawable.getGL();
        gl.glShadeModel(GL.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        gLDrawable.addKeyListener(this);
    }
 
    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
        final GL gl = gLDrawable.getGL();
        if(height <= 0) {
            height = 1;
        }
        final float h = (float)width / (float)height;
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(50.0f, h, 1.0, 1000.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
 
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            // no hace falta llamar al método Animator#stop()
            System.exit(0);
        }
    }
 
    public void keyReleased(KeyEvent e) {
    }
 
    public void keyTyped(KeyEvent e) {
    }
 }

Main class—El código dibuja la escena en la GLCanvas.

 import javax.media.opengl.GLCanvas;
 import java.awt.Frame;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import com.sun.opengl.util.Animator;
 
 public class Main {     
     public static void main(String[] args) {
         Main app = new Main();
         app.createAndRun();
     }
 
     public void createAndRun() {
         Frame frame = new Frame("Jogl 3d Shape/Rotation");
         GLCanvas canvas = new GLCanvas();
         Animator animator = new Animator(canvas);
         animator.start();
         canvas.addGLEventListener(new JavaRenderer());
         frame.add(canvas);
         frame.setSize(640, 480);
         frame.setUndecorated(true);
         int size = frame.getExtendedState();
         size |= Frame.MAXIMIZED_BOTH;
         frame.setExtendedState(size);
 
         frame.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 // no hace falta llamar al método Animator#stop()si marca error eliminenla
                 animator.stop();
                 System.exit(0);
             }
         });
         frame.setVisible(true);
         canvas.requestFocus();
     }
 }

Véase también

editar
  • Xith3D : una API de desarrollo gráfico que usa JOGL.
  • JMonkey Engine : una API de desarrollo gráfico que usaba JOGL (hasta que fue sustituida por LWJGL).
  • LWJGL : otra biblioteca Java que permite el acceso a OpenGL.
  • OpenGL

Enlaces externos

editar