JOGL - 快速指南
JOGL - 概述
本章介绍 OpenGL、其功能、Java 中的 OpenGL 绑定(GL4java、LWJGL、JOGL)以及 JOGL 相对于其他 OpenGL 绑定的优势。
Java binding for 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 平台。 |
有各种 OpenGL 绑定Java。它们将在下文讨论
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
您可以从网站 www.jogamp.org
下载最新版本的 JOGL。
- 的主页。
单击 Builds/Downloads >当前 (zip)。

这将带您进入网站维护的所有 API 的 .jar 文件列表。

下载库 .jar 文件 jogamp-all-platforms.7z、OpenGL 本机库的 Java 文档 glugen-javadoc.7z 和 JOGL jogl-javadocs.7z。
使用任何 zip 解压软件解压下载的 .jar 文件。
打开解压的文件夹时,您将找到 jar文件夹、源代码和 其他文件。

获取源代码 gluegen-java-src.zip 和 jogl-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

为 Eclipse 4.4 设置 JOGL
按照给定的步骤设置 JOGL −
添加库
步骤 1 − 打开 Eclipse。
步骤 2 − 创建一个新项目。
步骤 3 − 在项目文件夹中创建一个名为 lib 的新文件夹。
步骤 4 −将文件 gluegen-rt-natives-windows-amd64.jar、gluegenrt.jar、jogl-all-natives-windowsamd64.jar 和 jogl-all.jar 复制到 lib 文件夹中。

步骤 5 − 现在选择这些文件并右键单击鼠标按钮。将显示一个快捷菜单,其中包含 Build Path > Add to Build Path。

步骤 6 − 要使所有 .jar 文件可供其他项目使用,请转到主菜单。选择窗口 > 首选项。出现"首选项"窗口。


在首选项窗口中,在左侧的下拉菜单中,按照层次结构进行操作 - Java → 构建路径 → 用户库。
单击"新建…"按钮。
它会打开一个对话框。输入库名称为 jogl2.1。
使用按钮"添加外部 JAR..."添加 jar 文件 glugen-rt.jar 和 jogl-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.jar 和 glugen-natives-windows-amd64.jar 提供的方法,设置 Javadoc、源代码和 jar 文件的位置。
为 NetBeans 4.4 设置 JOGL
让我们来看看为 NetBeans 4.4 设置 JOGL 的步骤 −
添加库
步骤 1 − 在主菜单中,选择 工具 > 库。

步骤 2 −它会引导您进入 Ant Library Manager。

步骤 3 − 在 Classpath 选项卡下,单击位于左下角的 New Library 按钮。它会打开一个小对话框。
步骤 4 − 输入库名称为 JoGl2.0。
步骤 5 − 单击"确定"按钮。

步骤 6 −单击"添加 JAR/文件夹…"按钮。
步骤 7 − 选择 .jar 文件 jogl.all.jar 和 gluegen-rt.jar 所在的路径。
要将 JOGL 库包含到每个项目中,请按照以下步骤 −
步骤 1 − 右键单击 项目名称。它会显示一个快捷菜单。

步骤 2 − 选择 属性。它将打开一个名为 项目属性 的窗口。

步骤 3 − 从左侧的类别中选择 库。
步骤 4 − 选择 编译选项卡 并单击"添加库..."按钮。出现添加库对话框。
步骤 5 −现在添加您之前创建的 JOGL2.0 库。
在每个项目中包含本机库
按照给定的步骤在每个项目中包含本机库 −
步骤 1 − 右键单击项目。
步骤 2 − 选择 设置配置 > 自定义…

它将引导您进入 项目属性 窗口。

步骤 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/libraries…"按钮。选择解压后的源代码所在的路径。
自定义 JDK 编辑器
步骤 1 − 为文件 jogl.all.jar 和 gluegen-rt.jar 设置 Classpath。
步骤 2 − 设置本机库 gluegen-rt-natives-windows-amd64.jar 和 joglall-natives-windowsamd64.jar 的路径,或者从您下载它们的文件夹中复制所有 jar 文件并将其粘贴到 jse lib 文件夹中。
JOGL - 基本模板的 API
使用 JOGL 编程,可以绘制各种图形形状,如直线、三角形、3D 形状,包括特殊效果,如旋转、照明、颜色等。要在 JOGL 中绘制对象,首先我们必须构建一个基本的 JOGL 框架。下面给出了构建基本框架所需的类。
GLEventListener 接口
要使您的程序能够使用 JOGL 图形 API,您需要实现 GLEventListener 接口。您可以在 javax.media.opengl 包中找到 GLEventListener 接口。
下表提供了 GLEventListener 接口的各种方法和说明的详细信息 −
Sr.No. | 方法和说明 |
---|---|
1 | Void display(GLAutoDrawable drawable) 它由 GLAutoDrawable 接口的对象调用,以由客户端启动 OpenGL 渲染。即该方法包含使用 OpenGL API 绘制图形元素的逻辑。 |
2 | Void dispose(GLAutoDrawable drawable) 该方法向侦听器发出信号,要求其释放每个 GLContext 中的所有 OpenGL 资源,例如内存缓冲区和 GLSL 程序。 |
3 | Void init(GLAutoDrawble drawable) 在 OpenGL 上下文初始化后,GLAutoDrawable 接口的对象会立即调用该方法。 |
4 | Void reshape(GLAutoDrawble drawble, int x, int y, int width, int height) 组件调整大小后,第一次重新绘制时,GLAutoDrawable 接口的对象会调用此方法。每当组件在窗口上的位置发生变化时,也会调用此方法。 |
GLEventListener 的所有方法都需要 GLAutoDrawable 接口的对象作为参数。
GLAutoDrawable 接口
此接口提供基于事件的机制 (GLEventListener),用于执行 OpenGL 渲染。 GLAutoDrawable 自动创建一个主渲染上下文,该上下文在对象的生命周期内与 GLAutoDrawable 相关联。
下表提供了 GLAutoDrawable 接口的各种方法和说明的详细信息 −
Sr.No | 方法和说明 |
---|---|
1 | GL getGL() 返回 GLAutoDrawable 接口的当前对象使用的 GL 管道对象。 |
2 | void addGLEventListener(GLEventListener Listener) 将给定的侦听器添加到当前可绘制队列的末尾。 |
3 | void addGLEventListener(int index, GLEventListener listener) 将给定的侦听器添加到此可绘制队列的给定索引处。 |
4 | void destroy() 销毁与此 GLAutoDrawable 接口对象关联的所有资源,包括 GLContext。 |
注意 − 此包中还有其他方法。此接口中仅讨论与模板相关的一些重要方法。
GLCanvas 类
GLCanvas 和 GLJpanel 是 JOGL GUI 的两个主要类,它们实现了 GLAutoDrawable 接口,可用作 OpenGL 命令的绘图表面。
GLCanvas 是一个重量级的 AWT 组件,它提供 OpenGL 渲染支持。这是 AWTAutoGLDrawable 接口的主要实现。它还继承了 java.awt.Canvas 类。由于它是一个重量级组件,在某些情况下,GLJCanvas 可能无法与 swing 组件正确集成。因此,在与 Swing 一起使用时必须小心。每当您在使用 GLJCanvas 时遇到问题时,您都必须使用 GLJPanel 类。
类 GLCanvas 的层次结构图如下所示 −

GLEventistener 接口与 GLCanvas 类一起工作。它响应 GLCanvas 类中的更改以及它们发出的绘制请求。
每当实例化 GLCanvas 类时,就会调用 GLEventListener 的 init() 方法。您可以重写此方法来初始化 OpenGL 状态。
每当首次绘制(实例化)或调整 GLCanvas 大小时,都会执行 GLEventListener 的 reshape() 方法。它用于初始化 OpenGL 视口和投影矩阵。每当组件的位置发生变化时,也会调用该方法。
GLEventListener 的 display() 方法包含用于渲染 3D 场景的代码。每当调用 GLCanvas 的 display() 方法时,都会调用它。
下面给出了实例化 GLCanvas 类所需的构造函数。
Sr.No | 构造函数和说明 |
---|---|
1 | GLCanvas() 它在默认屏幕设备上使用默认的 OpenGL 功能选择机制,创建一个具有一组默认 OpenGL 功能的新 GLCanvas 组件。 |
2 | GLCanvas(GLCapabilitiesImmutable) 它创建一个新的 GLCanvas 组件使用默认屏幕设备上的默认 OpenGL 功能选择机制,使用请求的 OpenGL 功能集。 |
下面给出了用于 GLCanvas 类事件处理的方法。
Sr.编号 | 方法和说明 |
---|---|
1 | void addGLEventListener(GLEventListener listener) 将给定的侦听器添加到此可绘制队列的末尾。 |
2 | void addGLEventListener(int indexGLEventListener listener) 将给定的侦听器添加到此可绘制队列的给定索引处。 |
要实例化 GLCanvas 类,您需要 GLCapabilitiesImmutable 接口的对象,该接口指定一组不可变的 OpenGL 功能。
获取对象的方法之一CapabilitiesImmutable 接口用于实例化实现该接口的 GLCapabilities 类。可以使用 GLCapabilities 类的实例来实现此目的。
GLCapabilities 类
此类指定一组 OpenGL 功能。它以 GLCapabilities 对象作为参数。GLCapabilities 类描述了渲染上下文必须支持的所需功能,例如 OpenGL 配置文件。
下面给出了一个用于实例化 GLCapabilities 类的构造函数
Sr. No. | 方法和说明 |
---|---|
1 | GLCapabilities(GLProfile glprofile) 它创建一个 GLCapabilities 对象。 |
要实例化 GLCanvas 类,您需要一个 GLCapabilitiesImmutable 接口的对象,该接口指定一组不可变的 OpenGL 功能。
获取 CapabilitiesImmutable 接口对象的方法之一是实例化实现该接口的 GLCapabilities 类。 GLCapabilities 类的实例可用于实现此目的。
GLCapabilities 类又需要一个 GLProfile 对象。
GLProfile 类
由于发布了多个版本的 OpenGL API;您需要向 Java 虚拟机 (JVM) 指定程序中使用的 OpenGL API 的确切版本。这可以使用 GLProfile 类来完成。
此类的 get() 方法接受不同的预定义 String 对象作为参数。每个 String 对象都是一个接口的名称,每个接口都支持某些版本的 OpenGL。如果您将此类初始化为静态和单例,它将为每个可用的 JOGL 配置文件提供单例 GLProfile 对象。
下面给出了 GLProfile 类的 get 方法的原型。
Sr.No. | 方法和说明 |
---|---|
1 | Static GLProfile get(String profile) 使用默认设备。 |
由于这是一个静态方法,您需要使用类名来调用它,并且它 需要一个预定义的静态字符串变量作为参数。此类中有 12 个这样的变量,每个变量代表 GL 接口的一个单独实现。
GLProfile.get(GLProfile.GL2);
get() 方法的参数
Sr.No | 预定义字符串值(接口名称)和描述 |
---|---|
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 类的类层次结构。

下面给出了 GLJPanel 类的各种构造函数。
Sr.编号 | 构造函数和说明 |
---|---|
1 | GJPanel() 它创建一个具有一组默认 OpenGL 功能的新 GLJPanel 组件。 |
2 | (GLCapabilitiesImmutable) 它创建一个具有一组请求的 OpenGL 功能的新 GLJPanel 组件。 |
3 | GLJPanel(GLCapabilitiesImmutable userCapsRequest, GLCapabilitiesChooser chooser) 它创建一个新的 GLJPanel组件。 |
下面给出了 GLJPanel 类的方法。
Sr.No. | 方法和说明 |
---|---|
1 | void addGLEventListener(GLEventListener listener) 此方法将给定的侦听器添加到此可绘制队列的末尾。 |
2 | void addGLEventListener(int indexGLEventListener listener) 此方法将给定的侦听器添加到此可绘制队列的给定索引处。 |
JOGL - 带有 AWT 的 Canvas
本章向您介绍如何使用带有 AWT 框架的 Canvas 绘制 JOGL 基本框架。在这里,我们将构造一个 AWT 框架,并使用框架类的 add() 方法将画布对象添加到 AWT 框架。
下面给出了编写程序的步骤,该程序结合 JOGL 的 Canvas 类和 AWT 的 Frame 类创建 JOGL 基本框架。
步骤 1:创建类
首先创建一个实现 GlEventListener 接口的类,并导入包 javax.media.opengl。实现所有四个方法 display()、dispose()、 reshape()、init()。由于这是基本框架,因此讨论了创建画布类、将其添加到框架等基本任务。所有 GLEVentListener 接口方法均未实现。
步骤 2:准备 Canvas
(a) 构造 GLCanvas 类对象
final GLCanvas glcanvas = new GLCanvas( xxxxxxx ); //此处应将 capabilities obj 作为参数传递
(b) 实例化 GLCapabilities 类
GLCapabilities capabilities = new GLCapabilities( xxxxx ); //此处应将配置文件 obj 作为参数传递
(c) 生成 GLProfile 对象
由于它是静态方法,因此使用类名调用它。由于本教程是关于 JOGL2 的,让我们生成 GL2 接口对象。
final GLProfile profile = GLProfile.get( GLProfile.GL2 ); // 变量和方法都是静态的,因此都使用类名调用。
让我们看看画布的代码片段。
//获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities);
(d) 现在使用方法 addGLEventListener() 将 GLEventListener 添加到画布。此方法需要 GLEventListener 接口的对象作为参数。因此,传递实现 GLEventListener 的类的对象。
BasicFrame basicframe = newBasic Frame( );// 实现 GLEventListener 接口的类 glcanvas.addGLEventListener( basicframe );
(e) 使用 GLCanvas 从 javax.media.opengl.awt.AWTGLAutoDrawable 继承的 setSize() 方法设置框架的大小。
glcanvas.setSize( 400, 400 );
现在您已准备好使用 GLCanvas。
步骤 3:创建框架
通过实例化 JSE AWT 框架组件的 Frame 类对象来创建框架。
向其添加画布并使框架可见。
//创建框架 final Frame frame = new frame( " Basic 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) { // 方法主体 } @Override public void dispose(GLAutoDrawable arg0) { //method body } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) { // 方法主体 } public static void main(String[] args) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); BasicFrame b = new BasicFrame(); glcanvas.addGLEventListener(b); glcanvas.setSize(400, 400); //创建框架 final Frame frame = new Frame (" Basic Frame"); //将画布添加到框架 frame.add(glcanvas); frame.setSize( 640, 480 ); frame.setVisible(true); } }
如果你编译并执行上述程序,将生成以下输出。 它显示了当我们将 GLCanvas 类与 AWT 结合使用时形成的基本框架 −

JOGL - 带有 Swing 的 Canvas
本章向您介绍如何使用 Canvas 和 javax.swing 包中的 JFrame 类绘制 JOGL 基本框架。在这里,我们将实例化 JFrame,并使用 add() 方法将画布对象添加到 JFrame 的实例中。
将 Canvas 与 AWT 结合使用可为您提供具有重量级功能的图形框架。要获得轻量级图形框架,您需要将 GLCanvas 与 Swing 结合使用。在 Swing 中使用 GLCanvas 时,可以将 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) { // 方法主体 } @Override public void dispose(GLAutoDrawable arg0) { //method body } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) { // 方法主体 } public static void main(String[] args) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); BasicFrame b = new BasicFrame(); glcanvas.addGLEventListener(b); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame (" Basic Frame"); //向其中添加画布 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of classimport
如果编译并执行上述程序,将生成以下输出。 它显示了当我们将 GLCanvas 与 Swing 窗口结合使用时形成的基本框架。

JOGL - GLJPanel 类
本章向您介绍如何使用 GLJpanel 类绘制 JOGL 基本框架。它是一个轻量级的 Swing 组件,提供 OpenGL 渲染支持。它是为了与 Swing 兼容而提供的。在这里我们将实例化一个 JFrame,并使用 add() 方法将 GLJpanel 对象添加到 JFrame 的实例中。
以下程序使用 GLJPanel 和 Swing 窗口生成一个基本框架 −
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) { // 方法主体 } @Override public void dispose(GLAutoDrawable arg0) { //method body } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) { // 方法主体 } public static void main(String[] args) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // GLJpanel 类 GLJPanel gljpanel = new GLJPanel( glcapabilities ); BasicFrame b = new BasicFrame(); gljpanel.addGLEventListener(b); gljpanel.setSize(400, 400); //创建框架 final JFrame frame = new JFrame (" Basic Frame"); //向其添加画布 frame.getContentPane().add( gljpanel); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of classimport
如果编译并执行上述程序,将生成以下输出。 它显示了当我们将 GLJPanel 与 swing 窗口结合使用时形成的基本框架 −

JOGL - 绘图基础
OpenGL API 提供了绘制基本图形元素(如点、顶点、线等)的原始方法。使用这些方法,您可以绘制三角形、多边形和圆形等形状。既有 2D 维度,也有 3D 维度。本章将教您如何在 Java 程序中使用 JOGL 绘制基本线条。
绘图对象
为了访问特定于硬件和操作系统平台的程序以及使用其他语言(如 C 和 C++(本机应用程序))编写的库,Java 使用一种称为 Java 本机接口 (JNI) 的编程框架。 JOGL 内部使用此接口来访问 OpenGL 函数,如下图所示。

GLEventListener 接口的所有四个方法都有代码(java JOGL 方法)来内部调用 OpenGL 函数。这些 JOGL 方法的命名也类似于 OpenGL 的命名约定。如果 OpenGL 中的函数名称是 glBegin(),则将其用作 gl.glBegin()。
每当调用 java JOGL 的 gl.glBegin() 方法时,它都会内部调用 OpenGL 的 glBegin() 方法。这就是在安装 JOGL 时在用户系统上安装本机库文件的原因。
Display() 方法
这是一个重要的方法,它保存了开发图形的代码。它 需要 GLAutoDrawable 接口对象作为其参数。
display() 方法最初使用 GL 接口的对象获取 OpenGL 上下文(GL 继承了 GLBase 接口,该接口包含生成所有 OpenGL 上下文对象的方法)。由于本教程是关于 JOGL2 的,让我们生成一个 GL2 对象。
以下代码片段显示了如何生成 GL2 对象 −
//生成 GL 对象 GL gl = drawable.getGL(); GL gl = drawable.getGL(); //使用此方法获取 Gl2 对象 //这可以写成一行,例如 final GL2 gl = drawable.getGL().getGL2();
使用 GL2 接口的对象,可以访问此接口的成员, 进而提供对 OpenGL [1.0... 3.0] 函数的访问。
绘制线条
GL2 接口包含大量方法,但这里讨论的是三个主要的重要方法,即 glBegin()、glVertex() 和 glEnd()。
Sr.No. | 方法和说明 |
---|---|
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) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); Line l = new Line(); glcanvas.addGLEventListener(l); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame ("straight Line"); //将画布添加到框架 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of classimport javax.media.opengl.GL2;

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); //绘制底部 gl.glBegin (GL2.GL_LINES); gl.glVertex3f(-0.50f, -0.50f, 0); gl.glVertex3f(0.50f, -0.50f, 0); gl.glEnd(); //绘制右边缘 gl.glBegin (GL2.GL_LINES); gl.glVertex3f(0f, 0.50f, 0); gl.glVertex3f(-0.50f, -0.50f, 0); gl.glEnd(); //绘制左边缘 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) { //方法主体 } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) { // 方法主体 } public static void main(String[] args) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); Triangle l = new Triangle(); glcanvas.addGLEventListener(l); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame ("Triangle"); //将画布添加到框架 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 绘制的三角形。

让我们通过一个程序来使用 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 ) { //方法主体 } @Override public void init(GLAutoDrawable arg0 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Rhombus rhombus = new Rhombus(); glcanvas.addGLEventListener( rhombus ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame ( "Rhombus" ); //将画布添加到框架 frame.getContentPane().add( glcanvas ); frame.setSize(frame.getContentPane().getPreferredSize() ); frame.setVisible( true ); } }
如果您编译并执行上述程序,您将获得以下输出。它显示了使用 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 House implements GLEventListener { @Override public void display( GLAutoDrawable drawable ) { final GL2 gl = drawable.getGL().getGL2(); //绘制顶部 gl.glBegin ( GL2.GL_LINES ); gl.glVertex3f( -0.3f, 0.3f, 0 ); gl.glVertex3f( 0.3f,0.3f, 0 ); gl.glEnd(); //绘制底部 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( -0.3f,-0.3f, 0 ); gl.glVertex3f( 0.3f,-0.3f, 0 ); gl.glEnd(); //绘制右边缘 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( -0.3f,0.3f, 0 ); gl.glVertex3f( -0.3f,-0.3f, 0 ); gl.glEnd(); //绘制左边缘 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( 0.3f,0.3f,0 ); gl.glVertex3f( 0.3f,-0.3f,0 ); gl.glEnd(); //建筑屋顶 //建筑左侧直径 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( 0f,0.6f, 0 ); gl.glVertex3f( -0.3f,0.3f, 0 ); gl.glEnd(); //建筑右侧直径 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( 0f,0.6f, 0 ); gl.glVertex3f( 0.3f,0.3f, 0 ); gl.glEnd(); //建筑门 //绘制顶部 gl.glBegin ( GL2.GL_LINES ); gl.glVertex3f( -0.05f, 0.05f, 0 ); gl.glVertex3f( 0.05f, 0.05f, 0 ); gl.glEnd(); //绘制左边缘 gl.glBegin ( GL2.GL_LINES ); gl.glVertex3f( -0.05f, 0.05f, 0 ); gl.glVertex3f( -0.05f, -0.3f, 0 ); gl.glEnd(); //绘制右边缘 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 ) { //方法主体 } @Override public void init( GLAutoDrawable arg0 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); House house = new House(); glcanvas.addGLEventListener( house ); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame( "House" ); //将画布添加到框架 frame.getContentPane().add( glcanvas ); frame.setSize(frame.getContentPane().getPreferredSize() ); frame.setVisible( true ); }//end of main }//end of class
如果您编译并执行上述程序,您将获得以下输出。它显示了使用 GL_LINES() 方法生成的房屋图。

JOGL - 预定义形状
在前面的章节中,我们学习了如何使用 JOGL 绘制线条、三角形、菱形等形状。我们通过将预定义字段 Gl_lines 传递给 glBegin() 方法来绘制线条。
除了 GL_LINES 之外,glBegin() 方法还接受另外八个参数。您可以使用它们来绘制不同的形状。这些使用方式与 GL_LINES 相同。
下表显示了 glBegin() 方法参数及其说明 −
Sr.No | 参数和说明 |
---|---|
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) { // 方法主体 } @Override public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) { // 方法主体 } public static void main(String[] args) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); LineStrip r = new LineStrip(); glcanvas.addGLEventListener(r); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame ("LineStrip"); //将画布添加到框架 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of classimport javax.media.opengl.GL2;
如果编译并执行上述代码,将生成以下输出 −

用于绘制线环的 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() 方法,编译并执行它,将生成以下输出 −

使用 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() 方法,编译并执行它,将生成以下输出 −

用于绘制三角形条带的 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() 方法,编译并执行它,将生成以下输出 −

用于绘制四边形的 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() 方法,编译并执行它,则会生成以下输出 −

用于绘制多边形的 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() 方法,编译并执行它,则会生成以下输出 −

JOGL - 变换
OpenGL 提供了更多功能,例如将颜色应用于对象、缩放、照明、旋转对象等。本章介绍使用 JOGL 对对象进行的一些变换。
在窗口上移动对象
在前面的章节中,我们讨论了绘制线条和使用简单线条绘制各种形状的程序。以这种方式创建的形状可以显示在窗口内的任何位置。这是使用方法 glTranslatef (float x, float y, float z) 完成的。
此方法属于 GLMatrixFunc 接口,位于 javax.media.opengl.fixedfunc 包中。
GLMatrixFunc 接口
接口 − GLMatrixFunc
包 − javax.media.opengl.fixedfunc
下表列出了此接口的一些重要方法 −
Sr.No. | 方法和说明 |
---|---|
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 自动生成的方法存根 final GL2 gl = drawable.getGL().getGL2(); // 获取 OpenGL 2 图形对象 if(height <= 0) height = 1; // 防止除以 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.glLoadIdentity(); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); }
JOGL - 着色
本章教您如何使用 JOGL 为对象应用颜色。要为对象应用颜色,请使用 GL2 的方法 glColor()。下面给出了使用 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); // 获得红色 gl.glColor3f(0f,1f,0f); // 获得绿色 gl.glColor3f(0f,0f,1f); //给我们蓝色
如果是三角形,你可以为每个顶点应用不同的颜色。
让我们通过程序将颜色应用到三角形 −
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 ); // 使用三角形绘制 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 ) { //方法主体 } @Override public void init( GLAutoDrawable arg0 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); TriangleColor triple = new TriangleColor(); glcanvas.addGLEventListener( triple ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame (" Colored Triangle"); //向其中添加画布 frame.getContentPane().add( glcanvas ); frame.setSize( frame.getContentPane().getPreferredSize()); frame.setVisible( true ); } //end of main } //end of class
编译并执行上述程序后,您将获得以下彩色三角形 −

将颜色应用于多边形
让我们通过程序将颜色应用于多边形 −
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 ) { //方法主体 } @Override public void init( GLAutoDrawable arg0 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); PolygonColor poly = new PolygonColor(); glcanvas.addGLEventListener( poly ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame ( "Colored Polygon" ); //将画布添加到框架 frame.getContentPane().add( glcanvas ); frame.setSize(frame.getContentPane().getPreferredSize() ); frame.setVisible( true ); } //end of main } //end of class
当您编译并执行上述程序时,您将获得以下彩色多边形 −

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 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Scaling scaling = new Scaling(); glcanvas.addGLEventListener( scaling ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame (" Dimnished Triangle (Scaling )"); //向其中添加画布 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); } //end of main } //end of classimport javax.media.opengl.GL2;
编译并执行上述程序后,我们得到以下输出。在这里,您可以观察到与 TriangleColor.java 生成的原始三角形相比缩小的三角形 −

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 类的各种构造函数。
Sr.No. | 方法和说明 |
---|---|
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 ); // 清除屏幕和深度缓冲区 gl.glLoadIdentity(); // 重置视图 //三角形旋转 gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f ); // 使用三角形绘图 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 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) { public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities); TriangleRotation triple = new TriangleRotation(); glcanvas.addGLEventListener( triple ); glcanvas.setSize( 400, 400 ); // 创建框架 final JFrame frame = new JFrame ("Rotating Triangle"); // 向其中添加画布 frame.getContentPane().add( glcanvas ); frame.setSize(frame.getContentPane() .getPreferredSize()); frame.setVisible( true ); //实例化并启动动画器 final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true); animator.start(); } } //end of main } //end of class
如果您编译并执行上述程序,它将生成以下输出。在这里,您可以观察到围绕 x 轴旋转彩色三角形的各种快照。

JOGL - 照明
本章向您介绍如何使用 JOGL 将照明效果应用于对象。
要设置照明,首先使用 glEnable() 方法启用照明。然后使用 GLLightingFunc 接口的 glLightfv(int light, int pname, float[] params, int params_offset) 方法为对象应用照明。此方法需要四个参数。
下表描述了 gllightfv() 方法的参数。
Sr.No. | 参数名称和说明 |
---|---|
1 | Light 指定光源。光源数量取决于实现,但至少支持八个光源。它接受十个值,这些参数在下面给出的名为"光源参数"的单独表格中讨论。 |
2 | Pname 指定单值光源参数。对于光源,有十个参数,如下所述。 |
3 | Params 指定指向设置为光源 light 的参数 pname 的值的指针。 |
4 | 光源参数 您可以使用下面给出的任何光源参数。 |
光源参数
Sr.No. | 参数和说明 |
---|---|
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 }; // 弱红色环境光 gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambientLight, 0); float[] difficileLight = { 1f,2f,1f,0f }; // 多色漫反射 gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, difficileLight, 0);
将光应用于旋转多边形
按照给定的步骤将光应用于旋转多边形。
使用 glRotate() 方法旋转多边形
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓冲区 gl.glLoadIdentity(); // 重置视图 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); //应用红色 // 清除屏幕和深度缓冲区 gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT ); gl.glLoadIdentity(); // 重置视图 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; //分配角度 gl.glEnable( GL2.GL_LIGHTING ); gl.glEnable( GL2.GL_LIGHT0 ); gl.glEnable( GL2.GL_NORMALIZE ); // 弱红色环境光 float[] ambientLight = { 0.1f, 0.f, 0.f,0f }; gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient-Light, 0); // 多色漫反射 float[] difficileLight = { 1f,2f,1f,0f }; gl.glLightfv( GL2.GL_LIGHT0, GL2.GL_DIFFUSE, difficile-Light, 0 ); } @Override public void dispose( GLAutoDrawable arg0 ) { //method body } @Override public void init( GLAutoDrawable arg0 ) { // 方法主体 } @Override public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) { // 方法主体 } public static void main( String[] args ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); PolygonLighting polylighting = new PolygonLighting(); glcanvas.addGLEventListener( polygonlighting ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame (" Polygon lighting "); //向其添加画布 frame.getContentPane().add( glcanvas ); frame.setSize( frame.getContentPane().getPreferredSize()); frame.setVisible( true ); //实例化并启动动画器 final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true ); animator.start(); } //end of main } //end of class
如果您编译并执行上述程序,它将生成以下输出。在这里,您可以观察到带有照明的旋转多边形的各种快照。

JOGL - 3D 基础
在前面的章节中,我们已经了解了如何创建 2d 对象、对其应用效果以及变换对象。本章将教您如何绘制具有 3 维的线和一些形状。
让我们绘制一条带有 z 轴的简单线,并查看 2D 和 3D 线之间的区别。首先绘制一条简单线,然后将第二条线绘制到窗口 3 个单位处。
让我们通过程序绘制 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 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 线 gl.glBegin( GL2.GL_LINES ); gl.glVertex3f( -0.75f,0f,3f );// 向窗口内移动 3 个单位 gl.glVertex3f( 0f,-0.75f,3f ); gl.glEnd(); } @Override public void dispose( GLAutoDrawable arg0 ) { //方法主体 } @Override public void init( GLAutoDrawable arg0 ) { // 方法主体 } @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 ) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Line3d line3d = new Line3d(); glcanvas.addGLEventListener( line3d ); glcanvas.setSize( 400, 400 ); //创建框架 final JFrame frame = new JFrame (" 3d line"); //向其中添加画布 frame.getContentPane().add( glcanvas ); frame.setSize(frame.getContentPane().getPreferredSize() ); frame.setVisible( true ); }//end of main }//end of class
编译并执行上述程序时,将生成以下输出 −

可以通过为 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 自动生成的方法存根 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 线 gl.glBegin(GL2.GL_LINES); //3 个单位进入窗口 gl.glVertex3f(-0.75f,0f,3f); 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(); //底部 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) { //方法主体 } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { // TODO 自动生成的方法 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) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); Edge1 b = new Edge1(); glcanvas.addGLEventListener(b); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame (" 3d edge"); //向其中添加画布 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of class
编译并执行上述程序时,将生成以下输出 −

同样,通过将 3D 边发展到任何 2D 四边形的对应边并连接相邻顶点,您可以得到一个 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); //绘制边缘 1..... 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 个单位 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(); // 底部 gl.glBegin(GL2.GL_LINES); gl.glVertex3f(0f,-0.75f, 0); gl.glVertex3f(0f,-0.75f,3f); gl.glEnd(); // 边缘 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(); //边 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(); //最终边缘 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) { //方法主体 } @Override public void init(GLAutoDrawable arg0) { // 方法主体 } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { // TODO 自动生成的方法存根 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) { //获取 GL2 配置文件的功能对象 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 final GLCanvas glcanvas = new GLCanvas(capabilities); Rhombus b = new Rhombus(); glcanvas.addGLEventListener(b); glcanvas.setSize(400, 400); //创建框架 final JFrame frame = new JFrame (" Rhombus 3d"); //向其中添加画布 frame.getContentPane().add(glcanvas); frame.setSize(frame.getContentPane().getPreferredSize()); frame.setVisible(true); }//end of main }//end of classimport javax.media.opengl.GL2;
编译并执行上述程序时,会生成以下输出。它显示了使用 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(); // 清除屏幕和深度缓冲区 gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT ); gl.glLoadIdentity(); // 重置视图 gl.glTranslatef( -0.5f, 0.0f, -6.0f ); // 移动三角形 gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f ); gl.glBegin( GL2.GL_TRIANGLES ); // 在所有维度上绘制三角形 // 正面 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(正面) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 三角形左侧(正面) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 三角形右侧(正面) // 右侧 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(右) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 三角形左侧(右) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 三角形右侧(右) // 左 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(后面) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 三角形左侧(后面) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 三角形右侧(后面) //左侧 gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(左侧) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 三角形左侧(左) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 三角形右侧(左) gl.glEnd(); // 完成绘制 3d 三角形(金字塔) gl.glFlush(); rtri += 0.2f; } @Override public void dispose( GLAutoDrawable drawable ) { //方法主体 } @Override public void init( GLAutoDrawable drawable ) { //方法主体 } @Override public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) { // TODO 自动生成的方法存根 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 自动生成的方法存根 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Triangle3d triple = new Triangle3d(); glcanvas.addGLEventListener( triple ); 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 三角形的快照。由于此程序不包含深度测试,因此三角形是空心的。

要使三角形成为实心的,您需要使用 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); // 清除屏幕和深度缓冲区 gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); // 重置视图 gl.glTranslatef( -0.5f,0.0f,-6.0f ); // 移动三角形 gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f ); gl.glBegin( GL2.GL_TRIANGLES ); //在所有维度上绘制三角形 //正面 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 顶部 gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 左 gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 右) //右 gl.glColor3f( 1.0f, 0.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 上 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 左 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 右 //左 gl.glColor3f( 1.0f, 0.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 上 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 左 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 右 //上 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 顶部 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 左侧 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 右侧 gl.glEnd(); // 完成绘制 3d 三角形(金字塔) 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 自动生成的方法存根 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 自动生成的方法存根 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Triangledepthtest tripledepthtest = new Triangledepthtest(); glcanvas.addGLEventListener( tripledepthtest ); 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 三角形的快照。由于此程序包含深度测试代码,因此三角形是实心的。

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 ); // 在 X、Y 和 Z 轴上旋转立方体 gl.glRotatef(rquad, 1.0f, 1.0f, 1.0f); // 为不同面赋予不同颜色 gl.glBegin(GL2.GL_QUADS); // 开始绘制立方体 gl.glColor3f(1f,0f,0f); // 红色 gl.glVertex3f(1.0f, 1.0f, -1.0f); // 四边形的右上方(顶部) gl.glVertex3f( -1.0f, 1.0f, -1.0f); // 四边形的左上方(顶部) gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的左下方(顶部) gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的右下方(顶部) gl.glColor3f( 0f,1f,0f ); //绿色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的右上方 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的左上方 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的左下方 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的右下方 gl.glColor3f( 0f,0f,1f ); //蓝色 gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的右上方(正面) gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的左上方(正面) gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的左下方 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的右下方 gl.glColor3f( 1f,1f,0f ); //黄色(红色 + 绿色) gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的左下角 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的右下角 gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // 四边形的右上角(背面) gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // 四边形的左上角(背面) gl.glColor3f( 1f,0f,1f ); //紫色(红色 + 绿色) gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的右上方(左) gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // 四边形的左上方(左) gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的左下方 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的右下方 gl.glColor3f( 0f,1f, 1f ); //天蓝色(蓝色 + 绿色) gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // 四边形的右上方(右) gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的左上角 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的左下角 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的右下角 gl.glEnd(); // 四边形绘制完成 gl.glFlush(); rquad -= 0.15f; } @Override public void dispose( GLAutoDrawable drawable ) { // TODO 自动生成的方法存根 } @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 自动生成的方法存根 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 ); // 画布 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 立方体。

将纹理应用于立方体
以下步骤用于将纹理应用于立方体 −
您可以使用 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 自动生成的方法存根 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); 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); // 正面 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.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); // 顶面 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); // 底面 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); // 右面 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); // 左面 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(); //在此处更改速度 xrot += .1f; yrot += .1f; zrot += .1f; } @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); // 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 自动生成的方法存根 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 自动生成的方法存根 final GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); // 画布 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 立方体。

JOGL - 附录
GPU − 图形处理单元,是一种加速图像渲染的特殊电子设备。
JNI − Java 本机接口。通过它,java 可以访问本机方法。
模型 − 它们是由基本图形基元(如点、线和多边形)构造的对象。
像素 − 屏幕上看到的最小显示单位。
投影 − 将对象的坐标映射到二维平面的方法称为投影。
投影矩阵 − 它是对象在 2D 表面上的线性变换。
渲染 −计算机根据模型创建图像的过程。
视口 − 视口是计算机图形学中屏幕上的查看区域。