文章詳情頁
你好,JOGL - Java與OpenGl的綁定
瀏覽:84日期:2024-06-06 16:57:40
內(nèi)容: 摘要在這篇文章里,摘錄了《學(xué)習(xí)Java對于OpenGl的綁定》。作者吉恩戴維斯解釋了如何開始用Java對于OpenGl的綁定開發(fā)圖形增強(qiáng)的程序這些年來,為了創(chuàng)建一個(gè)圖形增強(qiáng)的程序,從而出售給使用各種不同操作系統(tǒng)的用戶,程序員有一個(gè)選擇——OpenGL。GL代表圖形庫(graphics library)。OpenGL是SGI(美國圖形工作站生產(chǎn)廠商)的注冊商標(biāo)。OpenGL顯示了它是一個(gè)跨平臺(tái)的C語言編程API。但是事實(shí)上,在編程接口上,它是一個(gè)與硬件無關(guān)的規(guī)范。OpenGL是用來制圖的,速度非常快。大多數(shù)場合下,它是硬件加速的。看起來好像OpenGL可以實(shí)現(xiàn)一切你想要完成的圖形界面。不幸的是,OpenGL是為C語言而寫的。不得不承認(rèn),C語言不是用來編寫復(fù)雜應(yīng)用程序的流行語言。關(guān)于OpenGL一個(gè)最大的缺點(diǎn)就是:如果你不創(chuàng)建一個(gè)窗口(用來把你的圖形放入其中),你就什么都做不了。但是OpenGL沒有提供給你創(chuàng)建窗口的方法。這使得OpenGL對于初學(xué)者來說顯得比較難。幸運(yùn)地是,出現(xiàn)了GLUT (OpenGL Utility Toolkit)(OpenGL工具包)。它被用來輕松應(yīng)對窗口、按鈕以及用戶事件。盡管如此,對于想要使用面向?qū)ο蟮木幊痰某绦騿T來說,學(xué)習(xí)用C或者C++來編寫OpenGL程序仍然是一件痛苦的事。版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時(shí)請務(wù)必保留以下作者信息和鏈接作者:Gene Davis;chenroc(作者的blog:http://blog.matrix.org.cn/page/chenroc)原文:http://www.javaworld.com/javaworld/jw-02-2005/jw-0221-jogl.html譯文:http://www.matrix.org.cn/resource/article/44/44274_JOGL+OpenGl+Java.html關(guān)鍵字:JOGL;OpenGl然后出現(xiàn)了JOGLJava也許是最流行的真正的面向?qū)ο蟮木幊陶Z言。有許多用Java去結(jié)合OpenGL的嘗試,但是第一個(gè)被大家認(rèn)可并注意的是Java對于OpenGl的綁定(Java Bindings for OpenGL), 或者稱為JOGL。理由是它得到Sun(Java的創(chuàng)建者)和SGI(OpenGL的創(chuàng)建者)的支持。如今,Sun的游戲開發(fā)小組正在開發(fā)JOGL。它是以肯·拉塞爾和克里斯·克蘭開發(fā)的Jungle開始的。拉塞爾是Sun的員工,研發(fā)“HotSpot虛擬機(jī),擁有多年的三維經(jīng)驗(yàn)。克蘭則研發(fā)“荒謬的游戲,對三維圖形學(xué)也相當(dāng)有經(jīng)驗(yàn)。我個(gè)人對他們以及所有其它工作在JOGL上的人表示感謝。曾經(jīng)有許多想通過友好的Java API來使用OpenGL的嘗試——其中包括Java 3D, OpenGL for Java Technology (gl4java)(用于Java技術(shù)的OpenGL),Lightweight Java Game Library (LWJGL)(輕量級的Java游戲庫)。JOGL是第一個(gè)使我感到滿意的。JOGL是Sun支持的對于OpenGl的Java類綁定。哇!這句話說得太妙了。OpenGL被用來展示三維模型。它強(qiáng)大、快速,而且可能是自Swing出現(xiàn)以來最棒的一樣?xùn)|西。通過JOGL來使用OpenGL,你可以制作出很酷的游戲或是模型位置什么的,而在這之前創(chuàng)建它們需要非常昂貴的成本。有人寫了很厚很厚的書來描述OpenGL,當(dāng)你熟悉了它們以后這些書會(huì)很有用,但現(xiàn)在不行。你必須學(xué)習(xí)展現(xiàn)在你面前的OpenGL是如何使用Java API的。同樣你還得看一下關(guān)于net.java.games.jogl.*的基礎(chǔ)介紹,可能還得補(bǔ)習(xí)一下數(shù)學(xué)知識(shí)。獲取JOGL?如果你想使用JOGL,你需要得到j(luò)ogl.jar以及附帶的本機(jī)代碼。我希望有一天它可以成為Java的標(biāo)準(zhǔn)安裝,但現(xiàn)在它只是一個(gè)夢想。第一步是要找到你的操作系統(tǒng)所對應(yīng)的包,并進(jìn)行解壓縮。我是在http://www.javaworld.com/javaworld/jw-02-2005/jw-0221-jogl.html#resources上找到的。不同的操作系統(tǒng)有所區(qū)別,但需要安裝2個(gè)部分。系統(tǒng)的classpath里一定要有jogl.jar,而且binary庫必須放在和你操作系統(tǒng)的庫同一個(gè)地方。如果比較幸運(yùn)的話,安裝程序可以為你完成這些。如果你沒有安裝程序而且不知道該上哪里去尋找關(guān)于設(shè)置計(jì)算機(jī)的信息的話,你可以從我提供一個(gè)鏈接Resources開始搜索。我們的第一篇代碼是特別用來測試環(huán)境是否安裝正確的,所以對于測試安裝你不必緊張。JOGL的Javadocs同樣可以在和JOGL 的binary 發(fā)布版一樣的位置獲得Javadocs。Javadocs將會(huì)以類似jogl-1.0-usrdoc.tar的名字而命名。如果你瀏覽一下net.java.games.jogl包,你很快會(huì)注意到有些類非常大。GL便是一個(gè)完美的例子。別被這個(gè)嚇跑了,你很快能發(fā)現(xiàn)只需一點(diǎn)點(diǎn)JOGL的知識(shí),你就可以完成一些相當(dāng)復(fù)雜的事了。現(xiàn)在你需要掃視一下的類有:*GLDrawable *GLCanvas *GLJPanel *GLCapabilities *GLDrawableFactory這些是連接圖形世界基本的接口。如果你還記得,前面我提到對于初學(xué)OpenGL的人來說,有一個(gè)很大的缺點(diǎn),那就是缺乏窗口系統(tǒng)的標(biāo)準(zhǔn)。對應(yīng)于C語言,GLUT起到了相當(dāng)大的作用。而我們則有Swing和AWT(抽象窗口工具箱)。很可能你已經(jīng)使用過AWT或者Swing了,所以你不會(huì)感到自己在從頭學(xué)起。這是件非常好的事情。在通過了非常簡短的關(guān)于把JOGL組件放置到屏幕上的介紹以后,我們不需要多長時(shí)間就可以運(yùn)行出一個(gè)相當(dāng)酷而且流行的程序了。GlueGen...幾乎和JOGL一樣酷?你應(yīng)該意識(shí)到,OpenGL是為C程序員而寫的。這意味著Java想要利用它,必須要用到本機(jī)接口。不那么有趣的JNI(Java本機(jī)接口)必須用來進(jìn)行此連接。OpenGL太大了,手寫所有的連接太費(fèi)時(shí)。想稍微做出一點(diǎn)復(fù)雜的程序,有許多特別出售的特性,OpenGL則保持改進(jìn),那意味著得有相應(yīng)的變化來跟上OpenGL的步伐。簡而言之,對于任何試著寫與OpenGL保持同步,包含所有Java到本機(jī)的接口的代碼的嘗試,是非常困難的。讓我們進(jìn)入JOGL家族看看。他們打算利用C頭文件寫一些代碼來實(shí)現(xiàn)一切JNI做的事。他們管這個(gè)叫做GlueGen。GlueGen解析C頭文件然后魔法般地創(chuàng)建出Java和JNI代碼以便連接到本機(jī)庫。這意味著OpenGL的升級可以迅速地在JOGL里體現(xiàn)。Hello World!我是一個(gè)很傳統(tǒng)的人,所以當(dāng)然我們將從“你好世界程序開始。這個(gè)“你好世界程序?qū)z驗(yàn)我們的安裝是否全部或者一部分安裝正確。回憶一下安裝JOGL有2個(gè)部分,分別是jar文件里的Java庫以及其它庫的本機(jī)代碼。以下是我們的程序:import net.java.games.jogl.*;public class HelloWorld { public static void main (String args[]) { try { System.loadLibrary('jogl'); System.out.println( 'Hello World! (The native libraries are installed.)' ); GLCapabilities caps = new GLCapabilities(); System.out.println( 'Hello JOGL! (The jar appears to be available.)' ); } catch (Exception e) { System.out.println(e); } }} 首先,這個(gè)程序測試了本機(jī)庫和Java庫是否已經(jīng)安裝正確了。只有當(dāng)jogl.jar和本機(jī)庫(名字諸如libjogl.jnilib或者jogl.dll)兩者都安裝好了的時(shí)候,JOGL才算是安裝完全的。如果本機(jī)庫不可用,程序會(huì)拋java.lang.UnsatisfiedLinkError例外。如果classpath里沒有安裝JAR,程序則根本編譯都通不過。Javac編譯器會(huì)報(bào)諸如此類的錯(cuò)“net.java.games.jogl包不存在。當(dāng)這個(gè)程序編譯通過且運(yùn)行起來沒有異常的話,你可以繼續(xù)學(xué)習(xí)JOGL了。一個(gè)好的模板當(dāng)你對JOGL感到思維混亂的時(shí)候,讓我們來繼續(xù)看幾個(gè)類,你可以把它們當(dāng)成有用的模板來使用。我已經(jīng)不止一次把它們當(dāng)成模板用了。你可以隨心所欲地使用它們。這個(gè)模板由兩個(gè)類組成。第一個(gè)是如下所示的SimpleJoglApp,第二個(gè)是在簡短說明之后的SimpleGLEventListener。你必須輸入兩個(gè)類來編譯模板。主程序如下:import java.awt.*;import java.awt.event.*;import javax.swing.*;import net.java.games.jogl.*;/** * This is a basic JOGL app. Feel free to * reuse this code or modify it. * 這是個(gè)基礎(chǔ)的JOGL程序,你可以隨意重用該代碼或者修改它。 */public class SimpleJoglApp extends JFrame { public static void main(String[] args) { final SimpleJoglApp app = new SimpleJoglApp(); // show what we've done //看一下我們做了什么 SwingUtilities.invokeLater ( new Runnable() { public void run() { app.setVisible(true); } } ); } public SimpleJoglApp() { //set the JFrame title //設(shè)置JFrame標(biāo)題 super('Simple JOGL Application'); //kill the process when the JFrame is closed //當(dāng)JFrame關(guān)閉的時(shí)候,結(jié)束進(jìn)程 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //only three JOGL lines of code ... and here they are //只有三行JOGL代碼 ... 如下 GLCapabilities glcaps = new GLCapabilities(); GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); glcanvas.addGLEventListener(new SimpleGLEventListener()); //add the GLCanvas just like we would any Component //像其它組件一樣把GLCanvas加入 getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); //center the JFrame on the screen //使JFrame顯示在屏幕中央 centerWindow(this); } public void centerWindow(Component frame) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.width> screenSize.width ) frameSize.width = screenSize.width; if (frameSize.height> screenSize.height) frameSize.height = screenSize.height; frame.setLocation ( (screenSize.width - frameSize.width )>> 1, (screenSize.height - frameSize.height)>> 1 ); }} 代碼就是這些。讓我們把注意力集中在第一個(gè)類中與JOGL相關(guān)的三行代碼上。首先:這決定了我們的JOGL庫和JVM可以使用哪些OpenGL/圖形特色。接著:GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); 我們不能創(chuàng)建GLCanvas或者GLJPanel。我們得用GLDrawableFactory來創(chuàng)建它們。所以我們用GLDrawableFactory的靜態(tài)方法getFactory()取得了GLDrawableFactory。現(xiàn)在我們有GLDrawableFactory了。所以我們用createGLCanvas()方法來創(chuàng)建了可以往上畫畫的GLCanvas。如果我們不需要AWT組件,而是Swing組件,則可以用createGLJPanel()方法。注意我們把先前創(chuàng)建的GLCapabilities對象傳了進(jìn)去。這可以使我們創(chuàng)建的GLDrawable適當(dāng)?shù)乃鶆?chuàng)建。最后,我們準(zhǔn)備往GLCanvas上加GLEventListener。我們對GLEventListener的實(shí)現(xiàn)是SimpleGLEventListener。它負(fù)責(zé)當(dāng)接到GLDrawable或我們的或只是GLCanvas的調(diào)用時(shí),所需要完成的所有繪圖工作。你將會(huì)看到,我不打算在這個(gè)程序里畫任何東西。下面是GLEventListener的代碼:import java.awt.*;import java.awt.event.*;import net.java.games.jogl.*;/*** For our purposes only two of the* GLEventListeners matter. Those would* be init() and display().* 為了達(dá)到我們的目的,GLEventListener中只有兩個(gè)方法有用。* 它們是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 * won't need this, but you may eventually * need it -- just not yet. * 當(dāng)GLDrawable(GLCanvas或GLJPanel)大小改變時(shí)被調(diào)用。 * 我們不需要它,但你可能最后會(huì)用到——雖然現(xiàn)在并不需要。 */ 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 doesn't happen much, unless * a programmer has his program do it. * 當(dāng)程序運(yùn)行時(shí)顯示深度被改變的時(shí)候此方法被調(diào)用。 * 現(xiàn)在這種事發(fā)生得不多,除非程序里面觸發(fā)此事。 */ public void displayChanged(GLDrawable drawable,boolean modeChanged,boolean deviceChanged) {}} 以上就是我們要完成的JOGL核心工作。注意下面的UML圖。SimpleJoglApp是一個(gè)JFrame。它容納了GLDrawable,實(shí)際上是一個(gè)GLCanvas,但不要那樣稱呼它。我們加入了SimpleGLEventListener。SimpleGLEventListener實(shí)現(xiàn)了對于GLCanvas的GLEventListener,這樣當(dāng)它想執(zhí)行任何的OpenGL 工作的時(shí)候,GLCanvas就可以知道。GLDrawables能自動(dòng)執(zhí)行,所以你確實(shí)得使你的GLEventListener最優(yōu)化。這個(gè)程序運(yùn)行起來可能會(huì)根據(jù)你的操作系統(tǒng)顯得有點(diǎn)亂七八糟。這是預(yù)料之中的,因?yàn)槟阍谶@里只是往屏幕上顯示隨機(jī)的內(nèi)存。所以恭喜你具有了圖形創(chuàng)新的才能了。準(zhǔn)備實(shí)戰(zhàn)當(dāng)你熟悉了前面的例子以后,我們來畫一張漂亮的圖。這就是你接下來的程序。請確保你輸入了所有的代碼到你的編輯器中。調(diào)試這些程序可以快速地使你明白它們的工作原理。import java.awt.*;import java.awt.event.*;import javax.swing.*;import net.java.games.jogl.*;/*** This is a basic JOGL app. Feel free to* reuse this code or modify it.* 這是個(gè)基礎(chǔ)的JOGL程序,你可以隨意重用該代碼或者修改它。*/public class SecondJoglApp extends JFrame { public static void main(String[] args) { final SecondJoglApp app = new SecondJoglApp(); //show what we've done //看一下我們做了什么 SwingUtilities.invokeLater ( new Runnable() { public void run() { app.setVisible(true); } } ); } public SecondJoglApp() { //set the JFrame title //設(shè)置JFrame標(biāo)題 super('Second JOGL Application'); //kill the process when the JFrame is closed //當(dāng)JFrame關(guān)閉的時(shí)候,結(jié)束進(jìn)程 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //only three JOGL lines of code ... and here they are //只有三行JOGL代碼 ... 如下 GLCapabilities glcaps = new GLCapabilities(); GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); glcanvas.addGLEventListener(new SecondGLEventListener()); //add the GLCanvas just like we would any Component //像其它組件一樣把GLCanvas加入 getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); //center the JFrame on the screen //使JFrame顯示在屏幕中央 centerWindow(this); } public void centerWindow(Component frame) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.width> screenSize.width ) frameSize.width = screenSize.width; if (frameSize.height> screenSize.height) frameSize.height = screenSize.height; frame.setLocation ( (screenSize.width - frameSize.width )>> 1, (screenSize.height - frameSize.height)>> 1 ); }} 請注意這個(gè)類對于第一個(gè)類所作的改動(dòng)。改動(dòng)只有類名、frame名、以及GLEventListener名。希望你能夠閱讀代碼中的注釋,否則你會(huì)搞不清它要做什么。我們實(shí)現(xiàn)的GLEventListener確實(shí)相對于前面一個(gè)例子有了一些改進(jìn),它允許我們畫出一些漂亮的圖來。import net.java.games.jogl.*;/*** For our purposes only two of the GLEventListeners matter.* Those would be init() and display().* 為了達(dá)到我們的目的,GLEventListener中只有兩個(gè)方法有用。* 它們是init()和display()。*/public class SecondGLEventListener implements GLEventListener{ /** * Take care of initialization here. * 注意這里的初始化。 */ public void init(GLDrawable gld) { GL gl = gld.getGL(); GLU glu = gld.getGLU(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glViewport(0, 0, 500, 300); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluOrtho2D(0.0, 500.0, 0.0, 300.0); } /** * Take care of drawing here. * 注意這里的繪圖。 */ public void display(GLDrawable drawable) { float red = 0.0f; float green = 0.0f; float blue = 0.0f; GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glPointSize(5.0f); for (int i=0; i
標(biāo)簽:
Java
上一條:Java中的泛型 第一部分下一條:關(guān)于Java文件路徑問題
相關(guān)文章:
1. ASP 信息提示函數(shù)并作返回或者轉(zhuǎn)向2. python matplotlib:plt.scatter() 大小和顏色參數(shù)詳解3. vue使用webSocket更新實(shí)時(shí)天氣的方法4. 淺談python出錯(cuò)時(shí)traceback的解讀5. Python importlib動(dòng)態(tài)導(dǎo)入模塊實(shí)現(xiàn)代碼6. android studio 打包自動(dòng)生成版本號與日期,apk輸入路徑詳解7. 利用promise及參數(shù)解構(gòu)封裝ajax請求的方法8. 在Android中使用WebSocket實(shí)現(xiàn)消息通信的方法詳解9. Nginx+php配置文件及原理解析10. JSP數(shù)據(jù)交互實(shí)現(xiàn)過程解析
排行榜
