├── graalvm-env ├── config │ ├── proxy-config.json │ ├── serialization-config.json │ ├── resource-config.json │ ├── jni-config.json │ └── reflect-config.json ├── all.mp3 ├── gdx64.dll ├── wand1.wav ├── Pacifico.ttf ├── badlogic.jpg ├── gdx-box2d64.dll ├── jamepad64.dll ├── gdx-freetype64.dll ├── run_with_agent.bat ├── shaders │ ├── flash-vert.glsl │ ├── flash-frag.glsl │ ├── motionblur.fragment │ ├── blur.vertex │ ├── copy.fragment │ ├── screenspace.vertex │ ├── bias.fragment │ ├── zoom.fragment │ ├── radial-blur.vertex │ ├── zoom.vertex │ ├── convolve-1d.fragment │ ├── blur.fragment │ ├── radial-distortion.fragment │ ├── threshold.fragment │ ├── radial-blur.fragment │ ├── lensflare.fragment │ ├── combine.fragment │ ├── lensflare2.fragment │ ├── fxaa.fragment │ ├── camerablur.fragment │ ├── nfaa.fragment │ ├── vignetting.fragment │ └── crt-screen.fragment └── build_native.bat ├── settings.gradle ├── core ├── assets │ └── badlogic.jpg ├── build.gradle └── src │ └── com │ └── byern │ └── tanima │ ├── KryonetClientServer.java │ ├── BallPainter.java │ └── ClientMain.java ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── libgdx-native-image ├── build.gradle └── src │ └── main │ └── java │ └── com │ ├── byern │ └── libgdx │ │ └── nimage │ │ ├── LibgdxSubstitutions.java │ │ ├── RuntimeReflectionRegistrationFeature.java │ │ └── LwjglSubstitutions.java │ └── esotericsoftware │ └── kryo │ └── serializers │ └── KryoSubstitutions.java ├── desktop ├── src │ └── com │ │ └── byern │ │ └── tanima │ │ └── desktop │ │ └── DesktopLauncher.java └── build.gradle ├── .gitignore ├── gradlew.bat ├── README.md └── gradlew /graalvm-env/config/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /graalvm-env/config/serialization-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'desktop', 'core' 2 | include 'libgdx-native-image' 3 | 4 | -------------------------------------------------------------------------------- /graalvm-env/all.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/all.mp3 -------------------------------------------------------------------------------- /graalvm-env/gdx64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/gdx64.dll -------------------------------------------------------------------------------- /graalvm-env/wand1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/wand1.wav -------------------------------------------------------------------------------- /core/assets/badlogic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/core/assets/badlogic.jpg -------------------------------------------------------------------------------- /graalvm-env/Pacifico.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/Pacifico.ttf -------------------------------------------------------------------------------- /graalvm-env/badlogic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/badlogic.jpg -------------------------------------------------------------------------------- /graalvm-env/gdx-box2d64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/gdx-box2d64.dll -------------------------------------------------------------------------------- /graalvm-env/jamepad64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/jamepad64.dll -------------------------------------------------------------------------------- /graalvm-env/gdx-freetype64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByerN/libgdx-graalvm-example/HEAD/graalvm-env/gdx-freetype64.dll -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=true 2 | org.gradle.jvmargs=-Xms128m -Xmx1500m 3 | org.gradle.configureondemand=false 4 | -------------------------------------------------------------------------------- /graalvm-env/run_with_agent.bat: -------------------------------------------------------------------------------- 1 | java -agentlib:native-image-agent=config-output-dir=./config,config-write-period-secs=30 -jar desktop-1.0.jar -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = 1.8 2 | [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' 3 | 4 | sourceSets.main.java.srcDirs = [ "src/" ] 5 | 6 | eclipse.project.name = appName + "-core" 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /graalvm-env/shaders/flash-vert.glsl: -------------------------------------------------------------------------------- 1 | attribute vec4 a_position; 2 | attribute vec4 a_color; 3 | attribute vec2 a_texCoord0; 4 | uniform mat4 u_projTrans; 5 | varying vec4 v_color; 6 | varying vec2 v_texCoords; 7 | 8 | void main() { 9 | v_color = a_color; 10 | v_texCoords = a_texCoord0; 11 | gl_Position = u_projTrans * a_position; 12 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/flash-frag.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | varying vec4 v_color; 6 | varying vec2 v_texCoords; 7 | uniform sampler2D u_texture; 8 | 9 | void main() { 10 | 11 | vec4 texColor = texture2D(u_texture, v_texCoords); 12 | vec3 white = texColor.rgb + vec3(255, 255, 255); 13 | texColor.rgb = white; 14 | gl_FragColor = v_color * texColor; 15 | } -------------------------------------------------------------------------------- /libgdx-native-image/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | apply plugin: "java" 6 | apply plugin: "java-library" 7 | version '0.0.1' 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | compileOnly "org.graalvm.nativeimage:svm-hosted-native-windows-amd64:$graalvmVersion" 15 | compile "org.graalvm.nativeimage:svm:$graalvmVersion" 16 | api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" 17 | 18 | api "com.esotericsoftware:kryonet:2.22.0-RC1" 19 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/motionblur.fragment: -------------------------------------------------------------------------------- 1 | // Simple motion blur implementation by Toni Sagrista 2 | // Last frame is drawn with lower opacity 3 | 4 | #ifdef GL_ES 5 | precision mediump float; 6 | precision mediump int; 7 | #endif 8 | 9 | // Unprocessed image 10 | uniform sampler2D u_texture0; 11 | // Last frame 12 | uniform sampler2D u_texture1; 13 | // Last frame alpha 14 | uniform float u_blurOpacity; 15 | 16 | varying vec2 v_texCoords; 17 | 18 | void main() { 19 | gl_FragColor = max(texture2D(u_texture0, v_texCoords), texture2D(u_texture1, v_texCoords) * u_blurOpacity); 20 | } 21 | -------------------------------------------------------------------------------- /graalvm-env/build_native.bat: -------------------------------------------------------------------------------- 1 | native-image.cmd ^ 2 | -H:+ReportExceptionStackTraces ^ 3 | --report-unsupported-elements-at-runtime ^ 4 | --initialize-at-run-time=org.lwjgl ^ 5 | --no-fallback ^ 6 | --allow-incomplete-classpath ^ 7 | -H:ReflectionConfigurationFiles=config/reflect-config.json ^ 8 | -H:JNIConfigurationFiles=config/jni-config.json ^ 9 | -H:DynamicProxyConfigurationFiles=config/proxy-config.json ^ 10 | -H:SerializationConfigurationFiles=config/serialization-config.json ^ 11 | -H:ResourceConfigurationFiles=config/resource-config.json ^ 12 | -Dorg.lwjgl.librarypath=. ^ 13 | -jar desktop-1.0.jar -------------------------------------------------------------------------------- /graalvm-env/config/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | {"pattern":"\\Qgamecontrollerdb.txt\\E"}, 5 | {"pattern":"\\Qgdx-box2d64.dll\\E"}, 6 | {"pattern":"\\Qgdx-freetype64.dll\\E"}, 7 | {"pattern":"\\Qgdx64.dll\\E"}, 8 | {"pattern":"\\Qjamepad64.dll\\E"}, 9 | {"pattern":"\\Qorg/lwjgl/system/APIUtil.class\\E"}, 10 | {"pattern":"\\Qwindows/x64/org/lwjgl/glfw/glfw.dll\\E"}, 11 | {"pattern":"\\Qwindows/x64/org/lwjgl/jemalloc/jemalloc.dll\\E"}, 12 | {"pattern":"\\Qwindows/x64/org/lwjgl/lwjgl.dll\\E"}, 13 | {"pattern":"\\Qwindows/x64/org/lwjgl/openal/OpenAL.dll\\E"}, 14 | {"pattern":"\\Qwindows/x64/org/lwjgl/opengl/lwjgl_opengl.dll\\E"} 15 | ]}, 16 | "bundles":[] 17 | } 18 | -------------------------------------------------------------------------------- /graalvm-env/shaders/blur.vertex: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | attribute vec4 a_position; 25 | attribute vec2 a_texCoord0; 26 | varying vec2 v_texCoord0; 27 | 28 | void main() 29 | { 30 | v_texCoord0 = a_texCoord0; 31 | gl_Position = a_position; 32 | } -------------------------------------------------------------------------------- /desktop/src/com/byern/tanima/desktop/DesktopLauncher.java: -------------------------------------------------------------------------------- 1 | package com.byern.tanima.desktop; 2 | 3 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; 4 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; 5 | import com.byern.tanima.ClientMain; 6 | import com.byern.tanima.KryonetClientServer; 7 | 8 | import java.util.Optional; 9 | 10 | public class DesktopLauncher { 11 | public static void main(String[] arg) { 12 | System.setProperty("org.lwjgl.librarypath", "./"); 13 | System.setProperty("java.library.path", "./"); 14 | System.out.println("java.library.path " + System.getProperty("java.library.path")); 15 | System.out.println("org.lwjgl.librarypath " + System.getProperty("org.lwjgl.librarypath")); 16 | Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); 17 | 18 | new Lwjgl3Application( 19 | new ClientMain( 20 | Optional.of( 21 | new KryonetClientServer.ClientServerConfig( 22 | arg.length > 0 ? Integer.parseInt(arg[0]) : 6669 23 | ) 24 | ) 25 | ), 26 | config 27 | ); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /graalvm-env/shaders/copy.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform sampler2D u_texture0; 25 | varying vec2 v_texCoords; 26 | 27 | void main(void) 28 | { 29 | vec3 col = texture2D(u_texture0,v_texCoords).xyz; 30 | gl_FragColor = vec4(col,1.0); 31 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/screenspace.vertex: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | attribute vec4 a_position; 25 | attribute vec2 a_texCoord0; 26 | varying vec2 v_texCoords; 27 | 28 | void main() 29 | { 30 | v_texCoords = a_texCoord0; 31 | gl_Position = a_position; 32 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/bias.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 tsagrista 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | precision mediump float; 19 | precision mediump int; 20 | #endif 21 | 22 | uniform sampler2D u_texture0; 23 | uniform float u_bias; 24 | varying vec2 v_texCoords; 25 | 26 | void main() 27 | { 28 | vec4 tex = texture2D(u_texture0, v_texCoords); 29 | float avg = (tex.r + tex.g + tex.b) / 3.0; 30 | gl_FragColor = vec4(max(0.0, avg + u_bias)) * 50.0; 31 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/zoom.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform sampler2D u_texture0; 25 | uniform float offset_x; 26 | uniform float offset_y; 27 | uniform float zoom; 28 | varying vec2 v_texCoord0; 29 | 30 | void main() 31 | { 32 | gl_FragColor = texture2D(u_texture0, (v_texCoord0) + vec2(offset_x, offset_y)); 33 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/radial-blur.vertex: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | attribute vec4 a_position; 25 | attribute vec2 a_texCoord0; 26 | 27 | uniform float offset_x; 28 | uniform float offset_y; 29 | 30 | varying vec2 v_texCoord0; 31 | 32 | void main() 33 | { 34 | v_texCoord0 = a_texCoord0 - vec2(offset_x, offset_y); 35 | gl_Position = a_position; 36 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/zoom.vertex: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | attribute vec4 a_position; 25 | attribute vec2 a_texCoord0; 26 | 27 | uniform float offset_x; 28 | uniform float offset_y; 29 | uniform float zoom; 30 | 31 | varying vec2 v_texCoord0; 32 | 33 | void main() 34 | { 35 | v_texCoord0 = (a_texCoord0 - vec2(offset_x, offset_y)) * zoom; 36 | gl_Position = a_position; 37 | } -------------------------------------------------------------------------------- /desktop/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = 1.8 2 | sourceSets.main.java.srcDirs = [ "src/" ] 3 | sourceSets.main.resources.srcDirs = ["../core/assets"] 4 | 5 | project.ext.mainClassName = "com.byern.tanima.desktop.DesktopLauncher" 6 | project.ext.assetsDir = new File("../core/assets") 7 | 8 | task run(dependsOn: classes, type: JavaExec) { 9 | main = project.mainClassName 10 | classpath = sourceSets.main.runtimeClasspath 11 | standardInput = System.in 12 | workingDir = project.assetsDir 13 | ignoreExitValue = true 14 | } 15 | 16 | task debug(dependsOn: classes, type: JavaExec) { 17 | main = project.mainClassName 18 | classpath = sourceSets.main.runtimeClasspath 19 | standardInput = System.in 20 | workingDir = project.assetsDir 21 | ignoreExitValue = true 22 | debug = true 23 | } 24 | 25 | task dist(type: Jar) { 26 | manifest { 27 | attributes 'Main-Class': project.mainClassName 28 | } 29 | dependsOn configurations.runtimeClasspath 30 | from { 31 | configurations.runtimeClasspath.collect { 32 | it.isDirectory() ? it : 33 | (it.name.endsWith("tar.gz")? tarTree(it) : 34 | zipTree(it)) 35 | } 36 | } 37 | with jar 38 | } 39 | 40 | 41 | dist.dependsOn classes 42 | 43 | eclipse.project.name = appName + "-desktop" 44 | -------------------------------------------------------------------------------- /graalvm-env/shaders/convolve-1d.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | #ifndef LENGTH 25 | #error Please define a LENGTH 26 | #endif 27 | 28 | varying vec2 v_texCoords; 29 | uniform PRECISION sampler2D u_texture0; 30 | uniform PRECISION vec2 SampleOffsets[LENGTH]; 31 | uniform PRECISION float SampleWeights[LENGTH]; 32 | 33 | void main() 34 | { 35 | vec4 c = vec4(0); 36 | 37 | // Combine a number of weighted image filter taps. 38 | for (int i = 0; i < LENGTH; i++) 39 | { 40 | c += texture2D(u_texture0, v_texCoords + SampleOffsets[i]) * SampleWeights[i]; 41 | } 42 | 43 | gl_FragColor = c; 44 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/blur.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | #ifndef RADIUS 25 | #error Please define a RADIUS 26 | #endif 27 | 28 | #define KERNEL_SIZE (RADIUS * 2 + 1) 29 | 30 | varying vec2 v_texCoord0; 31 | uniform PRECISION sampler2D u_texture0; 32 | uniform PRECISION vec2 SampleOffsets[KERNEL_SIZE]; 33 | uniform PRECISION float SampleWeights[KERNEL_SIZE]; 34 | 35 | void main() 36 | { 37 | vec4 c = vec4(0); 38 | 39 | // Combine a number of weighted image filter taps. 40 | for (int i = 0; i < KERNEL_SIZE; i++) 41 | { 42 | c += texture2D(u_texture0, v_texCoord0 + SampleOffsets[i]) * SampleWeights[i]; 43 | } 44 | 45 | gl_FragColor = c; 46 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/radial-distortion.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform sampler2D u_texture0; 25 | varying vec2 v_texCoords; 26 | 27 | uniform float distortion;// = 0.3 28 | uniform float zoom;// = 1 29 | 30 | vec2 radialDistortion(vec2 coord) 31 | { 32 | vec2 cc = coord - 0.5; 33 | float dist = dot(cc, cc) * distortion; 34 | return (coord + cc * (1.0 + dist) * dist); 35 | } 36 | 37 | void main() { 38 | vec2 uv = radialDistortion(v_texCoords); 39 | uv = 0.5 + (uv-0.5)*(zoom); 40 | 41 | if(uv.s<0.0 || uv.s>1.0 || uv.t<0.0 || uv.t >1.0) { 42 | gl_FragColor = vec4(0.0,0.0,0.0,1.0); 43 | return; 44 | } 45 | 46 | gl_FragColor = vec4(texture2D(u_texture0, uv).rgb,1.0); 47 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/threshold.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform PRECISION sampler2D u_texture0; 25 | uniform float treshold; 26 | uniform float tresholdInvTx; 27 | varying vec2 v_texCoords; 28 | 29 | void main() 30 | { 31 | vec4 tex = texture2D(u_texture0, v_texCoords); 32 | //gl_FragColor = vec4(tex.a); 33 | 34 | // adjust it to keep only values brighter than the specified 35 | // threshold, scaling back up to preserve full color range 36 | 37 | // threshold 38 | //gl_FragColor.rgb = (tex.rgb-treshold) * tresholdInvTx; 39 | 40 | // masked threshold (use texture's alpha channel) 41 | //gl_FragColor = vec4((tex.rgb-treshold) * tresholdInvTx * tex.a, tex.a); 42 | 43 | // alpha threshold 44 | gl_FragColor = (tex-treshold) * tresholdInvTx; 45 | } -------------------------------------------------------------------------------- /libgdx-native-image/src/main/java/com/byern/libgdx/nimage/LibgdxSubstitutions.java: -------------------------------------------------------------------------------- 1 | package com.byern.libgdx.nimage; 2 | 3 | 4 | import com.badlogic.gdx.utils.GdxRuntimeException; 5 | import com.oracle.svm.core.annotate.Alias; 6 | import com.oracle.svm.core.annotate.Substitute; 7 | import com.oracle.svm.core.annotate.TargetClass; 8 | 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.zip.ZipEntry; 14 | import java.util.zip.ZipFile; 15 | 16 | @TargetClass(com.badlogic.gdx.utils.SharedLibraryLoader.class) 17 | final class com_badlogic_gdx_utils_SharedLibraryLoader { 18 | 19 | @Alias 20 | private String nativesJar; 21 | 22 | @Substitute 23 | private InputStream readFile (String path) { 24 | if (nativesJar == null) { 25 | //Line below causes error 26 | //InputStream input = SharedLibraryLoader.class.getResourceAsStream("/" + path); 27 | InputStream input = null; 28 | try { 29 | input = new FileInputStream(System.getProperty("java.library.path") + "\\" + path); 30 | } catch (FileNotFoundException e) { 31 | e.printStackTrace(); 32 | } 33 | if (input == null) throw new GdxRuntimeException("Unable to read file for extraction: " + path); 34 | return input; 35 | } 36 | 37 | // Read from JAR. 38 | try { 39 | ZipFile file = new ZipFile(nativesJar); 40 | ZipEntry entry = file.getEntry(path); 41 | if (entry == null) throw new GdxRuntimeException("Couldn't find '" + path + "' in JAR: " + nativesJar); 42 | return file.getInputStream(entry); 43 | } catch (IOException ex) { 44 | throw new GdxRuntimeException("Error reading '" + path + "' in JAR: " + nativesJar, ex); 45 | } 46 | } 47 | } 48 | public class LibgdxSubstitutions { 49 | } 50 | -------------------------------------------------------------------------------- /graalvm-env/shaders/radial-blur.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | varying vec2 v_texCoord0; 25 | uniform sampler2D u_texture0; 26 | 27 | uniform float blur_div; 28 | uniform float offset_x; 29 | uniform float offset_y; 30 | uniform float zoom; 31 | 32 | #ifndef BLUR_LENGTH 33 | #error Please define a BLUR_LENGTH 34 | #endif 35 | 36 | #ifndef ONE_ON_BLUR_LENGTH 37 | #error Please define a ONE_ON_BLUR_LENGTH 38 | #endif 39 | 40 | // avoid compile errors 41 | #define BLUR_LEN BLUR_LENGTH 42 | #define ONE_ON_BLUR_LEN ONE_ON_BLUR_LENGTH 43 | 44 | 45 | // precompute blur factors (faster, loops will be unrolled) 46 | const float blur_start = 1.0; 47 | 48 | // performant version 49 | void main() 50 | { 51 | float scale = blur_start * zoom; 52 | vec2 o = vec2(offset_x, offset_y); 53 | 54 | vec4 c = vec4(0); 55 | for( int i = 0; i < BLUR_LEN; ++i ) 56 | { 57 | c += texture2D(u_texture0, (v_texCoord0 * scale) + o); 58 | scale += blur_div; 59 | } 60 | 61 | gl_FragColor = c * ONE_ON_BLUR_LEN; 62 | } -------------------------------------------------------------------------------- /graalvm-env/config/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"com.badlogic.gdx.physics.box2d.World", 4 | "methods":[ 5 | {"name":"beginContact","parameterTypes":["long"] }, 6 | {"name":"contactFilter","parameterTypes":["long","long"] }, 7 | {"name":"endContact","parameterTypes":["long"] }, 8 | {"name":"postSolve","parameterTypes":["long","long"] }, 9 | {"name":"preSolve","parameterTypes":["long","long"] }, 10 | {"name":"reportFixture","parameterTypes":["long"] }, 11 | {"name":"reportRayFixture","parameterTypes":["long","float","float","float","float","float"] } 12 | ] 13 | }, 14 | { 15 | "name":"java.lang.ClassLoader", 16 | "methods":[{"name":"getPlatformClassLoader","parameterTypes":[] }] 17 | }, 18 | { 19 | "name":"java.lang.NoSuchMethodError" 20 | }, 21 | { 22 | "name":"org.lwjgl.system.CallbackI$B", 23 | "methods":[{"name":"callback","parameterTypes":["long"] }] 24 | }, 25 | { 26 | "name":"org.lwjgl.system.CallbackI$D", 27 | "methods":[{"name":"callback","parameterTypes":["long"] }] 28 | }, 29 | { 30 | "name":"org.lwjgl.system.CallbackI$F", 31 | "methods":[{"name":"callback","parameterTypes":["long"] }] 32 | }, 33 | { 34 | "name":"org.lwjgl.system.CallbackI$I", 35 | "methods":[{"name":"callback","parameterTypes":["long"] }] 36 | }, 37 | { 38 | "name":"org.lwjgl.system.CallbackI$J", 39 | "methods":[{"name":"callback","parameterTypes":["long"] }] 40 | }, 41 | { 42 | "name":"org.lwjgl.system.CallbackI$N", 43 | "methods":[{"name":"callback","parameterTypes":["long"] }] 44 | }, 45 | { 46 | "name":"org.lwjgl.system.CallbackI$P", 47 | "methods":[{"name":"callback","parameterTypes":["long"] }] 48 | }, 49 | { 50 | "name":"org.lwjgl.system.CallbackI$S", 51 | "methods":[{"name":"callback","parameterTypes":["long"] }] 52 | }, 53 | { 54 | "name":"org.lwjgl.system.CallbackI$V", 55 | "methods":[{"name":"callback","parameterTypes":["long"] }] 56 | }, 57 | { 58 | "name":"org.lwjgl.system.CallbackI$Z", 59 | "methods":[{"name":"callback","parameterTypes":["long"] }] 60 | } 61 | ] 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Java 2 | 3 | *.class 4 | *.war 5 | *.ear 6 | hs_err_pid* 7 | 8 | ## Robovm 9 | /ios/robovm-build/ 10 | 11 | ## GWT 12 | /html/war/ 13 | /html/gwt-unitCache/ 14 | .apt_generated/ 15 | .gwt/ 16 | gwt-unitCache/ 17 | www-test/ 18 | .gwt-tmp/ 19 | 20 | ## Android Studio and Intellij and Android in general 21 | /android/libs/armeabi/ 22 | /android/libs/armeabi-v7a/ 23 | /android/libs/arm64-v8a/ 24 | /android/libs/x86/ 25 | /android/libs/x86_64/ 26 | /android/gen/ 27 | .idea/ 28 | *.ipr 29 | *.iws 30 | *.iml 31 | /android/out/ 32 | com_crashlytics_export_strings.xml 33 | 34 | ## Eclipse 35 | 36 | .classpath 37 | .project 38 | .metadata/ 39 | /android/bin/ 40 | /core/bin/ 41 | /desktop/bin/ 42 | /html/bin/ 43 | /ios/bin/ 44 | *.tmp 45 | *.bak 46 | *.swp 47 | *~.nib 48 | .settings/ 49 | .loadpath 50 | .externalToolBuilders/ 51 | *.launch 52 | 53 | ## NetBeans 54 | 55 | /nbproject/private/ 56 | /android/nbproject/private/ 57 | /core/nbproject/private/ 58 | /desktop/nbproject/private/ 59 | /html/nbproject/private/ 60 | /ios/nbproject/private/ 61 | 62 | /build/ 63 | /android/build/ 64 | /core/build/ 65 | /desktop/build/ 66 | /html/build/ 67 | /ios/build/ 68 | 69 | /nbbuild/ 70 | /android/nbbuild/ 71 | /core/nbbuild/ 72 | /desktop/nbbuild/ 73 | /html/nbbuild/ 74 | /ios/nbbuild/ 75 | 76 | /dist/ 77 | /android/dist/ 78 | /core/dist/ 79 | /desktop/dist/ 80 | /html/dist/ 81 | /ios/dist/ 82 | 83 | /nbdist/ 84 | /android/nbdist/ 85 | /core/nbdist/ 86 | /desktop/nbdist/ 87 | /html/nbdist/ 88 | /ios/nbdist/ 89 | 90 | nbactions.xml 91 | nb-configuration.xml 92 | 93 | ## Gradle 94 | 95 | /local.properties 96 | .gradle/ 97 | gradle-app.setting 98 | /build/ 99 | /android/build/ 100 | /core/build/ 101 | /desktop/build/ 102 | /html/build/ 103 | /ios/build/ 104 | 105 | ## OS Specific 106 | .DS_Store 107 | Thumbs.db 108 | 109 | ## iOS 110 | /ios/xcode/*.xcodeproj/* 111 | !/ios/xcode/*.xcodeproj/xcshareddata 112 | !/ios/xcode/*.xcodeproj/project.pbxproj 113 | /ios/xcode/native/ 114 | /ios/IOSLauncher.app 115 | /ios/IOSLauncher.app.dSYM 116 | -------------------------------------------------------------------------------- /graalvm-env/shaders/lensflare.fragment: -------------------------------------------------------------------------------- 1 | // Simple lens flare implementation by Toni Sagrista 2 | 3 | #ifdef GL_ES 4 | precision mediump float; 5 | precision mediump int; 6 | #endif 7 | 8 | uniform sampler2D u_texture0; 9 | 10 | // Viewport dimensions along X and Y 11 | uniform vec2 u_viewport; 12 | uniform float u_intensity; 13 | uniform vec2 u_lightPosition; 14 | uniform vec3 u_color; 15 | 16 | varying vec2 v_texCoords; 17 | 18 | vec3 lensflare(vec2 uv,vec2 pos) 19 | { 20 | vec2 main = uv-pos; 21 | vec2 uvd = uv*(length(uv)); 22 | 23 | float dist=length(main); dist = pow(dist,.1); 24 | 25 | 26 | float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0; 27 | 28 | float f2 = max(1.0/(1.0+32.0*pow(length(uvd+0.8*pos),2.0)),.0)*00.1; 29 | float f22 = max(1.0/(1.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*00.08; 30 | float f23 = max(1.0/(1.0+32.0*pow(length(uvd+0.9*pos),2.0)),.0)*00.06; 31 | 32 | vec2 uvx = mix(uv,uvd,-0.5); 33 | 34 | float f4 = max(0.01-pow(length(uvx+0.4*pos),2.4),.0)*6.0; 35 | float f42 = max(0.01-pow(length(uvx+0.45*pos),2.4),.0)*5.0; 36 | float f43 = max(0.01-pow(length(uvx+0.5*pos),2.4),.0)*3.0; 37 | 38 | uvx = mix(uv,uvd,-.4); 39 | 40 | float f5 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0; 41 | float f52 = max(0.01-pow(length(uvx+0.4*pos),5.5),.0)*2.0; 42 | float f53 = max(0.01-pow(length(uvx+0.6*pos),5.5),.0)*2.0; 43 | 44 | uvx = mix(uv,uvd,-0.5); 45 | 46 | float f6 = max(0.01-pow(length(uvx-0.3*pos),1.6),.0)*6.0; 47 | float f62 = max(0.01-pow(length(uvx-0.325*pos),1.6),.0)*3.0; 48 | float f63 = max(0.01-pow(length(uvx-0.35*pos),1.6),.0)*5.0; 49 | 50 | vec3 c = vec3(.0); 51 | 52 | c.r+=f2+f4+f5+f6; c.g+=f22+f42+f52+f62; c.b+=f23+f43+f53+f63; 53 | c = c*1.3 - vec3(length(uvd)*.05); 54 | 55 | return c * u_intensity; 56 | } 57 | 58 | vec3 cc(vec3 color, float factor,float factor2) // color modifier 59 | { 60 | float w = color.x+color.y+color.z; 61 | return mix(color,vec3(w)*factor,w*factor2); 62 | } 63 | 64 | void main(void) 65 | { 66 | vec2 uv = v_texCoords - 0.5; 67 | uv.x *= u_viewport.x / u_viewport.y; 68 | vec2 lpos = u_lightPosition; 69 | lpos.x *= u_viewport.x / u_viewport.y; 70 | vec3 color = u_color * lensflare(uv, lpos); 71 | color = cc(color,.5,.1) + texture2D(u_texture0, v_texCoords); 72 | gl_FragColor = vec4(color, 1.0); 73 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/combine.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform PRECISION sampler2D u_texture0; 25 | uniform PRECISION sampler2D u_texture1; 26 | uniform float Src1Intensity; 27 | uniform float Src2Intensity; 28 | uniform float Src1Saturation; 29 | uniform float Src2Saturation; 30 | 31 | varying vec2 v_texCoords; 32 | 33 | // The constants 0.3, 0.59, and 0.11 are chosen because the 34 | // human eye is more sensitive to green light, and less to blue. 35 | const vec3 GRAYSCALE = vec3(0.3, 0.59, 0.11); 36 | 37 | // 0 = totally desaturated 38 | // 1 = saturation unchanged 39 | // higher = increase saturation 40 | //const float BaseSat = 1; 41 | //const float BloomSat = 1; 42 | 43 | vec3 adjustSaturation(vec3 color, float saturation) 44 | { 45 | vec3 grey = vec3(dot(color, GRAYSCALE)); 46 | //vec3 grey = vec3((color.r+color.g+color.b)*0.333); 47 | return mix(grey, color, saturation); 48 | } 49 | 50 | void main() 51 | { 52 | // lookup inputs 53 | vec4 src1 = texture2D(u_texture0, v_texCoords) * Src1Intensity; 54 | vec4 src2 = texture2D(u_texture1, v_texCoords) * Src2Intensity; 55 | 56 | // adjust color saturation and intensity 57 | src1.rgb = adjustSaturation(src1.rgb,Src1Saturation); 58 | src2.rgb = adjustSaturation(src2.rgb,Src2Saturation); 59 | 60 | // darken the base image in areas where ther's a lot of bloom 61 | // to prevent things looking excessively burned-out 62 | //original *= (1.0 - clamp(bloom, 0.0, 1.0)); 63 | src1 *= (1.0 - src2); 64 | 65 | // combine 66 | gl_FragColor = src1 + src2; 67 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/lensflare2.fragment: -------------------------------------------------------------------------------- 1 | // Lens flare implementation by Toni Sagrista 2 | // From John Chapman's article http://john-chapman-graphics.blogspot.co.uk/2013/02/pseudo-lens-flare.html 3 | #version 120 4 | #ifdef GL_ES 5 | precision mediump float; 6 | precision mediump int; 7 | #endif 8 | 9 | // Unprocessed image 10 | uniform sampler2D u_texture0; 11 | // Lens color 12 | uniform sampler2D u_texture1; 13 | 14 | varying vec2 v_texCoords; 15 | 16 | uniform vec2 u_viewportInverse; 17 | uniform int u_ghosts; // number of ghost samples 18 | uniform float u_ghostDispersal = 0.25; // dispersion factor 19 | uniform float u_haloWidth; 20 | uniform float u_distortion = 1.0; 21 | 22 | /*----------------------------------------------------------------------------*/ 23 | vec4 textureDistorted( 24 | sampler2D tex, 25 | vec2 texcoord, 26 | vec2 direction, 27 | vec3 distortion 28 | ) { 29 | return vec4( 30 | texture2D(tex, texcoord + direction * distortion.r).r, 31 | texture2D(tex, texcoord + direction * distortion.g).g, 32 | texture2D(tex, texcoord + direction * distortion.b).b, 33 | 1.0 34 | ); 35 | } 36 | 37 | /*----------------------------------------------------------------------------*/ 38 | void main() { 39 | vec2 texcoord = -v_texCoords + vec2(1.0); 40 | vec2 texelSize = u_viewportInverse; 41 | 42 | // ghost vector to image centre: 43 | vec2 ghostVec = (vec2(0.5) - texcoord) * u_ghostDispersal; 44 | vec2 haloVec = normalize(ghostVec) * u_haloWidth; 45 | 46 | vec3 distortion = vec3(-texelSize.x * u_distortion, 0.0, texelSize.x * u_distortion); 47 | 48 | // sample ghosts: 49 | vec4 result = vec4(0.0); 50 | for (int i = 0; i < u_ghosts; ++i) { 51 | vec2 offset = fract(texcoord + ghostVec * float(i)); 52 | 53 | float weight = length(vec2(0.5) - offset) / length(vec2(0.5)); 54 | weight = pow(1.0 - weight, 2.0); 55 | 56 | result += textureDistorted( 57 | u_texture0, 58 | offset, 59 | normalize(ghostVec), 60 | distortion 61 | ) * weight; 62 | 63 | 64 | } 65 | result *= texture2D(u_texture1, vec2(length(vec2(0.5) - texcoord) / length(vec2(0.5)))); 66 | 67 | // sample halo: 68 | float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5)); 69 | weight = pow(1.0 - weight, 2.0); 70 | result += textureDistorted( 71 | u_texture0, 72 | fract(texcoord + haloVec), 73 | normalize(ghostVec), 74 | distortion 75 | ) * weight; 76 | 77 | gl_FragColor = result; 78 | } 79 | -------------------------------------------------------------------------------- /libgdx-native-image/src/main/java/com/byern/libgdx/nimage/RuntimeReflectionRegistrationFeature.java: -------------------------------------------------------------------------------- 1 | package com.byern.libgdx.nimage; 2 | 3 | import com.oracle.svm.core.annotate.AutomaticFeature; 4 | import org.graalvm.nativeimage.hosted.Feature; 5 | import org.graalvm.nativeimage.hosted.RuntimeReflection; 6 | 7 | /* 8 | This class shows how reflection config can be implemented in java instead of json config files. 9 | */ 10 | @AutomaticFeature 11 | class RuntimeReflectionRegistrationFeature implements Feature { 12 | public void beforeAnalysis(BeforeAnalysisAccess access) { 13 | try { 14 | RuntimeReflection.register(java.lang.Object.class); 15 | RuntimeReflection.register(com.badlogic.gdx.LifecycleListener.class); 16 | RuntimeReflection.register(com.badlogic.gdx.backends.lwjgl3.audio.OpenALMusic.class); 17 | RuntimeReflection.register(org.lwjgl.PointerBuffer.class); 18 | RuntimeReflection.register(org.lwjgl.PointerBuffer.class.getDeclaredFields()); 19 | RuntimeReflection.register(org.lwjgl.PointerBuffer.class.getMethods()); 20 | RuntimeReflection.register(org.lwjgl.PointerBuffer.class.getDeclaredClasses()); 21 | RuntimeReflection.register(org.lwjgl.PointerBuffer.class.getDeclaredConstructors()); 22 | 23 | RuntimeReflection.register(false, true, java.nio.Buffer.class.getDeclaredField("address")); 24 | RuntimeReflection.register(java.io.File.class.getDeclaredMethod("canExecute")); 25 | RuntimeReflection.register(java.lang.ClassLoader.class.getDeclaredMethod("findLibrary", String.class)); 26 | RuntimeReflection.register(sun.misc.Unsafe.class.getDeclaredFields()); 27 | RuntimeReflection.register( 28 | com.badlogic.gdx.backends.lwjgl3.audio.Wav.Music.class.getConstructor( 29 | com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio.class, 30 | com.badlogic.gdx.files.FileHandle.class 31 | ) 32 | ); 33 | RuntimeReflection.register( 34 | com.badlogic.gdx.backends.lwjgl3.audio.Mp3.Music.class.getConstructor( 35 | com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio.class, 36 | com.badlogic.gdx.files.FileHandle.class 37 | ) 38 | ); 39 | RuntimeReflection.register( 40 | com.badlogic.gdx.backends.lwjgl3.audio.Wav.Sound.class.getConstructor( 41 | com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio.class, 42 | com.badlogic.gdx.files.FileHandle.class 43 | ) 44 | ); 45 | RuntimeReflection.register(false, true, org.lwjgl.opengl.GLCapabilities.class.getDeclaredFields()); 46 | 47 | } catch (NoSuchMethodException | NoSuchFieldException e ) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /graalvm-env/shaders/fxaa.fragment: -------------------------------------------------------------------------------- 1 | // FXAA shader, GLSL code adapted from: 2 | // http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA 3 | // Whitepaper describing the technique: 4 | // http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf 5 | 6 | #ifdef GL_ES 7 | precision mediump float; 8 | precision mediump int; 9 | #endif 10 | 11 | uniform sampler2D u_texture0; 12 | 13 | // The inverse of the viewport dimensions along X and Y 14 | uniform vec2 u_viewportInverse; 15 | uniform float FXAA_REDUCE_MIN; 16 | uniform float FXAA_REDUCE_MUL; 17 | uniform float FXAA_SPAN_MAX; 18 | 19 | varying vec2 v_texCoords; 20 | 21 | vec4 fxaa(sampler2D texture, vec2 texCoords, vec2 viewportInv) { 22 | vec3 rgbNW = texture2D(texture, 23 | texCoords.xy + (vec2(-1.0, -1.0) * viewportInv)).xyz; 24 | vec3 rgbNE = texture2D(texture, 25 | texCoords.xy + (vec2(+1.0, -1.0) * viewportInv)).xyz; 26 | vec3 rgbSW = texture2D(texture, 27 | texCoords.xy + (vec2(-1.0, +1.0) * viewportInv)).xyz; 28 | vec3 rgbSE = texture2D(texture, 29 | texCoords.xy + (vec2(+1.0, +1.0) * viewportInv)).xyz; 30 | vec3 rgbM = texture2D(texture, texCoords.xy).xyz; 31 | 32 | vec3 luma = vec3(0.299, 0.587, 0.114); 33 | float lumaNW = dot(rgbNW, luma); 34 | float lumaNE = dot(rgbNE, luma); 35 | float lumaSW = dot(rgbSW, luma); 36 | float lumaSE = dot(rgbSE, luma); 37 | float lumaM = dot(rgbM, luma); 38 | 39 | float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); 40 | float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 41 | 42 | vec2 dir; 43 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 44 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 45 | 46 | float dirReduce = max( 47 | (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), 48 | FXAA_REDUCE_MIN); 49 | 50 | float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); 51 | 52 | dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), 53 | max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) 54 | * viewportInv; 55 | 56 | vec3 rgbA = 57 | (1.0 / 2.0) 58 | * (texture2D(texture, 59 | texCoords.xy + dir * (1.0 / 3.0 - 0.5)).xyz 60 | + texture2D(texture, 61 | texCoords.xy + dir * (2.0 / 3.0 - 0.5)).xyz); 62 | vec3 rgbB = 63 | rgbA * (1.0 / 2.0) 64 | + (1.0 / 4.0) 65 | * (texture2D(texture, 66 | texCoords.xy + dir * (0.0 / 3.0 - 0.5)).xyz 67 | + texture2D(texture, 68 | texCoords.xy 69 | + dir * (3.0 / 3.0 - 0.5)).xyz); 70 | float lumaB = dot(rgbB, luma); 71 | 72 | vec4 color = vec4(0.0); 73 | 74 | if ((lumaB < lumaMin) || (lumaB > lumaMax)) { 75 | color.xyz = rgbA; 76 | } else { 77 | color.xyz = rgbB; 78 | } 79 | color.a = 1.0; 80 | return color; 81 | } 82 | 83 | void main() { 84 | gl_FragColor = fxaa(u_texture0, v_texCoords, u_viewportInverse); 85 | } 86 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /graalvm-env/shaders/camerablur.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | 25 | uniform PRECISION sampler2D u_texture0; // scene 26 | uniform PRECISION sampler2D u_texture1; // depthmap 27 | uniform PRECISION mat4 ctp; 28 | uniform PRECISION float near, far; 29 | uniform vec2 viewport; 30 | uniform mat4 inv_proj; 31 | uniform float blur_scale; 32 | uniform float depth_scale; 33 | uniform int blur_passes; 34 | 35 | varying vec2 v_texCoords; 36 | 37 | vec3 get_eye_normal(){ 38 | vec2 frag_coord = gl_FragCoord.xy/viewport; 39 | frag_coord = (frag_coord-0.5)*2.0; 40 | vec4 device_normal = vec4(frag_coord, 0.0, 1.0); 41 | return normalize((inv_proj * device_normal).xyz); 42 | } 43 | 44 | vec3 decode_normal(vec2 enc){ 45 | vec2 fenc = enc*4.0-2.0; 46 | float f = dot(fenc,fenc); 47 | float g = sqrt(1.0-f/4.0); 48 | return vec3(fenc*g, 1.0-f/2.0); 49 | } 50 | 51 | float decode_depth(vec2 src){ 52 | float depth = src.x/255.0+src.y; 53 | depth *= depth_scale; 54 | return depth*far+near; 55 | } 56 | 57 | void main() { 58 | vec3 eye_ray = get_eye_normal(); 59 | vec4 eye_data = texture2D(u_texture1, v_texCoords); 60 | vec3 eye_normal = decode_normal(eye_data.xy); 61 | float eye_depth = decode_depth(eye_data.zw); 62 | 63 | vec4 current = vec4(eye_ray * eye_depth, 1.0); 64 | vec4 previous = ctp * current; 65 | previous.xyz /= previous.w; 66 | previous.xy = previous.xy * 0.5 + 0.5; 67 | 68 | vec2 velocity = (previous.xy - v_texCoords) * 0.5 * blur_scale; 69 | 70 | // blur pass 71 | vec4 result = vec4(0.0); 72 | float oneOnNumPasses = 1.0 / float(blur_passes); 73 | 74 | for (int i = 0; i < blur_passes; ++i) { 75 | // make offset in [-0.5, 0.5] range 76 | float scale = (float(i) * oneOnNumPasses) - 0.5; 77 | vec2 offset = scale * velocity; 78 | result += texture2D(u_texture0, v_texCoords + offset); 79 | } 80 | 81 | //// Get the initial color at this pixel. 82 | //result = texture2D(u_texture0, v_texCoords); 83 | //vec2 texCoord = v_texCoords + velocity; 84 | //for(int i = 1; i < blur_passes; ++i, texCoord += velocity) 85 | //{ 86 | //// Add the current color to our color sum. 87 | //result += texture2D(u_texture0, texCoord); 88 | //} 89 | 90 | gl_FragColor = result * oneOnNumPasses; 91 | } -------------------------------------------------------------------------------- /graalvm-env/shaders/nfaa.fragment: -------------------------------------------------------------------------------- 1 | // Normal filtered anti-aliasing. 2 | // See http://blenderartists.org/forum/showthread.php?209574-Full-Screen-Anti-Aliasing-(NFAA-DLAA-SSAA) 3 | // and http://www.gamedev.net/topic/580517-nfaa---a-post-process-anti-aliasing-filter-results-implementation-details/ 4 | // Copyright Styves, Martinsh 5 | // Modified by Sagrista, Toni 6 | 7 | #ifdef GL_ES 8 | precision mediump float; 9 | precision mediump int; 10 | #endif 11 | 12 | uniform sampler2D u_texture0; 13 | // The inverse of the viewport dimensions along X and Y 14 | uniform vec2 u_viewportInverse; 15 | 16 | varying vec2 v_texCoords; 17 | 18 | float lumRGB(vec3 v) 19 | { 20 | return dot(v, vec3(0.212, 0.716, 0.072)); 21 | } 22 | 23 | const float fScale = 1.0; 24 | 25 | vec4 nfaa(sampler2D texture, vec2 texCoords, vec2 viewportInverse){ 26 | // Offset coordinates 27 | vec2 upOffset = vec2(0.0, viewportInverse.y) * fScale; 28 | vec2 rightOffset = vec2(viewportInverse.x, 0.0) * fScale; 29 | 30 | float topHeight = lumRGB(texture2D(texture, texCoords.xy + upOffset).rgb); 31 | float bottomHeight = lumRGB(texture2D(texture, texCoords.xy - upOffset).rgb); 32 | float rightHeight = lumRGB(texture2D(texture, texCoords.xy + rightOffset).rgb); 33 | float leftHeight = lumRGB(texture2D(texture, texCoords.xy - rightOffset).rgb); 34 | float leftTopHeight = lumRGB(texture2D(texture, texCoords.xy - rightOffset + upOffset).rgb); 35 | float leftBottomHeight = lumRGB(texture2D(texture, texCoords.xy - rightOffset - upOffset).rgb); 36 | float rightBottomHeight = lumRGB(texture2D(texture, texCoords.xy + rightOffset + upOffset).rgb); 37 | float rightTopHeight = lumRGB(texture2D(texture, texCoords.xy + rightOffset - upOffset).rgb); 38 | 39 | // Normal map creation 40 | float sum0 = rightTopHeight + topHeight + rightBottomHeight; 41 | float sum1 = leftTopHeight + bottomHeight + leftBottomHeight; 42 | float sum2 = leftTopHeight + leftHeight + rightTopHeight; 43 | float sum3 = leftBottomHeight + rightHeight + rightBottomHeight; 44 | float vect1 = (sum1 - sum0); 45 | float vect2 = (sum2 - sum3); 46 | 47 | // Put them together and scale. 48 | vec2 Normal = vec2(vect1, vect2) * viewportInverse * fScale; 49 | 50 | // Color 51 | vec4 Scene0 = texture2D(texture, texCoords.xy); 52 | vec4 Scene1 = texture2D(texture, texCoords.xy + Normal.xy); 53 | vec4 Scene2 = texture2D(texture, texCoords.xy - Normal.xy); 54 | vec4 Scene3 = texture2D(texture, texCoords.xy + vec2(Normal.x, -Normal.y) * 0.5); 55 | vec4 Scene4 = texture2D(texture, texCoords.xy - vec2(Normal.x, -Normal.y) * 0.5); 56 | 57 | // Final color 58 | return vec4((Scene0.rgb + Scene1.rgb + Scene2.rgb + Scene3.rgb + Scene4.rgb) * 0.2, 1.0); 59 | 60 | // Debug 61 | //return vec4(normalize(vec3(vect1, vect2 , 1.0) * 0.5 + 0.5), 1.0); 62 | 63 | } 64 | 65 | float GetColorLuminance(vec3 i_vColor){ 66 | return dot(i_vColor, vec3(0.2126, 0.7152, 0.0722)); 67 | } 68 | 69 | void main(){ 70 | gl_FragColor = nfaa(u_texture0, v_texCoords, u_viewportInverse); 71 | } 72 | -------------------------------------------------------------------------------- /core/src/com/byern/tanima/KryonetClientServer.java: -------------------------------------------------------------------------------- 1 | package com.byern.tanima; 2 | 3 | import com.esotericsoftware.kryonet.Client; 4 | import com.esotericsoftware.kryonet.Connection; 5 | import com.esotericsoftware.kryonet.Listener; 6 | import com.esotericsoftware.kryonet.Server; 7 | 8 | import java.io.IOException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class KryonetClientServer { 13 | 14 | public static class ClientServerConfig { 15 | private final Integer listeningPort; 16 | 17 | public Boolean isMaster() { 18 | return master; 19 | } 20 | 21 | private Boolean master; 22 | 23 | public ClientServerConfig(Integer listeningPort) { 24 | this.listeningPort = listeningPort; 25 | } 26 | } 27 | 28 | public Server server; 29 | public Client client; 30 | public final ClientServerConfig config; 31 | private List connectionList = new ArrayList<>(); 32 | private long lastTimeConnected = 0L; 33 | 34 | public KryonetClientServer(ClientServerConfig config) throws IOException, InterruptedException { 35 | this.config = config; 36 | client = new Client(); 37 | //client.getKryo().register(BallPainter.BallMessage.class); 38 | try { 39 | client.start(); 40 | client.connect(5000, "127.0.0.1", config.listeningPort); 41 | this.config.master = false; 42 | } catch (Exception e) { 43 | System.out.println("Cannot connect to the server: 127.0.0.1:" + config.listeningPort); 44 | System.out.println("Creating server instead"); 45 | this.config.master = true; 46 | server = new Server(); 47 | server.start(); 48 | server.bind(config.listeningPort); 49 | server.addListener(new Listener() { 50 | @Override 51 | public void connected(Connection connection) { 52 | System.out.println("Connected: " + connection.getRemoteAddressTCP().getPort()); 53 | connectionList.add(connection); 54 | lastTimeConnected = System.currentTimeMillis(); 55 | } 56 | 57 | @Override 58 | public void disconnected(Connection connection) { 59 | System.out.println("Disconnected: " + connection.getRemoteAddressTCP().getPort()); 60 | } 61 | 62 | public void received(Connection connection, Object object) { 63 | System.out.println("Received " + object); 64 | } 65 | }); 66 | } 67 | 68 | } 69 | 70 | public boolean canSend() { 71 | return (connectionList.size() > 0 && System.currentTimeMillis() - lastTimeConnected > 5000) || !config.isMaster(); 72 | } 73 | 74 | public void send(Object msg) { 75 | if (config.isMaster()) { 76 | System.out.println("Sending " + msg + " as server"); 77 | connectionList.forEach(c -> c.sendTCP(msg)); 78 | } else { 79 | System.out.println("Sending " + msg + " as client"); 80 | client.sendTCP(msg); 81 | } 82 | } 83 | 84 | public void dispose() { 85 | try { 86 | client.close(); 87 | server.close(); 88 | client.dispose(); 89 | server.dispose(); 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /graalvm-env/shaders/vignetting.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #ifdef GL_ES 18 | #define PRECISION mediump 19 | precision PRECISION float; 20 | #else 21 | #define PRECISION 22 | #endif 23 | 24 | uniform PRECISION sampler2D u_texture0; 25 | uniform float VignetteIntensity; 26 | uniform float VignetteX; 27 | uniform float VignetteY; 28 | uniform float CenterX; 29 | uniform float CenterY; 30 | 31 | varying vec2 v_texCoords; 32 | 33 | 34 | #ifdef CONTROL_SATURATION 35 | uniform float Saturation; 36 | uniform float SaturationMul; 37 | const vec3 GRAYSCALE = vec3(0.3, 0.59, 0.11); 38 | 39 | // 0 = totally desaturated 40 | // 1 = saturation unchanged 41 | // higher = increase saturation 42 | //const float BaseSat = 1; 43 | //const float BloomSat = 1; 44 | 45 | vec3 adjustSaturation(vec3 color, float saturation) { 46 | vec3 grey = vec3(dot(color, GRAYSCALE)); 47 | //vec3 grey = vec3((color.r+color.g+color.b)*0.333); // simple 48 | return mix(grey, color, saturation); // correct 49 | } 50 | #endif 51 | 52 | 53 | 54 | #ifdef ENABLE_GRADIENT_MAPPING 55 | uniform PRECISION sampler2D u_texture1; 56 | uniform float LutIntensity; 57 | 58 | uniform int LutIndex; 59 | uniform int LutIndex2; 60 | uniform float LutIndexOffset; 61 | 62 | uniform float LutStep; 63 | uniform float LutStepOffset; 64 | 65 | vec3 do_lookup( vec3 color ) { 66 | vec3 curveColorA; 67 | vec3 curveColorB; 68 | 69 | float idxA = float(LutIndex) * LutStep + LutStepOffset; 70 | float idxB = float(LutIndex2) * LutStep + LutStepOffset; 71 | 72 | curveColorA.r = texture2D( u_texture1, vec2(color.r, idxA ) ).r; 73 | curveColorA.g = texture2D( u_texture1, vec2(color.g, idxA ) ).g; 74 | curveColorA.b = texture2D( u_texture1, vec2(color.b, idxA ) ).b; 75 | 76 | curveColorB.r = texture2D( u_texture1, vec2(color.r, idxB ) ).r; 77 | curveColorB.g = texture2D( u_texture1, vec2(color.g, idxB ) ).g; 78 | curveColorB.b = texture2D( u_texture1, vec2(color.b, idxB ) ).b; 79 | 80 | return mix(color,mix(curveColorA,curveColorB,LutIndexOffset),LutIntensity); 81 | } 82 | #endif 83 | 84 | void main() { 85 | vec3 rgb = texture2D(u_texture0, v_texCoords).xyz; 86 | float d = distance(v_texCoords, vec2(CenterX, CenterY)); 87 | float factor = smoothstep(VignetteX, VignetteY, d); 88 | rgb = rgb*factor + rgb*(1.0-factor) * (1.0-VignetteIntensity); 89 | 90 | #ifdef CONTROL_SATURATION 91 | rgb = adjustSaturation(rgb,Saturation) * SaturationMul; 92 | #endif 93 | 94 | 95 | #ifdef ENABLE_GRADIENT_MAPPING 96 | // theoretically, this conditional though still a branch instruction 97 | // should be able to shave some cycles instead of blindly performing 98 | // 3 lookups+mix with a 0 intensity... still, i don't like this 99 | if( LutIndex > -1 ) { 100 | rgb = do_lookup(rgb); 101 | } 102 | #endif 103 | 104 | gl_FragColor = vec4(rgb,1); 105 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Libgdx + Graalvm native-image example 2 | ![logo](https://media.giphy.com/media/PI8mWU9WeLFgnKN9E2/giphy.gif) 3 | 4 | ## Introduction 5 | Please check my video for short introduction: https://www.youtube.com/watch?v=9eevmylv0fU&ab_channel=ByerNiX 6 | 7 | ## Why? 8 | I was curious how much Graalvm native-image could help with my java game. 9 | Main things that could be improved was: 10 | * File size 11 | * Memory consumption 12 | * Performance 13 | 14 | ## How? 15 | GraalVM uses SubstrateVM under the hood for native-image generation. 16 | Native image is generated as AOT (ahead of time) compiled java. 17 | There is no JIT compiler, native-image has to be compiled on the system for which is created, 18 | result is one executable file with JRE classes compiled inside. 19 | Let's go through the process. 20 | 21 | ### Setup 22 | Install GraalVM, set it as default java in environment variables, make sure you use windows x64 native tools when running GraalVM native-image on Windows (other systems were not tested in scope of this project). 23 | I've used this [link](https://tsuyoshiushio.medium.com/playing-with-graalvm-on-windows-10-8be837007b33) when doing it first time. 24 | 25 | Next, clone this repo, make fat-jar as normal (desktop dist). Put your jar in the graalvm-env directory and run build_native.bat 26 | 27 | ### What do we have here? 28 | desktop and core contains sample code covering: 29 | * graphics 30 | * music/sound 31 | * mouse/keyboard/controller input 32 | * box2d/box2dlights 33 | * freetype fonts 34 | * shaders 35 | * kryonet (without Kryo pojo serialization) 36 | 37 | libgdx-native-image contains substitutions for Kryo, Libgdx nad Lwjgl. 38 |
39 | graalvm-env contains GraalVM config files, assets and libs ready to run and test result application. 40 | 41 | ## Troubleshooting 42 | Native image is a little tricky to work with. 43 | There are some limitations (mainly reflections and jni) that has to be somehow addressed. 44 | 45 | ### Tips and tricks: 46 | * When compiling new jar, run analysis first. 47 | GraalVM provides useful java agent that can be used for configuration generation (see graalvm-env/run_with_agent.bat). 48 | It scans your application at runtime trying to find all of runtime reflection/jni/java-proxy invocations, 49 | and converts it into configs. 50 | After each run- delete old config files or move them somewhere- in my tests 51 | agent did nothing if found old configs in its destination location. 52 | * Sometimes classes from graalvm itself are mentioned in config files generated by agent. Delete them or compilation will fail as these libs are not part of your runtime env. 53 | * If configs won't help, try to use --initialize-at-run-time/--initialize-at-build-time parameters but these can have their drawbacks in result. 54 | * If everything fails, you can write your own substituting code (check libgdx-native-image). 55 | It replaces original code when generating native-image. Very useful when hacking 3rd party libraries. 56 | 57 | ## Is it worth? 58 | I don't think so. I've compiled my own game TAnima: 59 | 60 | ![tanima](https://i.giphy.com/media/TiOwMaWAKiQj3DMAAA/giphy.webp) 61 | 62 | to native image and I don't see any significant boost. 63 | I'd say that same app on jvm16 (graalvm is only java11 right now) performs even better. 64 | Comparing java11 with graalvm native image- native is much more stable, takes a little less memory and less GC pauses. 65 | 66 | ## Disadvantages 67 | * compile time (TAnima is like 15 minutes) 68 | * complexity - changing configuration + long compile time makes it hard 69 | * problems with heavy reflection usage libs - Kryo in Kryonet generates new classes at runtime. It won't work with native-image without rewriting library. 70 | If you want to use it, try choosing libraries that use reflection only at build time. 71 | -------------------------------------------------------------------------------- /libgdx-native-image/src/main/java/com/esotericsoftware/kryo/serializers/KryoSubstitutions.java: -------------------------------------------------------------------------------- 1 | package com.esotericsoftware.kryo.serializers; 2 | 3 | import com.esotericsoftware.kryo.Kryo; 4 | import com.esotericsoftware.kryo.KryoException; 5 | import com.esotericsoftware.kryo.serializers.FieldSerializer; 6 | import com.esotericsoftware.kryo.serializers.FieldSerializerGenericsUtil; 7 | import com.esotericsoftware.kryo.serializers.ObjectField; 8 | import com.esotericsoftware.kryo.util.Util; 9 | import com.esotericsoftware.reflectasm.ConstructorAccess; 10 | import com.oracle.svm.core.annotate.Alias; 11 | import com.oracle.svm.core.annotate.RecomputeFieldValue; 12 | import com.oracle.svm.core.annotate.Substitute; 13 | import com.oracle.svm.core.annotate.TargetClass; 14 | import org.objenesis.instantiator.ObjectInstantiator; 15 | import org.objenesis.strategy.InstantiatorStrategy; 16 | 17 | import java.lang.reflect.Constructor; 18 | import java.lang.reflect.Field; 19 | import java.lang.reflect.Modifier; 20 | import java.lang.reflect.Type; 21 | import java.util.Arrays; 22 | 23 | import static com.esotericsoftware.kryo.util.Util.className; 24 | import static com.esotericsoftware.minlog.Log.TRACE; 25 | import static com.esotericsoftware.minlog.Log.trace; 26 | /* 27 | @TargetClass(com.esotericsoftware.kryo.serializers.FieldSerializer.class) 28 | abstract class com_esotericsoftware_kryo_serializers_FieldSerializer extends FieldSerializer { 29 | 30 | @Alias 31 | @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true) 32 | Kryo kryo; 33 | 34 | public com_esotericsoftware_kryo_serializers_FieldSerializer(Kryo kryo, Class type) { 35 | super(kryo, type); 36 | } 37 | 38 | @Alias 39 | private FieldSerializer.CachedFieldFactory getObjectFieldFactory (){ 40 | return null; 41 | } 42 | 43 | @Substitute 44 | FieldSerializer.CachedField newMatchingCachedField (Field field, int accessIndex, Class fieldClass, Type fieldGenericType, 45 | Class[] fieldGenerics) { 46 | FieldSerializer.CachedField cachedField; 47 | cachedField = getObjectFieldFactory().createCachedField(fieldClass, field, this); 48 | if (fieldGenerics != null) 49 | ((ObjectField)cachedField).generics = fieldGenerics; 50 | else { 51 | Class[] cachedFieldGenerics = FieldSerializerGenericsUtil.getGenerics(fieldGenericType, kryo); 52 | ((ObjectField)cachedField).generics = cachedFieldGenerics; 53 | if (TRACE) trace("kryo", "Field generics: " + Arrays.toString(cachedFieldGenerics)); 54 | } 55 | 56 | return cachedField; 57 | } 58 | }*/ 59 | @TargetClass(com.esotericsoftware.kryo.Kryo.DefaultInstantiatorStrategy.class) 60 | final class com_esotericsoftware_kryo_Kryo_DefaultInstantiatorStrategy { 61 | @Alias 62 | private InstantiatorStrategy fallbackStrategy; 63 | 64 | @Substitute 65 | public ObjectInstantiator newInstantiatorOf(final Class type) { 66 | // Reflection. 67 | try { 68 | Constructor ctor; 69 | try { 70 | ctor = type.getConstructor((Class[])null); 71 | } catch (Exception ex) { 72 | ctor = type.getDeclaredConstructor((Class[])null); 73 | ctor.setAccessible(true); 74 | } 75 | final Constructor constructor = ctor; 76 | return new ObjectInstantiator() { 77 | public Object newInstance () { 78 | try { 79 | return constructor.newInstance(); 80 | } catch (Exception ex) { 81 | throw new KryoException("Error constructing instance of class: " + className(type), ex); 82 | } 83 | } 84 | }; 85 | } catch (Exception ignored) { 86 | } 87 | if (fallbackStrategy == null) { 88 | if (type.isMemberClass() && !Modifier.isStatic(type.getModifiers())) 89 | throw new KryoException("Class cannot be created (non-static member class): " + className(type)); 90 | else 91 | throw new KryoException("Class cannot be created (missing no-arg constructor): " + className(type)); 92 | } 93 | // InstantiatorStrategy. 94 | return fallbackStrategy.newInstantiatorOf(type); 95 | } 96 | } 97 | 98 | @TargetClass(com.esotericsoftware.kryo.Kryo.class) 99 | final class com_esotericsoftware_kryo_Kryo { 100 | 101 | @Alias 102 | private InstantiatorStrategy strategy; 103 | 104 | @Substitute 105 | protected ObjectInstantiator newInstantiator(final Class type) { 106 | //if you want to log what failed 107 | //System.out.println("Instantiator for: " + type.getName()); 108 | return strategy.newInstantiatorOf(type); 109 | } 110 | 111 | } 112 | 113 | public class KryoSubstitutions { 114 | } 115 | -------------------------------------------------------------------------------- /core/src/com/byern/tanima/BallPainter.java: -------------------------------------------------------------------------------- 1 | package com.byern.tanima; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics; 5 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window; 6 | import com.badlogic.gdx.graphics.Texture; 7 | import com.badlogic.gdx.graphics.g2d.Sprite; 8 | import com.badlogic.gdx.graphics.g2d.SpriteBatch; 9 | import com.esotericsoftware.kryonet.Connection; 10 | import com.esotericsoftware.kryonet.Listener; 11 | 12 | import java.util.Optional; 13 | import java.util.Random; 14 | import java.util.UUID; 15 | 16 | public class BallPainter { 17 | 18 | private int id; 19 | private Sprite ballSprite; 20 | private float x = 0; 21 | private float y = 250; 22 | private float size = 100; 23 | private float speed = 20f; 24 | 25 | private int maxW; 26 | 27 | private boolean rightDirection = true; 28 | private Optional maybeKryonet; 29 | private boolean master = true; 30 | private Lwjgl3Window window; 31 | 32 | public static class BallMessage { 33 | boolean rightDirection; 34 | float windowY; 35 | float y; 36 | int id; 37 | 38 | public BallMessage() { 39 | } 40 | 41 | public BallMessage(boolean rightDirection, float windowY, float y, int id) { 42 | this.rightDirection = rightDirection; 43 | this.windowY = windowY; 44 | this.y = y; 45 | this.id = id; 46 | } 47 | 48 | public boolean isRightDirection() { 49 | return rightDirection; 50 | } 51 | 52 | public void setRightDirection(boolean rightDirection) { 53 | this.rightDirection = rightDirection; 54 | } 55 | 56 | public float getWindowY() { 57 | return windowY; 58 | } 59 | 60 | public void setWindowY(float windowY) { 61 | this.windowY = windowY; 62 | } 63 | 64 | public float getY() { 65 | return y; 66 | } 67 | 68 | public void setY(float y) { 69 | this.y = y; 70 | } 71 | 72 | public int getId() { 73 | return id; 74 | } 75 | 76 | public void setId(int id) { 77 | this.id = id; 78 | } 79 | } 80 | 81 | public BallPainter(int id, int w, int h, Optional maybeKryonet) { 82 | this.id = id; 83 | this.window = ((Lwjgl3Graphics) Gdx.graphics).getWindow(); 84 | 85 | ballSprite = new Sprite(new Texture("badlogic.jpg")); 86 | this.maybeKryonet = maybeKryonet; 87 | maybeKryonet.ifPresent(k -> 88 | (k.config.isMaster() ? k.server : k.client).addListener(new Listener() { 89 | @Override 90 | public void received(Connection connection, Object object) { 91 | if (object instanceof String) { 92 | String msg = (String) object; 93 | String[] strings = msg.split(":"); 94 | if (strings.length == 5 && strings[0].equals("Direction") && Integer.parseInt(strings[4]) == id) { 95 | rightDirection = Boolean.parseBoolean(strings[1]); 96 | float windowY = window.getPositionY(); 97 | float receivedWindowY = Float.parseFloat(strings[2]); 98 | float receivedY = Float.parseFloat(strings[3]); 99 | y = receivedY + (windowY - receivedWindowY); 100 | /* 101 | if(object instanceof BallMessage) { 102 | BallMessage ballMessage = (BallMessage) object; 103 | if(ballMessage.id == id){ 104 | rightDirection = ballMessage.rightDirection; 105 | float windowY = window.getPositionY(); 106 | y = ballMessage.y + (windowY - ballMessage.windowY);*/ 107 | 108 | master = true; 109 | if(rightDirection) { 110 | x = -size; 111 | } else { 112 | x = maxW; 113 | } 114 | } 115 | } 116 | } 117 | })); 118 | this.master = maybeKryonet.map(k -> k.config.isMaster()).orElse(true); 119 | maxW = w; 120 | Random random = new Random(); 121 | x = random.nextInt((int) (maxW - size * 2)); 122 | y = random.nextInt((int) (h - size)); 123 | } 124 | 125 | public void paint(SpriteBatch spriteBatch) { 126 | if (master) { 127 | spriteBatch.draw(ballSprite, x, y, size, size); 128 | x += speed * (rightDirection ? 1 : -1); 129 | if (rightDirection && x > (maxW) || !rightDirection && x < -size) { 130 | if (maybeKryonet.isPresent() && maybeKryonet.get().canSend()) { 131 | maybeKryonet.get().send("Direction:" + rightDirection + ":" + window.getPositionY() + ":" + y + ":" + id); 132 | /*maybeKryonet.get().send( 133 | new BallPainter.BallMessage( 134 | rightDirection, 135 | window.getPositionY(), 136 | y, 137 | id 138 | ) 139 | );*/ 140 | master = false; 141 | } 142 | rightDirection = !rightDirection; 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /graalvm-env/shaders/crt-screen.fragment: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012 bmanuel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | /** 18 | * Credits to Inigo Quilez 2009 (iq/rgba) for the original 'Postpro' 19 | * code at http://www.iquilezles.org/apps/shadertoy/?p=postpro 20 | * 21 | * This version of the original fragment program has been adapted and 22 | * parameterized to permit runtime configuration. 23 | * 24 | * Furthermore it has been reworked to mimic the GL_REPEAT texture 25 | * wrapping on the FBO due to problems arised when running on a real 26 | * Android device, equipped with a Tegra2 GPU (Asus TF101). 27 | */ 28 | 29 | #ifdef GL_ES 30 | #define PRECISION mediump 31 | precision PRECISION float; 32 | #else 33 | #define PRECISION 34 | #endif 35 | 36 | uniform vec3 tint; 37 | uniform float time; 38 | uniform sampler2D u_texture0; 39 | varying vec2 v_texCoords; 40 | 41 | #ifdef ENABLE_RGB_SHIFT 42 | // sane values between ~[-0.003, 0.003]; 43 | uniform float offset; 44 | #endif 45 | 46 | #ifdef ENABLE_CHROMATIC_ABERRATIONS 47 | // x -> red/cyan, y -> blue/yellow, both in [-1, 1] 48 | uniform vec2 chromaticDispersion; 49 | #endif 50 | 51 | const vec4 Zero = vec4(0.0,0.0,0.0,1.0); 52 | 53 | #ifdef ENABLE_BARREL_DISTORTION 54 | uniform float Distortion; // ~0.3 55 | uniform float zoom; 56 | 57 | vec2 barrelDistortion(vec2 coord) 58 | { 59 | vec2 cc = coord - 0.5; 60 | float dist = dot(cc, cc) * Distortion; 61 | return (coord + cc * (1.0 + dist) * dist); 62 | } 63 | #endif 64 | 65 | #ifdef ENABLE_CHROMATIC_ABERRATIONS 66 | 67 | vec3 colorAberrate(sampler2D tex, vec2 coord) 68 | { 69 | // index of refraction of each color channel, causing chromatic dispersion 70 | vec3 eta = vec3(1.0+chromaticDispersion.x*0.09, 71 | 1.0+chromaticDispersion.x*0.06, 72 | 1.0+chromaticDispersion.x*0.03); 73 | 74 | vec3 eta2 = vec3(1.0+chromaticDispersion.y*0.06, 75 | 1.0+chromaticDispersion.y*0.06, 76 | 1.0+chromaticDispersion.y*0.03); 77 | 78 | vec3 frag; 79 | 80 | // apply aberrations, if needed 81 | if (chromaticDispersion.x == 0.0 && chromaticDispersion.y == 0.0) { 82 | float x = (coord.x-0.5)+0.5; 83 | float y = (coord.y-0.5)+0.5; 84 | frag = texture2D(tex,vec2(x,y)).rgb; 85 | } else { 86 | vec2 rCoords = (eta.r*eta2.r)*(coord.xy-0.5)+0.5; 87 | vec2 gCoords = (eta.g*eta2.g)*(coord.xy-0.5)+0.5; 88 | vec2 bCoords = (eta.b*eta2.b)*(coord.xy-0.5)+0.5; 89 | float x = (coord.x-0.5)+0.5; 90 | float y = (coord.y-0.5)+0.5; 91 | 92 | // avoid edge duplication 93 | // although this produces left/right banding, only the red channel is needed 94 | if(rCoords.x<0.0 || rCoords.x>1.0 || rCoords.y<0.0 || rCoords.y >1.0) { 95 | return Zero.rgb; 96 | } 97 | 98 | frag = vec3( 99 | texture2D(tex,rCoords).r, 100 | texture2D(tex,gCoords).g, 101 | texture2D(tex,bCoords).b 102 | //,texture2D(tex,vec2(x,y)).a 103 | ); 104 | } 105 | 106 | return frag; 107 | } 108 | #endif 109 | 110 | #ifdef ENABLE_SCAN_DISTORTION 111 | 112 | vec2 scandistort(vec2 uv) { 113 | float amplitude = 10.0; 114 | float scan1 = clamp(cos(uv.y * 2.0 + time), 0.0, 1.0); 115 | float scan2 = clamp(cos(uv.y * 2.0 + time + 4.0) * amplitude, 0.0, 1.0) ; 116 | float amount = scan1 * scan2 * uv.x; 117 | 118 | //uv.x -= 0.05 * mix(texture2D(iChannel1, vec2(uv.x, amount)).r * amount, amount, 0.9); 119 | uv.x -= 0.05 * amount; 120 | 121 | return uv; 122 | } 123 | #endif 124 | 125 | void main(void) 126 | { 127 | vec2 uv = v_texCoords; 128 | uv.y = 1.0 - uv.y; 129 | 130 | #ifdef ENABLE_BARREL_DISTORTION 131 | uv = barrelDistortion(uv); 132 | uv = 0.5 + (uv-0.5)*(zoom); 133 | 134 | if(uv.s<0.0 || uv.s>1.0 || uv.t<0.0 || uv.t >1.0) { 135 | gl_FragColor = Zero; 136 | return; 137 | } 138 | #endif 139 | 140 | #ifdef ENABLE_SCAN_DISTORTION 141 | uv = scandistort(uv); 142 | #endif 143 | 144 | vec2 flipped_uv = vec2(uv.x,1.0-uv.y); 145 | 146 | float org_alpha = texture2D(u_texture0,flipped_uv).a; 147 | vec3 col; 148 | 149 | #ifdef ENABLE_RGB_SHIFT 150 | col.r = texture2D(u_texture0,fract(vec2(uv.x+offset,-uv.y))).r; 151 | col.g = texture2D(u_texture0,fract(vec2(uv.x+0.000,-uv.y))).g; 152 | col.b = texture2D(u_texture0,fract(vec2(uv.x-offset,-uv.y))).b; 153 | #endif 154 | 155 | #ifdef ENABLE_CHROMATIC_ABERRATIONS 156 | col = colorAberrate(u_texture0, flipped_uv); 157 | #endif 158 | 159 | #ifdef ENABLE_TWEAK_CONTRAST 160 | // contrast up, lightness down a bit, loose detail in dark areas 161 | col = clamp(col*0.5+0.5*col*col*1.2,0.0,1.0); 162 | #endif 163 | 164 | #ifdef ENABLE_VIGNETTE 165 | // vignette 166 | col *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y); 167 | #endif 168 | 169 | #ifdef ENABLE_TINT 170 | // tint 171 | col *= tint; 172 | #endif 173 | 174 | #ifdef ENABLE_SCANLINES 175 | // scanline 176 | col *= 0.9+0.1*sin(10.0*time-uv.y*1000.0); 177 | #endif 178 | 179 | #ifdef ENABLE_PHOSPHOR_VIBRANCE 180 | // phosphor vibrance 181 | col *= 0.97+0.03*sin(110.0*time); 182 | #endif 183 | 184 | gl_FragColor = vec4(col,org_alpha); 185 | } -------------------------------------------------------------------------------- /libgdx-native-image/src/main/java/com/byern/libgdx/nimage/LwjglSubstitutions.java: -------------------------------------------------------------------------------- 1 | package com.byern.libgdx.nimage; 2 | 3 | import static org.lwjgl.system.MemoryUtil.*; 4 | import static org.lwjgl.system.MemoryUtil.NULL; 5 | import static org.lwjgl.system.MemoryUtil.getAllocator; 6 | import static org.lwjgl.system.MemoryUtil.memGetAddress; 7 | import static org.lwjgl.system.MemoryUtil.memPutAddress; 8 | import static org.lwjgl.system.Pointer.*; 9 | import static org.lwjgl.system.Pointer.POINTER_SIZE; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.PrintStream; 14 | import java.lang.reflect.Field; 15 | import java.net.URL; 16 | import java.util.ArrayList; 17 | import java.util.Enumeration; 18 | import java.util.List; 19 | import java.util.Optional; 20 | import java.util.jar.Attributes; 21 | import java.util.jar.JarFile; 22 | import java.util.jar.Manifest; 23 | 24 | import org.lwjgl.system.APIUtil; 25 | 26 | import com.oracle.svm.core.annotate.Alias; 27 | import com.oracle.svm.core.annotate.RecomputeFieldValue; 28 | import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; 29 | import com.oracle.svm.core.annotate.Substitute; 30 | import com.oracle.svm.core.annotate.TargetClass; 31 | 32 | /** 33 | * source https://github.com/chirontt/lwjgl3-helloworld-native/blob/main/src/main/java/com/github/chirontt/lwjgl/graalvm/LwjglSubstitutions.java 34 | */ 35 | @TargetClass(org.lwjgl.system.APIUtil.class) 36 | final class Target_org_lwjgl_system_APIUtil { 37 | 38 | @Alias 39 | @RecomputeFieldValue(kind = Kind.FromAlias, isFinal = true) 40 | public static PrintStream DEBUG_STREAM; 41 | 42 | @Substitute 43 | public static Optional apiGetManifestValue(String attributeName) { 44 | if (attributeName == null || attributeName.isEmpty()) return Optional.empty(); 45 | 46 | Package currentPackage = APIUtil.class.getPackage(); 47 | String manifestValue = null; 48 | switch (attributeName.toLowerCase()) { 49 | case "implementation-title": 50 | manifestValue = currentPackage.getImplementationTitle(); 51 | return Optional.ofNullable(manifestValue); 52 | case "implementation-vendor": 53 | manifestValue = currentPackage.getImplementationVendor(); 54 | return Optional.ofNullable(manifestValue); 55 | case "implementation-version": 56 | manifestValue = currentPackage.getImplementationVersion(); 57 | return Optional.ofNullable(manifestValue); 58 | case "specification-title": 59 | manifestValue = currentPackage.getSpecificationTitle(); 60 | return Optional.ofNullable(manifestValue); 61 | case "specification-vendor": 62 | manifestValue = currentPackage.getSpecificationVendor(); 63 | return Optional.ofNullable(manifestValue); 64 | case "specification-version": 65 | manifestValue = currentPackage.getSpecificationVersion(); 66 | return Optional.ofNullable(manifestValue); 67 | default: 68 | ClassLoader loader = APIUtil.class.getClassLoader(); 69 | try { 70 | //find a MANIFEST.MF resource from one of the LWJGL jars 71 | for (Enumeration e = loader.getResources(JarFile.MANIFEST_NAME); e.hasMoreElements(); ) { 72 | URL url = e.nextElement(); 73 | try (InputStream stream = url.openStream()) { 74 | Attributes attributes = new Manifest(stream).getMainAttributes(); 75 | //is this manifest resource from LWJGL? 76 | if ("lwjgl.org".equals(attributes.getValue("Implementation-Vendor"))) 77 | return Optional.ofNullable(attributes.getValue(attributeName)); 78 | } 79 | } 80 | } catch (IOException ioe) { 81 | ioe.printStackTrace(DEBUG_STREAM); 82 | } 83 | 84 | return Optional.empty(); 85 | } 86 | } 87 | } 88 | 89 | @TargetClass(org.lwjgl.system.ThreadLocalUtil.class) 90 | final class Target_org_lwjgl_system_ThreadLocalUtil { 91 | 92 | @Alias 93 | @RecomputeFieldValue(kind = Kind.FromAlias, isFinal = true) 94 | private static long JNI_NATIVE_INTERFACE; 95 | 96 | @Alias 97 | @RecomputeFieldValue(kind = Kind.FromAlias, isFinal = true) 98 | private static long FUNCTION_MISSING_ABORT; 99 | 100 | @Substitute 101 | public static void setFunctionMissingAddresses(Class capabilitiesClass, int index) { 102 | if (capabilitiesClass == null) { 103 | long missingCaps = memGetAddress(JNI_NATIVE_INTERFACE + Integer.toUnsignedLong(index) * POINTER_SIZE); 104 | if (missingCaps != NULL) { 105 | getAllocator().free(missingCaps); 106 | memPutAddress(JNI_NATIVE_INTERFACE + Integer.toUnsignedLong(index) * POINTER_SIZE, NULL); 107 | } 108 | } else { 109 | int functionCount = getFieldsFromCapabilities(capabilitiesClass).size(); 110 | 111 | long missingCaps = getAllocator().malloc(Integer.toUnsignedLong(functionCount) * POINTER_SIZE); 112 | for (int i = 0; i < functionCount; i++) { 113 | memPutAddress(missingCaps + Integer.toUnsignedLong(i) * POINTER_SIZE, FUNCTION_MISSING_ABORT); 114 | } 115 | 116 | //the whole purpose of substituting this method is just to remove the following line 117 | //(which causes the resulting native image to crash!) 118 | //memPutAddress(JNI_NATIVE_INTERFACE + Integer.toUnsignedLong(index) * POINTER_SIZE, missingCaps); 119 | } 120 | } 121 | 122 | //copied verbatim from the original class 123 | @Substitute 124 | private static List getFieldsFromCapabilities(Class capabilitiesClass) { 125 | List fields = new ArrayList<>(); 126 | for (Field field : capabilitiesClass.getFields()) { 127 | if (field.getType() == long.class) { 128 | fields.add(field); 129 | } 130 | } 131 | return fields; 132 | } 133 | } 134 | 135 | /** Dummy class with the file's name. */ 136 | public class LwjglSubstitutions { 137 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /graalvm-env/config/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"com.badlogic.gdx.backends.lwjgl3.audio.Mp3$Music", 4 | "methods":[{"name":"","parameterTypes":["com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio","com.badlogic.gdx.files.FileHandle"] }] 5 | }, 6 | { 7 | "name":"com.badlogic.gdx.backends.lwjgl3.audio.OpenALMusic[]" 8 | }, 9 | { 10 | "name":"com.badlogic.gdx.backends.lwjgl3.audio.Wav$Sound", 11 | "methods":[{"name":"","parameterTypes":["com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio","com.badlogic.gdx.files.FileHandle"] }] 12 | }, 13 | { 14 | "name":"com.badlogic.gdx.controllers.desktop.JamepadControllerManager", 15 | "methods":[{"name":"","parameterTypes":[] }] 16 | }, 17 | { 18 | "name":"com.badlogic.gdx.graphics.Color", 19 | "methods":[{"name":"","parameterTypes":[] }] 20 | }, 21 | { 22 | "name":"com.badlogic.gdx.graphics.g2d.GlyphLayout", 23 | "methods":[{"name":"","parameterTypes":[] }] 24 | }, 25 | { 26 | "name":"com.badlogic.gdx.graphics.g2d.GlyphLayout$GlyphRun", 27 | "methods":[{"name":"","parameterTypes":[] }] 28 | }, 29 | { 30 | "name":"com.esotericsoftware.kryo.serializers.FieldSerializer", 31 | "methods":[{"name":"","parameterTypes":["com.esotericsoftware.kryo.Kryo","java.lang.Class"] }] 32 | }, 33 | { 34 | "name":"com.esotericsoftware.kryo.serializers.FieldSerializerUnsafeUtilImpl", 35 | "methods":[{"name":"","parameterTypes":["com.esotericsoftware.kryo.serializers.FieldSerializer"] }] 36 | }, 37 | { 38 | "name":"com.esotericsoftware.kryo.serializers.UnsafeCachedFieldFactory", 39 | "methods":[{"name":"","parameterTypes":[] }] 40 | }, 41 | { 42 | "name":"com.esotericsoftware.kryo.util.UnsafeUtil", 43 | "methods":[ 44 | {"name":"sortFieldsByOffset","parameterTypes":["java.util.List"] }, 45 | {"name":"unsafe","parameterTypes":[] } 46 | ] 47 | }, 48 | { 49 | "name":"com.esotericsoftware.kryonet.FrameworkMessage", 50 | "methods":[{"name":"","parameterTypes":[] }], 51 | "allDeclaredFields":true, 52 | "allDeclaredFields":true, 53 | "allPublicFields":true, 54 | "allDeclaredMethods":true, 55 | "allPublicMethods":true, 56 | "allDeclaredConstructors":true, 57 | "allPublicConstructors":true, 58 | "allDeclaredClasses":true, 59 | "allPublicClasses":true 60 | }, 61 | { 62 | "name":"com.byern.tanima.BallPainter$BallMessage", 63 | "methods":[{"name":"","parameterTypes":[] }], 64 | "allDeclaredFields":true, 65 | "allDeclaredFields":true, 66 | "allPublicFields":true, 67 | "allDeclaredMethods":true, 68 | "allPublicMethods":true, 69 | "allDeclaredConstructors":true, 70 | "allPublicConstructors":true, 71 | "allDeclaredClasses":true, 72 | "allPublicClasses":true 73 | }, 74 | { 75 | "name":"com.esotericsoftware.kryonet.FrameworkMessage$DiscoverHost", 76 | "methods":[{"name":"","parameterTypes":[] }], 77 | "allDeclaredFields":true, 78 | "allDeclaredFields":true, 79 | "allPublicFields":true, 80 | "allDeclaredMethods":true, 81 | "allPublicMethods":true, 82 | "allDeclaredConstructors":true, 83 | "allPublicConstructors":true, 84 | "allDeclaredClasses":true, 85 | "allPublicClasses":true 86 | }, 87 | { 88 | "name":"com.esotericsoftware.kryonet.FrameworkMessage$KeepAlive", 89 | "allDeclaredFields":true, 90 | "methods":[{"name":"","parameterTypes":[] }], 91 | "allDeclaredFields":true, 92 | "allPublicFields":true, 93 | "allDeclaredMethods":true, 94 | "allPublicMethods":true, 95 | "allDeclaredConstructors":true, 96 | "allPublicConstructors":true, 97 | "allDeclaredClasses":true, 98 | "allPublicClasses":true 99 | }, 100 | { 101 | "name":"com.esotericsoftware.kryonet.FrameworkMessage$Ping", 102 | "allDeclaredFields":true, 103 | "methods":[{"name":"","parameterTypes":[] }], 104 | "fields":[ 105 | {"name":"id", "allowUnsafeAccess":true}, 106 | {"name":"isReply", "allowUnsafeAccess":true} 107 | ], 108 | "allDeclaredFields":true, 109 | "allPublicFields":true, 110 | "allDeclaredMethods":true, 111 | "allPublicMethods":true, 112 | "allDeclaredConstructors":true, 113 | "allPublicConstructors":true, 114 | "allDeclaredClasses":true, 115 | "allPublicClasses":true 116 | }, 117 | { 118 | "name":"com.esotericsoftware.kryonet.FrameworkMessage$RegisterTCP", 119 | "allDeclaredFields":true, 120 | "fields":[{"name":"connectionID", "allowUnsafeAccess":true}], 121 | "methods":[{"name":"","parameterTypes":[] }], 122 | "allDeclaredFields":true, 123 | "allPublicFields":true, 124 | "allDeclaredMethods":true, 125 | "allPublicMethods":true, 126 | "allDeclaredConstructors":true, 127 | "allPublicConstructors":true, 128 | "allDeclaredClasses":true, 129 | "allPublicClasses":true 130 | }, 131 | { 132 | "name":"com.esotericsoftware.kryonet.FrameworkMessage$RegisterUDP", 133 | "allDeclaredFields":true, 134 | "fields":[{"name":"connectionID", "allowUnsafeAccess":true}], 135 | "methods":[{"name":"","parameterTypes":[] }], 136 | "allDeclaredFields":true, 137 | "allPublicFields":true, 138 | "allDeclaredMethods":true, 139 | "allPublicMethods":true, 140 | "allDeclaredConstructors":true, 141 | "allPublicConstructors":true, 142 | "allDeclaredClasses":true, 143 | "allPublicClasses":true 144 | }, 145 | { 146 | "name":"java.lang.ClassLoader", 147 | "methods":[{"name":"defineClass","parameterTypes":["java.lang.String","byte[]","int","int","java.security.ProtectionDomain"] }] 148 | }, 149 | { 150 | "name":"java.lang.Object[]" 151 | }, 152 | { 153 | "name":"java.nio.DirectByteBuffer", 154 | "methods":[{"name":"","parameterTypes":["long","int","java.lang.Object"] }] 155 | }, 156 | { 157 | "name":"java.security.MessageDigestSpi" 158 | }, 159 | { 160 | "name":"java.security.SecureRandomParameters" 161 | }, 162 | { 163 | "name":"org.lwjgl.glfw.GLFW", 164 | "allDeclaredFields":true 165 | }, 166 | { 167 | "name":"org.lwjgl.openal.ALCapabilities", 168 | "allPublicFields":true 169 | }, 170 | { 171 | "name":"org.lwjgl.opengl.GLCapabilities", 172 | "allPublicFields":true 173 | }, 174 | { 175 | "name":"org.lwjgl.system.CallbackI$B", 176 | "methods":[{"name":"callback","parameterTypes":["long"] }] 177 | }, 178 | { 179 | "name":"org.lwjgl.system.CallbackI$D", 180 | "methods":[{"name":"callback","parameterTypes":["long"] }] 181 | }, 182 | { 183 | "name":"org.lwjgl.system.CallbackI$F", 184 | "methods":[{"name":"callback","parameterTypes":["long"] }] 185 | }, 186 | { 187 | "name":"org.lwjgl.system.CallbackI$I", 188 | "methods":[{"name":"callback","parameterTypes":["long"] }] 189 | }, 190 | { 191 | "name":"org.lwjgl.system.CallbackI$J", 192 | "methods":[{"name":"callback","parameterTypes":["long"] }] 193 | }, 194 | { 195 | "name":"org.lwjgl.system.CallbackI$N", 196 | "methods":[{"name":"callback","parameterTypes":["long"] }] 197 | }, 198 | { 199 | "name":"org.lwjgl.system.CallbackI$P", 200 | "methods":[{"name":"callback","parameterTypes":["long"] }] 201 | }, 202 | { 203 | "name":"org.lwjgl.system.CallbackI$S", 204 | "methods":[{"name":"callback","parameterTypes":["long"] }] 205 | }, 206 | { 207 | "name":"org.lwjgl.system.CallbackI$V", 208 | "methods":[{"name":"callback","parameterTypes":["long"] }] 209 | }, 210 | { 211 | "name":"org.lwjgl.system.CallbackI$Z", 212 | "methods":[{"name":"callback","parameterTypes":["long"] }] 213 | }, 214 | { 215 | "name":"org.lwjgl.system.CustomBuffer", 216 | "fields":[ 217 | {"name":"capacity", "allowUnsafeAccess":true}, 218 | {"name":"container", "allowUnsafeAccess":true}, 219 | {"name":"limit", "allowUnsafeAccess":true}, 220 | {"name":"mark", "allowUnsafeAccess":true}, 221 | {"name":"position", "allowUnsafeAccess":true} 222 | ] 223 | }, 224 | { 225 | "name":"org.lwjgl.system.Pointer$Default", 226 | "fields":[{"name":"address", "allowUnsafeAccess":true}] 227 | }, 228 | { 229 | "name":"org.lwjgl.system.jemalloc.JEmallocAllocator", 230 | "methods":[{"name":"","parameterTypes":[] }] 231 | }, 232 | { 233 | "name":"sun.misc.Unsafe", 234 | "allDeclaredFields":true 235 | }, 236 | { 237 | "name":"sun.security.provider.DRBG", 238 | "methods":[{"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] 239 | }, 240 | { 241 | "name":"sun.security.provider.SHA", 242 | "methods":[{"name":"","parameterTypes":[] }] 243 | }, 244 | { 245 | "name":"sun.security.provider.SHA2$SHA256", 246 | "methods":[{"name":"","parameterTypes":[] }] 247 | } 248 | ] 249 | -------------------------------------------------------------------------------- /core/src/com/byern/tanima/ClientMain.java: -------------------------------------------------------------------------------- 1 | package com.byern.tanima; 2 | 3 | import box2dLight.PointLight; 4 | import box2dLight.RayHandler; 5 | import com.badlogic.gdx.ApplicationAdapter; 6 | import com.badlogic.gdx.Gdx; 7 | import com.badlogic.gdx.InputProcessor; 8 | import com.badlogic.gdx.audio.Music; 9 | import com.badlogic.gdx.audio.Sound; 10 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics; 11 | import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window; 12 | import com.badlogic.gdx.controllers.Controller; 13 | import com.badlogic.gdx.controllers.ControllerListener; 14 | import com.badlogic.gdx.controllers.Controllers; 15 | import com.badlogic.gdx.graphics.*; 16 | import com.badlogic.gdx.graphics.g2d.BitmapFont; 17 | import com.badlogic.gdx.graphics.g2d.SpriteBatch; 18 | import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; 19 | import com.badlogic.gdx.math.Vector2; 20 | import com.badlogic.gdx.physics.box2d.*; 21 | import com.bitfire.postprocessing.PostProcessor; 22 | import com.bitfire.postprocessing.effects.Bloom; 23 | import com.bitfire.postprocessing.effects.Curvature; 24 | import com.bitfire.utils.ShaderLoader; 25 | 26 | import java.io.IOException; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.Optional; 30 | import java.util.stream.Collectors; 31 | import java.util.stream.IntStream; 32 | 33 | public class ClientMain extends ApplicationAdapter implements InputProcessor, ControllerListener { 34 | 35 | Integer w; 36 | Integer h; 37 | SpriteBatch batch; 38 | Texture img; 39 | Sound sound; 40 | Music music; 41 | SchedulerCaller soundScheduler; 42 | SchedulerCaller musicPositionCheckerScheduler; 43 | SchedulerCaller box2dObjectsCheckerScheduler; 44 | SchedulerCaller controllersScheduler; 45 | SchedulerCaller pingScheduler; 46 | World world; 47 | RayHandler rayHandler; 48 | Box2DDebugRenderer debugRenderer; 49 | Camera camera; 50 | FreeTypeFontGenerator generator; 51 | List box2dObjects = new ArrayList<>(); 52 | BitmapFont font12; 53 | PostProcessor postProcessor; 54 | Optional maybeKryonet; 55 | List ballPainters; 56 | 57 | public ClientMain(Optional maybeConfig) { 58 | maybeKryonet = maybeConfig.map(c -> { 59 | try { 60 | return new KryonetClientServer(c); 61 | } catch (IOException | InterruptedException e) { 62 | e.printStackTrace(); 63 | throw new IllegalStateException(e); 64 | } 65 | }); 66 | } 67 | 68 | public static class SchedulerCaller { 69 | 70 | private Long lastTimeUsed = 0L; 71 | private Boolean initialized = false; 72 | 73 | private final Integer threshold; 74 | private final Runnable runnable; 75 | private final Boolean onlyOnce; 76 | 77 | public SchedulerCaller(Integer threshold, Runnable runnable) { 78 | this.threshold = threshold; 79 | this.runnable = runnable; 80 | this.onlyOnce = false; 81 | } 82 | 83 | public SchedulerCaller(Runnable runnable) { 84 | this.threshold = 0; 85 | this.runnable = runnable; 86 | this.onlyOnce = true; 87 | } 88 | 89 | public void call() { 90 | long now = System.currentTimeMillis(); 91 | if ((!initialized || !onlyOnce) && (now - lastTimeUsed > threshold)) { 92 | lastTimeUsed = now; 93 | runnable.run(); 94 | } 95 | initialized = true; 96 | } 97 | 98 | } 99 | 100 | @Override 101 | public void create() { 102 | w = Gdx.graphics.getWidth(); 103 | h = Gdx.graphics.getHeight(); 104 | ballPainters = IntStream.range(0, 1).mapToObj( 105 | i -> new BallPainter(i, w, h, maybeKryonet) 106 | ).collect(Collectors.toList()); 107 | generator = new FreeTypeFontGenerator(Gdx.files.internal("Pacifico.ttf")); 108 | FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter(); 109 | parameter.size = 62; 110 | parameter.color = Color.BLACK; 111 | font12 = generator.generateFont(parameter); // font size 12 pixels 112 | Box2D.init(); 113 | batch = new SpriteBatch(); 114 | img = new Texture("badlogic.jpg"); 115 | sound = Gdx.audio.newSound(Gdx.files.internal("wand1.wav")); 116 | music = Gdx.audio.newMusic(Gdx.files.internal("all.mp3")); 117 | // music.play(); 118 | music.setPosition(0.5f); 119 | soundScheduler = new SchedulerCaller(5000, new Runnable() { 120 | @Override 121 | public void run() { 122 | // sound.play(); 123 | } 124 | }); 125 | musicPositionCheckerScheduler = new SchedulerCaller(2000, new Runnable() { 126 | @Override 127 | public void run() { 128 | System.out.println("music.isPlaying(): " + music.isPlaying()); 129 | System.out.println("music.getPosition(): " + music.getPosition()); 130 | } 131 | }); 132 | box2dObjectsCheckerScheduler = new SchedulerCaller(2000, new Runnable() { 133 | @Override 134 | public void run() { 135 | for (Fixture fixture : box2dObjects) { 136 | System.out.println("box2d fixture.getBody().getPosition()" + fixture.getBody().getPosition().x + " " + fixture.getBody().getPosition().y); 137 | } 138 | 139 | } 140 | }); 141 | controllersScheduler = new SchedulerCaller(2000, new Runnable() { 142 | @Override 143 | public void run() { 144 | for (Controller controller : Controllers.getControllers()) { 145 | System.out.println("Controller: " + controller.getName()); 146 | } 147 | } 148 | }); 149 | pingScheduler = new SchedulerCaller(2000, () -> { 150 | System.out.println("'Hi' sent"); 151 | maybeKryonet.ifPresent(kryonet -> kryonet.send("Hi")); 152 | }); 153 | System.out.println("music.isPlaying(): " + music.isPlaying()); 154 | Gdx.input.setInputProcessor(this); 155 | Controllers.addListener(this); 156 | world = new World(new Vector2(0, -10), true); 157 | rayHandler = new RayHandler(world); 158 | debugRenderer = new Box2DDebugRenderer(); 159 | camera = new OrthographicCamera(w, h); 160 | camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0); 161 | camera.update(); 162 | new PointLight(rayHandler, 1000, new Color(1, 1, 1, 1), 1000, w / 2, h / 2); 163 | 164 | ShaderLoader.BasePath = "./shaders/"; 165 | postProcessor = new PostProcessor( false, false, true ); 166 | Curvature curvature = new Curvature(); 167 | 168 | postProcessor.addEffect( curvature ); 169 | } 170 | 171 | @Override 172 | public void render() { 173 | camera.update(); 174 | Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1); 175 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 176 | 177 | postProcessor.capture(); 178 | batch.begin(); 179 | batch.draw(img, 0, 0); 180 | ballPainters.forEach(b -> b.paint(batch)); 181 | batch.end(); 182 | 183 | postProcessor.render(); 184 | 185 | soundScheduler.call(); 186 | musicPositionCheckerScheduler.call(); 187 | pingScheduler.call(); 188 | box2dObjectsCheckerScheduler.call(); 189 | debugRenderer.render(world, camera.combined); 190 | world.step(1 / 60f, 6, 2); 191 | rayHandler.setCombinedMatrix((OrthographicCamera) camera); 192 | rayHandler.updateAndRender(); 193 | batch.begin(); 194 | font12.draw(batch, "Hello Native!", w/2, h/2); 195 | batch.end(); 196 | } 197 | 198 | @Override 199 | public void dispose() { 200 | maybeKryonet.ifPresent(KryonetClientServer::dispose); 201 | postProcessor.dispose(); 202 | batch.dispose(); 203 | img.dispose(); 204 | sound.dispose(); 205 | generator.dispose(); 206 | music.dispose(); 207 | world.dispose(); 208 | rayHandler.dispose(); 209 | for (Fixture fixture : box2dObjects) { 210 | fixture.getShape().dispose(); 211 | } 212 | } 213 | 214 | 215 | @Override 216 | public boolean keyDown(int i) { 217 | System.out.println("keyDown " + i); 218 | return true; 219 | } 220 | 221 | @Override 222 | public boolean keyUp(int i) { 223 | System.out.println("keyUp " + i); 224 | return true; 225 | } 226 | 227 | @Override 228 | public boolean keyTyped(char c) { 229 | System.out.println("keyTyped " + c); 230 | return true; 231 | } 232 | 233 | @Override 234 | public boolean touchDown(int i, int i1, int i2, int i3) { 235 | System.out.println("touchDown " + i + " " + i1 + " " + i2 + " " + i3); 236 | createBox2dBody(i, (int) (h - i1)); 237 | return true; 238 | } 239 | 240 | @Override 241 | public boolean touchUp(int i, int i1, int i2, int i3) { 242 | System.out.println("touchUp " + i + " " + i1 + " " + i2 + " " + i3); 243 | return true; 244 | } 245 | 246 | @Override 247 | public boolean touchDragged(int i, int i1, int i2) { 248 | System.out.println("touchDragged " + i + " " + i1 + " " + i2); 249 | return true; 250 | } 251 | 252 | @Override 253 | public boolean mouseMoved(int i, int i1) { 254 | //System.out.println("mouseMoved " + i + " " + i1 ); 255 | return true; 256 | } 257 | 258 | @Override 259 | public boolean scrolled(float v, float v1) { 260 | System.out.println("scrolled " + v + " " + v1); 261 | return true; 262 | } 263 | 264 | 265 | @Override 266 | public void connected(Controller controller) { 267 | System.out.println("Controller connected: " + controller.getName()); 268 | } 269 | 270 | @Override 271 | public void disconnected(Controller controller) { 272 | System.out.println("Controller disconnected: " + controller.getName()); 273 | 274 | } 275 | 276 | @Override 277 | public boolean buttonDown(Controller controller, int buttonCode) { 278 | System.out.println("Controller buttonDown: " + buttonCode); 279 | 280 | return true; 281 | } 282 | 283 | @Override 284 | public boolean buttonUp(Controller controller, int buttonCode) { 285 | System.out.println("Controller buttonUp: " + buttonCode); 286 | return true; 287 | } 288 | 289 | @Override 290 | public boolean axisMoved(Controller controller, int axisCode, float value) { 291 | System.out.println("Controller axisMoved: " + axisCode + " " + value); 292 | return true; 293 | } 294 | 295 | 296 | public void createBox2dBody(int x, int y) { 297 | //https://github.com/libgdx/libgdx/wiki/Box2d 298 | // First we create a body definition 299 | BodyDef bodyDef = new BodyDef(); 300 | // We set our body to dynamic, for something like ground which doesn't move we would set it to StaticBody 301 | bodyDef.type = BodyDef.BodyType.DynamicBody; 302 | // Set our body's starting position in the world 303 | bodyDef.position.set(x, y); 304 | 305 | // Create our body in the world using our body definition 306 | Body body = world.createBody(bodyDef); 307 | 308 | // Create a circle shape and set its radius to 6 309 | CircleShape circle = new CircleShape(); 310 | circle.setRadius(6f); 311 | 312 | // Create a fixture definition to apply our shape to 313 | FixtureDef fixtureDef = new FixtureDef(); 314 | fixtureDef.shape = circle; 315 | fixtureDef.density = 0.5f; 316 | fixtureDef.friction = 0.4f; 317 | fixtureDef.restitution = 0.6f; // Make it bounce a little bit 318 | 319 | // Create our fixture and attach it to the body 320 | Fixture fixture = body.createFixture(fixtureDef); 321 | box2dObjects.add(fixture); 322 | System.out.println("Body created at " + x + " " + y); 323 | // Remember to dispose of any shapes after you're done with them! 324 | // BodyDef and FixtureDef don't need disposing, but shapes do. 325 | //circle.dispose(); 326 | } 327 | } 328 | --------------------------------------------------------------------------------