mirror of https://github.com/Minestom/Minestom.git
Build system update (#527)
This commit is contained in:
parent
de817e5e52
commit
3089843cc9
|
@ -31,7 +31,7 @@
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
|
|
||||||
### Gradle template
|
### Gradle template
|
||||||
.gradle
|
**/.gradle
|
||||||
**/build/
|
**/build/
|
||||||
|
|
||||||
# Ignore Gradle GUI config
|
# Ignore Gradle GUI config
|
||||||
|
@ -53,5 +53,6 @@ gradle-app.setting
|
||||||
/src/main/java/com/mcecraft/
|
/src/main/java/com/mcecraft/
|
||||||
|
|
||||||
# When running the demo we generate the extensions folder
|
# When running the demo we generate the extensions folder
|
||||||
/extensions/
|
# Incase people are using IntelliJ to run the server, this will exclude extensions from any folder.
|
||||||
/.mixin.out/
|
/demo/extensions
|
||||||
|
/extensions
|
|
@ -0,0 +1,16 @@
|
||||||
|
plugins {
|
||||||
|
`kotlin-dsl`
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
val indraVersion = "2.0.6"
|
||||||
|
implementation("org.jetbrains.kotlin", "kotlin-gradle-plugin", "1.6.10")
|
||||||
|
implementation("net.kyori", "indra-common", indraVersion)
|
||||||
|
implementation("net.kyori", "indra-publishing-sonatype", indraVersion)
|
||||||
|
implementation("org.graalvm.buildtools", "native-gradle-plugin", "0.9.9")
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
plugins {
|
||||||
|
java
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always exclude checker-qual. This is the single most annoying thing that always reappears.
|
||||||
|
configurations.all {
|
||||||
|
// We only use Jetbrains Annotations
|
||||||
|
exclude("org.checkerframework", "checker-qual")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<JavaCompile> {
|
||||||
|
// We are fully aware, that we should be suppressing these instead of ignoring them here, but man keep my terminal clean.
|
||||||
|
options.compilerArgs.addAll(listOf("-Xlint:none", "-Xlint:-deprecation", "-Xlint:-unchecked"))
|
||||||
|
}
|
||||||
|
withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
plugins {
|
||||||
|
id("minestom.common-conventions")
|
||||||
|
id("org.graalvm.buildtools.native")
|
||||||
|
}
|
||||||
|
|
||||||
|
graalvmNative {
|
||||||
|
binaries {
|
||||||
|
named("main") {
|
||||||
|
buildArgs.add("--allow-incomplete-classpath")
|
||||||
|
// One day toolchains will support getting this automagically, but that day is not today.
|
||||||
|
toolchainDetection.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
plugins {
|
||||||
|
id("net.kyori.indra")
|
||||||
|
id("net.kyori.indra.publishing")
|
||||||
|
id("net.kyori.indra.publishing.sonatype")
|
||||||
|
}
|
||||||
|
|
||||||
|
indra {
|
||||||
|
javaVersions {
|
||||||
|
target(17)
|
||||||
|
testWith(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
github("Minestom", "Minestom") {
|
||||||
|
ci(true)
|
||||||
|
}
|
||||||
|
apache2License()
|
||||||
|
|
||||||
|
configurePublications {
|
||||||
|
pom {
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id.set("TheMode")
|
||||||
|
name.set("TheMode")
|
||||||
|
}
|
||||||
|
developer {
|
||||||
|
id.set("jglrxavpok")
|
||||||
|
name.set("jglrxavpok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
186
build.gradle
186
build.gradle
|
@ -1,186 +0,0 @@
|
||||||
import org.gradle.internal.os.OperatingSystem
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id 'java-library'
|
|
||||||
id 'maven-publish'
|
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.5.31'
|
|
||||||
//id 'checkstyle'
|
|
||||||
}
|
|
||||||
|
|
||||||
group 'net.minestom.server'
|
|
||||||
version '1.0'
|
|
||||||
|
|
||||||
sourceCompatibility = 17
|
|
||||||
project.ext.lwjglVersion = "3.2.3"
|
|
||||||
|
|
||||||
switch (OperatingSystem.current()) {
|
|
||||||
case OperatingSystem.LINUX:
|
|
||||||
def osArch = System.getProperty("os.arch")
|
|
||||||
project.ext.lwjglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64")
|
|
||||||
? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}"
|
|
||||||
: "natives-linux"
|
|
||||||
break
|
|
||||||
case OperatingSystem.MAC_OS:
|
|
||||||
project.ext.lwjglNatives = "natives-macos"
|
|
||||||
break
|
|
||||||
case OperatingSystem.WINDOWS:
|
|
||||||
project.ext.lwjglNatives = System.getProperty("os.arch").contains("64") ? "natives-windows" : "natives-windows-x86"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
maven { url 'https://jitpack.io' }
|
|
||||||
}
|
|
||||||
javadoc {
|
|
||||||
options {
|
|
||||||
addBooleanOption('html5', true)
|
|
||||||
links "https://jd.adventure.kyori.net/api/$adventureVersion/"
|
|
||||||
links "https://docs.oracle.com/en/java/javase/11/docs/api/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// see https://stackoverflow.com/a/56641766
|
|
||||||
doLast {
|
|
||||||
// Append the fix to the file
|
|
||||||
def searchScript = new File(destinationDir, '/search.js')
|
|
||||||
searchScript.append '\n\n' +
|
|
||||||
'getURLPrefix = function(ui) {\n' +
|
|
||||||
' return \'\';\n' +
|
|
||||||
'};\n'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//checkstyle {
|
|
||||||
// toolVersion "8.42"
|
|
||||||
// configFile file("${projectDir}/minestom_checks.xml")
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java {
|
|
||||||
srcDir 'src/main/java'
|
|
||||||
srcDir 'src/autogenerated/java'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lwjgl {
|
|
||||||
java {
|
|
||||||
srcDir 'src/lwjgl/java'
|
|
||||||
}
|
|
||||||
|
|
||||||
compileClasspath += sourceSets.main.runtimeClasspath
|
|
||||||
runtimeClasspath += sourceSets.main.runtimeClasspath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
// Minestom uses LWJGL libs as optional dependency if interfacing with a GPU is asked
|
|
||||||
registerFeature("lwjgl") {
|
|
||||||
usingSourceSet(sourceSets.lwjgl)
|
|
||||||
withJavadocJar()
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
withJavadocJar()
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(Zip).configureEach {
|
|
||||||
duplicatesStrategy DuplicatesStrategy.EXCLUDE
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Junit Testing Framework
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
|
|
||||||
testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.8.2')
|
|
||||||
|
|
||||||
// Only here to ensure J9 module support for extensions and our classloaders
|
|
||||||
testCompileOnly 'org.mockito:mockito-core:4.2.0'
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/it.unimi.dsi/fastutil
|
|
||||||
api 'it.unimi.dsi:fastutil:8.5.6'
|
|
||||||
implementation group: 'space.vectrix.flare', name: 'flare', version: '2.0.0'
|
|
||||||
implementation group: 'space.vectrix.flare', name: 'flare-fastutil', version: '2.0.0'
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
|
||||||
api 'com.google.code.gson:gson:2.8.9'
|
|
||||||
|
|
||||||
// Noise library for terrain generation
|
|
||||||
// https://jitpack.io/#Articdive/Jnoise
|
|
||||||
api 'com.github.Articdive:Jnoise:2.1.0'
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
api 'org.apache.logging.log4j:log4j-core:2.17.0'
|
|
||||||
// SLF4J is the base logger for most libraries, therefore we can hook it into log4j2.
|
|
||||||
api 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.0'
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.jline/jline
|
|
||||||
implementation group: 'org.jline', name: 'jline', version: '3.20.0'
|
|
||||||
// https://mvnrepository.com/artifact/org.jline/jline-terminal-jansi
|
|
||||||
implementation group: 'org.jline', name: 'jline-terminal-jansi', version: '3.20.0'
|
|
||||||
|
|
||||||
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.5'
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.jctools/jctools-core
|
|
||||||
implementation group: 'org.jctools', name: 'jctools-core', version: '3.3.0'
|
|
||||||
|
|
||||||
// Guava 21.0+ required for Mixin
|
|
||||||
api 'com.google.guava:guava:31.0.1-jre'
|
|
||||||
|
|
||||||
// Path finding
|
|
||||||
api 'com.github.MadMartian:hydrazine-path-finding:1.6.0'
|
|
||||||
|
|
||||||
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${project.kotlinVersion}"
|
|
||||||
api "org.jetbrains.kotlin:kotlin-reflect:${project.kotlinVersion}"
|
|
||||||
|
|
||||||
// NBT parsing/manipulation/saving
|
|
||||||
api("io.github.jglrxavpok.hephaistos:common:${project.hephaistosVersion}")
|
|
||||||
api("io.github.jglrxavpok.hephaistos:gson:${project.hephaistosVersion}")
|
|
||||||
/* api("io.github.jglrxavpok.hephaistos:common:${project.hephaistosVersion}") {
|
|
||||||
capabilities {
|
|
||||||
requireCapability("io.github.jglrxavpok.hephaistos:Hephaistos-gson")
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
api "com.github.Minestom:DependencyGetter:v1.0.1"
|
|
||||||
implementation 'com.github.Minestom:MinestomDataGenerator:801b8007cf'
|
|
||||||
|
|
||||||
// Adventure, for user-interface
|
|
||||||
api "net.kyori:adventure-api:$adventureVersion"
|
|
||||||
api "net.kyori:adventure-text-serializer-gson:$adventureVersion"
|
|
||||||
api "net.kyori:adventure-text-serializer-plain:$adventureVersion"
|
|
||||||
api "net.kyori:adventure-text-serializer-legacy:$adventureVersion"
|
|
||||||
|
|
||||||
// LWJGL, for map rendering
|
|
||||||
lwjglApi platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
|
||||||
|
|
||||||
lwjglApi "org.lwjgl:lwjgl"
|
|
||||||
lwjglApi "org.lwjgl:lwjgl-egl"
|
|
||||||
lwjglApi "org.lwjgl:lwjgl-opengl"
|
|
||||||
lwjglApi "org.lwjgl:lwjgl-opengles"
|
|
||||||
lwjglApi "org.lwjgl:lwjgl-glfw"
|
|
||||||
lwjglApi "org.lwjgl:lwjgl-glfw"
|
|
||||||
lwjglApi 'org.joml:joml:1.10.2'
|
|
||||||
lwjglRuntimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
|
||||||
lwjglRuntimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
|
||||||
lwjglRuntimeOnly "org.lwjgl:lwjgl-opengles::$lwjglNatives"
|
|
||||||
lwjglRuntimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.all {
|
|
||||||
// we use jetbrains annotations
|
|
||||||
exclude group: "org.checkerframework", module: "checker-qual"
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
mavenJava(MavenPublication) {
|
|
||||||
from components.java
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
id("minestom.publishing-conventions")
|
||||||
|
id("minestom.native-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
group = "net.minestom.server"
|
||||||
|
version = "1.0"
|
||||||
|
description = "Lightweight and multi-threaded Minecraft server implementation"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDir(file("src/autogenerated/java"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
withJavadocJar()
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<Javadoc> {
|
||||||
|
(options as? StandardJavadocDocletOptions)?.apply {
|
||||||
|
encoding = "UTF-8"
|
||||||
|
|
||||||
|
// Custom options
|
||||||
|
addBooleanOption("html5", true)
|
||||||
|
addStringOption("-release", "17")
|
||||||
|
// Links to external javadocs
|
||||||
|
links("https://docs.oracle.com/en/java/javase/17/docs/api/")
|
||||||
|
links("https://jd.adventure.kyori.net/api/${libs.versions.adventure.get()}/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withType<Zip> {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Junit Testing Framework
|
||||||
|
testImplementation(libs.junit.api)
|
||||||
|
testRuntimeOnly(libs.junit.engine)
|
||||||
|
// Only here to ensure J9 module support for extensions and our classloaders
|
||||||
|
testCompileOnly(libs.mockito.core)
|
||||||
|
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
implementation(libs.bundles.logging)
|
||||||
|
// Libraries required for the terminal
|
||||||
|
implementation(libs.bundles.terminal)
|
||||||
|
|
||||||
|
// Performance improving libraries
|
||||||
|
implementation(libs.caffeine)
|
||||||
|
api(libs.fastutil)
|
||||||
|
implementation(libs.bundles.flare)
|
||||||
|
|
||||||
|
// Libraries
|
||||||
|
api(libs.guava)
|
||||||
|
api(libs.gson)
|
||||||
|
implementation(libs.jcTools)
|
||||||
|
// Path finding
|
||||||
|
api(libs.hydrazine)
|
||||||
|
|
||||||
|
// Adventure, for user-interface
|
||||||
|
api(libs.bundles.adventure)
|
||||||
|
|
||||||
|
// Kotlin Libraries
|
||||||
|
api(libs.bundles.kotlin)
|
||||||
|
|
||||||
|
// Extension Management System dependency handler.
|
||||||
|
api(libs.dependencyGetter)
|
||||||
|
|
||||||
|
// Minestom Data (From MinestomDataGenerator)
|
||||||
|
implementation(libs.minestomData)
|
||||||
|
|
||||||
|
// NBT parsing/manipulation/saving
|
||||||
|
api("io.github.jglrxavpok.hephaistos:common:${libs.versions.hephaistos.get()}")
|
||||||
|
api("io.github.jglrxavpok.hephaistos:gson:${libs.versions.hephaistos.get()}")
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
plugins {
|
|
||||||
id 'java'
|
|
||||||
id 'application'
|
|
||||||
// Used to download our data
|
|
||||||
}
|
|
||||||
|
|
||||||
group 'net.minestom.server'
|
|
||||||
version '1.0'
|
|
||||||
|
|
||||||
sourceCompatibility = 17
|
|
||||||
|
|
||||||
application {
|
|
||||||
mainClass.set("net.minestom.codegen.Generators")
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'com.google.code.gson:gson:2.8.7'
|
|
||||||
implementation 'org.jetbrains:annotations:21.0.1'
|
|
||||||
implementation 'com.squareup:javapoet:1.13.0'
|
|
||||||
// Logging
|
|
||||||
implementation 'org.apache.logging.log4j:log4j-core:2.14.1'
|
|
||||||
// SLF4J is the base logger for most libraries, therefore we can hook it into log4j2.
|
|
||||||
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.14.1'
|
|
||||||
// Contains the json files
|
|
||||||
implementation 'com.github.Minestom:MinestomDataGenerator:801b8007cf'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
run {
|
|
||||||
// Update version
|
|
||||||
setArgs(List.of(
|
|
||||||
// Points to src/autogenerated/java
|
|
||||||
project.rootProject.projectDir.getPath() + "${File.separatorChar}src${File.separatorChar}autogenerated${File.separatorChar}java"
|
|
||||||
) as List<String>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
plugins {
|
||||||
|
application
|
||||||
|
id("minestom.common-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set("net.minestom.codegen.Generators")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.gson)
|
||||||
|
implementation(libs.jetbrainsAnnotations)
|
||||||
|
implementation(libs.javaPoet)
|
||||||
|
// Logging
|
||||||
|
implementation(libs.bundles.logging)
|
||||||
|
// Contains the json files
|
||||||
|
implementation(libs.minestomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
getByName<JavaExec>("run") {
|
||||||
|
args = listOf(project.rootProject.projectDir.resolve("src").resolve("autogenerated").resolve("java").absolutePath)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
plugins {
|
||||||
|
application
|
||||||
|
id("minestom.common-conventions")
|
||||||
|
id("minestom.native-conventions")
|
||||||
|
id("com.github.johnrengelman.shadow") version("7.1.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set("net.minestom.demo.Main")
|
||||||
|
// This is included because Shadow is buggy. Wait for https://github.com/johnrengelman/shadow/issues/613 to befixed.
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
mainClassName = "net.minestom.demo.Main"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(rootProject)
|
||||||
|
implementation(libs.jNoise)
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
package demo;
|
package net.minestom.demo;
|
||||||
|
|
||||||
import demo.commands.*;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.format.Style;
|
import net.kyori.adventure.text.format.Style;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.minestom.demo.commands.*;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.event.server.ServerListPingEvent;
|
import net.minestom.server.event.server.ServerListPingEvent;
|
||||||
|
@ -31,7 +31,6 @@ public class Main {
|
||||||
|
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
commandManager.register(new TestCommand());
|
commandManager.register(new TestCommand());
|
||||||
commandManager.register(new GamemodeCommand());
|
|
||||||
commandManager.register(new EntitySelectorCommand());
|
commandManager.register(new EntitySelectorCommand());
|
||||||
commandManager.register(new HealthCommand());
|
commandManager.register(new HealthCommand());
|
||||||
commandManager.register(new LegacyCommand());
|
commandManager.register(new LegacyCommand());
|
|
@ -1,4 +1,4 @@
|
||||||
package demo;
|
package net.minestom.demo;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
|
@ -1,7 +1,7 @@
|
||||||
package demo;
|
package net.minestom.demo;
|
||||||
|
|
||||||
import demo.generator.ChunkGeneratorDemo;
|
import net.minestom.demo.generator.ChunkGeneratorDemo;
|
||||||
import demo.generator.NoiseTestGenerator;
|
import net.minestom.demo.generator.NoiseTestGenerator;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.adventure.audience.Audiences;
|
import net.minestom.server.adventure.audience.Audiences;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.block;
|
package net.minestom.demo.block;
|
||||||
|
|
||||||
import net.minestom.server.instance.block.BlockHandler;
|
import net.minestom.server.instance.block.BlockHandler;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.inventory.Book;
|
import net.kyori.adventure.inventory.Book;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.audience.MessageType;
|
import net.kyori.adventure.audience.MessageType;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
||||||
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
|
import net.minestom.server.command.builder.arguments.minecraft.ArgumentBlockState;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.commands;
|
package net.minestom.demo.commands;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.entity;
|
package net.minestom.demo.entity;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.entity;
|
package net.minestom.demo.entity;
|
||||||
|
|
||||||
import net.minestom.server.entity.EntityCreature;
|
import net.minestom.server.entity.EntityCreature;
|
||||||
import net.minestom.server.entity.EntityType;
|
import net.minestom.server.entity.EntityType;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.generator;
|
package net.minestom.demo.generator;
|
||||||
|
|
||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.instance.ChunkGenerator;
|
import net.minestom.server.instance.ChunkGenerator;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.generator;
|
package net.minestom.demo.generator;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.JNoise;
|
||||||
import de.articdive.jnoise.interpolation.InterpolationType;
|
import de.articdive.jnoise.interpolation.InterpolationType;
|
|
@ -1,4 +1,4 @@
|
||||||
package demo.generator;
|
package net.minestom.demo.generator;
|
||||||
|
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
|
@ -1,6 +0,0 @@
|
||||||
# Update this version with every release. It is purely used for the code generator and data dependency.
|
|
||||||
mcVersion = 1.17
|
|
||||||
|
|
||||||
hephaistosVersion=2.3.2
|
|
||||||
kotlinVersion=1.5.31
|
|
||||||
adventureVersion=4.9.3
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
metadata.format.version = "1.1"
|
||||||
|
|
||||||
|
[versions]
|
||||||
|
|
||||||
|
# Important dependencies
|
||||||
|
adventure = "4.9.3"
|
||||||
|
kotlin = "1.6.10"
|
||||||
|
hydrazine = "1.7.2"
|
||||||
|
dependencyGetter = "v1.0.1"
|
||||||
|
minestomData = "801b8007cf"
|
||||||
|
hephaistos = "2.3.2"
|
||||||
|
jetbrainsAnnotations = "23.0.0"
|
||||||
|
|
||||||
|
# Terminal / Logging
|
||||||
|
tinylog = "2.4.1"
|
||||||
|
jline = "3.21.0"
|
||||||
|
|
||||||
|
# Performance / Data Structures
|
||||||
|
caffeine = "3.0.5"
|
||||||
|
fastutil = "8.5.6"
|
||||||
|
flare = "2.0.0"
|
||||||
|
gson = "2.8.9"
|
||||||
|
guava = "31.0.1-jre"
|
||||||
|
jcTools = "3.3.0"
|
||||||
|
|
||||||
|
# Code Generation
|
||||||
|
javaPoet = "1.13.0"
|
||||||
|
|
||||||
|
# Demo
|
||||||
|
jNoise = "3.0.1"
|
||||||
|
|
||||||
|
# Test
|
||||||
|
junit-jupiter = "5.8.2"
|
||||||
|
mockito = "4.2.0"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
|
||||||
|
# Important Dependencies
|
||||||
|
# Adventure
|
||||||
|
adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" }
|
||||||
|
adventure-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" }
|
||||||
|
adventure-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" }
|
||||||
|
adventure-serializer-plain = { group = "net.kyori", name = "adventure-text-serializer-plain", version.ref = "adventure" }
|
||||||
|
|
||||||
|
# Kotlin
|
||||||
|
kotlin-reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" }
|
||||||
|
kotlin-stdlib-jdk8 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
hydrazine = { group = "com.github.MadMartian", name = "hydrazine-path-finding", version.ref = "hydrazine" }
|
||||||
|
dependencyGetter = { group = "com.github.Minestom", name = "DependencyGetter", version.ref = "dependencyGetter" }
|
||||||
|
minestomData = { group = "com.github.Minestom", name = "MinestomDataGenerator", version.ref = "minestomData" }
|
||||||
|
jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrainsAnnotations" }
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
tinylog-api = { group = "org.tinylog", name = "tinylog-api", version.ref = "tinylog" }
|
||||||
|
tinylog-impl = { group = "org.tinylog", name = "tinylog-impl", version.ref = "tinylog" }
|
||||||
|
tinylog-slf4j = { group = "org.tinylog", name = "slf4j-tinylog", version.ref = "tinylog" }
|
||||||
|
|
||||||
|
# Terminal
|
||||||
|
jline = { group = "org.jline", name = "jline", version.ref = "jline"}
|
||||||
|
jline-jansi = { group = "org.jline", name = "jline-terminal-jansi", version.ref = "jline" }
|
||||||
|
|
||||||
|
# Performance / Data Structures
|
||||||
|
caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine" }
|
||||||
|
fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" }
|
||||||
|
flare = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare"}
|
||||||
|
flare-fastutil = { group = "space.vectrix.flare", name = "flare", version.ref = "flare"}
|
||||||
|
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
|
||||||
|
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
|
||||||
|
jcTools = { group = "org.jctools", name = "jctools-core", version.ref = "jcTools"}
|
||||||
|
|
||||||
|
# Test
|
||||||
|
junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit-jupiter" }
|
||||||
|
junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit-jupiter" }
|
||||||
|
mockito-core = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" }
|
||||||
|
|
||||||
|
# Code Generation
|
||||||
|
javaPoet = { group = "com.squareup", name = "javapoet", version.ref = "javaPoet" }
|
||||||
|
|
||||||
|
# Demo
|
||||||
|
jNoise = { group = "com.github.Articdive", name = "JNoise", version.ref = "jNoise" }
|
||||||
|
|
||||||
|
[bundles]
|
||||||
|
|
||||||
|
kotlin = ["kotlin-stdlib-jdk8", "kotlin-reflect"]
|
||||||
|
flare = ["flare", "flare-fastutil"]
|
||||||
|
adventure = ["adventure-api", "adventure-serializer-gson", "adventure-serializer-legacy", "adventure-serializer-plain"]
|
||||||
|
logging = ["tinylog-api", "tinylog-impl", "tinylog-slf4j"]
|
||||||
|
terminal = ["jline", "jline-jansi"]
|
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright ? 2015-2021 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -32,10 +32,10 @@
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
# requires all of these POSIX shell features:
|
# requires all of these POSIX shell features:
|
||||||
# * functions;
|
# * functions;
|
||||||
# * expansions <EFBFBD>á$var<61>â, <20>á${var}<7D>â, <20>á${var:-default}<7D>â, <20>á${var+SET}<7D>â,
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
# <EFBFBD>á${var#prefix}<7D>â, <20>á${var%suffix}<7D>â, and <20>á$( cmd )<29>â;
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
# * compound commands having a testable exit status, especially <EFBFBD>ácase<EFBFBD>â;
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
# * various built-in commands including <EFBFBD>ácommand<EFBFBD>â, <20>áset<65>â, and <20>áulimit<69>â.
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
#
|
#
|
||||||
# Important for patching:
|
# Important for patching:
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
plugins {
|
||||||
|
id("me.champeau.jmh") version ("0.6.6")
|
||||||
|
id("minestom.common-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(rootProject)
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package net.minestom.jmh.event;
|
||||||
|
|
||||||
|
import net.minestom.server.event.Event;
|
||||||
|
import net.minestom.server.event.EventNode;
|
||||||
|
import net.minestom.server.event.ListenerHandle;
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Warmup(iterations = 5, time = 1500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Measurement(iterations = 10, time = 1500, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
@Fork(3)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public class SingleNodeBenchmark {
|
||||||
|
|
||||||
|
@Param({"0", "1", "2", "3", "5", "10"})
|
||||||
|
public int listenerCount;
|
||||||
|
|
||||||
|
private EventNode<Event> node;
|
||||||
|
private ListenerHandle<TestEvent> handle;
|
||||||
|
|
||||||
|
record TestEvent() implements Event {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
node = EventNode.all("node");
|
||||||
|
for (int i = 0; i < listenerCount; i++) {
|
||||||
|
node.addListener(TestEvent.class, testEvent -> {
|
||||||
|
// Empty
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.handle = node.getHandle(TestEvent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void call() {
|
||||||
|
node.call(new TestEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void handleCall() {
|
||||||
|
handle.call(new TestEvent());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +0,0 @@
|
||||||
rootProject.name = 'Minestom'
|
|
||||||
include 'code-generators'
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
enableFeaturePreview("VERSION_CATALOGS")
|
||||||
|
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositories {
|
||||||
|
maven("https://jitpack.io")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
includeBuild("build-logic")
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "Minestom"
|
||||||
|
include("code-generators")
|
||||||
|
include("jmh-benchmarks")
|
||||||
|
include("demo")
|
|
@ -1,6 +0,0 @@
|
||||||
# Minestom LWJGL code
|
|
||||||
|
|
||||||
Here is all LWJGL-related code in Minestom.
|
|
||||||
Accessible when using "lwjgl" as an optional dependency in Gradle when declaring Minestom as a dependency
|
|
||||||
|
|
||||||
Go to [LWJGL Minestom Example](https://github.com/Minestom/LWJGL-Example) to see in details how to use.
|
|
|
@ -1,129 +0,0 @@
|
||||||
package net.minestom.demo.largeframebuffers;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.metadata.other.ItemFrameMeta;
|
|
||||||
import net.minestom.server.instance.Instance;
|
|
||||||
import net.minestom.server.instance.InstanceManager;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import net.minestom.server.item.metadata.MapMeta;
|
|
||||||
import net.minestom.server.map.Framebuffer;
|
|
||||||
import net.minestom.server.map.LargeFramebuffer;
|
|
||||||
import net.minestom.server.map.MapColors;
|
|
||||||
import net.minestom.server.map.framebuffers.LargeDirectFramebuffer;
|
|
||||||
import net.minestom.server.map.framebuffers.LargeGLFWFramebuffer;
|
|
||||||
import net.minestom.server.map.framebuffers.LargeGraphics2DFramebuffer;
|
|
||||||
import net.minestom.server.map.framebuffers.MapColorRenderer;
|
|
||||||
import net.minestom.server.network.packet.server.play.MapDataPacket;
|
|
||||||
import net.minestom.server.utils.time.TimeUnit;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class Demo {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
MainDemo.main(args); // used to avoid code duplication
|
|
||||||
initDemo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initDemo() {
|
|
||||||
InstanceManager instances = MinecraftServer.getInstanceManager();
|
|
||||||
Instance instance = instances.getInstances().stream().findAny().get();
|
|
||||||
|
|
||||||
LargeDirectFramebuffer directFramebuffer = new LargeDirectFramebuffer(512, 512);
|
|
||||||
LargeGraphics2DFramebuffer graphics2DFramebuffer = new LargeGraphics2DFramebuffer(512, 512);
|
|
||||||
LargeGLFWFramebuffer glfwFramebuffer = new LargeGLFWFramebuffer(512, 512);
|
|
||||||
|
|
||||||
glfwFramebuffer.changeRenderingThreadToCurrent();
|
|
||||||
OpenGLRendering.init();
|
|
||||||
MapColorRenderer renderer = new MapColorRenderer(glfwFramebuffer, OpenGLRendering::render);
|
|
||||||
glfwFramebuffer.unbindContextFromThread();
|
|
||||||
|
|
||||||
// renderingLoop(0, directFramebuffer, Demo::directRendering);
|
|
||||||
// renderingLoop(101, graphics2DFramebuffer, Demo::graphics2DRendering);
|
|
||||||
renderingLoop(201, glfwFramebuffer, f -> {
|
|
||||||
});
|
|
||||||
|
|
||||||
glfwFramebuffer.setupRenderLoop(15, TimeUnit.MILLISECOND, renderer);
|
|
||||||
|
|
||||||
for (int x = -2; x <= 2; x++) {
|
|
||||||
for (int z = -2; z <= 2; z++) {
|
|
||||||
instance.loadChunk(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setupMaps(instance, 0, 10);
|
|
||||||
setupMaps(instance, 101, 20);
|
|
||||||
setupMaps(instance, 201, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void createFrame(Instance instance, int id, int x, int y, int z) {
|
|
||||||
Entity itemFrame = new Entity(EntityType.ITEM_FRAME);
|
|
||||||
|
|
||||||
ItemFrameMeta itemFrameMeta = (ItemFrameMeta) itemFrame.getEntityMeta();
|
|
||||||
|
|
||||||
itemFrameMeta.setNotifyAboutChanges(false);
|
|
||||||
|
|
||||||
itemFrameMeta.setOrientation(ItemFrameMeta.Orientation.NORTH);
|
|
||||||
|
|
||||||
ItemStack map = ItemStack.builder(Material.FILLED_MAP)
|
|
||||||
.meta(new MapMeta.Builder().mapId(id).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
itemFrameMeta.setItem(map);
|
|
||||||
itemFrameMeta.setCustomNameVisible(true);
|
|
||||||
itemFrameMeta.setCustomName(Component.text("MapID: " + id));
|
|
||||||
|
|
||||||
itemFrameMeta.setNotifyAboutChanges(true);
|
|
||||||
|
|
||||||
itemFrame.setInstance(instance, new Pos(x, y, z, 180, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setupMaps(Instance instance, int mapIDStart, int zCoordinate) {
|
|
||||||
for (int y = 0; y < 4; y++) {
|
|
||||||
for (int x = 0; x < 4; x++) {
|
|
||||||
createFrame(instance, mapIDStart + y * 4 + x, 2 - x, 45 - y, zCoordinate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T extends LargeFramebuffer> void renderingLoop(int mapIDStart, T framebuffer, Consumer<T> renderingCode) {
|
|
||||||
final Framebuffer[] subviews = new Framebuffer[4 * 4];
|
|
||||||
for (int i = 0; i < subviews.length; i++) {
|
|
||||||
int x = (i % 4) * 128;
|
|
||||||
int y = (i / 4) * 128;
|
|
||||||
subviews[i] = framebuffer.createSubView(x, y);
|
|
||||||
}
|
|
||||||
MinecraftServer.getSchedulerManager().buildTask(() -> {
|
|
||||||
renderingCode.accept(framebuffer);
|
|
||||||
for (int i = 0; i < subviews.length; i++) {
|
|
||||||
Framebuffer f = subviews[i];
|
|
||||||
MapDataPacket packet = f.preparePacket(mapIDStart + i);
|
|
||||||
sendPacket(packet);
|
|
||||||
}
|
|
||||||
}).repeat(15, TimeUnit.MILLISECOND).schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void sendPacket(MapDataPacket packet) {
|
|
||||||
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(p -> p.getPlayerConnection().sendPacket(packet));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void directRendering(LargeDirectFramebuffer framebuffer) {
|
|
||||||
Arrays.fill(framebuffer.getColors(), 0, 512 * 40 + 128, MapColors.COLOR_CYAN.baseColor());
|
|
||||||
Arrays.fill(framebuffer.getColors(), 512 * 40 + 128, framebuffer.getColors().length, MapColors.COLOR_RED.baseColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void graphics2DRendering(LargeGraphics2DFramebuffer framebuffer) {
|
|
||||||
Graphics2D renderer = framebuffer.getRenderer();
|
|
||||||
renderer.setColor(Color.BLACK);
|
|
||||||
renderer.clearRect(0, 0, 512, 512);
|
|
||||||
renderer.setColor(Color.WHITE);
|
|
||||||
renderer.drawString("Here's a very very long string that needs multiple maps to fit", 0, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
package net.minestom.demo.largeframebuffers;
|
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.GameMode;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.event.GlobalEventHandler;
|
|
||||||
import net.minestom.server.event.player.PlayerLoginEvent;
|
|
||||||
import net.minestom.server.event.player.PlayerSpawnEvent;
|
|
||||||
import net.minestom.server.instance.*;
|
|
||||||
import net.minestom.server.instance.batch.ChunkBatch;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MainDemo {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// Initialization
|
|
||||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
|
||||||
|
|
||||||
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
|
||||||
// Create the instance
|
|
||||||
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();
|
|
||||||
// Set the ChunkGenerator
|
|
||||||
instanceContainer.setChunkGenerator(new GeneratorDemo());
|
|
||||||
// Enable the auto chunk loading (when players come close)
|
|
||||||
instanceContainer.enableAutoChunkLoad(true);
|
|
||||||
|
|
||||||
// Add event listeners
|
|
||||||
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
|
||||||
// Set the spawning instance
|
|
||||||
globalEventHandler.addListener(PlayerLoginEvent.class, event -> {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
event.setSpawningInstance(instanceContainer);
|
|
||||||
player.setRespawnPoint(new Pos(0, 45, 0));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Teleport the player at spawn
|
|
||||||
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
player.teleport(new Pos(0, 45, 0));
|
|
||||||
player.setGameMode(GameMode.CREATIVE);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Start the server
|
|
||||||
minecraftServer.start("localhost", 25565);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GeneratorDemo implements ChunkGenerator {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generateChunkData(@NotNull ChunkBatch batch, int chunkX, int chunkZ) {
|
|
||||||
// Set chunk blocks
|
|
||||||
for (byte x = 0; x < Chunk.CHUNK_SIZE_X; x++)
|
|
||||||
for (byte z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
|
||||||
for (byte y = 0; y < 40; y++) {
|
|
||||||
batch.setBlock(x, y, z, Block.STONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ChunkPopulator> getPopulators() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
package net.minestom.demo.largeframebuffers;
|
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
import org.lwjgl.opengl.GLUtil;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.*;
|
|
||||||
|
|
||||||
public final class OpenGLRendering {
|
|
||||||
|
|
||||||
private static int vbo;
|
|
||||||
private static int indexBuffer;
|
|
||||||
private static final int VERTEX_SIZE = 5*4; // position + tex
|
|
||||||
|
|
||||||
// array of vertices (order: X,Y,Z, Tex U, Tex V)
|
|
||||||
private static float[] vertices = {
|
|
||||||
// front face
|
|
||||||
-1f, -1f, -1f, 0, 0,
|
|
||||||
1f, -1f, -1f, 1, 0,
|
|
||||||
1f, 1f, -1f, 1, 1,
|
|
||||||
-1f, 1f, -1f, 0, 1,
|
|
||||||
|
|
||||||
// back face
|
|
||||||
-1f, -1f, 1f, 0, 1,
|
|
||||||
1f, -1f, 1f, 1, 1,
|
|
||||||
1f, 1f, 1f, 1, 0,
|
|
||||||
-1f, 1f, 1f, 0, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
private static int[] indices = {
|
|
||||||
// south face
|
|
||||||
0,1,2,
|
|
||||||
2,3,0,
|
|
||||||
|
|
||||||
// north face
|
|
||||||
4,5,6,
|
|
||||||
6,7,4,
|
|
||||||
|
|
||||||
// west face
|
|
||||||
0,4,7,
|
|
||||||
7,3,0,
|
|
||||||
|
|
||||||
// east face
|
|
||||||
1,5,6,
|
|
||||||
6,2,1,
|
|
||||||
|
|
||||||
// top face
|
|
||||||
3, 2, 6,
|
|
||||||
6, 7, 3
|
|
||||||
};
|
|
||||||
private static int renderShader;
|
|
||||||
private static Matrix4f projectionMatrix;
|
|
||||||
private static Matrix4f viewMatrix;
|
|
||||||
private static Matrix4f modelMatrix;
|
|
||||||
private static int projectionUniform;
|
|
||||||
private static int viewUniform;
|
|
||||||
private static int modelUniform;
|
|
||||||
private static int boxTexture;
|
|
||||||
|
|
||||||
static void init() {
|
|
||||||
GLUtil.setupDebugMessageCallback();
|
|
||||||
|
|
||||||
boxTexture = loadTexture("box");
|
|
||||||
|
|
||||||
vbo = glGenBuffers();
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
indexBuffer = glGenBuffers();
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// prepare matrices and shader
|
|
||||||
renderShader = glCreateProgram();
|
|
||||||
projectionMatrix = new Matrix4f().setPerspective((float) (Math.PI/4f), 1f, 0.001f, 100f);
|
|
||||||
viewMatrix = new Matrix4f().setLookAt(5f, 5f, 5f, 0, 0, 0, 0, -1, 0);
|
|
||||||
modelMatrix = new Matrix4f().identity();
|
|
||||||
int vertexShader = createShader("/shaders/vertex.glsl", GL_VERTEX_SHADER);
|
|
||||||
int fragmentShader = createShader("/shaders/fragment.glsl", GL_FRAGMENT_SHADER);
|
|
||||||
glAttachShader(renderShader, vertexShader);
|
|
||||||
glAttachShader(renderShader, fragmentShader);
|
|
||||||
glLinkProgram(renderShader);
|
|
||||||
if(glGetProgrami(renderShader, GL_LINK_STATUS) == 0) {
|
|
||||||
System.err.println("Link error: "+glGetProgramInfoLog(renderShader));
|
|
||||||
}
|
|
||||||
|
|
||||||
projectionUniform = glGetUniformLocation(renderShader, "projection");
|
|
||||||
viewUniform = glGetUniformLocation(renderShader, "view");
|
|
||||||
modelUniform = glGetUniformLocation(renderShader, "model");
|
|
||||||
int boxUniform = glGetUniformLocation(renderShader, "box");
|
|
||||||
|
|
||||||
glUseProgram(renderShader); {
|
|
||||||
uploadMatrix(projectionUniform, projectionMatrix);
|
|
||||||
uploadMatrix(viewUniform, viewMatrix);
|
|
||||||
|
|
||||||
glUniform1i(boxUniform, 0); // texture unit 0
|
|
||||||
}
|
|
||||||
glUseProgram(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int loadTexture(String filename) {
|
|
||||||
int tex = glGenTextures();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
BufferedImage image;
|
|
||||||
try {
|
|
||||||
image = ImageIO.read(OpenGLRendering.class.getResourceAsStream("/textures/"+filename+".png"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException("Missing image "+filename, e);
|
|
||||||
}
|
|
||||||
ByteBuffer pixels = BufferUtils.createByteBuffer(image.getWidth()*image.getHeight()*4);
|
|
||||||
for (int y = 0; y < image.getHeight(); y++) {
|
|
||||||
for (int x = 0; x < image.getWidth(); x++) {
|
|
||||||
int rgb = image.getRGB(x, y);
|
|
||||||
int alpha = (rgb >> 24) & 0xFF;
|
|
||||||
int red = (rgb >> 16) & 0xFF;
|
|
||||||
int green = (rgb >> 8) & 0xFF;
|
|
||||||
int blue = rgb & 0xFF;
|
|
||||||
pixels.put((byte) red);
|
|
||||||
pixels.put((byte) green);
|
|
||||||
pixels.put((byte) blue);
|
|
||||||
pixels.put((byte) alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pixels.flip();
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
|
|
||||||
// closest neighbor required here, as pixels can have very different rgb values, and interpolation will break palette lookup
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void uploadMatrix(int uniform, Matrix4f matrix) {
|
|
||||||
float[] values = new float[4*4];
|
|
||||||
matrix.get(values);
|
|
||||||
glUniformMatrix4fv(uniform, false, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int createShader(String filename, int type) {
|
|
||||||
int shader = glCreateShader(type);
|
|
||||||
try(BufferedReader reader = new BufferedReader(new InputStreamReader(OpenGLRendering.class.getResourceAsStream(filename)))) {
|
|
||||||
String source = reader.lines().collect(Collectors.joining("\n"));
|
|
||||||
glShaderSource(shader, source);
|
|
||||||
glCompileShader(shader);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long lastTime = System.currentTimeMillis();
|
|
||||||
|
|
||||||
private static int frame = 0;
|
|
||||||
|
|
||||||
static void render() {
|
|
||||||
if(frame % 100 == 0) {
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
long dt = time-lastTime;
|
|
||||||
System.out.println(">> Render time for 100 frames: "+dt);
|
|
||||||
System.out.println(">> Average time per frame: "+(dt/100.0));
|
|
||||||
System.out.println(">> Average FPS: "+(1000.0/(dt/100.0)));
|
|
||||||
lastTime = time;
|
|
||||||
}
|
|
||||||
frame++;
|
|
||||||
|
|
||||||
|
|
||||||
glClearColor(0f, 0f, 0f, 1f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
modelMatrix.rotateY((float) (Math.PI/60f));
|
|
||||||
|
|
||||||
glUseProgram(renderShader); {
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, boxTexture);
|
|
||||||
|
|
||||||
uploadMatrix(modelUniform, modelMatrix);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, VERTEX_SIZE, 0); // position
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, false, VERTEX_SIZE, 3*4); // color
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
|
||||||
glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
||||||
glUseProgram(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package net.minestom.server.map;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class PaletteGenerator {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Int2IntMap colors = new Int2IntOpenHashMap();
|
|
||||||
int highestIndex = 0;
|
|
||||||
for(MapColors c : MapColors.values()) {
|
|
||||||
if (c == MapColors.NONE)
|
|
||||||
continue;
|
|
||||||
for(MapColors.Multiplier m : MapColors.Multiplier.values()) {
|
|
||||||
int index = ((int)m.apply(c)) & 0xFF;
|
|
||||||
if(index > highestIndex) {
|
|
||||||
highestIndex = index;
|
|
||||||
}
|
|
||||||
int rgb = MapColors.PreciseMapColor.toRGB(c, m);
|
|
||||||
colors.put(index, rgb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedImage paletteTexture = new BufferedImage(highestIndex+1, 1, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
for (int i = 0; i <= highestIndex; i++) {
|
|
||||||
int rgb = colors.getOrDefault(i, 0);
|
|
||||||
int argb = (0xFF << 24) | (rgb & 0xFFFFFF);
|
|
||||||
paletteTexture.setRGB(i, 0, argb);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ImageIO.write(paletteTexture, "png", new File("src/lwjgl/resources/textures/palette.png"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
package net.minestom.server.map.framebuffers;
|
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.map.Framebuffer;
|
|
||||||
import net.minestom.server.map.MapColors;
|
|
||||||
import net.minestom.server.timer.Task;
|
|
||||||
import net.minestom.server.utils.thread.ThreadBindingExecutor;
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
import org.lwjgl.PointerBuffer;
|
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
|
||||||
import org.lwjgl.opengl.GL;
|
|
||||||
import org.lwjgl.system.MemoryStack;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.temporal.TemporalUnit;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
|
||||||
|
|
||||||
public abstract class GLFWCapableBuffer {
|
|
||||||
|
|
||||||
protected final byte[] colors;
|
|
||||||
private final ByteBuffer pixels;
|
|
||||||
private final long glfwWindow;
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
private final ByteBuffer colorsBuffer;
|
|
||||||
private boolean onlyMapColors;
|
|
||||||
|
|
||||||
private static ThreadBindingExecutor threadBindingPool;
|
|
||||||
|
|
||||||
protected GLFWCapableBuffer(int width, int height) {
|
|
||||||
this(width, height, GLFW_NATIVE_CONTEXT_API, GLFW_OPENGL_API);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the framebuffer and initializes a new context
|
|
||||||
*/
|
|
||||||
protected GLFWCapableBuffer(int width, int height, int apiContext, int clientAPI) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
this.colors = new byte[width*height];
|
|
||||||
colorsBuffer = BufferUtils.createByteBuffer(width*height);
|
|
||||||
this.pixels = BufferUtils.createByteBuffer(width*height*4);
|
|
||||||
if(!glfwInit()) {
|
|
||||||
throw new RuntimeException("Failed to init GLFW");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWErrorCallback.createPrint().set();
|
|
||||||
glfwDefaultWindowHints();
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, apiContext);
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, clientAPI);
|
|
||||||
|
|
||||||
this.glfwWindow = glfwCreateWindow(width, height, "", 0L, 0L);
|
|
||||||
if(glfwWindow == 0L) {
|
|
||||||
try(var stack = MemoryStack.stackPush()) {
|
|
||||||
PointerBuffer desc = stack.mallocPointer(1);
|
|
||||||
int errcode = glfwGetError(desc);
|
|
||||||
throw new RuntimeException("("+errcode+") Failed to create GLFW Window.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(GLFWCapableBuffer.class) {
|
|
||||||
if(threadBindingPool == null) {
|
|
||||||
threadBindingPool = new ThreadBindingExecutor(Runtime.getRuntime().availableProcessors()/2,
|
|
||||||
"GLFWCapableBuffer-ThreadBindingPool");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GLFWCapableBuffer unbindContextFromThread() {
|
|
||||||
glfwMakeContextCurrent(0L);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changeRenderingThreadToCurrent() {
|
|
||||||
glfwMakeContextCurrent(glfwWindow);
|
|
||||||
GL.createCapabilities();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task setupRenderLoop(long period, TemporalUnit unit, Runnable rendering) {
|
|
||||||
return setupRenderLoop(Duration.of(period, unit), rendering);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task setupRenderLoop(Duration period, Runnable rendering) {
|
|
||||||
return MinecraftServer.getSchedulerManager()
|
|
||||||
.buildTask(new Runnable() {
|
|
||||||
private boolean first = true;
|
|
||||||
private final Runnable subAction = () -> {
|
|
||||||
if(first) {
|
|
||||||
changeRenderingThreadToCurrent();
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
render(rendering);
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
threadBindingPool.execute(subAction);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.repeat(period)
|
|
||||||
.schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(Runnable rendering) {
|
|
||||||
rendering.run();
|
|
||||||
glfwSwapBuffers(glfwWindow);
|
|
||||||
prepareMapColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called in render after glFlush to read the pixel buffer contents and convert it to map colors.
|
|
||||||
* Only call if you do not use {@link #render(Runnable)} nor {@link #setupRenderLoop}
|
|
||||||
*/
|
|
||||||
public void prepareMapColors() {
|
|
||||||
if(onlyMapColors) {
|
|
||||||
colorsBuffer.rewind();
|
|
||||||
glReadPixels(0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, colorsBuffer);
|
|
||||||
colorsBuffer.get(colors);
|
|
||||||
} else {
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
int i = Framebuffer.index(x, y, width)*4;
|
|
||||||
int red = pixels.get(i) & 0xFF;
|
|
||||||
int green = pixels.get(i+1) & 0xFF;
|
|
||||||
int blue = pixels.get(i+2) & 0xFF;
|
|
||||||
int alpha = pixels.get(i+3) & 0xFF;
|
|
||||||
int argb = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
||||||
colors[Framebuffer.index(x, y, width)] = MapColors.closestColor(argb).getIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup() {
|
|
||||||
glfwTerminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getGLFWWindow() {
|
|
||||||
return glfwWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int width() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int height() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tells this buffer that the **RED** channel contains the index of the map color to use.
|
|
||||||
*
|
|
||||||
* This allows for optimizations and fast rendering (because there is no need for a conversion)
|
|
||||||
*/
|
|
||||||
public void useMapColors() {
|
|
||||||
onlyMapColors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opposite to {@link #useMapColors()}
|
|
||||||
*/
|
|
||||||
public void useRGB() {
|
|
||||||
onlyMapColors = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package net.minestom.server.map.framebuffers;
|
|
||||||
|
|
||||||
import net.minestom.server.map.Framebuffer;
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_NATIVE_CONTEXT_API;
|
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_API;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GLFW-based framebuffer.
|
|
||||||
*
|
|
||||||
* Due to its interfacing with OpenGL(-ES), extra care needs to be applied when using this framebuffer.
|
|
||||||
* Rendering to this framebuffer should only be done via the thread on which the context is present.
|
|
||||||
* To perform map conversion at the end of a frame, it is advised to use {@link #render(Runnable)} to render to the map.
|
|
||||||
*
|
|
||||||
* Use {@link #changeRenderingThreadToCurrent} in a thread to switch the thread on which to render.
|
|
||||||
*
|
|
||||||
* Use {@link #setupRenderLoop} with a callback to setup a task in the {@link net.minestom.server.timer.SchedulerManager}
|
|
||||||
* to automatically render to the offscreen buffer on a specialized thread.
|
|
||||||
*
|
|
||||||
* GLFWFramebuffer does not provide guarantee that the result of {@link #toMapColors()} is synchronized with rendering, but
|
|
||||||
* it will be updated after each frame rendered through {@link #render(Runnable)} or {@link #setupRenderLoop(long, java.time.temporal.TemporalUnit, Runnable)}.
|
|
||||||
*
|
|
||||||
* This framebuffer is meant to render to a single map (ie it is only compatible with 128x128 rendering)
|
|
||||||
*/
|
|
||||||
public class GLFWFramebuffer extends GLFWCapableBuffer implements Framebuffer {
|
|
||||||
|
|
||||||
private final byte[] colors = new byte[WIDTH*HEIGHT];
|
|
||||||
private final ByteBuffer pixels = BufferUtils.createByteBuffer(WIDTH*HEIGHT*4);
|
|
||||||
|
|
||||||
public GLFWFramebuffer() {
|
|
||||||
this(GLFW_NATIVE_CONTEXT_API, GLFW_OPENGL_API);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the framebuffer and initializes a new context
|
|
||||||
*/
|
|
||||||
public GLFWFramebuffer(int apiContext, int clientAPI) {
|
|
||||||
super(WIDTH, HEIGHT, apiContext, clientAPI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] toMapColors() {
|
|
||||||
return colors;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package net.minestom.server.map.framebuffers;
|
|
||||||
|
|
||||||
import net.minestom.server.map.Framebuffer;
|
|
||||||
import net.minestom.server.map.LargeFramebuffer;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_NATIVE_CONTEXT_API;
|
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_API;
|
|
||||||
|
|
||||||
public class LargeGLFWFramebuffer extends GLFWCapableBuffer implements LargeFramebuffer {
|
|
||||||
public LargeGLFWFramebuffer(int width, int height) {
|
|
||||||
this(width, height, GLFW_NATIVE_CONTEXT_API, GLFW_OPENGL_API);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LargeGLFWFramebuffer(int width, int height, int apiContext, int clientAPI) {
|
|
||||||
super(width, height, apiContext, clientAPI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Framebuffer createSubView(int left, int top) {
|
|
||||||
return new LargeFramebufferDefaultView(this, left, top);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte getMapColor(int x, int y) {
|
|
||||||
return colors[Framebuffer.index(x, y, width())];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,257 +0,0 @@
|
||||||
package net.minestom.server.map.framebuffers;
|
|
||||||
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL30.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class designed to help OpenGL users to convert their RGB values to map colors inside a post processing pass
|
|
||||||
* with a shader provided by Minestom.
|
|
||||||
*
|
|
||||||
* When rendering to a {@link GLFWFramebuffer} or a {@link LargeGLFWFramebuffer}, wrap your rendering in a MapColorRenderer to render to the GLFW with map colors.
|
|
||||||
*
|
|
||||||
* {@link MapColorRenderer} sets up an OpenGL framebuffer with the size of the underlying framebuffer and renders to it.
|
|
||||||
* The initialization of the framebuffer is done in the constructor.
|
|
||||||
* Therefore, the constructor call should be done inside the thread linked to the OpenGL context. The context can
|
|
||||||
* be moved through {@link GLFWCapableBuffer#changeRenderingThreadToCurrent()} and {@link GLFWCapableBuffer#unbindContextFromThread()}
|
|
||||||
*
|
|
||||||
* <hr>
|
|
||||||
* Resources created in constructor are:
|
|
||||||
* <ul>
|
|
||||||
* <li>Framebuffer</li>
|
|
||||||
* <li>Color texture (if default fbo initialization chosen)</li>
|
|
||||||
* <li>Depth24 Stencil8 render buffer (if default fbo initialization chosen)</li>
|
|
||||||
* <li>Post processing shader program</li>
|
|
||||||
* <li>Palette texture</li>
|
|
||||||
* <li>Screen quad VAO</li>
|
|
||||||
* <li>Screen quad index buffer</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* The constructor also puts the given buffer in map color mode.
|
|
||||||
*/
|
|
||||||
public class MapColorRenderer implements Runnable {
|
|
||||||
|
|
||||||
private final int fboID;
|
|
||||||
private final GLFWCapableBuffer framebuffer;
|
|
||||||
private final Runnable renderCode;
|
|
||||||
private final int colorTextureID;
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
private final int renderShader;
|
|
||||||
private final int screenQuadIndices;
|
|
||||||
private int paletteTexture;
|
|
||||||
private float paletteSize;
|
|
||||||
private final int screenQuadVAO;
|
|
||||||
|
|
||||||
public MapColorRenderer(GLFWCapableBuffer framebuffer, Runnable renderCode) {
|
|
||||||
this(framebuffer, renderCode, MapColorRenderer.defaultFramebuffer(framebuffer.width(), framebuffer.height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public MapColorRenderer(GLFWCapableBuffer framebuffer, Runnable renderCode, FboInitialization fboInitialization) {
|
|
||||||
this.framebuffer = framebuffer;
|
|
||||||
this.framebuffer.useMapColors();
|
|
||||||
|
|
||||||
this.renderCode = renderCode;
|
|
||||||
this.width = framebuffer.width();
|
|
||||||
this.height = framebuffer.height();
|
|
||||||
|
|
||||||
this.fboID = glGenFramebuffers();
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
|
|
||||||
this.colorTextureID = fboInitialization.initFbo(fboID);
|
|
||||||
|
|
||||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
throw new RuntimeException("Framebuffer is not complete!");
|
|
||||||
}
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
|
|
||||||
// create post-process shader
|
|
||||||
this.renderShader = glCreateProgram();
|
|
||||||
int vertexShader = createShader("/shaders/mapcolorconvert.vertex.glsl", GL_VERTEX_SHADER);
|
|
||||||
int fragmentShader = createShader("/shaders/mapcolorconvert.fragment.glsl", GL_FRAGMENT_SHADER);
|
|
||||||
glAttachShader(renderShader, vertexShader);
|
|
||||||
glAttachShader(renderShader, fragmentShader);
|
|
||||||
glLinkProgram(renderShader);
|
|
||||||
if(glGetProgrami(renderShader, GL_LINK_STATUS) == 0) {
|
|
||||||
throw new RuntimeException("Link error: "+glGetProgramInfoLog(renderShader));
|
|
||||||
}
|
|
||||||
|
|
||||||
loadPalette("palette");
|
|
||||||
|
|
||||||
// create screen quad VAO
|
|
||||||
screenQuadVAO = glGenBuffers();
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, screenQuadVAO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, new float[] {
|
|
||||||
-1f, -1f,
|
|
||||||
1f, -1f,
|
|
||||||
1f, 1f,
|
|
||||||
-1f, 1f
|
|
||||||
}, GL_STATIC_DRAW);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
screenQuadIndices = glGenBuffers();
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuadIndices);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, new int[] {0,1,2, 2,3,0}, GL_STATIC_DRAW);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
int paletteSizeUniform = glGetUniformLocation(renderShader, "paletteSize");
|
|
||||||
int paletteUniform = glGetUniformLocation(renderShader, "palette");
|
|
||||||
int frameUniform = glGetUniformLocation(renderShader, "frame");
|
|
||||||
|
|
||||||
glUseProgram(renderShader); {
|
|
||||||
glUniform1i(frameUniform, 0); // texture unit 0
|
|
||||||
glUniform1i(paletteUniform, 1); // texture unit 1
|
|
||||||
glUniform1f(paletteSizeUniform, paletteSize);
|
|
||||||
}
|
|
||||||
glUseProgram(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FboInitialization defaultFramebuffer(int width, int height) {
|
|
||||||
return fboId -> defaultFramebufferInit(fboId, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int defaultFramebufferInit(int fbo, int width, int height) {
|
|
||||||
// color
|
|
||||||
int colorTexture = glGenTextures();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, colorTexture);
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0L);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
// attach to framebuffer
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
// depth
|
|
||||||
int depthStencilBuffer = glGenRenderbuffers();
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilBuffer);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
||||||
return colorTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
// run user code inside of framebuffer
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
|
|
||||||
renderCode.run();
|
|
||||||
|
|
||||||
// run post processing to display on screen
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
glClearColor(0f, 0f, 0f, 1f); // 0 on RED channel makes maps use NONE
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, colorTextureID);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, paletteTexture);
|
|
||||||
|
|
||||||
glUseProgram(renderShader); {
|
|
||||||
// render post processing quad
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, screenQuadVAO);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2*4, 0); // position
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, screenQuadIndices);
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glUseProgram(0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees OpenGL resources used by this renderer.
|
|
||||||
* You should NOT render with this renderer after this call.
|
|
||||||
*/
|
|
||||||
public void cleanupResources() {
|
|
||||||
glDeleteFramebuffers(fboID);
|
|
||||||
glDeleteProgram(renderShader);
|
|
||||||
glDeleteTextures(paletteTexture);
|
|
||||||
// TODO: more cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadPalette(String filename) {
|
|
||||||
int tex = glGenTextures();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
|
||||||
BufferedImage image;
|
|
||||||
try {
|
|
||||||
image = ImageIO.read(MapColorRenderer.class.getResourceAsStream("/textures/"+filename+".png"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException("Missing image "+filename, e);
|
|
||||||
}
|
|
||||||
ByteBuffer pixels = BufferUtils.createByteBuffer(image.getWidth()*image.getHeight()*4);
|
|
||||||
for (int y = 0; y < image.getHeight(); y++) {
|
|
||||||
for (int x = 0; x < image.getWidth(); x++) {
|
|
||||||
int rgb = image.getRGB(x, y);
|
|
||||||
int alpha = (rgb >> 24) & 0xFF;
|
|
||||||
int red = (rgb >> 16) & 0xFF;
|
|
||||||
int green = (rgb >> 8) & 0xFF;
|
|
||||||
int blue = rgb & 0xFF;
|
|
||||||
pixels.put((byte) red);
|
|
||||||
pixels.put((byte) green);
|
|
||||||
pixels.put((byte) blue);
|
|
||||||
pixels.put((byte) alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pixels.flip();
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
|
|
||||||
// closest neighbor required here, as pixels can have very different rgb values, and interpolation will break palette lookup
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
this.paletteTexture = tex;
|
|
||||||
this.paletteSize = image.getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int createShader(String filename, int type) {
|
|
||||||
int shader = glCreateShader(type);
|
|
||||||
try(BufferedReader reader = new BufferedReader(new InputStreamReader(MapColorRenderer.class.getResourceAsStream(filename)))) {
|
|
||||||
String source = reader.lines().collect(Collectors.joining("\n"));
|
|
||||||
glShaderSource(shader, source);
|
|
||||||
glCompileShader(shader);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface FboInitialization {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the given framebuffer
|
|
||||||
* @param fboId
|
|
||||||
* @return the texture ID of the color texture, used for post processing.
|
|
||||||
*/
|
|
||||||
int initFbo(int fboId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
in vec2 uv;
|
|
||||||
|
|
||||||
out vec4 fragColor;
|
|
||||||
|
|
||||||
uniform sampler2D box;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec3 vertexColor = texture(box, uv).rgb;
|
|
||||||
fragColor = vec4(vertexColor, 1.0);
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
in vec2 fragCoords;
|
|
||||||
out vec4 fragColor;
|
|
||||||
|
|
||||||
uniform sampler2D frame;
|
|
||||||
uniform sampler2D palette;
|
|
||||||
uniform float paletteSize;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 uv = fragCoords;
|
|
||||||
uv.y = -uv.y;
|
|
||||||
vec3 fragmentColor = texture(frame, uv).rgb;
|
|
||||||
|
|
||||||
// render in map colors
|
|
||||||
int closest = 0;
|
|
||||||
uint closestDistance = uint(2147483647);
|
|
||||||
for(int i = 4; i < paletteSize; i++) {
|
|
||||||
vec3 mapColor = texture(palette, vec2((i+0.5f)/paletteSize, 0.0)).rgb;
|
|
||||||
int dr = int((mapColor.r - fragmentColor.r)*255);
|
|
||||||
int dg = int((mapColor.g - fragmentColor.g)*255);
|
|
||||||
int db = int((mapColor.b - fragmentColor.b)*255);
|
|
||||||
|
|
||||||
uint d = uint(dr*dr)+uint(dg*dg)+uint(db*db);
|
|
||||||
if(d < closestDistance) {
|
|
||||||
closestDistance = d;
|
|
||||||
closest = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragColor = vec4(closest/255.0, closest/255.0, closest/255.0, 1.0);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 pos;
|
|
||||||
|
|
||||||
out vec2 fragCoords;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
fragCoords = (pos+vec2(1.0))/2.0;
|
|
||||||
gl_Position = vec4(pos, 0.0, 1.0);
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 pos;
|
|
||||||
layout(location = 1) in vec2 texCoords;
|
|
||||||
|
|
||||||
out vec2 uv;
|
|
||||||
|
|
||||||
uniform mat4 projection;
|
|
||||||
uniform mat4 view;
|
|
||||||
uniform mat4 model;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
mat4 mvp = projection * view * model;
|
|
||||||
uv = texCoords;
|
|
||||||
gl_Position = mvp * vec4(pos, 1.0);
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 274 B |
Binary file not shown.
Before Width: | Height: | Size: 876 B |
|
@ -65,6 +65,12 @@ public final class PFBlock implements IBlockDescription, IBlockObject {
|
||||||
return block.namespace().asString().endsWith("door");
|
return block.namespace().asString().endsWith("door");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIntractable() {
|
||||||
|
// TODO: Interactability of blocks.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isImpeding() {
|
public boolean isImpeding() {
|
||||||
return block.isSolid();
|
return block.isSolid();
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Configuration status="WARN" strict="true" name="Minestom">
|
|
||||||
<Appenders>
|
|
||||||
<Appender type="Console" name="STDOUT">
|
|
||||||
<Layout type="PatternLayout" pattern="[%t] [%d{HH:mm:ss}] - %p - %m%n"/>
|
|
||||||
</Appender>
|
|
||||||
<Appender type="Console" name="STDOUT-WithCaller">
|
|
||||||
<Layout type="PatternLayout" pattern="[%t] [%d{HH:mm:ss}] (%C{1}.%M) - %p - %m%n"/>
|
|
||||||
</Appender>
|
|
||||||
</Appenders>
|
|
||||||
|
|
||||||
<Loggers>
|
|
||||||
<Root level="info">
|
|
||||||
<AppenderRef ref="STDOUT-WithCaller" level="info"/>
|
|
||||||
</Root>
|
|
||||||
</Loggers>
|
|
||||||
</Configuration>
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
autoshutdown=true
|
||||||
|
writer=console
|
||||||
|
writer.level=info
|
||||||
|
writer.format=[{thread}] [{date: HH:mm:ss}] ({class-name}.{method}) - {level} - {message}
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"entrypoint": "improveextensions.unloadcallbacks.UnloadCallbacksExtension",
|
|
||||||
"name": "UnloadCallbacksExtension"
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"entrypoint": "improveextensions.unloadextensiononstop.UnloadExtensionOnStop",
|
|
||||||
"name": "UnloadExtensionOnStop"
|
|
||||||
}
|
|
Loading…
Reference in New Issue