在Java中,欲處理3D可使用Java 3D API,除此之外,對於習慣OpenGL的開發者而言,Java Bindings for OpenGL (JOGL) 則是另一個不錯的選擇。
OpenGL其前身為IRIS GL,IRIS GL是Silicon Graphics Inc. (SGI) 為改進另一3D公開標準PHIGS (Programmer's Hierarchical Interactive Graphics System) 所開發的API,但由於SGI在開發IRIS GL時,其部份API並非與3D有關,而是與非標準之視窗、鍵盤及滑鼠有關,且由於牽涉到專利權的關係,因此SGI並未將IRIS GL定位為開放標準。至1992年,SGI以IRIS GL為基礎,宣佈成立OpenGL Architecture Review Board (OpenGL ARB),以開發及訂定OpenGL規格書。1995年,由於Microsoft發表Direct3D成為SGI OpenGL的最大競爭對手,此舉對SGI造成不少威脅,因此雙方於1997達成協議,試圖於兩者間建立標準的介面,但此計劃後來亦不了了之。
基本上,JOGL並非以Java重新開發OpenGL (雖然部份OpenGL的方法確實以Java改寫),而是在Java與OpenGL之間擔任中間銜接的角色,如同其名稱Binding一般,以下為各類程式語言與OpenGL間之銜接函式庫,JOGL則為其中之一:
- Delphi: Delphi OpenGL Toolkit (DOT).
- Fortran: Fortran 90 Bindings for OpenGL (F90GL).
- Java: Java Bindings for OpenGL (JOGL).
- Lightweight Java Game Library (LWJGL).
- Perl: Perl OpenGL (POGL).
- Python: Python OpenGL Bindings (PyOpenGL).
- Ruby: ruby-opengl.
- Visual Basic: OpenGL 1.1 ActiveX Control.
- jogl.jar
- jogl.dll
- jogl_awt.dll
- jogl_cg.dll
- gluegen-rt.jar
- gluegen-rt.dll
- JAVA_EXT=C:\jdk1.7.0\jre\lib\ext
- CLASSPATH=%CLASSPATH%;%JAVA_EXT%\jogl.jar;%JAVA_EXT%\gluegen-rt.jar
- PATH=%PATH%;%JAVA_EXT%\jogl.dll;%JAVA_EXT%\gluegen-rt.dll
- java.library.path=%JAVA_EXT%
- OpenGL Architecture Review Board, Dave Shreiner, Mason Woo, Jackie Neider, “OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 2 (5th Edition)”, Addison-Wesley Professional, 2005.
- OpenGL Architecture Review Board, Dave Shreiner, “OpenGL Reference Manual: The Official Reference Document to OpenGL, Version 1.4 (4th Edition)”, Addison-Wesley Professional, 2004.
- Randi J. Rost, "OpenGL Shading Language (2nd Edition)”, Addison-Wesley Professional, 2006.
- Richard S. Wright, Benjamin Lipchak, "OpenGL SuperBible (3rd Edition)”, SAMS, 2004.
- Tom McReynolds, David Blythe, "Advanced Graphics Programming Using OpenGL”, Morgan Kaufmann, 2005.
- Dave Astle, Kevin Hawkins, "Beginning OpenGL Game Programming", Course Technology PTR, 2004.
- Kevin Hawkins, Dave Astle, Andre LaMothe, "OpenGL Game Programming", Course Technology PTR, 2002.
- Dave Astle, "More OpenGL Game Programming", Course Technology PTR, 2005.
- javax.media.opengl
- javax.media.opengl.glu
- com.sun.opengl.cg
- com.sun.opengl.util
- com.sun.opengl.util.j2d
- com.sun.opengl.util.texture
- com.sun.opengl.util.texture.spi
在介紹JOGL的程式架構之前,首先介紹如何以C語言開發OpenGL程式,藉此比較C與Java兩者間之差異,請參考以下範例:
/* 以C語言開發OpenGL程式 */ /* DrawRect.c */ #include <windows.h> #include <gl/glut.h> /* 主程式 */ void main(void) { /* 設定顯示模式 */ glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); /* 建立視窗 */ glutCreateWindow("DrawRect"); /* 定義繪圖函式為自訂之RenderScene */ glutDisplayFunc(RenderScene); /* 定義當視窗大小改變時所呼叫之函式 */ glutReshapeFunc(ChangeSize); /* 自訂函式以初始化環境 */ Initialize(); /* 進入OpenGL迴圈 */ glutMainLoop(); } /* 初始化環境 */ void Initialize(void) { /* 以指定顏色清除背景 */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); } /* 繪圖 */ void RenderScene(void) { /* 以目前之顏色清除視窗 */ glClear(GL_COLOR_BUFFER_BIT); /* 設定目前繪圖顏色為紅色 */ glColor3f(1.0f, 0.0f, 0.0f); /* 繪製矩形並以目前顏色填滿面積 */ glRectf(100.0f, 150.0f, 150.0f, 100.0f); /* 即刻執行OpenGL指令 */ glFlush(); } /* 當視窗大小改變時 */ void ChangeSize(GLsizei w, GLsizei h) { /* 設定視界大小為視窗之大小 */ glViewport(0, 0, w, h); /* 重設座標系統*/ glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (0.0f, 250.0f, 0.0f, 250.0f*h/w, 1.0, -1.0); else glOrtho (0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } |
以C語言開發OpenGL程式,其中較重要的方法為:
- glutDisplayFunc():設定自訂的繪圖函式,為GLUT方法。
- glutReshapeFunc():設定當視窗大小改變時所呼叫的函式,為GLUT方法。
- glutMainLoop():進入OpenGL迴圈以偵測OpenGL相關狀態的改變,為GLUT方法。
- init(GLAutoDrawable drawable):初始化JOGL,可在此方法中定義JOGL之環境,如設定光源位置 (Light Position)、透視度 (Perspective) 等、或載入貼圖所需之圖像檔案,init()方法會在初次建立OpenGL Context之後執行,如同上述範例的Initialize()自訂函式般。
- display(GLAutoDrawable drawable):如同上述範例的glutDisplayFunc()方法中所定義的RenderScene()函式般,用以繪製圖形。
- reshape(GLAutoDrawable drawable, int x, int y, int width, int height):如同上述範例的glutReshapeFunc()方法中所定義之ChangeSize()函式般,當視窗大小改變時所呼叫的方法,通常在此方法中重設透視度 (Perspective) 及視界 (Viewport)。
- displayChanged(GLAutoDrawable drawable, boolean mode, boolean device):當顯示模式 (Display Mode) 或顯示裝置 (Display Device) 改變時所呼叫的方法,例如由16位元改為32位元顯示模式、或在支援虛擬多螢幕的顯示裝置中由一個螢幕移至另一螢幕。因此若無前述之改變,通常不需實作此方法之內容。
以GLCanvas類別實作GLEventListener介面的程式架構大致如下:
import java.awt.*; import java.awt.event.*; // JOGL import javax.media.opengl.*; import javax.media.opengl.glu.*; import com.sun.opengl.util.*; public class JOGLDemo extends Frame implements GLEventListener { ... // 建構函式 public JOGLDemo(){ ... // 建立GLCanvas物件 GLCanvas canvas = new GLCanvas(); // 註冊GLEventListener canvas.addGLEventListener(this); // 將GLCanvas物件加入Frame中 this.add(canvas); ... } // 實作GLEventListener介面的方法 // 初始化JOGL public void init(GLAutoDrawable drawable){...} // 繪製圖形 public void display(GLAutoDrawable drawable){...} // 當視窗大小改變時 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height){...} // 當顯示模式或裝置改變時 public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){...} } |
以GLJPanel類別實作GLEventListener介面的程式架構大致如下:
import java.awt.*; import java.awt.event.*; import javax.swing.*; // JOGL import javax.media.opengl.*; import javax.media.opengl.glu.*; import com.sun.opengl.util.*; public class JOGLDemo extends JFrame implements GLEventListener { ... // 建構函式 public JOGLDemo(){ ... // 建立GLJPanel物件 GLJPanel glpanel = new GLJPanel(); // 註冊GLEventListener glpanel.addGLEventListener(this); // 將GLJPanel物件加入JFrame中 this.add(glpanel); ... } // 實作GLEventListener介面的方法 // 初始化JOGL public void init(GLAutoDrawable drawable){...} // 繪製圖形 public void display(GLAutoDrawable drawable){...} // 當視窗大小改變時 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height){...} // 當顯示模式或裝置改變時 public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){...} } |
【執行結果】
【參考資料】
[1] Java Platform, Standard Edition 7, API Specification.
[2] Lance Williams, "Pyramidal Parametrics", Computer Graphics, Vol. 17 No.3, July 1983.
[3] Randi J. Rost, "OpenGL Shading Language (2nd Edition)", Addison-Wesley, 2006.
[4] Richard S. Wright, Benjamin Lipchak, "OpenGL SuperBible (3rd Edition)", SAMS, 2004.
[5] Delphi OpenGL Toolkit.
[6] Fortran 90 Bindings for OpenGL.
[7] GlueGen.
[8] JOAL.
[9] JOGL.
[10] LWJGL.
[11] OpenGL.
[12] Perl OpenGL.
[13] Python OpenGL Bindings.
[14] ruby-opengl.
[15] 黃嘉輝,完全探索網路程式設計 - 使用Java,上奇資訊。
[2] Lance Williams, "Pyramidal Parametrics", Computer Graphics, Vol. 17 No.3, July 1983.
[3] Randi J. Rost, "OpenGL Shading Language (2nd Edition)", Addison-Wesley, 2006.
[4] Richard S. Wright, Benjamin Lipchak, "OpenGL SuperBible (3rd Edition)", SAMS, 2004.
[5] Delphi OpenGL Toolkit.
[6] Fortran 90 Bindings for OpenGL.
[7] GlueGen.
[8] JOAL.
[9] JOGL.
[10] LWJGL.
[11] OpenGL.
[12] Perl OpenGL.
[13] Python OpenGL Bindings.
[14] ruby-opengl.
[15] 黃嘉輝,完全探索網路程式設計 - 使用Java,上奇資訊。
© Chia-Hui Huang
沒有留言:
張貼留言