JOGL 快速指南



JOGL - 概述

本章介紹 OpenGL、其功能、Java 中的 OpenGL 繫結(GL4java、LWJGL、JOGL)以及 JOGL 相比其他 OpenGL 繫結的優勢。

Java 繫結 OpenGL (JOGL) 是 Java 中 OpenGL 圖形 API 的最新繫結。它是一個包裝庫,可以訪問 OpenGL API,並且旨在建立用 Java 編寫的 2D 和 3D 圖形應用程式。JOGL 是一個開源庫,最初由麻省理工學院前研究生 Ken Russell 和 Chris Kline 開發。後來,它被 Sun Microsystems 的遊戲小組採用,現在由 Java on Graphics Audio and Processing (JOGAMP) 維護。JOGL 在各種作業系統上執行,例如 Windows、Solaris、Mac OS X 和 Linux(在 x86 上)。

什麼是 OpenGL?

OpenGL 代表開放圖形庫,它是一組用於建立 2D 和 3D 圖形的命令。使用 OpenGL,您可以使用非常基本的圖元(如點、線、多邊形、點陣圖和影像)建立複雜的 3D 形狀。

以下是 OpenGL 的一些功能 -

  • 它可以在多個平臺上工作。

  • 它在多種語言中都有繫結,例如 C++、Python 等

  • 它可以渲染 2D 和 3D 向量圖形。

  • 它與圖形處理單元 (GPU) 互動以實現快速和高質量的渲染。渲染是從 2D 或 3D 模型建立影像的過程。

  • 它是編寫 3D 圖形應用程式的行業標準 API。例如,遊戲、螢幕保護程式等。

  • 它包含大約 150 個命令,程式設計師可以使用這些命令來指定物件和操作以開發應用程式。

  • 它包含 OpenGL 實用程式庫 (GLU),該庫提供各種建模功能,例如二次曲面和 NURBS 曲線。GLU 是 OpenGL 的標準組件。

  • OpenGL 的設計側重於效率、有效性和使用多種語言在多個平臺上實現。為了保持 OpenGL API 的簡單性,不包括視窗任務。

因此,OpenGL 依賴於其他程式語言來執行視窗任務。

OpenGL API 的 Java 繫結

它是一個 Java 規範請求 (JSR) API 規範,允許在 Java 平臺上使用 OpenGL。

規範 細節
JSR 231 此 Java 繫結包支援 Java SE 平臺。
JSR 239 此 Java 繫結包支援 Java ME 平臺。

Java 中有各種 OpenGL 繫結。下面將討論它們

GL4java

它被稱為 Java 技術的 OpenGL。它與 OpenGL 1.3 以及幾乎所有供應商擴充套件都有連結。此外,它可以與抽象視窗工具包 (AWT) 和 Swings 一起使用。它是一個以遊戲為中心的 OpenGL 繫結,它是一個顯示全屏應用程式的單個視窗。

LWJGL

  • 輕量級 Java 遊戲庫 (LWJGL) 使用 OpenGL 1.5 並與最新版本的 Java 配合使用。

  • 它可以使用 JSE 1.4 的全屏功能。它對 AWT/Swings 的支援有限。

  • 它適用於輕量級裝置,例如手機、嵌入式裝置等。

JOGL

  • JOGL 僅專注於 2D 和 3D 渲染。處理聲音和輸入/輸出的介面未包含在 JOGL 中。

  • 它包括圖形實用程式庫 (GLU)、GL 實用程式工具包 (GLUT) 及其自己的 API - 本機視窗工具包 (NEWT)。

為什麼選擇 JOGL?

  • 它提供了對 OpenGL API(版本 1.0、4.3、ES 1、ES 2 和 ES 3)以及幾乎所有供應商擴充套件的完全訪問許可權。因此,OpenGL 中的所有功能都包含在 JOGL 中。

  • JOGL 與 AWT、Swing 和標準小部件工具包 (SWT) 整合。它還包括自己的本機視窗工具包 (NEWT)。因此,它提供了對視窗的完全支援。

JOGL 的歷史

  • 1992 年 - Silicon Graphics Inc. 釋出了第一個 OpenGL 規範。

  • 2003 年 - Java.net 網站推出,具有新功能,JOGL 首次在同一網站上釋出。

  • 2010 年 - 自 2010 年以來,它一直是 BSD 許可下的獨立開源專案,BSD 許可是計算機軟體的寬鬆許可證。

JOGL - 安裝

本章介紹如何在您的系統上使用不同的整合開發環境 (IDE) 設定使用 JOGL 的環境。

安裝 JOGL

要安裝 JOGL,您需要具備以下系統要求 -

系統要求

第一個要求是在您的機器上安裝 Java 開發工具包 (JDK)。

要求 描述
JDK 版本 1.4 或更高版本
記憶體 沒有最低要求
磁碟空間 沒有最低要求
作業系統 沒有最低要求

您需要按照以下步驟設定您的環境以開始 JOGL 應用程式開發 -

步驟 1 - 驗證您的機器上是否安裝了 Java

開啟系統的控制檯並執行以下 java 命令 -

平臺 任務 命令
Windows 開啟命令控制檯 C:\>java-version
Linux 開啟命令終端 $ java -version
MAC 開啟終端 Machine:~ joseph$ java -version

驗證各個作業系統上的輸出。

平臺 輸出
Windows

Java “1.6.0.21”

java(TM) SE Runtime Environment(build 1..6.0_21-b07)Java HotSpot(TM) Client VM(build 17.0-b7, mixed mode, sharing)

Linux

Java “1.6.0.21”

java(TM) SE Runtime Environment(build 1..6.0_21-b07)Java HotSpot(TM) Client VM(build 17.0-b7, mixed mode, sharing)

MAC

Java “1.6.0.21”

java(TM) SE Runtime Environment(build 1..6.0_21-b07)Java HotSpot(TM) Client VM(build 17.0-b7, mixed mode, sharing)

步驟 2 – 設定 Java 開發工具包 (JDK)

如果您的機器上未安裝 Java,則需要從 Oracle 網站安裝 Java SDK: Oracle。您可以從下載的檔案中找到安裝 JDK 的說明。您需要按照給定的說明安裝和配置設定。最後,設定 PATH 和 JAVA_HOME 環境變數以引用包含 java.exe 和 javac.exe 檔案的目錄,通常分別為 java_install_dir/bin 和 java_install_dir。

設定Java-home環境變數以指向同一路徑上的基本目錄位置,Java 安裝在您的機器上。

平臺 命令
Windows 將環境變數 JAVA_HOME 設定為 C:\ProgramFiles\Java\Jdk1.6.0_21
Linux Export JAVA_HOME=/usr/local/java-current
MAC Export JAVA_HOME=/Library/Java/Home

將 Java 編譯器位置追加到系統路徑,如下所示 -

平臺 命令
Windows 在系統變數和路徑的末尾追加字串 ;%JAVA_HOME% bin
Linux Export PATH=$PATH:$JAVA_HOME/bin/
MAC 不需要

步驟 3 – 下載 JOGL

Jogamp Home Page

這將帶您進入網站維護的所有 API 的 .jar 檔案列表。

JAR Files List
  • 下載庫 .jar 檔案jogamp-all-platforms.7z、OpenGL 本機庫的 Java 文件glugen-javadoc.7z和 JOGL jogl-javadocs.7z。

  • 使用任何 zip 解壓縮軟體解壓縮下載的 .jar 檔案。

開啟解壓縮的資料夾後,您會找到 jar 資料夾、原始碼和其他檔案。

Source Code Folder

獲取原始碼gluegen-java-src.zipjogl-java-src.zip以支援 IDE。這是可選的。

  • 在 jar 資料夾內,有多個 .jar 檔案。此檔案集合屬於 Glugen 和 JOGL。

  • JOAMP 提供支援各種作業系統的本機庫,例如 Windows、Solaris、Linux 和 Android。因此,您需要獲取可以在您的目標平臺上執行的適當的 jar 檔案。例如,如果您使用的是 Windows 64 位作業系統,則從 jar 資料夾中獲取以下 .jar 檔案 -

    • gluegenrt.jar
    • jogl-all.jar
    • gluegen-rt-natives-windows-amd64.jar
    • jogl-all-natives-windowsamd64.jar
JAR Files

為 Eclipse 4.4 設定 JOGL

按照以下步驟設定 JOGL -

新增庫

步驟 1 - 開啟 Eclipse。

步驟 2 - 建立一個新專案。

步驟 3 - 在專案資料夾中建立一個名為lib的新資料夾。

步驟 4 - 將檔案gluegen-rt-natives-windows-amd64.jar、gluegenrt.jar、jogl-all-natives-windowsamd64.jarjogl-all.jar複製到lib資料夾中。

Eclipse1

步驟 5 - 現在選擇這些檔案並右鍵單擊滑鼠按鈕。將顯示一個快捷選單,其中包含構建路徑 > 新增到構建路徑。

Eclipse2

步驟 6 - 要使所有 .jar 檔案可供其他專案使用,請轉到主選單。選擇視窗 > 首選項。將出現“首選項”視窗。

Eclipse3 Eclipse4
  • 在“首選項”視窗中,在左側的下拉選單中,按照層次結構 - Java → 構建路徑 → 使用者庫。

  • 單擊“新建…”按鈕。

  • 它將開啟一個對話方塊。將庫名稱輸入為 jogl2.1。

  • 使用按鈕“新增外部 JAR…”新增 jar 檔案glugen-rt.jarjogl-all.jar

  • 它將建立一個名為jogl2.1的新使用者庫。

同樣,我們可以為新增的 .jar 檔案新增 Java 文件和原始碼。

新增本機庫

步驟 1 - 展開 jogl-all.jar 節點,選擇 Javadoc 位置(無)。

步驟 2 - 單擊“新建…”按鈕。輸入 JOGL Java 文件的名稱。

步驟 3 - 單擊“新增外部 JAR…”按鈕。

步驟 4 - 它將開啟一個對話方塊,您需要在其中選擇 JOGL Java 文件的位置,我們之前已經下載了該文件。

新增原始碼

步驟 1 - 選擇節點本機庫位置:(無)。

步驟 2 - 單擊“新建…”按鈕。

步驟 3 - 輸入本機庫的名稱並單擊“確定”按鈕。

步驟 4 - 單擊“新增外部 JAR…”按鈕。

步驟 5 − 現在選擇包含原生庫檔案('gluegen-rt-natives-windows-amd64.jar 和 joglall-natives-windows-amd64.jar') 的路徑。

步驟 6 − 對原始碼重複相同的步驟。

步驟 7 − 我們可以像上面為兩個原生庫檔案glegen-rt.jarglugen-natives-windows-amd64.jar 設定的那樣,以相同的方式設定Javadoc、原始碼和jar檔案的路徑。

在 NetBeans 4.4 中設定 JOGL

讓我們一起了解在 NetBeans 4.4 中設定 JOGL 的步驟 −

新增庫

步驟 1 − 在主選單中,選擇工具 > 庫

NetBeans1

步驟 2 − 這將引導您進入Ant 庫管理器

NetBeans2

步驟 3 − 在類路徑選項卡下,點選位於左下角的新建庫按鈕。這將開啟一個小對話方塊。

步驟 4 − 輸入庫名稱為JoGl2.0

步驟 5 − 點選“確定”按鈕。

NetBeans3

步驟 6 − 點選“新增 JAR/資料夾...”按鈕。

步驟 7 − 選擇包含 .jar 檔案jogl.all.jargluegen-rt.jar 的路徑。

要將 JOGL 庫包含到每個專案中,請按照以下步驟操作 −

步驟 1 − 右鍵點選專案名稱。這將顯示一個快捷選單。

NetBeans4

步驟 2 − 選擇屬性。這將開啟一個名為專案屬性的視窗。

NetBeans7

步驟 3 − 從左側的類別中選擇

步驟 4 − 選擇編譯選項卡並點選“新增庫...”按鈕。新增庫對話方塊將彈出。

步驟 5 − 現在新增您之前建立的 JOGL2.0 庫。

在每個專案中包含原生庫

按照以下步驟在每個專案中包含原生庫 −

步驟 1 − 右鍵點選專案。

步驟 2 − 選擇設定配置 > 自定義…

NetBeans8

這將引導您進入專案屬性視窗。

NetBeans9

步驟 3 − 在右側的VM 選項中,點選“自定義”按鈕。

步驟 4 − 瀏覽包含 JOGL 原生庫gluegen-rtnatives-windows-amd64.jar'''jogl-all-natives-windowsamd64.jar 的路徑。

新增原生庫的 Java 文件

您需要再次開啟 Ant 庫管理器,以便使原始碼和 Javadoc 對每個專案可用。請按照以下步驟操作 −

步驟 1 − 開啟主選單

步驟 2 − 選擇工具 > 庫。這將引導您進入庫管理器

步驟 3 − 在JavaDoc選項卡下,點選“新建庫…”按鈕。

步驟 4 − 輸入JOGLJavadoc名稱。(您可以輸入任何所需的名稱。)

步驟 5 − 點選“新增 jar/庫…”按鈕。

步驟 6 − 選擇解壓縮的JOGL 文件程式碼所在的路徑。

新增原生庫的原始碼

步驟 1 − 在原始碼選項卡下,點選“新建庫…”按鈕。輸入JOGLsources名稱。

步驟 2 − 點選“新增 jar/庫…”按鈕。選擇解壓縮的原始碼所在的路徑。

自定義 JDK 編輯器

步驟 1 − 為檔案jogl.all.jargluegen-rt.jar 設定類路徑

步驟 2 − 設定原生庫gluegen-rt-natives-windows-amd64.jarjoglall-natives-windowsamd64.jar 的路徑,或者將所有 jar 檔案從您下載它們的資料夾複製並貼上到jse lib資料夾中。

JOGL - 基本模板的 API

使用 JOGL 程式設計,可以繪製各種圖形形狀,例如直線、三角形、3D 形狀,包括旋轉、燈光、顏色等特殊效果。要在 JOGL 中繪製物件,首先必須構建一個基本的 JOGL 框架。下面給出的是構建基本框架所需的類。

GLEventListener 介面

要使您的程式能夠使用 JOGL 圖形 API,您需要實現GLEventListener介面。您可以在javax.media.opengl包中找到GLEventListener介面。

下表提供了GLEventListener介面中各種方法的詳細資訊和描述 −

序號 方法和描述
1

Void display(GLAutoDrawable drawable)

它由 GLAutoDrawable 介面的物件呼叫,以啟動客戶端的 OpenGL 渲染。即,此方法包含使用 OpenGL API 繪製圖形元素的邏輯。

2

Void dispose(GLAutoDrawable drawable)

此方法向偵聽器發出訊號,指示其為每個 GLContext 釋放所有 OpenGL 資源,例如記憶體緩衝區和 GLSL 程式。

3

Void init(GLAutoDrawble drawable)

它由 GLAutoDrawable 介面的物件在 OpenGL 上下文初始化後立即呼叫。

4

Void reshape(GLAutoDrawble drawble, int x, int y, int width, int height)

它由 GLAutoDrawable 介面的物件在元件調整大小後的第一次重繪期間呼叫。當元件在視窗中的位置發生變化時,也會呼叫它。

GLEventListener的所有方法都需要GLAutoDrawable介面的物件作為引數。

GLAutoDrawable 介面

此介面提供了一種基於事件的機制(GLEventListener)來執行 OpenGL 渲染。GLAutoDrawable自動建立一個主渲染上下文,該上下文與GLAutoDrawable關聯,並在物件的生命週期記憶體在。

下表提供了GLAutoDrawable介面中各種方法的詳細資訊和描述 −

序號 方法和描述
1

GL getGL()

返回 GLAutoDrawable 介面的當前物件使用的 GL 管道物件。

2

void addGLEventListener(GLEventListener Listener)

將給定的偵聽器新增到當前可繪製佇列的末尾。

3

void addGLEventListener(int index, GLEventListener listener)

在給定索引處將給定的偵聽器新增到此可繪製佇列。

4

void destroy()

銷燬與 GLAutoDrawable 介面的此物件關聯的所有資源,包括 GLContext。

注意 − 此包中還有其他方法。在此介面中僅討論了與模板相關的一些重要方法。

GLCanvas 類

GLCanvasGLJpanel 是 JOGL GUI 的兩個主要類,它們實現了GLAutoDrawable介面,可以用作 OpenGL 命令的繪圖表面。

GLCanvas 是一個重量級 AWT 元件,提供 OpenGL 渲染支援。這是AWTAutoGLDrawable介面的主要實現。它還繼承了java.awt.Canvas類。由於它是一個重量級元件,因此在某些情況下,GLJCanvas可能無法與 swing 元件正確整合。因此,在與 Swing 一起使用時必須小心。每當您遇到GLJCanvas的問題時,都必須使用GLJPanel類。

GLCanvas的層次結構圖如下所示 −

Canvas
  • GLEventistener介面與GLCanvas類一起工作。它響應GLCanvas類的更改以及它們發出的繪圖請求。

  • 每當例項化GLCanvas類時,都會呼叫GLEventListenerinit()方法。您可以重寫此方法以初始化 OpenGL 狀態。

  • 每當GLCanvas最初繪製(例項化)或調整大小時,都會執行GLEventListenerreshape()方法。它用於初始化 OpenGL 視口和投影矩陣。當元件的位置發生變化時,也會呼叫它。

  • GLEventListener的display()方法包含渲染 3D 場景的程式碼。每當呼叫GLCanvas的display()方法時,都會呼叫它。

下面給出的是例項化 GLCanvas 類所需的建構函式。

序號 建構函式和描述
1

GLCanvas()

它使用預設的 OpenGL 功能選擇機制,在預設螢幕裝置上建立一個具有預設 OpenGL 功能集的新 GLCanvas 元件。

2

GLCanvas(GLCapabilitiesImmutable)

它使用預設的 OpenGL 功能選擇機制,在預設螢幕裝置上建立一個具有請求的 OpenGL 功能集的新 GLCanvas 元件。

下面給出的是用於 GLCanvas 類事件處理的方法。

序號 方法和描述
1

void addGLEventListener(GLEventListener listener)

將給定的偵聽器新增到此可繪製佇列的末尾。

2

void addGLEventListener(int indexGLEventListener listener)

在給定索引處將給定的偵聽器新增到此可繪製佇列。

要例項化GLCanvas類,您需要GLCapabilitiesImmutable介面的物件,它指定一組不可變的 OpenGL 功能。

獲取CapabilitiesImmutable介面物件的一種方法是例項化GLCapabilities類,該類實現了該介面。GLCapabilities類的例項可以用於實現此目的。

GLCapabilities 類

此類指定一組 OpenGL 功能。它將 GLCapabilities 物件作為引數。GLCapabilities類描述了渲染上下文必須支援的所需功能,例如 OpenGL 配置檔案。

下面給出的是例項化 GLCapabilities 類的建構函式

序號 方法和描述
1

GLCapabilities(GLProfile glprofile)

它建立一個 GLCapabilities 物件。

要例項化GLCanvas類,您需要 GLCapabilitiesImmutable 介面的物件,它指定一組不可變的 OpenGL 功能。

獲取CapabilitiesImmutable介面物件的一種方法是例項化GLCapabilities類,該類實現了該介面。GLCapabilities類的例項可以用於實現此目的。

GLCapabilities類反過來需要一個GLProfile物件。

GLProfile 類

由於釋出了幾個版本的 OpenGL API;您需要將程式中使用的 OpenGL API 的確切版本指定給您的 Java 虛擬機器 (JVM)。這是使用GLProfile類完成的。

此類的get()方法接受不同的預定義String物件作為引數。每個 String 物件都是一個介面的名稱,並且每個介面都支援某些版本的 OpenGL。如果將此類初始化為靜態和單例,則它將為您提供每個可用 JOGL 配置檔案的單例GLProfile物件。

下面給出的是 GLProfile 類 get 方法的原型。

序號 方法和描述
1

Static GLProfile get(String profile)

使用預設裝置。

由於這是一個靜態方法,您需要使用類名來呼叫它,並且它需要一個預定義的靜態字串變數作為引數。此類中共有 12 個這樣的變數,每個變數代表 GL 介面的一個單獨實現。

GLProfile.get(GLProfile.GL2);

get() 方法的引數

序號 預定義字串值(介面名稱)和描述
1

GL2

此介面包含所有 OpenGL [1.0 … 3.0] 方法以及在此規範編寫時定義的大多數擴充套件。

2

GLES1

此介面包含所有 OpenGL ES [1.0 ... 1.1] 方法以及在此規範編寫時定義的大多數擴充套件。

3

GLES2

此介面包含所有 OpenGL ES 2.0 方法以及在此規範編寫時定義的大多數擴充套件。

4

GLES3

此介面包含所有 OpenGL ES 3.0 方法以及在此規範編寫時定義的大多數擴充套件。

5

GL2ES1

此介面包含 GL2 和 GLES1 的公共子集。

6

GL2ES2

此介面包含 GL3、GL2 和 GLES2 的公共子集。

7

GL2GL3

此介面包含核心 GL3(OpenGL 3.1+)和 GL2 的公共子集。

8

GL3

此介面包含所有 OpenGL [3.1 ... 3.3] 的核心方法以及在此規範編寫時定義的大多數擴充套件。

9

GL3bc

此介面包含所有 OpenGL [3.1 ... 3.3] 的相容性方法,以及在此規範編寫時定義的大多數擴充套件。

10

GL3ES3

此介面包含核心 GL3(OpenGL 3.1+)和 GLES3(OpenGL ES 3.0)的公共子集。

11

GL4

此介面包含所有 OpenGL [4.0 ... 4.3] 的核心方法,以及在此規範編寫時定義的大多數擴充套件。

12

GL4bc

此介面包含所有 OpenGL [4.0 ... 4.3] 的相容性配置檔案,以及在此規範編寫時定義的大多數擴充套件。

13

GL4ES3

包含核心 GL4(OpenGL 4.0+)和 GLES3(OpenGL ES 3.0)的公共子集的介面。

GLJPanel 類

它是一個輕量級的 Swing 元件,提供 OpenGL 渲染支援。它為了與 Swing 相容而提供。

GLJPanel 類層次結構

下面給出的圖表示 GLJPanel 類的類層次結構。

GJPanel

下面給出的是 GLJPanel 類的各種建構函式。

序號 建構函式和描述
1

GJPanel()

它使用一組預設的 OpenGL 功能建立一個新的 GLJPanel 元件。

2

(GLCapabilitiesImmutable)

它使用請求的 OpenGL 功能集建立一個新的 GLJPanel 元件。

3

GLJPanel(GLCapabilitiesImmutable userCapsRequest, GLCapabilitiesChooser chooser)

它建立一個新的 GLJPanel 元件。

下面給出的是 GLJPanel 類的 方法。

序號 方法和描述
1

void addGLEventListener(GLEventListener listener)

此方法將給定的偵聽器新增到此可繪製佇列的末尾。

2

void addGLEventListener(int indexGLEventListener listener)

此方法在給定索引處將給定的偵聽器新增到此可繪製佇列。

JOGL - 使用 AWT 的畫布

本章解釋瞭如何使用帶有 AWT 框架的 Canvas 繪製 JOGL 基本框架。在這裡,我們將構造一個 AWT 框架並將 canvas 物件使用框架類的add()方法新增到 AWT 框架中。

下面給出的是編寫一個程式的步驟,該程式使用 JOGL 的 Canvas 類和 AWT 的 Frame 類組合建立一個 JOGL 基本框架。

步驟 1:建立類

首先建立一個實現GlEventListener介面的類,並匯入包 javax.media.opengl。實現所有四個方法display()、dispose()、reshape()、init()。由於這是基本框架,因此討論了建立 canvas 類、將其新增到框架等基本任務。所有GLEventListener介面方法都未實現。

步驟 2:準備 Canvas

(a) 構造GLCanvas類物件

final GLCanvas glcanvas = new GLCanvas( xxxxxxx );

//here capabilities obj should be passed as parameter

(b) 例項化GLCapabilities

GLCapabilities capabilities = new GLCapabilities( xxxxx );

//here profile obj should be passed as parameter

(c) 生成GLProfile物件

由於它是靜態方法,因此使用類名呼叫它。由於本教程是關於 JOGL2 的,因此讓我們生成 GL2 介面物件。

final GLProfile profile = GLProfile.get( GLProfile.GL2 );

// both, variable and method are static hence both are called using class name.

讓我們看看 canvas 的程式碼片段。

//getting the capabilities object of GL2 profile

final GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities capabilities = new GLCapabilities(profile);

// The canvas
final GLCanvas glcanvas = new GLCanvas(capabilities);

(d) 現在使用addGLEventListener()方法將GLEventListener新增到 canvas。此方法需要GLEventListener介面的物件作為引數。因此,傳遞實現GLEventListener的類的物件。

BasicFrame basicframe = newBasic Frame( );// class which implements
GLEventListener interface
glcanvas.addGLEventListener( basicframe );

(e) 使用從 javax.media.opengl.awt.AWTGLAutoDrawable 繼承的 setSize() 方法設定框架的大小。

glcanvas.setSize( 400, 400 );

現在您已準備好GLCanvas

步驟 3:建立框架

透過例項化 JSE AWT 框架元件的Frame類物件來建立框架。

將 canvas 新增到其中並使框架可見。

//creating frame
final Frame frame = new frame( " Basic Frame" );

//adding canvas to frame
frame.add( glcanvas );
frame.setVisible( true ); 

步驟 4:以全屏方式檢視框架

要以全屏方式檢視框架,請使用java.awt.Toolkit類獲取預設螢幕大小。現在,使用這些預設螢幕尺寸,使用setSize()方法設定框架大小。

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(screenSize.width, screenSize.height);

讓我們一起了解使用 AWT 生成基本框架的程式 -

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class BasicFrame implements GLEventListener {

   @Override
   public void display(GLAutoDrawable arg0) {
      // method body
   }
	
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
	
   @Override
   public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
      // method body
   }
	
   public static void main(String[] args) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
        
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      BasicFrame b = new BasicFrame();
      glcanvas.addGLEventListener(b);        
      glcanvas.setSize(400, 400);
        
      //creating frame
      final Frame frame = new Frame (" Basic Frame");
        
      //adding canvas to frame
      frame.add(glcanvas);
      frame.setSize( 640, 480 );
      frame.setVisible(true);
   }
	
}

如果您編譯並執行上述程式,則會生成以下輸出。它顯示了當我們使用GLCanvas類與 AWT 結合時形成的基本框架 -

Basic Frame

JOGL - 使用 Swing 的畫布

本章解釋瞭如何使用Canvas和 javax.swing 包的JFrame類繪製 JOGL 基本框架。在這裡,我們將例項化一個 JFrame 並使用add()方法將 canvas 物件新增到 JFrame 的例項中。

使用 Canvas 與 AWT 為您提供具有重量級功能的圖形框架。為了擁有輕量級圖形框架,您需要將GLCanvas與 Swing 結合使用。在將GLCanvas與 Swing 結合使用時,您可以直接將GLCanvas放置在JFrame視窗中,也可以將其新增到JPanel中。

下面給出的程式使用 JOGL 的GLCanvas類和javax.swing包的JFrame類組合建立一個 JOGL 基本框架。

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class BasicFrame implements GLEventListener {

   @Override
   public void display(GLAutoDrawable arg0) {
      // method body
   }
	
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   } 
	
   @Override
   public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
      // method body
   }
	
   public static void main(String[] args) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
               
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      BasicFrame b = new BasicFrame();
      glcanvas.addGLEventListener(b);
      glcanvas.setSize(400, 400);
		
      //creating frame
      final JFrame frame = new JFrame (" Basic Frame");
		
      //adding canvas to it
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      
   }//end of main
	
}//end of classimport          

如果您編譯並執行上述程式,則會生成以下輸出。它顯示了當我們使用GLCanvas與 Swing 視窗結合時形成的基本框架。

Basic Frame

JOGL - GLJPanel 類

本章解釋瞭如何使用 GLJpanel 類繪製 JOGL 基本框架。它是一個輕量級的 Swing 元件,提供 OpenGL 渲染支援。它為了與 Swing 相容而提供。在這裡,我們將例項化一個 JFrame 並使用add()方法將 GLJpanel 物件新增到 JFrame 的例項中。

以下程式使用 Swing 視窗生成一個使用GLJPanel的基本框架 -

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class BasicFrame implements GLEventListener {

   @Override
   public void display(GLAutoDrawable arg0) {
      // method body
   }
   
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
   
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
   
   @Override
   public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
      // method body
   }
   
   public static void main(String[] args) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
      
      // The GLJpanel class
      GLJPanel gljpanel = new GLJPanel( glcapabilities ); 
      BasicFrame b = new BasicFrame();
      gljpanel.addGLEventListener(b);
      gljpanel.setSize(400, 400);
      
      //creating frame
      final JFrame frame = new JFrame (" Basic Frame");
      
      //adding canvas to it
      frame.getContentPane().add( gljpanel);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      
   }//end of main
	
}//end of classimport

如果您編譯並執行上述程式,則會生成以下輸出。它顯示了當我們使用GLJPanel與 Swing 視窗結合時形成的基本框架 -

Basic Frame

JOGL - 繪製基礎

OpenGL API 提供了用於繪製基本圖形元素(如點、頂點、線等)的原始方法。使用這些方法,您可以開發諸如三角形、多邊形和圓形之類的形狀。在 2D 和 3D 尺寸中。本章教你如何在 Java 程式中使用 JOGL 繪製基本線條。

繪製物件

為了訪問特定於硬體和作業系統平臺的程式,以及庫是用其他語言(如 C 和 C++)編寫的程式(原生應用程式),Java 使用了一個稱為Java 本地介面 (JNI)的程式設計框架。JOGL 在內部使用此介面來訪問 OpenGL 函式,如下面的圖所示。

JNI

GLEventListener介面的所有四個方法都包含呼叫 OpenGL 函式的程式碼(Java JOGL 方法)。這些 JOGL 方法的命名也類似於 OpenGL 的命名約定。如果 OpenGL 中的函式名為glBegin(),則使用gl.glBegin()

每當呼叫 Java JOGL 的gl.glBegin()方法時,它都會在內部呼叫 OpenGL 的glBegin()方法。這就是在安裝 JOGL 時在使用者系統上安裝原生庫檔案的原因。

Display() 方法

這是一個重要的方法,它包含用於開發圖形的程式碼。它需要GLAutoDrawable介面物件作為其引數。

display()方法最初使用 GL 介面的物件獲取 OpenGL 上下文(GL 繼承 GLBase 介面,該介面包含生成所有 OpenGL 上下文物件的方法)。由於本教程是關於 JOGL2 的,因此讓我們生成一個 GL2 物件。

以下程式碼片段顯示瞭如何生成 GL2 物件 -

//Generating GL object
GL gl = drawable.getGL();
GL gl = drawable.getGL();

//Using this Getting the Gl2 Object
//this can be written in a single line like
final GL2 gl = drawable.getGL().getGL2();

使用 GL2 介面的物件,可以訪問此介面的成員,進而提供對 OpenGL [1.0... 3.0] 函式的訪問。

繪製線條

GL2 介面包含大量方法列表,但這裡討論了三個主要的重要方法,即glBegin()glVertex()glEnd()

序號 方法和描述
1

glBegin()

此方法開始繪製線條的過程。它將預定義的字串整數“GL_LINES”作為引數,該引數繼承自 GL 介面。

2

glVertex3f()/glVertex2f()

此方法建立頂點,我們必須將座標作為引數 3f 和 2f 傳遞,它們分別表示三維浮點座標和二維浮點座標。

3

glEnd()

結束線條

下面給出的程式使用 JOGL 繪製基本線條 -

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class Line implements GLEventListener{

   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
            
      gl.glBegin (GL2.GL_LINES);//static field
      gl.glVertex3f(0.50f,-0.50f,0);
      gl.glVertex3f(-0.50f,0.50f,0);
      gl.glEnd();

   }
            
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
            
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
	
   public static void main(String[] args) {

      //getting the capabilities object of GL2 profile        
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
   
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      Line l = new Line();
      glcanvas.addGLEventListener(l);
      glcanvas.setSize(400, 400);
   
      //creating frame
      final JFrame frame = new JFrame ("straight Line");
   
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
                 
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      
   }//end of main
	
}//end of classimport javax.media.opengl.GL2;
Line

JOGL - 使用 GL 線繪製

在上一章中,我們學習瞭如何使用 JOGL 繪製基本線條。我們透過將預定義欄位Gl_lines傳遞給glBegin()方法來繪製線條。

本章提供了一些示例,使用 glBegin() 方法和 GL_Lines 繪製三角形、菱形和房屋等形狀。

讓我們一起了解使用 GL_LINES 繪製三角形的程式 -

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class Triangle implements GLEventListener{

   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glBegin (GL2.GL_LINES);
   
      //drawing the base
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(-0.50f, -0.50f, 0);
      gl.glVertex3f(0.50f, -0.50f, 0);
      gl.glEnd();
   
      //drawing the right edge
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(0f, 0.50f, 0);
      gl.glVertex3f(-0.50f, -0.50f, 0);
      gl.glEnd();
   
      //drawing the lft edge
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(0f, 0.50f, 0);
      gl.glVertex3f(0.50f, -0.50f, 0);
      gl.glEnd();
      gl.glFlush();
   }
   
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
   
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
   
   @Override
   public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
      // method body
   }
   
   public static void main(String[] args) {
      
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
   
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      Triangle l = new Triangle();
      glcanvas.addGLEventListener(l);
      glcanvas.setSize(400, 400);
   
      //creating frame
      final JFrame frame = new JFrame ("Triangle");
   
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
          
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      
   }//end of main
	
}//end of classimport javax.media.opengl.GL2;

如果您編譯並執行上述程式,則會生成以下輸出。它顯示了使用glBegin()方法的 GL_LINES 繪製的三角形。

Triangle

讓我們一起了解使用 GL_LINES 繪製菱形的程式 -

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class Rhombus implements GLEventListener{

   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      
      //edge1  
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.0f,0.75f,0 );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glEnd();
      
      //edge2
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glEnd();
      
      //edge3
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glVertex3f( 0.75f,0f, 0 );
      gl.glEnd();
      
      //edge4
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.75f,0f, 0 );
      gl.glVertex3f( 0.0f,0.75f,0 );
      gl.glEnd();
      gl.glFlush();
   }
	
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
	
   @Override
   public void init(GLAutoDrawable arg0 ) {
      // method body
   }
	
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
	
   public static void main( String[] args ) {
	
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities(profile);
      
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Rhombus rhombus = new Rhombus();
      glcanvas.addGLEventListener( rhombus );
      glcanvas.setSize( 400, 400 );
      
      //creating frame
      final JFrame frame = new JFrame ( "Rhombus" );
      
      //adding canvas to frame
      frame.getContentPane().add( glcanvas );
      frame.setSize(frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }
	
}

如果您編譯並執行上述程式,則會得到以下輸出。它顯示了使用glBegin()方法的 GL_LINES 生成的菱形。

Rhombus

讓我們一起了解使用 GL_LINES 繪製房屋的程式 -

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class House implements GLEventListener{

   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      
      //drawing top
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.3f, 0.3f, 0 );
      gl.glVertex3f( 0.3f,0.3f, 0 );
      gl.glEnd();
      
      //drawing bottom
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.3f,-0.3f, 0 );
      gl.glVertex3f( 0.3f,-0.3f, 0 );
      gl.glEnd();
      
      //drawing the right edge
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.3f,0.3f, 0 );
      gl.glVertex3f( -0.3f,-0.3f, 0 );
      gl.glEnd();
      
      //drawing the left edge
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.3f,0.3f,0 );
      gl.glVertex3f( 0.3f,-0.3f,0 );
      gl.glEnd();
      
      //building roof
      //building lft dia
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,0.6f, 0 );
      gl.glVertex3f( -0.3f,0.3f, 0 );
      gl.glEnd();
      
      //building rt dia
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,0.6f, 0 );
      gl.glVertex3f( 0.3f,0.3f, 0 );
      gl.glEnd();
      
      //building door
      //drawing top
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.05f, 0.05f, 0 );
      gl.glVertex3f( 0.05f, 0.05f, 0 );
      gl.glEnd();
      
      //drawing the left edge
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.05f, 0.05f, 0 );
      gl.glVertex3f( -0.05f, -0.3f, 0 );
      gl.glEnd();
      
      //drawing the right edge
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( 0.05f, 0.05f, 0 );
      gl.glVertex3f( 0.05f, -0.3f, 0 );
      gl.glEnd();
   }
      
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }       
   
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
	
   public static void main( String[] args ) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities(profile);
   
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      House house = new House();
      glcanvas.addGLEventListener( house );
      glcanvas.setSize(400, 400);
   
      //creating frame
      final JFrame frame = new JFrame( "House" );
   
      //adding canvas to frame
      frame.getContentPane().add( glcanvas );
      frame.setSize(frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      
   }//end of main
	
}//end of class

如果您編譯並執行上述程式,則會得到以下輸出。它顯示了使用 GL_LINES() 方法生成的房屋示意圖。

House

JOGL - 預定義形狀

在前面的章節中,我們學習瞭如何使用 JOGL 繪製線條、三角形、菱形等形狀。我們透過將預定義欄位Gl_lines傳遞給glBegin()方法來繪製線條。

除了GL_LINES之外,glBegin()方法還可以接受另外八個引數。您可以使用它們來繪製不同的形狀。它們的使用方式與 GL_LINES 相同。

下表顯示了glBegin()方法的引數及其描述 -

序號 引數和描述
1

GL_LINES

將每對頂點建立為獨立的線段。

2

GL_LINE_STRIP

從第一個頂點到最後一個頂點繪製一組連線的線段。

3

GL_LINE_LOOP

從第一個頂點到最後一個頂點繪製一組連線的線段,然後再次回到第一個頂點。

4

GL_TRIANGLES

將每三個頂點視為一個獨立的三角形。

5

GL_TRIANGLE_STRIP

繪製一個連線的三角形組。在繪製前兩個頂點之後,每個頂點都會定義一個三角形。

6

GL_TRIANGLE_FAN

繪製一個連線的三角形組。在繪製前兩個頂點之後,每個頂點都會定義一個三角形。

7

GL_QUADS

將每組四個頂點視為一個獨立的四邊形。

8

GL_QUAD_STRIP

繪製一個連線的四邊形組。在繪製第一對頂點之後,每對頂點都會定義一個四邊形。

9

GL_POLYGON

繪製一個單一的凸多邊形。頂點 1,…,n 定義此多邊形。

讓我們看看一些使用glBegin()引數的示例。

繪製線段的程式

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;

import javax.swing.JFrame;

public class LineStrip implements GLEventListener{

   @Override
   public void display(GLAutoDrawable drawable) {
   
      final GL2 gl = drawable.getGL().getGL2();
		
      gl.glBegin (GL2.GL_LINE_STRIP);
      gl.glVertex3f(-0.50f,-0.75f, 0);
      gl.glVertex3f(0.7f,0.5f, 0);
      gl.glVertex3f(0.70f,-0.70f, 0);
      gl.glVertex3f(0f,0.5f, 0);
      gl.glEnd();
   }
   
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
   
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
   
   @Override
   public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
      // method body
   }
   
   public static void main(String[] args) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
      
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      LineStrip r = new LineStrip();
      glcanvas.addGLEventListener(r);
      glcanvas.setSize(400, 400);
      
      //creating frame
      final JFrame frame = new JFrame ("LineStrip");
      
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
            
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      
   }//end of main
	
}//end of classimport javax.media.opengl.GL2;

如果編譯並執行上述程式碼,將生成以下輸出:

LineStrip

繪製閉合線段的display()方法程式碼片段

public void display(GLAutoDrawable drawable) {

   final GL2 gl = drawable.getGL().getGL2();
   
   gl.glBegin (GL2.GL_LINE_LOOP);
   
   gl.glVertex3f( -0.50f, -0.75f, 0);
   gl.glVertex3f(0.7f, .5f, 0);
   gl.glVertex3f(0.70f, -0.70f, 0);
   gl.glVertex3f(0f, 0.5f, 0);
   
   gl.glEnd();
}

如果將任何基本模板程式的display()方法替換為上述程式碼,編譯並執行它,則會生成以下輸出:

Line Loop

使用GL_TRIANGLES繪製三角形的display()方法程式碼片段

public void display(GLAutoDrawable drawable) {

   final GL2 gl = drawable.getGL().getGL2();
   
   gl.glBegin(GL2.GL_TRIANGLES);        // Drawing Using Triangles
   
   gl.glVertex3f(0.5f,0.7f,0.0f);       // Top
   gl.glVertex3f(-0.2f,-0.50f,0.0f);    // Bottom Left
   gl.glVertex3f(0.5f,-0.5f,0.0f);      // Bottom Right
   
   gl.glEnd();
}

如果將任何基本模板程式的display()方法替換為上述程式碼,編譯並執行它,則會生成以下輸出:

Triangles

繪製三角形帶的display()方法程式碼片段

public void display(GLAutoDrawable drawable) {

   final GL2 gl = drawable.getGL().getGL2();
   
   gl.glBegin (GL2.GL_TRIANGLE_STRIP);
   
   gl.glVertex3f(0f,0.5f,0);
   gl.glVertex3f(-0.50f,-0.75f,0);
   gl.glVertex3f(0.28f,0.06f,0);
   gl.glVertex3f(0.7f,0.5f,0);
   gl.glVertex3f(0.7f,-0.7f,0);
   
   gl.glEnd();
}

如果將任何基本模板程式的display()方法替換為上述程式碼,編譯並執行它,則會生成以下輸出:

Triangle Strip

繪製四邊形的display()方法程式碼片段

public void display(GLAutoDrawable drawable) {

   final GL2 gl = drawable.getGL().getGL2();
   
   gl.glBegin(GL2.GL_QUADS);
   
   gl.glVertex3f( 0.0f,0.75f,0);
   gl.glVertex3f(-0.75f,0f,0);
   gl.glVertex3f(0f,-0.75f,0);
   gl.glVertex3f(0.75f,0f,0);
   
   gl.glEnd();
}

如果將任何基本模板程式的display()方法替換為上述程式碼,編譯並執行它,則會生成以下輸出:

Quads

繪製多邊形的display()方法程式碼片段

public void display(GLAutoDrawable drawable) {

   final GL2 gl = drawable.getGL().getGL2();
   
   gl.glBegin(GL2.GL_POLYGON);
   
   gl.glVertex3f(0f,0.5f,0f);
   gl.glVertex3f(-0.5f,0.2f,0f);
   gl.glVertex3f(-0.5f,-0.2f,0f);
   gl.glVertex3f(0f,-0.5f,0f);
   gl.glVertex3f(0f,0.5f,0f);
   gl.glVertex3f(0.5f,0.2f,0f);
   gl.glVertex3f(0.5f,-0.2f,0f);
   gl.glVertex3f(0f,-0.5f,0f);
   
   gl.glEnd();
}

如果將任何基本模板程式的display()方法替換為上述程式碼,編譯並執行它,則會生成以下輸出:

Polygon

JOGL - 變換

OpenGL 提供了更多功能,例如將顏色應用於物件、縮放、照明、旋轉物件等。本章介紹了一些使用 JOGL 對物件進行變換的方法。

在視窗上移動物件

在前面的章節中,我們討論了使用簡單線條繪製線條和繪製各種形狀的程式。這樣建立的形狀可以顯示在視窗內的任何位置。這是使用glTranslatef (float x, float y, float z)方法完成的。

此方法屬於GLMatrixFunc介面,該介面位於javax.media.opengl.fixedfunc包中。

GLMatrixFunc 介面

介面 - GLMatrixFunc

- javax.media.opengl.fixedfunc

下表列出了此介面的一些重要方法:

序號 方法和描述
1

void glRotatef(float angle, float x, float y, float z)

旋轉當前矩陣。

2

void glScalef(float x, float y, float z)

用於縮放當前矩陣。

3

void glTranslatef(float x, float y,float z)

用於平移當前矩陣。

4

void glLoadIdentity()

用單位矩陣載入當前矩陣。

glTranslate() 方法將座標系的原點移動到由引數 (x,y,z) 指定的點,這些引數作為

引數傳遞給glTranslate() 方法。要儲存和恢復未平移的座標系,可以使用glPushMatrix()glPopMatrix()方法。

gl.glTranslatef(0f, 0f, -2.5f); 

無論何時使用glTranslate(),它都會更改螢幕上元件的位置。因此,應覆蓋GLEventListener介面的reshape()方法,並初始化 OpenGL 視口和投影矩陣。

以下程式碼顯示了初始化視口和投影矩陣的模板:

public void reshape(GLAutoDrawable drawable, int x,  int y, int width, int height) { 
  
   // TODO Auto-generated method stub 
   final GL2 gl = drawable.getGL().getGL2();  
            
   // get the OpenGL 2 graphics object   
   if(height <=0) height = 1; 
       
   //preventing devided by 0 exception height = 1; 
   final float h = (float) width / (float) height; 
            
   // display area to cover the entire window 
   gl.glViewport(0, 0, width, height); 
            
   //transforming projection matrix 
   gl.glMatrixMode(GL2.GL_PROJECTION); 
   gl.glLoadIdentity(); 
   glu.gluPerspective(45.0f, h, 1.0, 20.0); 
      
   //transforming model view gl.glLoadIdentity(); 
   gl.glMatrixMode(GL2.GL_MODELVIEW); 
   gl.glLoadIdentity(); 
}

JOGL - 著色

本章將教你如何使用 JOGL 將顏色應用於物件。要將顏色應用於物件,請使用GL2glColor()方法。下面給出的是使用 glColor 方法的語法。

語法

gl.glColorXY(1f,0f,0f); 

其中,

  • X 表示使用的顏色數量,3(紅、綠、藍)或 4(紅、綠、藍、alpha)。為了獲得各種顏色組合,這些顏色的值作為引數傳遞。顏色引數的順序必須按該順序保持。

    示例

    如果將顏色值作為 (1, 0, 0) 傳遞,則會得到紅色。類似地,(1, 1, 0) 會給你黃色。

  • Y 表示資料型別,它接受諸如 byte(b)、double(d)、float(f)、int(i)、short(s)、ubyte(ub)、uint(ui) 和 ushort(us) 之類的引數。

gl.glColor3f(1f,0f,0f);   //gives us red          
gl.glColor3f(0f,1f,0f);   //gives us green            
gl.glColor3f(0f,0f,1f);   //gives us blue

對於三角形,可以為每個頂點應用不同的顏色。

讓我們來看一下將顏色應用於三角形的程式:

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLCapabilities; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.awt.GLCanvas; 

import javax.swing.JFrame; 
 
public class TriangleColor implements GLEventListener { 

   @Override 
   public void display( GLAutoDrawable drawable ) { 
   
      final GL2 gl = drawable.getGL().getGL2(); 
      gl.glBegin( GL2.GL_TRIANGLES );  
      
      // Drawing Using Triangles 
    
      gl.glColor3f( 1.0f, 0.0f, 0.0f );   // Red 
      gl.glVertex3f( 0.5f,0.7f,0.0f );    // Top 
		
      gl.glColor3f( 0.0f,1.0f,0.0f );     // green 
      gl.glVertex3f( -0.2f,-0.50f,0.0f ); // Bottom Left 
		
      gl.glColor3f( 0.0f,0.0f,1.0f );     // blue 
      gl.glVertex3f( 0.5f,-0.5f,0.0f );   // Bottom Right 
		
      gl.glEnd();         
   } 
   
   @Override 
   public void dispose( GLAutoDrawable arg0 ) { 
      //method body 
   } 
   
   @Override 
   public void init( GLAutoDrawable arg0 ) { 
      // method body    
   }
   
   @Override 
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { 
      // method body 
   } 
   
   public static void main( String[] args ) {    
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 ); 
      GLCapabilities capabilities = new GLCapabilities(profile);
          
      // The canvas  
      final GLCanvas glcanvas = new GLCanvas( capabilities ); 
      TriangleColor triangle = new TriangleColor(); 
      glcanvas.addGLEventListener( triangle ); 
      glcanvas.setSize( 400, 400 );   
      
      //creating frame 
      final JFrame frame = new JFrame (" Colored Triangle"); 
          
      //adding canvas to it 
      frame.getContentPane().add( glcanvas ); 
      frame.setSize( frame.getContentPane().getPreferredSize()); 
      frame.setVisible( true );   
      
   } //end of main
	
} //end of class 

編譯並執行上述程式後,將得到以下彩色三角形:

Triangle Color

將顏色應用於多邊形

讓我們來看一下將顏色應用於多邊形的程式:

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLCapabilities; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.awt.GLCanvas; 

import javax.swing.JFrame; 

public class PolygonColor implements GLEventListener { 

   @Override 
   public void display( GLAutoDrawable drawable ) { 
   
      final GL2 gl = drawable.getGL().getGL2(); 
      gl.glColor3f( 1f,0f,0f ); //applying red  
  
      gl.glBegin( GL2.GL_POLYGON ); 
      
      gl.glVertex3f( 0f,0.5f,0f  ); 
      gl.glVertex3f( -0.5f,0.2f,0f ); 
      gl.glVertex3f( -0.5f,-0.2f,0f ); 
      gl.glVertex3f( 0f,-0.5f,0f ); 
      gl.glVertex3f( 0f,0.5f,0f ); 
      gl.glVertex3f( 0.5f,0.2f,0f ); 
      gl.glVertex3f( 0.5f,-0.2f,0f ); 
      gl.glVertex3f( 0f,-0.5f,0f ); 
      
      gl.glEnd(); 
   }
   
   @Override 
   public void dispose( GLAutoDrawable arg0 ) { 
      //method body 
   } 
   
   @Override 
   public void init( GLAutoDrawable arg0 ) {   
      // method body 
   } 
   
   @Override 
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {    
      // method body 
   } 
   
   public static void main( String[] args ) { 
   
      //getting the capabilities object of GL2 profile  
      final GLProfile profile = GLProfile.get( GLProfile.GL2 ); 
      GLCapabilities capabilities = new GLCapabilities(profile); 
      
      // The canvas  
      final GLCanvas glcanvas = new GLCanvas( capabilities ); 
      PolygonColor polygon = new PolygonColor(); 
      glcanvas.addGLEventListener( polygon ); 
      glcanvas.setSize( 400, 400 ); 
      
      //creating frame 
      final JFrame frame = new JFrame ( "Colored Polygon" ); 
      
      //adding canvas to frame 
      frame.getContentPane().add( glcanvas ); 
      frame.setSize(frame.getContentPane().getPreferredSize() ); 
      frame.setVisible( true );    
      
   } //end of main 
	
 } //end of class 

編譯並執行上述程式後,將得到以下彩色多邊形:

Polygon Color

JOGL - 縮放

本章將教你如何縮放物件,即使用 JOGL 增大或減小物件的大小。

縮放物件是透過使用GLMatrixFunc介面的glScalef(float x, float y, float z)方法完成的。此方法接受三個浮點引數,我們使用這些引數分別指定沿 x、y 和 z 軸的縮放因子。

例如,在下面的程式中,三角形縮小到 50%。這裡,值 50 作為所有軸的引數傳遞。

讓我們來看一下縮放三角形的程式:

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLCapabilities; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.awt.GLCanvas; 

import javax.swing.JFrame;
 
public class Scaling implements GLEventListener {
 
   @Override 
	
   public void display( GLAutoDrawable drawable ) { 
   
      final GL2 gl = drawable.getGL().getGL2(); 
      gl.glScalef( 0.50f,0.25f,0.50f ); 
      gl.glBegin( GL2.GL_TRIANGLES );
		
      // Drawing Using Triangles 
      gl.glColor3f( 1.0f, 0.0f, 0.0f );   // Red 
      gl.glVertex3f( 0.5f,0.7f,0.0f );    // Top 
		
      gl.glColor3f( 0.0f,1.0f,0.0f );     // blue 
      gl.glVertex3f( -0.2f,-0.50f,0.0f ); // Bottom Left 
		
      gl.glColor3f( 0.0f,0.0f,1.0f );     // green 
      gl.glVertex3f( 0.5f,-0.5f,0.0f );   // Bottom Right 
		
      gl.glEnd(); 
   }
   
   @Override 
   public void dispose( GLAutoDrawable arg0 ) { 
      //method body 
   } 
   
   @Override 
   public void init( GLAutoDrawable arg0 ) { 
      // method body 
   } 
   
   @Override 
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { 
      // method body 
   }
   
   public static void main( String[] args ) {   
   
      //getting the capabilities object of GL2 profile 
      final GLProfile profile = GLProfile.get( GLProfile.GL2 ); 
      GLCapabilities capabilities = new GLCapabilities(profile);
        
      // The canvas  
      final GLCanvas glcanvas = new GLCanvas( capabilities ); 
      Scaling scaling = new Scaling(); 
      glcanvas.addGLEventListener( scaling ); 
      glcanvas.setSize( 400, 400 );  

      //creating frame 
      final JFrame frame  = new JFrame (" Dimnished Triangle (Scaling )");   

      //adding canvas to it 
      frame.getContentPane().add(glcanvas); 
      frame.setSize(frame.getContentPane().getPreferredSize()); 
      frame.setVisible(true);         
      
   } //end of main 
	
} //end of classimport javax.media.opengl.GL2; 

編譯並執行上述程式後,我們將獲得以下輸出。在這裡,您可以觀察到與 TriangleColor.java 生成的原始三角形相比,縮小的三角形:

Scaling

JOGL - 旋轉

在本章中,我們向您解釋瞭如何使用 JOGL 旋轉物件。可以使用GLMatrixFunc介面的glRotatef(float angle, float x, float y, float z)方法沿任意三個軸中的任何一個旋轉物件。您需要將旋轉角度和 x、y、z 軸作為引數傳遞給此方法。

以下步驟指導您成功旋轉物件:

  • 最初使用gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT)方法清除顏色緩衝區和深度緩衝區。此方法會擦除物件的先前狀態並使檢視清晰。

  • 使用glLoadIdentity()方法重置投影矩陣。

例項化動畫器類並使用start()方法啟動動畫器。

FPSAnimator 類

下面給出的是 FPSAnimator 類的各種建構函式。

序號 方法和描述
1

FPSAnimator(GLAutoDrawable drawable, int fps)

它使用給定的目標幀速率值和要動畫化的初始可繪製物件建立一個 FPSAnimator。

2

FPSAnimator(GLAutoDrawable drawable, int fps, boolean cheduleAtFixedRate)

它使用給定的目標幀速率值、要動畫化的初始可繪製物件和一個指示是否使用固定速率排程的標誌建立一個 FPSAnimator。

3

FPSAnimator(int fps)

它使用給定的目標幀速率值建立一個 FPSAnimator。

4 它使用給定的目標幀速率值和一個指示是否使用固定速率排程的標誌建立一個 FPSAnimator。

它使用給定的目標幀速率值和一個指示是否使用固定速率排程的標誌建立一個 FPSAnimator。

start()stop()是此類中的兩個重要方法。以下程式顯示瞭如何使用 FPSAnimator 類旋轉三角形:

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLCapabilities; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.awt.GLCanvas; 

import javax.swing.JFrame; 

import com.jogamp.opengl.util.FPSAnimator; 

public class TriangleRotation implements GLEventListener { 
   private float rtri;  //for angle of rotation
      
   @Override 
   public void display( GLAutoDrawable drawable ) {
   
      final GL2 gl = drawable.getGL().getGL2(); 
      gl.glClear (GL2.GL_COLOR_BUFFER_BIT |  GL2.GL_DEPTH_BUFFER_BIT );  
      
      // Clear The Screen And The Depth Buffer 
      gl.glLoadIdentity();  // Reset The View     
              
      //triangle rotation      
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );  
              
      // Drawing Using Triangles 
      gl.glBegin( GL2.GL_TRIANGLES );          
      
      gl.glColor3f( 1.0f, 0.0f, 0.0f );   // Red 
      gl.glVertex3f( 0.5f,0.7f,0.0f );    // Top 
      gl.glColor3f( 0.0f,1.0f,0.0f );     // blue 
      gl.glVertex3f( -0.2f,-0.50f,0.0f ); // Bottom Left 
      gl.glColor3f( 0.0f,0.0f,1.0f );     // green 
      gl.glVertex3f( 0.5f,-0.5f,0.0f );   // Bottom Right 
      
      gl.glEnd();    
      gl.glFlush(); 
      
      rtri +=0.2f;  //assigning the angle               
   } 
	
   @Override 
   public void dispose( GLAutoDrawable arg0 ) { 
      //method body 
   } 
   
   @Override 
   public void init( GLAutoDrawable arg0 ) { 
      // method body 
   }
   
   @Override 
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) { 
   
      public static void main( String[] args ) {
		
         //getting the capabilities object of GL2 profile
         final GLProfile profile  = GLProfile.get(GLProfile.GL2 ); 
         GLCapabilities capabilities  = new GLCapabilities( profile );

         // The canvas  
         final GLCanvas glcanvas = new GLCanvas( capabilities); 
         TriangleRotation triangle = new TriangleRotation(); 
         glcanvas.addGLEventListener( triangle ); 
         glcanvas.setSize( 400, 400 );  

         // creating frame 
         final JFrame frame = new JFrame ("Rotating Triangle");

         // adding canvas to it 
         frame.getContentPane().add( glcanvas ); 
         frame.setSize(frame.getContentPane() .getPreferredSize());                 
         frame.setVisible( true ); 
                
         //Instantiating and Initiating Animator 
         final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true); 
         animator.start(); 
      }
		
   } //end of main
	
} //end of class 

如果編譯並執行上述程式,它將生成以下輸出。在這裡,您可以觀察到圍繞 x 軸旋轉的彩色三角形的各種快照。

Triangle Rotation

JOGL - 光照

本章向您解釋瞭如何使用 JOGL 將照明效果應用於物件。

要設定照明,首先使用glEnable()方法啟用照明。然後使用GLLightingFunc介面的glLightfv(int light, int pname, float[] params, int params_offset)方法為物件應用照明。此方法採用四個引數。

下表描述了gllightfv()方法的引數。

序號 引數名稱和描述
1

光源

指定一個光源。光源的數量取決於實現,但至少支援八個光源。它接受十個值,這些引數在下面名為“光源引數”的單獨表格中討論。

2

Pname

指定一個單值光源引數。對於光源,有十個引數,如下所述。

3

Params

指定指向設定為光源lightpname引數的值或值的指標。

4

光源引數

您可以使用下面給出的任何光源引數。

光源引數

序號 引數和描述
1

GL_AMBIENT

它包含指定光源的環境強度的引數。

2

GL_DIFFUSE

它包含指定光源的漫射強度的引數。

3

GL_SPECULAR

它包含指定光源的鏡面反射強度的引數。

4

GL_POSITION

它包含四個整數或浮點值,用於指定光源在齊次物件座標中的位置。

5

GL_SPOT_DIRECTION

它包含指定光源在齊次物件座標中的方向的引數。

6

GL_SPOT_EXPONENT

其引數指定光源的強度分佈。

7

GL_SPOT_CUTOFF

這的單個引數指定光源的最大散佈角。

8

GL_CONSTANT_ATTENUATION 或 GL_LINEAR_ATTENUATION 或 GL_QUADRATIC_ATTENUATION

您可以使用這些衰減因子中的任何一個,它由單個值表示。

照明是使用glEnable()glDisable()方法以及引數GL_LIGHTING啟用或停用。

以下給出了照明模板:

gl.glEnable(GL2.GL_LIGHTING); 
gl.glEnable(GL2.GL_LIGHT0);  
gl.glEnable(GL2.GL_NORMALIZE); 

float[] ambientLight = { 0.1f, 0.f, 0.f,0f };  // weak RED ambient 
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambientLight, 0); 

float[] diffuseLight = { 1f,2f,1f,0f };  // multicolor diffuse 
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuseLight, 0); 

將光應用於旋轉多邊形

按照給定的步驟將光應用於旋轉多邊形。

使用 glRotate() 方法旋轉多邊形

gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 
  
// Clear The Screen And The Depth Buffer  
gl.glLoadIdentity();  
                 
// Reset The View  
gl.glRotatef(rpoly, 0.0f, 1.0f, 0.0f); 

讓我們來看一下將光應用於旋轉多邊形的程式:

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLCapabilities; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.GLProfile; 
import javax.media.opengl.awt.GLCanvas; 

import javax.swing.JFrame; 

import com.jogamp.opengl.util.FPSAnimator; 
 
public class PolygonLighting implements GLEventListener { 
   private float rpoly;
	
   @Override 
	
   public void display( GLAutoDrawable drawable ) {
   
      final GL2 gl = drawable.getGL().getGL2(); 
      gl.glColor3f(1f,0f,0f); //applying red
      
      // Clear The Screen And The Depth Buffer 
      gl.glClear( GL2.GL_COLOR_BUFFER_BIT |  
      GL2.GL_DEPTH_BUFFER_BIT );   
      gl.glLoadIdentity();       // Reset The View    
      gl.glRotatef( rpoly, 0.0f, 1.0f, 0.0f ); 
		
      gl.glBegin( GL2.GL_POLYGON ); 
      
      gl.glVertex3f( 0f,0.5f,0f ); 
      gl.glVertex3f( -0.5f,0.2f,0f ); 
      gl.glVertex3f( -0.5f,-0.2f,0f ); 
      gl.glVertex3f( 0f,-0.5f,0f ); 
      gl.glVertex3f( 0f,0.5f,0f ); 
      gl.glVertex3f( 0.5f,0.2f,0f ); 
      gl.glVertex3f( 0.5f,-0.2f,0f ); 
      gl.glVertex3f( 0f,-0.5f,0f ); 
      
      gl.glEnd(); 
		
      gl.glFlush(); 
      
      rpoly += 0.2f;  //assigning the angle 
      
      gl.glEnable( GL2.GL_LIGHTING );  
      gl.glEnable( GL2.GL_LIGHT0 );  
      gl.glEnable( GL2.GL_NORMALIZE );  

      // weak RED ambient 
      float[] ambientLight = { 0.1f, 0.f, 0.f,0f };  
      gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient-Light, 0);  

      // multicolor diffuse 
      float[] diffuseLight = { 1f,2f,1f,0f };  
      gl.glLightfv( GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse-Light, 0 ); 
   }  
      
   @Override 
   public void dispose( GLAutoDrawable arg0 ) { 
      //method body  
   } 
  
   @Override 
   public void init( GLAutoDrawable arg0 ) { 
      // method body     
   } 
	
   @Override 
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { 
      // method body 
   } 
	
   public static void main( String[] args ) { 
   
      //getting the capabilities object of GL2 profile 
      final GLProfile profile = GLProfile.get( GLProfile.GL2 ); 
      GLCapabilities capabilities = new GLCapabilities( profile);

      // The canvas  
      final GLCanvas glcanvas = new GLCanvas( capabilities ); 
      PolygonLighting polygonlighting = new PolygonLighting(); 
      glcanvas.addGLEventListener( polygonlighting ); 
      glcanvas.setSize( 400, 400 ); 

      //creating frame 
      final JFrame frame = new JFrame (" Polygon lighting ");  

      //adding canvas to it 
      frame.getContentPane().add( glcanvas ); 
      frame.setSize( frame.getContentPane().getPreferredSize()); 
      frame.setVisible( true );  
                    
      //Instantiating and Initiating Animator 
      final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true ); 
      animator.start();                     
      
   } //end of main 
	
} //end of class 

如果編譯並執行上述程式,它將生成以下輸出。在這裡,您可以觀察到具有照明的旋轉多邊形的各種快照。

Polygon Lighting

JOGL - 3D 基礎

在前面的章節中,我們已經看到了如何建立二維物件、對其應用效果以及變換物件。本章將教你如何繪製具有第三維的線條和一些形狀。

讓我們繪製一條簡單的帶有 z 軸的線條,並檢視二維線條和三維線條之間的區別。首先繪製一條簡單的線條,然後將第二條線條繪製到視窗中 3 個單位。

讓我們來看一下繪製三維線條的程式:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;
   
public class Line3d implements GLEventListener {
   private GLU glu = new GLU();
	
   @Override
   
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef( 0f, 0f, -2.5f );
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glEnd();
      
      //3d line
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,3f );// 3 units into the window
      gl.glVertex3f( 0f,-0.75f,3f );
      gl.glEnd();
   }
   
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
	
      GL2 gl = drawable.getGL().getGL2();
      
      if( height <= 0 )
         height = 1;
			
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
		
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   
   public static void main( String[] args ) {
	
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities(profile);
          
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Line3d line3d = new Line3d();
      glcanvas.addGLEventListener( line3d );
      glcanvas.setSize( 400, 400 );
       
      //creating frame
      final JFrame frame = new JFrame (" 3d line");
          
      //adding canvas to it
      frame.getContentPane().add( glcanvas );
      frame.setSize(frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }//end of main
	
}//end of class

編譯並執行上述程式後,將生成以下輸出:

3D Line

可以透過為glVertex3f()方法的 z 象限提供非零值來繪製 3D 形狀,從而生成上述檢視。現在連線剩餘的線條將導致 3D 邊緣。

現在,以相同的方式,讓我們開發一個具有第三維的邊緣。

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

public class Edge1 implements GLEventListener {
   private GLU glu = new GLU();
	
   @Override
   public void display(GLAutoDrawable drawable) {
   
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef(0f, 0f, -2.5f);
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glEnd();

      //3d line
      gl.glBegin(GL2.GL_LINES);

      //3 units in to the window
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();

      //top
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();

      //bottom
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
   }

   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
   
   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
	
      // TODO Auto-generated method stubfinal
      GL2 gl = drawable.getGL().getGL2();
      if(height <= 0)
         height = 1;
			
      final float h = (float) width / (float) height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL2.GL_PROJECTION);
      gl.glLoadIdentity();
		
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL2.GL_MODELVIEW);
      gl.glLoadIdentity();

   }
   
   public static void main(String[] args) {
   
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);

      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      Edge1 b = new Edge1();
      glcanvas.addGLEventListener(b);
      glcanvas.setSize(400, 400);

      //creating frame
      final JFrame frame = new JFrame (" 3d edge");

      //adding canvas to it
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
	
}//end of class

編譯並執行上述程式後,將生成以下輸出:

3D Edge

同樣,透過為任何二維四邊形的對應邊開發 3D 邊緣並連線相鄰的頂點,您可以獲得一個 3D 四邊形。

下面給出一個使用 JOGL 繪製菱形的程式。

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

public class Rhombus implements GLEventListener {
   private GLU glu = new GLU();
    
   @Override
   public void display(GLAutoDrawable drawable) {
	
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef(0f, 0f, -2.5f);

      //drawing edge1.....
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,3f); // 3 units into the window
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();

      //top
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();

      // bottom
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
   
      // edge 2....
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 3f);
      gl.glVertex3f(0.75f,0f, 3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f, 3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f(0.75f,0f, 3f);
      gl.glEnd();

      //Edge 3.............
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();

      //final edge
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f,3f);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f(0.75f,0f,3f);
      gl.glEnd();
		
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
   }
   
   @Override
   public void dispose(GLAutoDrawable arg0) {
      //method body
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
      // method body
   }
	
   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
   
      // TODO Auto-generated method stub final
      GL2 gl = drawable.getGL().getGL2();
      if(height lt;= 0)
         height = 1;
			
      final float h = (float) width / (float) height;
      gl.glViewport(3, 6, width, height);
      gl.glMatrixMode(GL2.GL_PROJECTION);
      gl.glLoadIdentity();
		
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL2.GL_MODELVIEW);
      gl.glLoadIdentity();
   }
   
   public static void main(String[] args) {
	
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);

      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      Rhombus b = new Rhombus();
      glcanvas.addGLEventListener(b);
      glcanvas.setSize(400, 400);

      //creating frame
      final JFrame frame = new JFrame (" Rhombus 3d");

      //adding canvas to it
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
	
}//end of classimport javax.media.opengl.GL2;

編譯並執行以上程式,將生成以下輸出。它顯示了一個使用 3D 線繪製的菱形。

Rhombus 3D

glBegin() 方法的預定義引數可用於繪製 3D 形狀。

JOGL - 3D 三角形

在上一章中,我們已經瞭解瞭如何繪製 3D 形狀,本章將教你如何繪製 3D 三角形並對其進行旋轉。

下面給出的是繪製 3D 三角形並旋轉它的程式。

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;

public class Triangle3d implements GLEventListener {

   private GLU glu = new GLU();
   private float rtri = 0.0f;
      
   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();

      // Clear The Screen And The Depth Buffer
      gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
      gl.glLoadIdentity(); // Reset The View
      gl.glTranslatef( -0.5f, 0.0f, -6.0f ); // Move the triangle
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );
      gl.glBegin( GL2.GL_TRIANGLES ); 
        
      //drawing triangle in all dimensions
      // Front
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Front)
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Left Of Triangle (Front)
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Right Of Triangle (Front)
        
      // Right
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Right)
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Left Of Triangle (Right)
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Right Of Triangle (Right)
        
      // Left
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Back)
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Left Of Triangle (Back)
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Right Of Triangle (Back)
        
      //left
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Left)
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Left Of Triangle (Left)
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Right Of Triangle (Left)
		
      gl.glEnd(); // Done Drawing 3d triangle (Pyramid)
      gl.glFlush();
      rtri += 0.2f;
   }
   
   @Override
   public void dispose( GLAutoDrawable drawable ) {
      //method body
   }
   
   @Override
   public void init( GLAutoDrawable drawable ) {
      //method body
   }
   
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
	
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      if(height lt;=;)
         height = 1;
			
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
		
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   
   public static void main( String[] args ) {
   
      // TODO Auto-generated method stub
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
         
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Triangle3d triangle = new Triangle3d();
		
      glcanvas.addGLEventListener( triangle );
      glcanvas.setSize( 400, 400 );
		
      final JFrame frame = new JFrame ( "3d Triangle (shallow)" );
		
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
		
      final FPSAnimator animator = new FPSAnimator(glcanvas,300,true);
      animator.start();
   }
	
}

編譯並執行以上程式,將生成以下輸出。這裡,您有旋轉的 3D 三角形的快照。由於此程式不包含深度測試,因此生成的三角形是空心的。

Triangle 3D

要使三角形變為實心,需要使用glEnable(GL_DEPTH_TEST)啟用深度測試。啟用深度緩衝區會導致螢幕變為空白。可以透過使用glClear(GL_COLOR_BUFFERBIT | GL_DEPTH_BUFFER_BIT)方法清除顏色來解決此問題。要在 init() 方法或glDisplay()方法中啟用深度測試,請編寫以下程式碼:

public void init(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
	
   gl.glShadeModel(GL2.GL_SMOOTH);
   gl.glClearColor(0f, 0f, 0f, 0f);
   gl.glClearDepth(1.0f);
   gl.glEnable(GL2.GL_DEPTH_TEST);
   gl.glDepthFunc(GL2.GL_LEQUAL);
   gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
 }

下面給出的是繪製帶有深度測試的 3D 三角形的程式。

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;

public class Triangledepthtest implements GLEventListener {

   private GLU glu = new GLU();
   private float rtri = 0.0f; 
	
   @Override
   public void display( GLAutoDrawable drawable ) {
	
      final GL2 gl = drawable.getGL().getGL2();
		
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);

      // Clear The Screen And The Depth Buffer
      gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 
      gl.glLoadIdentity(); // Reset The View
      gl.glTranslatef( -0.5f,0.0f,-6.0f ); // Move the triangle
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );
      gl.glBegin( GL2.GL_TRIANGLES ); 

      //drawing triangle in all dimensions
      //front
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Left
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Right)

      //right
      gl.glColor3f( 1.0f, 0.0f, 0.0f );
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f );
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Left
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f );
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Right

      //left
      gl.glColor3f( 1.0f, 0.0f, 0.0f );
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f );
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Left 
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f );
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Right 

      //top
      gl.glColor3f( 0.0f, 1.0f, 0.0f );
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top
		
      gl.glColor3f( 0.0f, 0.0f, 1.0f );
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Left
		
      gl.glColor3f( 0.0f, 1.0f, 0.0f );
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Right
		
      gl.glEnd(); // Done Drawing 3d triangle (Pyramid)

      gl.glFlush();
      rtri += 0.2f;
   }
      
   @Override
   public void dispose( GLAutoDrawable drawable ) {
   }
   
   @Override
   public void init( GLAutoDrawable drawable ) {
	
      final GL2 gl = drawable.getGL().getGL2();
		
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
   }
   
   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height ) {
	
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      if( height <= 0 ) 
         height = 1;
			
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
		
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
      
   public static void main( String[] args ) {
	
      // TODO Auto-generated method stub
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
		
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Triangledepthtest triangledepthtest = new Triangledepthtest();
		
      glcanvas.addGLEventListener( triangledepthtest );
      glcanvas.setSize( 400, 400 );
		
      final JFrame frame = new JFrame ( "3d Triangle (solid)" );
      frame.getContentPane().add(glcanvas);
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true);
		
      animator.start();
   }
	
}

編譯並執行以上程式,將生成以下輸出。

在這裡,您可以看到旋轉的 3D 三角形的快照。由於此程式包含深度測試程式碼,因此生成的三角形是實心的。

Triangle Depth Test

JOGL - 3D 立方體

在前面的章節中,我們已經瞭解瞭如何繪製 3D 三角形並對其進行旋轉。現在,在本節中,您可以學習如何繪製 3D 立方體、如何旋轉它以及如何在它上面附加影像。同樣,本章提供了繪製 3D 立方體、對其應用顏色以及在其上附加影像的示例。

下面給出的是繪製 3D 立方體並對其應用顏色的程式。

import java.awt.DisplayMode;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;

public class Cube implements GLEventListener {

   public static DisplayMode dm, dm_old;
   private GLU glu = new GLU();
   private float rquad = 0.0f;
      
   @Override
   public void display( GLAutoDrawable drawable ) {
	
      final GL2 gl = drawable.getGL().getGL2();
      gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
      gl.glLoadIdentity();
      gl.glTranslatef( 0f, 0f, -5.0f ); 

      // Rotate The Cube On X, Y & Z
      gl.glRotatef(rquad, 1.0f, 1.0f, 1.0f); 
 
      //giving different colors to different sides
      gl.glBegin(GL2.GL_QUADS); // Start Drawing The Cube
      gl.glColor3f(1f,0f,0f); //red color
      gl.glVertex3f(1.0f, 1.0f, -1.0f); // Top Right Of The Quad (Top)
      gl.glVertex3f( -1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Bottom Left Of The Quad (Top)
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Bottom Right Of The Quad (Top)
		
      gl.glColor3f( 0f,1f,0f ); //green color
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Top Right Of The Quad
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Top Left Of The Quad
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad 

      gl.glColor3f( 0f,0f,1f ); //blue color
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Top Right Of The Quad (Front)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Top Left Of The Quad (Front)
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Bottom Left Of The Quad
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Bottom Right Of The Quad 

      gl.glColor3f( 1f,1f,0f ); //yellow (red + green)
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad
      gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // Top Right Of The Quad (Back)
      gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // Top Left Of The Quad (Back)

      gl.glColor3f( 1f,0f,1f ); //purple (red + green)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Top Right Of The Quad (Left)
      gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // Top Left Of The Quad (Left)
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Bottom Right Of The Quad 

      gl.glColor3f( 0f,1f, 1f ); //sky blue (blue +green)
      gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // Top Right Of The Quad (Right)
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Top Left Of The Quad
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Bottom Left Of The Quad
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad
      gl.glEnd(); // Done Drawing The Quad
      gl.glFlush();
      rquad -= 0.15f;
   }
   
   @Override
   public void dispose( GLAutoDrawable drawable ) {
      // TODO Auto-generated method stub
   }
   
   @Override
   public void init( GLAutoDrawable drawable ) {
	
      final GL2 gl = drawable.getGL().getGL2();
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
   }
      
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
	
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      if( height lt;= 0 )
         height = 1;
			
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
		
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
      
   public static void main( String[] args ) {
	
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      
      // The canvas
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Cube cube = new Cube();
		
      glcanvas.addGLEventListener( cube );
      glcanvas.setSize( 400, 400 );
		
      final JFrame frame = new JFrame ( " Multicolored cube" );
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true);
		
      animator.start();
   }
	
}

編譯並執行以上程式,將生成以下輸出。它顯示了一個彩色的 3D 立方體。

Multicolored Cube

在立方體上應用紋理

以下步驟介紹瞭如何在立方體上應用紋理:

  • 您可以使用 Drawable 介面的gl.glBindTexture(GL2.GL_TEXTURE_2D.texture)方法將所需的紋理繫結到立方體。

  • 此方法需要紋理 (int) 引數以及GL2.GL_TEXTURE_2D(int)

  • 在執行Display()之前,需要建立紋理變數。

  • init()方法或glDisplay()方法的起始行中,使用gl.glEnable(GL2.GL_TEXTURE_2D)方法啟用紋理。

  • 建立紋理物件,它需要一個檔案物件作為引數,而檔案物件又需要用作紋理的影像的路徑。

File file = new File(“c:\\pictures\\boy.jpg”);
Texture t = textureIO.newTexture(file, true);
texture = t.getTextureObject(gl);
  • 處理“檔案未找到”異常。

下面給出的是在立方體上附加影像的程式。

import java.awt.DisplayMode;

import java.io.File;
import java.io.IOException;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;

import javax.swing.JFrame;

import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureIO;

public class CubeTexture implements GLEventListener {

   public static DisplayMode dm, dm_old;
   private GLU glu = new GLU();
   private float xrot,yrot,zrot;
   private int texture;
   
   @Override
   public void display(GLAutoDrawable drawable) {
   
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
      gl.glLoadIdentity(); // Reset The View
      gl.glTranslatef(0f, 0f, -5.0f);
		
      gl.glRotatef(xrot, 1.0f, 1.0f, 1.0f);
      gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
      gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
		
      gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
      gl.glBegin(GL2.GL_QUADS);

      // Front Face
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f);
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f);

      // Back Face
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);

      // Top Face
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f);

      // Bottom Face
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);

      // Right face
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f);
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f);
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f);

      // Left Face
      gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
      gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
      gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f);
      gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f);
      gl.glEnd();
      gl.glFlush();

      //change the speeds here
      xrot += .1f;
      yrot += .1f;
      zrot += .1f;
   }
   
   @Override
   public void dispose(GLAutoDrawable drawable) {
      // method body
   }
   
   @Override
   public void init(GLAutoDrawable drawable) {
	
      final GL2 gl = drawable.getGL().getGL2();
		
      gl.glShadeModel(GL2.GL_SMOOTH);
      gl.glClearColor(0f, 0f, 0f, 0f);
      gl.glClearDepth(1.0f);
      gl.glEnable(GL2.GL_DEPTH_TEST);
      gl.glDepthFunc(GL2.GL_LEQUAL);
      gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
      
      //
      gl.glEnable(GL2.GL_TEXTURE_2D);
      try{
		
         File im = new File("E:\\office\\boy.jpg ");
         Texture t = TextureIO.newTexture(im, true);
         texture= t.getTextureObject(gl);
          
      }catch(IOException e){
         e.printStackTrace();
      }
   }
      
   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
   
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      if(height lt;= 0)
         height = 1;
			
      final float h = (float) width / (float) height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL2.GL_PROJECTION);
      gl.glLoadIdentity();
		
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL2.GL_MODELVIEW);
      gl.glLoadIdentity();
   }
   
   public static void main(String[] args) {
   
      // TODO Auto-generated method stub
      final GLProfile profile = GLProfile.get(GLProfile.GL2);
      GLCapabilities capabilities = new GLCapabilities(profile);
      
      // The canvas
      final GLCanvas glcanvas = new GLCanvas(capabilities);
      CubeTexture r = new CubeTexture();
		
      glcanvas.addGLEventListener(r);
      glcanvas.setSize(400, 400);
		
      final JFrame frame = new JFrame (" Textured Cube");
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
      final FPSAnimator animator = new FPSAnimator(glcanvas, 300, true);
		
      animator.start();
   }
	
}

編譯並執行以上程式,將生成以下輸出。您可以看到一個 3D 立方體,在其上應用了所需的紋理。

Texture Cube

JOGL - 附錄

GPU - 圖形處理單元,它是一種特殊的電子裝置,可以加速影像渲染。

JNI - Java 本地介面。Java 使用它來訪問本地方法。

模型 - 它們是由基本圖形圖元(如點、線和多邊形)構建的物件。

畫素 - 螢幕上看到的最小顯示單元。

投影 - 將物件座標對映到二維平面的方法稱為投影。

投影矩陣 - 它是物件在 2D 表面上的線性變換。

渲染 - 計算機從模型建立影像的過程。

視口 - 在計算機圖形學中,視口是螢幕上的一個檢視區域。

廣告