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。
  • 转到 www.jogamp.org

  • 的主页。
  • 单击 Builds/Downloads >当前 (zip)。

Jogamp 主页

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

JAR 文件列表
  • 下载库 .jar 文件 jogamp-all-platforms.7z、OpenGL 本机库的 Java 文档 glugen-javadoc.7z 和 JOGL jogl-javadocs.7z。

  • 使用任何 zip 解压软件解压下载的 .jar 文件。

打开解压的文件夹时,您将找到 jar文件夹、源代码和 其他文件。

源代码文件夹

获取源代码 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 文件

为 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 − 现在选择这些文件并右键单击鼠标按钮。将显示一个快捷菜单,其中包含 Build Path > Add to Build Path。

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 Library Manager

NetBeans2

步骤 3 − 在 Classpath 选项卡下,单击位于左下角的 New Library 按钮。它会打开一个小对话框。

步骤 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/libraries…"按钮。选择解压后的源代码所在的路径。

自定义 JDK 编辑器

步骤 1 − 为文件 jogl.all.jargluegen-rt.jar 设置 Classpath

步骤 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 接口的各种方法和说明的详细信息 −

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 类

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 类所需的构造函数。

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 类的类层次结构。

GJPanel

下面给出了 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 函数,如下图所示。

JNI

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;
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);
        
        //绘制底部
        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 绘制的三角形。

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 ) {
        //方法主体
   }
	
   @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 生成的菱形。

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();
      
        //绘制顶部
        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() 方法生成的房屋图。

House

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;

如果编译并执行上述代码,将生成以下输出 −

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

下表列出了此接口的一些重要方法 −

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 生成的原始三角形相比缩小的三角形 −

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 类的各种构造函数。

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 

如果您编译并执行上述程序,它将生成以下输出。在这里,您可以观察到带有照明的旋转多边形的各种快照。

Polygon Lighting

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

编译并执行上述程序时,将生成以下输出 −

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 自动生成的方法存根
        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 Edge

同样,通过将 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 线条绘制的菱形。

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();

        // 清除屏幕和深度缓冲区
        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 三角形的快照。由于此程序不包含深度测试,因此三角形是空心的。

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);
        
        // 清除屏幕和深度缓冲区
        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 三角形的快照。由于此程序包含深度测试代码,因此三角形是实心的。

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 );
        
        // 在 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 立方体。

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 自动生成的方法存根
        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 立方体。

Texture Cube

JOGL - 附录

GPU − 图形处理单元,是一种加速图像渲染的特殊电子设备。

JNI − Java 本机接口。通过它,java 可以访问本机方法。

模型 − 它们是由基本图形基元(如点、线和多边形)构造的对象。

像素 − 屏幕上看到的最小显示单位。

投影 − 将对象的坐标映射到二维平面的方法称为投影。

投影矩阵 − 它是对象在 2D 表面上的线性变换。

渲染 −计算机根据模型创建图像的过程。

视口 − 视口是计算机图形学中屏幕上的查看区域。