然後出現了JOGL
Java也許是最流行的真正的面向對象的編程語言有許多用Java去結合OpenGL的嘗試但是第一個被大家認可並注意的是Java對於OpenGl的綁定(Java Bindings for OpenGL) 或者稱為JOGL理由是它得到Sun(Java的創建者)和SGI(OpenGL的創建者)的支持
如今Sun的游戲開發小組正在開發JOGL它是以肯拉塞爾和克裡斯克蘭開發的Jungle開始的拉塞爾是Sun的員工研發HotSpot虛擬機擁有多年的三維經驗克蘭則研發荒謬的游戲對三維圖形學也相當有經驗
我個人對他們以及所有其它工作在JOGL上的人表示感謝曾經有許多想通過友好的Java API來使用OpenGL的嘗試——其中包括Java D OpenGL for Java Technology (gljava)(用於Java技術的OpenGL)Lightweight Java Game Library (LWJGL)(輕量級的Java游戲庫)JOGL是第一個使我感到滿意的
JOGL是Sun支持的對於OpenGl的Java類綁定哇!這句話說得太妙了
OpenGL被用來展示三維模型它強大快速而且可能是自Swing出現以來最棒的一樣東西通過JOGL來使用OpenGL你可以制作出很酷的游戲或是模型位置什麼的而在這之前創建它們需要非常昂貴的成本有人寫了很厚很厚的書來描述OpenGL當你熟悉了它們以後這些書會很有用但現在不行你必須學習展現在你面前的OpenGL是如何使用Java API的同樣你還得看一下關於netjavagamesjogl*的基礎介紹可能還得補習一下數學知識
獲取JOGL?
如果你想使用JOGL你需要得到jogljar以及附帶的本機代碼我希望有一天它可以成為Java的標准安裝但現在它只是一個夢想
第一步是要找到你的操作系統所對應的包並進行解壓縮我是在/l上找到的不同的操作系統有所區別但需要安裝個部分系統的classpath裡一定要有jogljar而且binary庫必須放在和你操作系統的庫同一個地方如果比較幸運的話安裝程序可以為你完成這些如果你沒有安裝程序而且不知道該上哪裡去尋找關於設置計算機的信息的話你可以從我提供一個鏈接Resources開始搜索我們的第一篇代碼是特別用來測試環境是否安裝正確的所以對於測試安裝你不必緊張
JOGL的Javadocs
同樣可以在和JOGL 的binary 發布版一樣的位置獲得JavadocsJavadocs將會以類似joglusrdoctar的名字而命名
如果你浏覽一下netjavagamesjogl包你很快會注意到有些類非常大GL便是一個完美的例子別被這個嚇跑了你很快能發現只需一點點JOGL的知識你就可以完成一些相當復雜的事了現在你需要掃視一下的類有*GLDrawable *GLCanvas *GLJPanel *GLCapabilities *GLDrawableFactory
這些是連接圖形世界基本的接口如果你還記得前面我提到對於初學OpenGL的人來說有一個很大的缺點那就是缺乏窗口系統的標准對應於C語言GLUT起到了相當大的作用而我們則有Swing和AWT(抽象窗口工具箱)很可能你已經使用過AWT或者Swing了所以你不會感到自己在從頭學起這是件非常好的事情在通過了非常簡短的關於把JOGL組件放置到屏幕上的介紹以後我們不需要多長時間就可以運行出一個相當酷而且流行的程序了
GlueGen……幾乎和JOGL一樣酷?
你應該意識到OpenGL是為C程序員而寫的這意味著Java想要利用它必須要用到本機接口不那麼有趣的JNI(Java本機接口)必須用來進行此連接OpenGL太大了手寫所有的連接太費時想稍微做出一點復雜的程序有許多特別出售的特性OpenGL則保持改進那意味著得有相應的變化來跟上OpenGL的步伐簡而言之對於任何試著寫與OpenGL保持同步包含所有Java到本機的接口的代碼的嘗試是非常困難的
讓我們進入JOGL家族看看他們打算利用C頭文件寫一些代碼來實現一切JNI做的事他們管這個叫做GlueGenGlueGen解析C頭文件然後魔法般地創建出Java和JNI代碼以便連接到本機庫這意味著OpenGL的升級可以迅速地在JOGL裡體現
Hello World!
我是一個很傳統的人所以當然我們將從你好世界程序開始這個你好世界程序將檢驗我們的安裝是否全部或者一部分安裝正確回憶一下安裝JOGL有個部分分別是jar文件裡的Java庫以及其它庫的本機代碼
以下是我們的程序import netjavagamesjogl*public class HelloWorld { public static void main (String args[]) { try { SystemloadLibrary(jogl) Systemoutprintln( Hello World! (The native libraries are installed) ) GLCapabilities caps = new GLCapabilities() Systemoutprintln( Hello JOGL! (The jar appears to be available) ) } catch (Exception e) { Systemoutprintln(e) } }}
首先這個程序測試了本機庫和Java庫是否已經安裝正確了只有當jogljar和本機庫(名字諸如libjogljnilib或者jogldll)兩者都安裝好了的時候JOGL才算是安裝完全的如果本機庫不可用程序會拋javalangUnsatisfiedLinkError例外如果classpath裡沒有安裝JAR程序則根本編譯都通不過Javac編譯器會報諸如此類的錯netjavagamesjogl包不存在當這個程序編譯通過且運行起來沒有異常的話你可以繼續學習JOGL了
一個好的模板
當你對JOGL感到思維混亂的時候讓我們來繼續看幾個類你可以把它們當成有用的模板來使用我已經不止一次把它們當成模板用了你可以隨心所欲地使用它們
這個模板由兩個類組成第一個是如下所示的SimpleJoglApp第二個是在簡短說明之後的SimpleGLEventListener你必須輸入兩個類來編譯模板主程序如下import javaawt*import javaawtevent*import javaxswing*import netjavagamesjogl*/** * This is a basic JOGL app Feel free to * reuse this code or modify it * 這是個基礎的JOGL程序你可以隨意重用該代碼或者修改它 */public class SimpleJoglApp extends JFrame { public static void main(String[] args) { final SimpleJoglApp app = new SimpleJoglApp() // show what weve done //看一下我們做了什麼 SwingUtilitiesinvokeLater ( new Runnable() { public void run() { appsetVisible(true) } } ) } public SimpleJoglApp() { //set the JFrame title //設置JFrame標題 super(Simple JOGL Application) //kill the process when the JFrame is closed //當JFrame關閉的時候結束進程 setDefaultCloseOperation(JFrameEXIT_ON_CLOSE) //only three JOGL lines of code …… and here they are //只有三行JOGL代碼 …… 如下 GLCapabilities glcaps = new GLCapabilities() GLCanvas glcanvas = GLDrawableFactorygetFactory()createGLCanvas(glcaps) glcanvasaddGLEventListener(new SimpleGLEventListener()) //add the GLCanvas just like we would any Component //像其它組件一樣把GLCanvas加入 getContentPane()add(glcanvas BorderLayoutCENTER) setSize( ) //center the JFrame on the screen //使JFrame顯示在屏幕中央 centerWindow(this) } public void centerWindow(Component frame) { Dimension screenSize = ToolkitgetDefaultToolkit()getScreenSize() Dimension frameSize = framegetSize() if (frameSizewidth > screenSizewidth ) frameSizewidth = screenSizewidth if (frameSizeheight > screenSizeheight) frameSizeheight = screenSizeheight framesetLocation ( (screenSizewidth frameSizewidth ) >> (screenSizeheight frameSizeheight) >> ) }}
代碼就是這些讓我們把注意力集中在第一個類中與JOGL相關的三行代碼上首先
這決定了我們的JOGL庫和JVM可以使用哪些OpenGL/圖形特色
接著GLCanvas glcanvas = GLDrawableFactorygetFactory()createGLCanvas(glcaps)
我們不能創建GLCanvas或者GLJPanel我們得用GLDrawableFactory來創建它們所以我們用GLDrawableFactory的靜態方法getFactory()取得了GLDrawableFactory
現在我們有GLDrawableFactory了所以我們用createGLCanvas()方法來創建了可以往上畫畫的GLCanvas如果我們不需要AWT組件而是Swing組件則可以用createGLJPanel()方法
注意我們把先前創建的GLCapabilities對象傳了進去這可以使我們創建的GLDrawable適當的所創建
最後我們准備往GLCanvas上加GLEventListener
我們對GLEventListener的實現是SimpleGLEventListener它負責當接到GLDrawable或我們的或只是GLCanvas的調用時所需要完成的所有繪圖工作你將會看到我不打算在這個程序裡畫任何東西下面是GLEventListener的代碼import javaawt*import javaawtevent*import netjavagamesjogl*/*** For our purposes only two of the* GLEventListeners matter Those would* be init() and display()* 為了達到我們的目的GLEventListener中只有兩個方法有用* 它們是init()和display()*/public class SimpleGLEventListener implements GLEventListener{ /** * Take care of initialization here * 注意這裡的初始化 */ public void init(GLDrawable drawable) { } /** * Take care of drawing here * 注意這裡的繪圖 */ public void display(GLDrawable drawable) { } /** * Called when the GLDrawable (GLCanvas * or GLJPanel) has changed in size We * wont need this but you may eventually * need it —— just not yet * 當GLDrawable(GLCanvas或GLJPanel)大小改變時被調用 * 我們不需要它但你可能最後會用到——雖然現在並不需要 */ public void reshape( GLDrawable drawable int x int y int width int height ) {} /** * If the display depth is changed while the * program is running this method is called * Nowadays this doesnt happen much unless * a programmer has his program do it * 當程序運行時顯示深度被改變的時候此方法被調用 * 現在這種事發生得不多除非程序裡面觸發此事 */ public void displayChanged( GLDrawable drawable boolean modeChanged boolean deviceChanged ) {}}
以上就是我們要完成的JOGL核心工作注意下面的UML圖SimpleJoglApp是一個JFrame它容納了GLDrawable實際上是一個GLCanvas但不要那樣稱呼它我們加入了SimpleGLEventListenerSimpleGLEventListener實現了對於GLCanvas的GLEventListener這樣當它想執行任何的OpenGL 工作的時候GLCanvas就可以知道GLDrawables能自動執行所以你確實得使你的GLEventListener最優化
這個程序運行起來可能會根據你的操作系統顯得有點亂七八糟這是預料之中的因為你在這裡只是往屏幕上顯示隨機的內存所以恭喜你具有了圖形創新的才能了
准備實戰
當你熟悉了前面的例子以後我們來畫一張漂亮的圖
這就是你接下來的程序請確保你輸入了所有的代碼到你的編輯器中調試這些程序可以快速地使你明白它們的工作原理
import javaawt*import javaawtevent*import javaxswing*import netjavagamesjogl*/*** This is a basic JOGL app Feel free to* reuse this code or modify it* 這是個基礎的JOGL程序你可以隨意重用該代碼或者修改它*/public class SecondJoglApp extends JFrame { public static void main(String[] args) { final SecondJoglApp app = new SecondJoglApp() //show what weve done //看一下我們做了什麼 SwingUtilitiesinvokeLater ( new Runnable() { public void run() { appsetVisible(true) } } ) } public SecondJoglApp() { //set the JFrame title //設置JFrame標題 super(Second JOGL Application) //kill the process when the JFrame is closed //當JFrame關閉的時候結束進程 setDefaultCloseOperation(JFrameEXIT_ON_CLOSE) //only three JOGL lines of code …… and here they are //只有三行JOGL代碼 …… 如下 GLCapabilities glcaps = new GLCapabilities() GLCanvas glcanvas = GLDrawableFactorygetFactory()createGLCanvas(glcaps) glcanvasaddGLEventListener(new SecondGLEventListener()) //add the GLCanvas just like we would any Component //像其它組件一樣把GLCanvas加入 getContentPane()add(glcanvas BorderLayoutCENTER) setSize( ) //center the JFrame on the screen //使JFrame顯示在屏幕中央 centerWindow(this) } public void centerWindow(Component frame) { Dimension screenSize = ToolkitgetDefaultToolkit()getScreenSize() Dimension frameSize = framegetSize() if (frameSizewidth > screenSizewidth ) frameSizewidth = screenSizewidth if (frameSizeheight > screenSizeheight) frameSizeheight = screenSizeheight framesetLocation ( (screenSizewidth frameSizewidth ) >> (screenSizeheight frameSizeheight) >> ) }}
請注意這個類對於第一個類所作的改動改動只有類名frame名以及GLEventListener名希望你能夠閱讀代碼中的注釋否則你會搞不清它要做什麼
我們實現的GLEventListener確實相對於前面一個例子有了一些改進它允許我們畫出一些漂亮的圖來
import netjavagamesjogl*/*** For our purposes only two of the GLEventListeners matter* Those would be init() and display()* 為了達到我們的目的GLEventListener中只有兩個方法有用* 它們是init()和display()*/public class SecondGLEventListener implements GLEventListener{ /** * Take care of initialization here * 注意這裡的初始化 */ public void init(GLDrawable gld) { GL gl = gldgetGL() GLU glu = gldgetGLU() glglClearColor(f f f f) glglViewport( ) glglMatrixMode(GLGL_PROJECTION) glglLoadIdentity() glugluOrthoD( ) } /** * Take care of drawing here * 注意這裡的繪圖 */ public void display(GLDrawable drawable) { float red = f float green = f float blue = f GL gl = drawablegetGL() glglClear(GLGL_COLOR_BUFFER_BIT) glglPointSize(f) for (int i= i< i++) { red = f green = f blue = f if (red < ) red = f if (green < ) green = f if (blue < ) blue = f glglColorf(red green blue) glglBegin(GLGL_POINTS) glglVertexi((i*) ) glglEnd() }}public void reshape( GLDrawable drawable int x int y int width int height ) {}public void displayChanged( GLDrawable drawable boolean modeChanged boolean deviceChanged ) {}}
以上就是我們第一個有趣的JOGL程序下圖是輸出有很多好看的顏色
當你看到GLEventListener的實現時可能會感到不知所措如果你有用C語言編寫OpenGL程序的經驗的話你也許能猜測出一些東西如果你覺得比較茫然不必擔心也不要擔心我會讓你記住這些東西至少現在不必本書接下來的篇幅將會對這個例子中的SecondGLEventListener作出解釋現在你只需要試著去猜測試著去修改代碼產生兩行或者一行斜的而不是一行水平線或是讓所有的點都變成藍色或紅色盡情娛樂這就是你接下來學習JOGL的方式
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19394.html