1. 程式人生 > >點點滴滴,終匯一海!

點點滴滴,終匯一海!

        有許多用Java去結合OpenGL的嘗試,但是第一個被大家認可並注意的是Java對於OpenGL的繫結(Java Bindings for OpenGL),或者稱為JOGL。

===================================================================================================================================

JOGL的背景

===================================================================================================================================

       為了建立一個圖形增強的程式,從而出售給使用各種不同作業系統的使用者,程式設計師有一個選擇——OpenGL。GL代表圖形庫(graphics library)。OpenGL是SGI的註冊商標。OpenGL顯示它是一個跨平臺的C語言程式設計API。但是事實上,在程式設計介面上,它是一個與硬體無關的規範。

OpenGL用來製圖,速度非常快。大多數情況下,它是硬體加速的。看起來好像OpenGL可以實現一切你想要完成的圖形介面。

然而,OpenGL是為C語言而寫的。而C語言不是用來編寫複雜應用程式的流行語言。而OpenGL一個最大的缺點是:如果不建立一個視窗(用來把圖形放在裡面),就什麼都做不了(當然,這也是OpenGL的最大優點,它獨立於具體的作業系統,語言,甚至是硬體)。而OpenGL沒有提供建立視窗的方法。如此使得OpenGL對於初學者來說顯得比較困難。

       因此,有了GLUT(OpenGL Utility ToolKit)。它被用來輕鬆應對視窗、按鈕以及使用者事件。但是,對於想要使用面向物件方法程式設計的程式設計師來說,學習用C或者C++來編寫OpenGL程式仍然不是一件簡單的事情。

==================================================================================================================================

JOGL

==================================================================================================================================

      Java也許是最流行的真正的面向物件的程式語言。有許多用Java去嘗試結合OpenGL的嘗試,但是第一個被大家認可並注意的是Java對於OpenGL的繫結——JOGL。因為它得到Sun和SGI的支援。

       OpenGL被用來展示三維模型。它強大、快速,而且可能是自Swing出現以來最棒的一樣東西。通過JOGL來使用OpenGL,可以製作出很酷的遊戲或者是模型位置等,而在這之前建立它們需要非常昂貴的成本。

JOGL-獲取JOGL

       就是要找到你作業系統所對應的包,並進行解壓。

這個是可以從https://jogl.dev.java.net/找到的,進入網站後點左側的文件和檔案,我下載了Release Builds 2008\JSR-231 1.1.1 - May 22 (15)裡面的jogl-1.1.1-windows-i586.zip,解壓就得到要的jogl.jar和其他檔案了。

JOGL-例項 

        這就是你接下來的程式。請確保你輸入了所有的程式碼到你的編輯器中。除錯這些程式可以快速地使你明白它們的工作原理。

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.
* 這是個基礎的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
       //設定JFrame標題
       super("Second JOGL Application");

       //kill the process when the JFrame is closed
       //當JFrame關閉的時候,結束程序
       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
          );
    }
}

       請注意這個類對於第一個類所作的改動。改動只有類名、frame名、以及GLEventListener名。希望你能夠閱讀程式碼中的註釋,否則你會搞不清它要做什麼。
我們實現的GLEventListener確實相對於前面一個例子有了一些改進,它允許我們畫出一些漂亮的圖來。

import net.java.games.jogl.*;

/**
* 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 = 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<50; i++) {

          red -= .09f;
          green -= .12f;
          blue -= .15f;

       if (red < 0.15) red = 1.0f;
       if (green < 0.15) green = 1.0f;
       if (blue < 0.15) blue = 1.0f;

       gl.glColor3f(red, green, blue);

       gl.glBegin(GL.GL_POINTS);
          gl.glVertex2i((i*10), 150);
       gl.glEnd();
    }
}

public void reshape(
                      GLDrawable drawable,
                      int x,
                      int y,
                      int width,
                      int height
                    ) {}
public void displayChanged(
                             GLDrawable drawable,
                             boolean modeChanged,
                             boolean deviceChanged
                           ) {}
}


        當你看到GLEventListener的實現時,可能會感到不知所措。如果你有用C語言編寫OpenGL程式的經驗的話,你也許能猜測出一些東西。如果你 覺得比較茫然,不必擔心,也不要擔心我會讓你記住這些東西,至少現在不必。本書接下來的篇幅將會對這個例子中的 SecondGLEventListener作出解釋。現在,你只需要試著去猜測。試著去修改程式碼,產生兩行,或者一行斜的,而不是一行水平線;或是讓所 有的點都變成藍色或紅色。盡情娛樂,這就是你接下來學習JOGL的方式。

JOGL-例項

       這就是你接下來的程式。請確保你輸入了所有的程式碼到你的編輯器中。除錯這些程式可以快速地使你明白它們的工作原理。

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.
* 這是個基礎的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
       //設定JFrame標題
       super("Second JOGL Application");

       //kill the process when the JFrame is closed
       //當JFrame關閉的時候,結束程序
       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
          );
    }
}


       請注意這個類對於第一個類所作的改動。改動只有類名、frame名、以及GLEventListener名。希望你能夠閱讀程式碼中的註釋,否則你會搞不清它要做什麼。
我們實現的GLEventListener確實相對於前面一個例子有了一些改進,它允許我們畫出一些漂亮的圖來。

import net.java.games.jogl.*;

/**
* 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 = 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<50; i++) {

          red -= .09f;
          green -= .12f;
          blue -= .15f;

       if (red < 0.15) red = 1.0f;
       if (green < 0.15) green = 1.0f;
       if (blue < 0.15) blue = 1.0f;

       gl.glColor3f(red, green, blue);

       gl.glBegin(GL.GL_POINTS);
          gl.glVertex2i((i*10), 150);
       gl.glEnd();
    }
}

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的方式。