Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile BGFX demos to native executable #34

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
/.project
/*.iml
/dependency-reduced-pom.xml
.gradle
166 changes: 153 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,162 @@
# lwjgl3-demos
Demo suite for LWJGL 3
# lwjgl3-bgfx-demos + GraalVM native image

## Building
BGFX Demos for LWJGL 3 compiled to native executable by GraalVM native-image utility.

./mvnw package
To override main class
Four BGFX demos are included in the build: [Bump](src/org/lwjgl/demo/bgfx/Bump.java),
[Cubes](src/org/lwjgl/demo/bgfx/Cubes.java), [Metaballs](src/org/lwjgl/demo/bgfx/Metaballs.java),
and [Raymarch](src/org/lwjgl/demo/bgfx/Raymarch.java).

./mvnw package -Dclass=opengl.UniformArrayDemo
Gradle and Maven build scripts are provided for building the project,
which requires JDK 11+ or GraalVM 21+ (for native image).

## Running
## GraalVM pre-requisites

java -jar target/lwjgl3-demos.jar
The [GraalVM native-image](https://www.graalvm.org/reference-manual/native-image) page
shows how to set up GraalVM and its native-image utility for common platforms.
[Gluon](https://gluonhq.com/) also provides some setup
[details](https://docs.gluonhq.com/#_platforms) for GraalVM native-image creation.

on Mac OS you need to specify the `-XstartOnFirstThread` JVM argument, so the above becomes:
This project's Gradle build script uses the
[client-gradle-plugin](https://github.com/gluonhq/client-gradle-plugin)
from Gluon to build the native executable from Gradle with GraalVM.

java -XstartOnFirstThread -jar target/lwjgl3-demos.jar
The GraalVM native-image utility will use the configuration files in
`res/META-INF/native-image` folder to assist in the native-image generation.

To override main class
Gluon also provides the [client-maven-plugin](https://github.com/gluonhq/client-maven-plugin)
which is used in this project's Maven build script and works similarly to the above
client-gradle-plugin.

## Gradle build tasks

To build and run the BGFX demos in standard JVM with Gradle, execute the `run` task:

gradlew run

By default, the [Bump](src/org/lwjgl/demo/bgfx/Bump.java) demo is executed
by the above `run` task without parameter. To run a different BGFX demo, e.g.
[Raymarch](src/org/lwjgl/demo/bgfx/Raymarch.java), execute the `run` task
with that specific demo class as parameter (prefixed by `bgfx.`):

gradlew run --args=bgfx.Raymarch

System properties can be passed on to the running demo with the -D parameter,
e.g. to print out some debug info in the console:

gradlew run --args=bgfx.Raymarch -Dorg.lwjgl.util.Debug=true

The above tasks can use any standard JDK 11+.

To generate native executable, GraalVM 21+ need be set up as mentioned in
*GraalVM pre-requisites* section above.

Once GraalVM is set up and available in the path, run the `nativeBuild` task:

gradlew nativeBuild

The `nativeBuild` task would take a while to compile the BGFX demo source code and
link them with the LWJGL libraries into an executable file.
The resulting `lwjgl3-bgfx-demos` file is:

build/client/x86_64-linux/lwjgl3-bgfx-demos

(or if building on a Windows machine:

build\client\x86_64-windows\lwjgl3-bgfx-demos.exe

)

which can then be run directly:

./build/client/x86_64-linux/lwjgl3-bgfx-demos

or, for example, with the [Cubes](src/org/lwjgl/demo/bgfx/Cubes.java)
demo as parameter prefixed by `bgfx.`:

./build/client/x86_64-linux/lwjgl3-bgfx-demos bgfx.Cubes

System properties can be passed on to the running demo with the -D parameter,
e.g. to print out some debug info in the console:

./build/client/x86_64-linux/lwjgl3-bgfx-demos bgfx.Cubes -Dorg.lwjgl.util.Debug=true

(or if building on a Windows machine:

build\client\x86_64-windows\lwjgl3-bgfx-demos.exe
build\client\x86_64-windows\lwjgl3-bgfx-demos.exe bgfx.Cubes
build\client\x86_64-windows\lwjgl3-bgfx-demos.exe bgfx.Cubes -Dorg.lwjgl.util.Debug=true

)

## Maven build tasks

To build and run the BGFX demos in standard JVM with Maven, execute the
`compile` then `exec:exec` tasks:

mvnw compile
mvnw exec:exec

By default, the [Bump](src/org/lwjgl/demo/bgfx/Bump.java) demo is executed
by the above `exec:exec` task without parameter. To run a different BGFX demo, e.g.
[Raymarch](src/org/lwjgl/demo/bgfx/Raymarch.java), execute the `exec:exec` task
with that specific demo class (prefixed by `bgfx.`) as value of the property `class`:

mvnw exec:exec -Dclass=bgfx.Raymarch

System properties can be passed on to the running demo with the -Dsys.props parameter,
e.g. to print out some debug info in the console:

mvnw exec:exec -Dclass=bgfx.Raymarch -Dsys.props="-Dorg.lwjgl.util.Debug=true"

The above tasks can use any standard JDK 11+.

To generate native executable, GraalVM 21+ need be set up as mentioned in
*GraalVM pre-requisites* section above.

Once GraalVM is set up and available in the path, run the `client:build` task:

mvnw client:build

The `client:build` task would take a while to compile the BGFX demo source code and
link them with the LWJGL libraries into an executable file.
The resulting `lwjgl3-bgfx-demos` file is:

target/client/x86_64-linux/lwjgl3-bgfx-demos

(or if building on a Windows machine:

target\client\x86_64-windows\lwjgl3-bgfx-demos.exe

)

which can then be run directly:

./target/client/x86_64-linux/lwjgl3-bgfx-demos

or, for example, with the [Metaballs](src/org/lwjgl/demo/bgfx/Metaballs.java)
demo as parameter prefixed by `bgfx.`:

./target/client/x86_64-linux/lwjgl3-bgfx-demos bgfx.Metaballs

System properties can be passed on to the running demo with the -D parameter,
e.g. to print out some debug info in the console:

./target/client/x86_64-linux/lwjgl3-bgfx-demos bgfx.Metaballs -Dorg.lwjgl.util.Debug=true

(or if building on a Windows machine:

target\client\x86_64-windows\lwjgl3-bgfx-demos.exe
target\client\x86_64-windows\lwjgl3-bgfx-demos.exe bgfx.Metaballs
target\client\x86_64-windows\lwjgl3-bgfx-demos.exe bgfx.Metaballs -Dorg.lwjgl.util.Debug=true

)

## Compressed native executable

The resulting `lwjgl3-bgfx-demos` executable file, whether produced by Gradle or Maven build script,
can be further reduced in size via compression using the [UPX](https://upx.github.io) utility,
as described [here](https://medium.com/graalvm/compressed-graalvm-native-images-4d233766a214).

For example, the resulting `lwjgl3-bgfx-demos.exe` native application file produced in Windows
is normally 59MB in size, but is compressed to 16MB with the UPX command: `upx --best lwjgl3-bgfx-demos.exe`

java -cp target/lwjgl3-demos.jar org.lwjgl.demo.opengl.UniformArrayDemo
113 changes: 113 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
plugins {
id 'application'
id 'com.gluonhq.client-gradle-plugin' version '0.1.36' //requires GraalVM 21+
}

wrapper {
gradleVersion = '6.8.3'
distributionType = Wrapper.DistributionType.ALL
}

group = 'org.lwjgl'
description = 'LWJGL3 BGFX demos with native image by GraalVM'
//version = '0.0.1-SNAPSHOT'

ext {
lwjglVersion = '3.2.3'
jomlVersion = '1.10.1'
graalvmVersion = '21.0.0.2'

//LWJGL modules used: minimal OpenGL (minus openal), plus bgfx
lwjglModules = ['lwjgl', 'lwjgl-assimp', 'lwjgl-bgfx', 'lwjgl-glfw', 'lwjgl-opengl', 'lwjgl-stb']

mainClassName = 'org.lwjgl.demo.DemoLauncher'
}

repositories {
mavenCentral()
mavenLocal()
}

//detect the OS (assuming 64-bit, on Intel/AMD hardware)
private static String getCurrentPlatform() {
def currentOS = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem;
if (currentOS.isWindows()) {
return 'windows'
} else if (currentOS.isLinux()) {
return 'linux'
} else if (currentOS.isMacOsX()) {
return 'macos'
}
return null
}

dependencies {
//get recommended dependency versions from the LWJGL BOM
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")

implementation "org.joml:joml:$jomlVersion"

def currentOS = getCurrentPlatform()

//add LWJGL modules and the current OS's natives to the compile and runtime classpaths
lwjglModules.each {
implementation "org.lwjgl:$it"
if (it != 'lwjgl-egl') { //lwjgl-egl has no native libraries
//use natives for 64-bit Intel/AMD platforms only
runtimeOnly "org.lwjgl:$it::natives-$currentOS"
}
}

//for compiling GraalVM substitution classes
compileOnly "org.graalvm.nativeimage:svm:$graalvmVersion"
}

sourceSets {
main {
java {
srcDirs = ['src']
//restrict to bgfx demo source code & GraalVM substitution code
include '**/DemoLauncher.java', '**/bgfx/*', '**/graalvm/*'
}
resources {
srcDirs = ['res']
//restrict to bgfx demo resources only
include 'org/lwjgl/demo/bgfx/**'
//include the GraalVM native-image configuration files
include 'META-INF/native-image/**'
}
}
}

application {
mainClass = project.mainClassName
applicationName = project.name //name of the resulting native executable
}

compileJava {
options.release = 11 //use JDK11+ for compiling & running
options.encoding = 'UTF-8'
}

jar.archiveBaseName = 'lwjgl3-bgfx-demos'

run {
//get system properties specified from the command line (for debugging, etc.)
//and pass them on to the running application's JVM
systemProperties = System.getProperties()

//use the following jvmArgs for as many different run scenarios as possible,
//and for all the code-execution paths as much as possible,
//to generate (or merge with) the GraalVM native-image configuration files
//in the res/META-INF/native-image directory.
//This directory is read by GraalVM during the native-image build.

//jvmArgs = ["-agentlib:native-image-agent=config-merge-dir=res/META-INF/native-image"]
}

gluonClient {
compilerArgs = [
'--initialize-at-run-time=org.lwjgl',
'--report-unsupported-elements-at-runtime',
]
}
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading