Initial work to update to 1.16.4

This commit is contained in:
James Seibel
2021-02-21 08:31:03 -06:00
parent 36c0244047
commit f754467450
56 changed files with 2651 additions and 1165 deletions
+5
View File
@@ -0,0 +1,5 @@
# Disable autocrlf on generated files, they always generate with LF
# Add any extra files or paths here to make git stop saying they
# are changed when only line endings change.
src/generated/**/.cache/cache text eol=lf
src/generated/**/*.json text eol=lf
+3 -4
View File
@@ -19,8 +19,7 @@ build
# other
eclipse
run
# minecraft run folder,
# ignore everything but the mods folder
run/*
!run/mods
# Files from Forge MDK
forge*changelog.txt
-4
View File
@@ -1,4 +0,0 @@
[submodule "ASMHelper"]
path = ASMHelper
url = https://github.com/squeek502/ASMHelper.git
branch = 1.12.x
+1 -1
View File
@@ -10,7 +10,7 @@ alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptian
of me taking over the project, who knows what Minecraft modding would be today.
Secondly, someone who has worked with me, and developed some of the core features
that allow modding to he as functional, and as simple as it is, cpw. For developing
that allow modding to be as functional, and as simple as it is, cpw. For developing
FML, which stabelized the client and server modding ecosystem. As well as the base
loading system that allows us to modify Minecraft's code as elegently as possible.
-10
View File
@@ -1,10 +0,0 @@
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,40 +0,0 @@
SoundSystem CodecIBXM Class License:
You are free to use this class for any purpose, commercial or otherwise.
You may modify this class or source code, and distribute it any way you
like, provided the following conditions are met:
1) You may not falsely claim to be the author of this class or any
unmodified portion of it.
2) You may not copyright this class or a modified version of it and then
sue me for copyright infringement.
3) If you modify the source code, you must clearly document the changes
made before redistributing the modified source code, so other users know
it is not the original code.
4) You are not required to give me credit for this class in any derived
work, but if you do, you must also mention my website:
http://www.paulscode.com
5) I the author will not be responsible for any damages (physical,
financial, or otherwise) caused by the use if this class or any
portion of it.
6) I the author do not guarantee, warrant, or make any representations,
either expressed or implied, regarding the use of this class or any
portion of it.
Author: Paul Lamb
http://www.paulscode.com
This software is based on or using the IBXM library available from
http://www.geocities.com/sunet2000/
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+2 -8
View File
@@ -3,8 +3,8 @@ parts herein are licensed under the terms of the LGPL 2.1 found
here http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt and
copied below.
Homepage: http://MinecraftForge.net/
http://github.com/MinecraftForge/MinecraftForge
Homepage: http://minecraftforge.net/
https://github.com/MinecraftForge/MinecraftForge
A note on authorship:
@@ -57,12 +57,6 @@ This software contains a partial repackaging of javaxdelta, a BSD licensed progr
binary differences and applying them, sourced from the subversion at http://sourceforge.net/projects/javaxdelta/
authored by genman, heikok, pivot.
The only changes are to replace some Trove collection types with standard Java collections, and repackaged.
This software contains potions of Paulscodee IBXM library, a BSD liceensed library for
loading and playing IBXM formated auto. No modifications havee beeen made. The associated
licenses can be found along side this one, or at
https://github.com/MinecraftForge/MinecraftForge/blob/1.12.x/LICENSE-Paulscode%20IBXM%20Library.txt
https://github.com/MinecraftForge/MinecraftForge/blob/1.12.x/LICENSE-Paulscode%20SoundSystem%20CodecIBXM.txt
=========================================================================
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
these are tools needed for looking at obfuscated minecraft code.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
these are tools needed for deobfuscating and looking at the code of optifine.
-3
View File
@@ -1,3 +0,0 @@
java -jar ./simpledeobf-0.6.jar --input ./OptiFine_1.12.2_HD_U_F5.jar --output ./OptiFine_1.12.2_HD_U_F5_dev.jar --mapFile C:/Users/James_Seibel/.gradle/caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/20171003/1.12.2/srgs/notch-mcp.srg --ref C:/Users/James_Seibel/.gradle/caches/minecraft/net/minecraft/minecraft/1.12.2/minecraft-1.12.2.jar
pause
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
./gradlew build
+135 -50
View File
@@ -1,77 +1,162 @@
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
maven { url = "https://files.minecraftforge.net/maven" }
mavenCentral()
maven { url='https://dist.creeper.host/Sponge/maven' }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
version = '1.0'
group = 'com.backsun.lod'
archivesBaseName = 'lod'
version = "1.0"
group = "com.backsun.lod" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "lod"
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
}
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft {
version = "1.12.2-14.23.5.2847"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "snapshot_20171003"
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'snapshot', version: '20201028-1.16.3'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'lod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods {
examplemod {
source sourceSets.main
}
}
}
}
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
dependencies {
// you may put jars on which you depend on in ./libs
// or you may define them like so..
//compile "some.group:artifact:version:classifier"
//compile "some.group:artifact:version"
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.16.4-35.1.4'
// real examples
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
// except that these dependencies get remapped to your current MCP mappings
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// for more info...
// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "Levels of Detail",
"Specification-Vendor": "examplemodsareus",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "${version}",
"Implementation-Vendor" :"examplemodsareus",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "lod.mixins.json",
])
}
}
// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
repositories {
maven {
url "file:///${project.projectDir}/mcmodsrepo"
}
}
}
mixin {
add sourceSets.main, "lod.refmap.json"
}
+165
View File
@@ -0,0 +1,165 @@
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
maven { url='https://dist.creeper.host/Sponge/maven' }
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
version = '1.0'
group = 'com.backsun.lod'
archivesBaseName = 'lod'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'snapshot', version: '20201028-1.16.3'
minecraft {
mappings = 'snapshot_20210218'
}
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
server {
workingDirectory project.file('run')
arg "-mixin.config=lod.mixins.json"
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
mods {
examplemod {
source sourceSets.main
}
}
}
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
args '--mod', 'lod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods {
examplemod {
source sourceSets.main
}
}
}
}
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.16.4-35.1.36'
// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"
// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "Levels of Detail",
"Specification-Vendor": "examplemodsareus",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "${version}",
"Implementation-Vendor" :"examplemodsareus",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs": "lod.mixins.json",
])
}
}
// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
repositories {
maven {
url "file:///${project.projectDir}/mcmodsrepo"
}
}
}
mixin {
add sourceSets.main, "lod.refmap.json"
}
+1523 -326
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1,3 +1,4 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Mon Sep 14 12:28:28 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
Vendored
+59 -51
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -6,47 +6,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
+4 -10
View File
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_MC_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
Binary file not shown.
Binary file not shown.
View File
View File
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
include ":ASMHelper"
+36 -28
View File
@@ -1,53 +1,61 @@
package com.backsun.lod;
import com.backsun.lod.proxy.ClientProxy;
import com.backsun.lod.proxy.CommonProxy;
import com.backsun.lod.util.Reference;
import com.backsun.lod.util.LodConfig;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
/**
*
* @author James Seibel
* @version 02-07-2021
*/
@IFMLLoadingPlugin.MCVersion("1.12.2")
@IFMLLoadingPlugin.TransformerExclusions({"com.backsun.lod.asm"})
@Mod(modid = Reference.MOD_ID, name = Reference.NAME, version = Reference.VERSION, dependencies = "required-after:lodcore@[1.0,)")
@Mod(ModInfo.MODID)
public class LodMain
{
@Instance
public static LodMain instance;
@SidedProxy(clientSide = Reference.CLIENT_PROXY_CLASS, serverSide = Reference.COMMON_PROXY_CLASS)
public static CommonProxy common_proxy;
public static ClientProxy client_proxy;
@EventHandler
public static void PreInit(FMLPreInitializationEvent event)
private void init(final FMLCommonSetupEvent event)
{
Minecraft.getMinecraft().getFramebuffer().enableStencil();
Minecraft.getInstance().getFramebuffer().enableStencil();
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, LodConfig.COMMON_SPEC);
}
@EventHandler
public static void Init(FMLInitializationEvent event)
{
MinecraftForge.EVENT_BUS.register(common_proxy);
client_proxy = new ClientProxy();
}
@EventHandler
public static void PostInit(FMLPostInitializationEvent event)
{
public LodMain()
{
// Register the methods
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init);
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onClientStart);
// Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this);
}
private void onClientStart(final FMLClientSetupEvent event)
{
client_proxy = new ClientProxy();
MinecraftForge.EVENT_BUS.register(client_proxy);
}
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event)
{
// this is called when the server starts
}
}
}
@@ -0,0 +1,16 @@
package com.backsun.lod;
/**
* This file is similar to mcmod.info
*
* @author James Seibel
* @version 02-17-2021
*/
public final class ModInfo
{
public static final String MODID = "lod";
public static final String MODNAME = "Levels of Detail";
public static final String MODAPI = "LodAPI";
public static final String VERSION = "${version}";
public static final String APIVERSION = "${apiversion}";
}
@@ -0,0 +1,20 @@
package com.backsun.lod.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.util.DamageSource;
@Mixin(ItemEntity.class)
public class MixinItemEntity
{
@Inject(at = @At("HEAD"), method = "attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z", cancellable = true)
private void attackEntityFrom(DamageSource source, float amount, CallbackInfoReturnable<Boolean> callback)
{
callback.setReturnValue(false);
}
}
@@ -0,0 +1,22 @@
package com.backsun.lod.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.backsun.lod.renderer.RenderGlobalHook;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.WorldRenderer;
@Mixin(WorldRenderer.class)
public class MixinWorldRenderer
{
@Inject(at = @At("HEAD"), method = "renderBlockLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/matrix/MatrixStack;DDD)V", cancellable = false)
private void renderBlockLayer(RenderType blockLayerIn, MatrixStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback)
{
RenderGlobalHook.startRenderingStencil(blockLayerIn);
}
}
@@ -5,13 +5,13 @@ import java.awt.Color;
import com.backsun.lod.util.enums.ColorDirection;
import com.backsun.lod.util.enums.LodLocation;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.chunk.ChunkSection;
/**
* This object contains position
@@ -33,8 +33,6 @@ public class LodChunk
private static final int CHUNK_DATA_WIDTH = WIDTH;
private static final int CHUNK_DATA_HEIGHT = WIDTH;
private final int airBlockId = Block.getIdFromBlock(Block.getBlockFromName("air"));
private final int waterBlockId = Block.getIdFromBlock(Block.getBlockFromName("water"));
private final int waterColor = colorToInt(new Color(36, 50, 171));
/**
@@ -220,8 +218,8 @@ public class LodChunk
}
x = chunk.x;
z = chunk.z;
x = chunk.getPos().x;
z = chunk.getPos().z;
top = new short[4];
bottom = new short[4];
@@ -261,7 +259,7 @@ public class LodChunk
// should have a length of 16
// (each storage is 16x16x16 and the
// world height is 256)
ExtendedBlockStorage[] data = chunk.getBlockStorageArray();
ChunkSection[] chunkSections = chunk.getSections();
@@ -314,20 +312,20 @@ public class LodChunk
if(getTopSection)
return determineTopPoint(data, startX, endX, startZ, endZ);
return determineTopPoint(chunkSections, startX, endX, startZ, endZ);
else
return determineBottomPoint(data, startX, endX, startZ, endZ);
return determineBottomPoint(chunkSections, startX, endX, startZ, endZ);
}
private short determineBottomPoint(ExtendedBlockStorage[] data, int startX, int endX, int startZ, int endZ)
private short determineBottomPoint(ChunkSection[] chunkSections, int startX, int endX, int startZ, int endZ)
{
// search from the bottom up
for(int i = 0; i < data.length; i++)
for(int i = 0; i < chunkSections.length; i++)
{
for(int y = 0; y < CHUNK_DATA_HEIGHT; y++)
{
if(isLayerValidLodPoint(data, startX, endX, startZ, endZ, i, y))
if(isLayerValidLodPoint(chunkSections, startX, endX, startZ, endZ, i, y))
{
// we found
// enough blocks in this
@@ -344,14 +342,14 @@ public class LodChunk
return -1;
}
private short determineTopPoint(ExtendedBlockStorage[] data, int startX, int endX, int startZ, int endZ)
private short determineTopPoint(ChunkSection[] chunkSections, int startX, int endX, int startZ, int endZ)
{
// search from the top down
for(int i = data.length - 1; i >= 0; i--)
for(int i = chunkSections.length - 1; i >= 0; i--)
{
for(int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--)
{
if(isLayerValidLodPoint(data, startX, endX, startZ, endZ, i, y))
if(isLayerValidLodPoint(chunkSections, startX, endX, startZ, endZ, i, y))
{
// we found
// enough blocks in this
@@ -373,10 +371,10 @@ public class LodChunk
* values a valid LOD point?
*/
private boolean isLayerValidLodPoint(
ExtendedBlockStorage[] data,
ChunkSection[] chunkSections,
int startX, int endX,
int startZ, int endZ,
int dataIndex, int y)
int sectionIndex, int y)
{
// search through this layer
int layerBlocks = 0;
@@ -385,7 +383,7 @@ public class LodChunk
{
for(int z = startZ; z < endZ; z++)
{
if(data[dataIndex] == null)
if(chunkSections[sectionIndex] == null)
{
// this section doesn't have any blocks,
// it is not a valid section
@@ -393,7 +391,7 @@ public class LodChunk
}
else
{
if(data[dataIndex].get(x, y, z) != null && Block.getIdFromBlock(data[dataIndex].get(x, y, z).getBlock()) != airBlockId)
if(chunkSections[sectionIndex].getBlockState(x, y, z) != null && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR)
{
// we found a valid block in
// in this layer
@@ -416,7 +414,7 @@ public class LodChunk
private Color generateLodColorSection(Chunk chunk, World world, ColorDirection colorDir)
{
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
BlockColors bc = mc.getBlockColors();
switch (colorDir)
@@ -445,7 +443,7 @@ public class LodChunk
*/
private Color generateLodColorVertical(Chunk chunk, ColorDirection colorDir, World world, BlockColors bc)
{
ExtendedBlockStorage[] data = chunk.getBlockStorageArray();
ChunkSection[] chunkSections = chunk.getSections();
int numbOfBlocks = 0;
int red = 0;
@@ -456,8 +454,8 @@ public class LodChunk
// either go top down or bottom up
int dataStart = goTopDown? data.length - 1 : 0;
int dataMax = data.length;
int dataStart = goTopDown? chunkSections.length - 1 : 0;
int dataMax = chunkSections.length;
int dataMin = 0;
int dataIncrement = goTopDown? -1 : 1;
@@ -472,18 +470,18 @@ public class LodChunk
{
boolean foundBlock = false;
for(int di = dataStart; !foundBlock && di >= dataMin && di < dataMax; di += dataIncrement)
for(int i = dataStart; !foundBlock && i >= dataMin && i < dataMax; i += dataIncrement)
{
if(!foundBlock && data[di] != null)
if(!foundBlock && chunkSections[i] != null)
{
for(int y = topStart; !foundBlock && y >= topMin && y < topMax; y += topIncrement)
{
int ci;
if(Block.getIdFromBlock(data[di].get(x, y, z).getBlock()) == waterBlockId)
if(chunkSections[i].getBlockState(x, y, z).getBlock() == Blocks.WATER)
// this is a special case since getColor on water generally returns white
ci = waterColor;
else
ci = bc.getColor(data[di].get(x, y, z), world, new BlockPos(x,y,z));
ci = bc.getColor(chunkSections[i].getBlockState(x, y, z), null, new BlockPos(x,y,z), 0);
if(ci == 0)
{
@@ -522,7 +520,7 @@ public class LodChunk
private Color generateLodColorHorizontal(Chunk chunk, ColorDirection colorDir, World world, BlockColors bc)
{
ExtendedBlockStorage[] data = chunk.getBlockStorageArray();
ChunkSection[] chunkSections = chunk.getSections();
int numbOfBlocks = 0;
int red = 0;
@@ -563,9 +561,9 @@ public class LodChunk
}
for (int di = 0; di < data.length; di++)
for (int i = 0; i < chunkSections.length; i++)
{
if (data[di] != null)
if (chunkSections[i] != null)
{
for (int y = 0; y < CHUNK_DATA_HEIGHT; y++)
{
@@ -607,11 +605,11 @@ public class LodChunk
}
int ci;
if(Block.getIdFromBlock(data[di].get(x, y, z).getBlock()) == waterBlockId)
if(chunkSections[i].getBlockState(x, y, z).getBlock() == Blocks.WATER)
// this is a special case since getColor on water generally returns white
ci = waterColor;
else
ci = bc.getColor(data[di].get(x, y, z), world, new BlockPos(x,y,z));
ci = bc.getColor(chunkSections[i].getBlockState(x, y, z), null, new BlockPos(x,y,z), 0);
if (ci == 0) {
// skip air or invisible blocks
@@ -2,7 +2,6 @@ package com.backsun.lod.objects;
import com.backsun.lod.util.LodFileHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.world.DimensionType;
/**
@@ -33,7 +32,7 @@ public class LodDimension
width = newMaxWidth;
// dimension 0 works here since we are just looking for the save handler anyway
rfHandler = new LodFileHandler(Minecraft.getMinecraft().getIntegratedServer().getWorld(0).getSaveHandler(), this);
rfHandler = new LodFileHandler(this);
regions = new LodRegion[width][width];
isRegionDirty = new boolean[width][width];
@@ -4,6 +4,8 @@ import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import net.minecraft.world.DimensionType;
/**
* This stores all LODs for a given world.
*
@@ -17,31 +19,31 @@ public class LodWorld
/**
* Key = Dimension id (as an int)
*/
private Dictionary<Integer, LodDimension> lodDimensions;
private Dictionary<DimensionType, LodDimension> lodDimensions;
public LodWorld(String newWorldName)
{
worldName = newWorldName;
lodDimensions = new Hashtable<Integer, LodDimension>();
lodDimensions = new Hashtable<>();
}
public void addLodDimension(LodDimension newStorage)
{
lodDimensions.put(newStorage.dimension.getId(), newStorage);
lodDimensions.put(newStorage.dimension, newStorage);
}
public LodDimension getLodDimension(int dimensionId)
public LodDimension getLodDimension(DimensionType dimension)
{
return lodDimensions.get(dimensionId);
return lodDimensions.get(dimension);
}
public void resizeDimensionRegionWidth(int newWidth)
{
Enumeration<Integer> keys = lodDimensions.keys();
Enumeration<DimensionType> keys = lodDimensions.keys();
while(keys.hasMoreElements())
lodDimensions.get(keys.nextElement()).setRegionWidth(newWidth);
@@ -10,23 +10,21 @@ import com.backsun.lod.objects.LodDimension;
import com.backsun.lod.objects.LodRegion;
import com.backsun.lod.objects.LodWorld;
import com.backsun.lod.renderer.LodRenderer;
import com.backsun.lod.renderer.RenderGlobalHook;
import com.backsun.lod.util.LodConfig;
import com.backsun.lod.util.LodFileHandler;
import com.backsun.lodCore.util.RenderGlobalHook;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
//TODO Find a way to replace getIntegratedServer so this mod could be used on non-local worlds.
// Minecraft.getMinecraft().getIntegratedServer()
// Minecraft.getInstance().getIntegratedServer()
/**
* This is used by the client.
@@ -34,11 +32,12 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
* @author James_Seibel
* @version 01-31-2021
*/
public class ClientProxy extends CommonProxy
public class ClientProxy
{
private LodRenderer renderer;
private LodWorld lodWorld;
private ExecutorService lodGenThreadPool = Executors.newFixedThreadPool(1);
Minecraft mc = Minecraft.getInstance();
/** Default size of any LOD regions we use */
private int regionWidth = 5;
@@ -61,7 +60,7 @@ public class ClientProxy extends CommonProxy
RenderGlobalHook.endRenderingStencil();
GL11.glStencilFunc(GL11.GL_EQUAL, 0, 0xFF);
if (LodConfig.drawLODs)
if (LodConfig.COMMON.drawLODs.get())
renderLods(event.getPartialTicks());
GL11.glDisable(GL11.GL_STENCIL_TEST);
@@ -69,7 +68,7 @@ public class ClientProxy extends CommonProxy
public void renderLods(float partialTicks)
{
int newWidth = Math.max(4, (Minecraft.getMinecraft().gameSettings.renderDistanceChunks * LodChunk.WIDTH * 2) / LodRegion.SIZE);
int newWidth = Math.max(4, (mc.gameSettings.renderDistanceChunks * LodChunk.WIDTH * 2) / LodRegion.SIZE);
if (lodWorld != null && regionWidth != newWidth)
{
lodWorld.resizeDimensionRegionWidth(newWidth);
@@ -80,18 +79,18 @@ public class ClientProxy extends CommonProxy
return;
}
Minecraft mc = Minecraft.getMinecraft();
if (mc == null || mc.player == null || lodWorld == null)
return;
int dimId = mc.player.dimension;
LodDimension lodDim = lodWorld.getLodDimension(dimId);
LodDimension lodDim = lodWorld.getLodDimension(mc.player.world.getDimensionType());
if (lodDim == null)
return;
mc.getProfiler().endSection();
mc.getProfiler().startSection("LOD");
double playerX = mc.player.posX;
double playerZ = mc.player.posZ;
double playerX = mc.player.getPosX();
double playerZ = mc.player.getPosZ();
int xOffset = ((int)playerX / (LodChunk.WIDTH * LodRegion.SIZE)) - lodDim.getCenterX();
int zOffset = ((int)playerZ / (LodChunk.WIDTH * LodRegion.SIZE)) - lodDim.getCenterZ();
@@ -112,8 +111,11 @@ public class ClientProxy extends CommonProxy
}
else
{
renderer.drawLODs(lodDim, partialTicks);
renderer.drawLODs(lodDim, partialTicks, mc.getProfiler());
}
// end of profiler tracking
mc.getProfiler().endSection();
}
@@ -128,62 +130,35 @@ public class ClientProxy extends CommonProxy
//===============//
@SubscribeEvent
public void chunkLoadEvent(ChunkEvent event)
public void chunkLoadEvent(ChunkEvent.Load event)
{
generateLodChunk(event.getChunk());
}
/**
* this event is called whenever a chunk is created for the first time.
*/
@SubscribeEvent
public void onChunkPopulate(PopulateChunkEvent event)
{
Minecraft mc = Minecraft.getMinecraft();
if (mc != null && event != null)
{
WorldClient world = mc.world;
World world = mc.world;
if(world != null)
{
generateLodChunk(world.getChunkFromChunkCoords(event.getChunkX(), event.getChunkZ()));
generateLodChunk((Chunk)event.getChunk());
}
}
}
/*
*
Use this for generating chunks and maybe determining if they are loaded at all?
Could I create my own chunk generator and multithread it? It wouldn't save to the world, but could I save it for LODs?
chunk = Minecraft.getMinecraft().getIntegratedServer().getWorld(0).getChunkProvider().chunkGenerator.generateChunk(chunk.x, chunk.z);
System.out.println(chunk.x + " " + chunk.z + "\tloaded: " + chunk.isLoaded() + "\tpop: " + chunk.isPopulated() + "\tter pop: " + chunk.isTerrainPopulated());
*/
private void generateLodChunk(Chunk chunk)
{
Minecraft mc = Minecraft.getMinecraft();
// don't try to create an LOD object
// if for some reason we aren't
// given a valid chunk object
// (Minecraft often gives back empty
// or null chunks in this method)
if (chunk == null || !isValidChunk(chunk))
return;
int dimId = chunk.getWorld().provider.getDimension();
World world = mc.getIntegratedServer().getWorld(dimId);
if (world == null)
if (chunk == null || chunk.getWorld() == null || !isValidChunk(chunk))
return;
Thread thread = new Thread(() ->
{
try
{
DimensionType dim = chunk.getWorldForge().getDimensionType();
World world = chunk.getWorld();
LodChunk lod = new LodChunk(chunk, world);
LodDimension lodDim;
@@ -208,15 +183,14 @@ public class ClientProxy extends CommonProxy
}
if (lodWorld.getLodDimension(dimId) == null)
if (lodWorld.getLodDimension(dim) == null)
{
DimensionType dim = DimensionType.getById(dimId);
lodDim = new LodDimension(dim, regionWidth);
lodWorld.addLodDimension(lodDim);
}
else
{
lodDim = lodWorld.getLodDimension(dimId);
lodDim = lodWorld.getLodDimension(dim);
}
lodDim.addLod(lod);
@@ -239,11 +213,11 @@ public class ClientProxy extends CommonProxy
*/
private boolean isValidChunk(Chunk chunk)
{
ExtendedBlockStorage[] data = chunk.getBlockStorageArray();
ChunkSection[] sections = chunk.getSections();
for(ExtendedBlockStorage e : data)
for(ChunkSection section : sections)
{
if(e != null && !e.isEmpty())
if(section != null && !section.isEmpty())
{
return true;
}
@@ -1,12 +0,0 @@
package com.backsun.lod.proxy;
/**
* This is used by the server.
*
* @author James_Seibel
* @version 08-31-2020
*/
public class CommonProxy
{
}
@@ -1,17 +1,16 @@
package com.backsun.lod.renderer;
import java.awt.Color;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.Callable;
import org.lwjgl.opengl.GL11;
import com.backsun.lod.util.enums.FogDistance;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper;
/**
*
@@ -21,8 +20,8 @@ import net.minecraft.util.math.MathHelper;
*/
public class BuildBufferThread implements Callable<NearFarBuffer>
{
public ByteBuffer nearBuffer;
public ByteBuffer farBuffer;
public BufferBuilder nearBuffer;
public BufferBuilder farBuffer;
public FogDistance distanceMode;
public AxisAlignedBB[][] lods;
public Color[][] colors;
@@ -42,20 +41,20 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
vertexCount = 0;
vertexFormat = DefaultVertexFormats.POSITION_COLOR;
vertexFormatIndex = 0;
vertexFormatElement = vertexFormat.getElement(vertexFormatIndex);
vertexFormatElement = vertexFormat.getElements().get(vertexFormatIndex);
}
BuildBufferThread(ByteBuffer newNearByteBuffer, ByteBuffer newFarByteBuffer, AxisAlignedBB[][] newLods, Color[][] newColors, FogDistance newDistanceMode, int threadNumber, int totalThreads)
BuildBufferThread(BufferBuilder newNearByteBuffer, BufferBuilder newFarByteBuffer, AxisAlignedBB[][] newLods, Color[][] newColors, FogDistance newDistanceMode, int threadNumber, int totalThreads)
{
setNewData(newNearByteBuffer, newFarByteBuffer, distanceMode, newLods, newColors, threadNumber, totalThreads);
vertexCount = 0;
vertexFormat = DefaultVertexFormats.POSITION_COLOR;
vertexFormatIndex = 0;
vertexFormatElement = vertexFormat.getElement(vertexFormatIndex);
vertexFormatElement = vertexFormat.getElements().get(vertexFormatIndex);
}
public void setNewData(ByteBuffer newNearByteBuffer, ByteBuffer newFarByteBuffer, FogDistance newDistanceMode, AxisAlignedBB[][] newLods, Color[][] newColors, int threadNumber, int totalThreads)
public void setNewData(BufferBuilder newNearByteBuffer, BufferBuilder newFarByteBuffer, FogDistance newDistanceMode, AxisAlignedBB[][] newLods, Color[][] newColors, int threadNumber, int totalThreads)
{
vertexCount = 0;
vertexFormatIndex = 0;
@@ -75,9 +74,12 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
@Override
public NearFarBuffer call()
{
nearBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
farBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
int numbChunksWide = lods.length;
ByteBuffer currentBuffer;
BufferBuilder currentBuffer;
AxisAlignedBB bb;
int red;
int green;
@@ -200,16 +202,20 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
return new NearFarBuffer(nearBuffer, farBuffer);
}
private void addPosAndColor(ByteBuffer buffer, double x, double y, double z, int red, int green, int blue, int alpha)
private void addPosAndColor(BufferBuilder buffer, double x, double y, double z, int red, int green, int blue, int alpha)
{
addPos(buffer, x, y, z);
addColor(buffer, red, green, blue, alpha);
endVertex();
buffer.pos(x, y, z).color(red, green, blue, alpha).endVertex();
// addPos(buffer, x, y, z);
// addColor(buffer, red, green, blue, alpha);
// endVertex();
}
/*
private void addPos(ByteBuffer byteBuffer, double x, double y, double z)
{
int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.getOffset(this.vertexFormatIndex);
int i = this.vertexCount * this.vertexFormat.getOffset(this.vertexFormatIndex+1) + this.vertexFormat.getOffset(this.vertexFormatIndex);
switch (this.vertexFormatElement.getType())
{
@@ -242,7 +248,7 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
private void addColor(ByteBuffer byteBuffer, int red, int green, int blue, int alpha)
{
int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.getOffset(this.vertexFormatIndex);
int i = this.vertexCount * this.vertexFormat.getOffset(this.vertexFormatIndex+1) + this.vertexFormat.getOffset(this.vertexFormatIndex);
switch (this.vertexFormatElement.getType())
{
@@ -292,10 +298,10 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
private void nextVertexFormatIndex()
{
++this.vertexFormatIndex;
this.vertexFormatIndex %= this.vertexFormat.getElementCount();
this.vertexFormatElement = this.vertexFormat.getElement(this.vertexFormatIndex);
this.vertexFormatIndex %= this.vertexFormat.getSize();
this.vertexFormatElement = this.vertexFormat.getElements().get(this.vertexFormatIndex);
if (this.vertexFormatElement.getUsage() == VertexFormatElement.EnumUsage.PADDING)
if (this.vertexFormatElement.getUsage() == VertexFormatElement.Usage.PADDING)
{
this.nextVertexFormatIndex();
}
@@ -303,14 +309,21 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
private void endVertex()
{
++this.vertexCount;
growBuffer(this.vertexFormat.getNextOffset());
// ++this.vertexCount;
// growBuffer(this.vertexFormat.getNextOffset());
if (this.vertexFormatIndex != 0) {
throw new IllegalStateException("Not filled all elements of the vertex");
} else {
++this.vertexCount;
this.growBuffer(vertexFormat.getSize());
}
}
private void growBuffer(int p_181670_1_)
{
//if (MathHelper.roundUp(p_181670_1_, 4) / 4 > this.rawIntBuffer.remaining() || this.vertexCount * this.vertexFormat.getNextOffset() + p_181670_1_ > this.byteBuffer.capacity())
if (this.vertexCount * this.vertexFormat.getNextOffset() + p_181670_1_ > nearBuffer.capacity())
if (this.vertexCount * this.vertexFormat.getOffset(this.vertexFormatIndex+1) + p_181670_1_ > nearBuffer.capacity())
{
int i = nearBuffer.capacity();
int j = i + MathHelper.roundUp(p_181670_1_, 2097152);
@@ -327,7 +340,7 @@ public class BuildBufferThread implements Callable<NearFarBuffer>
// this.rawShortBuffer.position(k << 1);
}
}
*/
}
@@ -13,7 +13,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;
import com.backsun.lod.objects.LodChunk;
import com.backsun.lod.objects.LodDimension;
@@ -23,15 +22,19 @@ import com.backsun.lod.util.enums.ColorDirection;
import com.backsun.lod.util.enums.FogDistance;
import com.backsun.lod.util.enums.FogQuality;
import com.backsun.lod.util.enums.LodLocation;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.profiler.IProfiler;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.chunk.Chunk;
/**
* @author James Seibel
@@ -44,6 +47,8 @@ public class LodRenderer
public boolean debugging = false;
private Minecraft mc;
private GameRenderer gameRender;
private IProfiler profiler;
private float farPlaneDistance;
// make sure this is an even number, or else it won't align with the chunk grid
/** this is the total width of the LODs (I.E the diameter, not the radius) */
@@ -66,10 +71,10 @@ public class LodRenderer
private int maxNumbThreads = Runtime.getRuntime().availableProcessors();
/** How many threads should be used for building the render buffer. */
private int numbBufferThreads = maxNumbThreads;
private int numbBufferThreads = 1;
private ArrayList<BuildBufferThread> bufferThreads = new ArrayList<BuildBufferThread>();
private volatile ByteBuffer[] nearBuffers = new ByteBuffer[maxNumbThreads];
private volatile ByteBuffer[] farBuffers = new ByteBuffer[maxNumbThreads];
private volatile BufferBuilder[] nearBuffers = new BufferBuilder[maxNumbThreads];
private volatile BufferBuilder[] farBuffers = new BufferBuilder[maxNumbThreads];
private ExecutorService bufferThreadPool = Executors.newFixedThreadPool(maxNumbThreads);
/*
* this is the maximum number of bytes a buffer
@@ -90,12 +95,14 @@ public class LodRenderer
/** if this is true the LODs should be regenerated */
private boolean regen = false;
private volatile boolean regenerating = false;
public LodRenderer()
{
mc = Minecraft.getMinecraft();
mc = Minecraft.getInstance();
gameRender = mc.gameRenderer;
// for some reason "Tessellator.getInstance()" won't work here, we have to create a new one
tessellator = new Tessellator(2097152);
@@ -104,36 +111,24 @@ public class LodRenderer
reflectionHandler = new ReflectionHandler();
}
private ExecutorService genThread = Executors.newSingleThreadExecutor();
private ExecutorService loadQueueThread = Executors.newSingleThreadExecutor();
public void drawLODs(LodDimension newDimension, float partialTicks)
public void drawLODs(LodDimension newDimension, float partialTicks, IProfiler newProfiler)
{
if (reflectionHandler.fovMethod == null)
{
// don't continue if we can't get the
// user's FOV
return;
}
if (reflectionHandler.fovMethod == null)
{
// we aren't able to get the user's
// FOV, don't render anything
return;
}
// should the LODs be regenerated?
if ((int)Minecraft.getMinecraft().player.posX / LodChunk.WIDTH != prevChunkX ||
(int)Minecraft.getMinecraft().player.posZ / LodChunk.WIDTH != prevChunkZ ||
if ((int)mc.player.getPosX() / LodChunk.WIDTH != prevChunkX ||
(int)mc.player.getPosZ() / LodChunk.WIDTH != prevChunkZ ||
previousChunkRenderDistance != mc.gameSettings.renderDistanceChunks ||
prevFogDistance != LodConfig.fogDistance ||
prevFogDistance != LodConfig.COMMON.fogDistance.get() ||
lodDimension != newDimension)
{
regen = true;
prevChunkX = (int)Minecraft.getMinecraft().player.posX / LodChunk.WIDTH;
prevChunkZ = (int)Minecraft.getMinecraft().player.posZ / LodChunk.WIDTH;
prevFogDistance = LodConfig.fogDistance;
prevChunkX = (int)mc.player.getPosX() / LodChunk.WIDTH;
prevChunkZ = (int)mc.player.getPosZ() / LodChunk.WIDTH;
prevFogDistance = LodConfig.COMMON.fogDistance.get();
}
else
{
@@ -143,6 +138,7 @@ public class LodRenderer
regen = false;
}
profiler = newProfiler;
lodDimension = newDimension;
if (lodDimension == null)
{
@@ -157,20 +153,19 @@ public class LodRenderer
// used for debugging and viewing how long different processes take
mc.mcProfiler.endSection();
mc.mcProfiler.startSection("LOD");
mc.mcProfiler.startSection("LOD setup");
profiler.startSection("LOD_setup");
@SuppressWarnings("unused")
long startTime = System.nanoTime();
if (LodConfig.drawCheckerBoard)
if (LodConfig.COMMON.drawCheckerBoard.get())
{
if (debugging != LodConfig.drawCheckerBoard)
if (debugging != LodConfig.COMMON.drawCheckerBoard.get())
regen = true;
debugging = true;
}
else
{
if (debugging != LodConfig.drawCheckerBoard)
if (debugging != LodConfig.COMMON.drawCheckerBoard.get())
regen = true;
debugging = false;
}
@@ -190,10 +185,11 @@ public class LodRenderer
// get the camera location
Entity player = mc.player;
double cameraX = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks;
double cameraY = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
double cameraZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
Vector3d projectedView = renderInfo.getProjectedView();
double cameraX = projectedView.x;
double cameraY = projectedView.y;
double cameraZ = projectedView.z;
@@ -224,113 +220,147 @@ public class LodRenderer
//=================//
// create the LODs //
//=================//
profiler.endStartSection("LOD_generation");
if (regen)
{
mc.mcProfiler.endStartSection("LOD generation");
// x axis
for (int i = 0; i < numbChunksWide; i++)
Thread t = new Thread(()->
{
// z axis
for (int j = 0; j < numbChunksWide; j++)
int numbChunksGen = 0;
int maxChunkGen = 640;
// x axis
for (int i = 0; i < numbChunksWide; i++)
{
// skip the middle
// (As the player moves some chunks will overlap or be missing,
// this is just how chunk loading/unloading works. This can hopefully
// be hidden with careful use of fog)
int middle = (numbChunksWide / 2);
if (RenderUtil.isCoordinateInLoadedArea(i, j, middle))
// z axis
for (int j = 0; j < numbChunksWide; j++)
{
continue;
}
// skip the middle
// (As the player moves some chunks will overlap or be missing,
// this is just how chunk loading/unloading works. This can hopefully
// be hidden with careful use of fog)
int middle = (numbChunksWide / 2);
if (RenderUtil.isCoordinateInLoadedArea(i, j, middle))
{
continue;
}
// set where this square will be drawn in the world
double xOffset = (LodChunk.WIDTH * i) + // offset by the number of LOD blocks
startX; // offset so the center LOD block is centered underneath the player
double yOffset = 0;
double zOffset = (LodChunk.WIDTH * j) + startZ;
// set where this square will be drawn in the world
double xOffset = (LodChunk.WIDTH * i) + // offset by the number of LOD blocks
startX; // offset so the center LOD block is centered underneath the player
double yOffset = 0;
double zOffset = (LodChunk.WIDTH * j) + startZ;
int chunkX = i + (startX / LodChunk.WIDTH);
int chunkZ = j + (startZ / LodChunk.WIDTH);
int chunkX = i + (startX / LodChunk.WIDTH);
int chunkZ = j + (startZ / LodChunk.WIDTH);
LodChunk lod = lodDimension.getLodFromCoordinates(chunkX, chunkZ); // new LodChunk(); //
if (lod == null)
{
// note: for some reason if any color or lod object are set here
// it causes the game to use 100% gpu, all of it undefined in the debug menu
// and drop to ~6 fps.
// colorArray[i][j] = null;
// lodArray[i][j] = null;
LodChunk lod = lodDimension.getLodFromCoordinates(chunkX, chunkZ);
if (lod == null)
{
// note: for some reason if any color or lod object are set here
// it causes the game to use 100% gpu, all of it undefined in the debug menu
// and drop to ~6 fps.
// colorArray[i][j] = null;
// lodArray[i][j] = null;
continue;
}
// TODO this partially works, but not fully
if (numbChunksGen < maxChunkGen)
{
// if (lod == null)
// {
// LodChunk placeholder = new LodChunk();
// placeholder.x = chunkX;
// placeholder.z = chunkZ;
// placeholder.colors[ColorDirection.TOP.value] = error;
// lodDimension.addLod(placeholder);
// }
Color c = new Color(
(lod.colors[ColorDirection.TOP.value].getRed()),
(lod.colors[ColorDirection.TOP.value].getGreen()),
(lod.colors[ColorDirection.TOP.value].getBlue()),
lod.colors[ColorDirection.TOP.value].getAlpha());
// Thread loadT = new Thread(()-> {
Chunk newChunk = mc.world.getChunk(chunkX, chunkZ);
lodDimension.addLod(new LodChunk(newChunk, newChunk.getWorld()));
System.out.println(chunkX + "," + chunkZ + "\t" + numbChunksGen);
// });
// loadQueueThread.execute(loadT);
numbChunksGen++;
}
continue;
}
Color c = new Color(
(lod.colors[ColorDirection.TOP.value].getRed()),
(lod.colors[ColorDirection.TOP.value].getGreen()),
(lod.colors[ColorDirection.TOP.value].getBlue()),
lod.colors[ColorDirection.TOP.value].getAlpha());
if (!debugging)
{
// add the color to the array
colorArray[i][j] = c;
}
else
{
// if debugging draw the squares as a black and white checker board
if ((chunkX + chunkZ) % 2 == 0)
c = white;
if (!debugging)
{
// add the color to the array
colorArray[i][j] = c;
}
else
c = black;
// draw the first square as red
if (i == 0 && j == 0)
c = red;
{
// if debugging draw the squares as a black and white checker board
if ((chunkX + chunkZ) % 2 == 0)
c = white;
else
c = black;
// draw the first square as red
if (i == 0 && j == 0)
c = red;
colorArray[i][j] = c;
colorArray[i][j] = c;
}
// add the new box to the array
int topPoint = getLodHeightPoint(lod.top);
int bottomPoint = getLodHeightPoint(lod.bottom);
// don't draw an LOD if it is empty
if (topPoint == -1 && bottomPoint == -1)
continue;
lodArray[i][j] = new AxisAlignedBB(0, bottomPoint, 0, LodChunk.WIDTH, topPoint, LodChunk.WIDTH).offset(xOffset, yOffset, zOffset);
}
// add the new box to the array
int topPoint = getLodHeightPoint(lod.top);
int bottomPoint = getLodHeightPoint(lod.bottom);
// don't draw an LOD if it is empty
if (topPoint == -1 && bottomPoint == -1)
continue;
lodArray[i][j] = new AxisAlignedBB(0, bottomPoint, 0, LodChunk.WIDTH, topPoint, LodChunk.WIDTH).offset(xOffset, yOffset, zOffset);
}
}
});
t.run();
// genThread.execute(t);
}
//===========================//
// GL settings for rendering //
//===========================//
profiler.endStartSection("LOD_setup");
// set the required open GL settings
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glLineWidth(2.0f);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GlStateManager.translate(-cameraX, -cameraY, -cameraZ);
RenderSystem.pushMatrix();
RenderSystem.rotatef(renderInfo.getPitch(), 1, 0, 0); // Fixes camera rotation.
RenderSystem.rotatef(renderInfo.getYaw() + 180, 0, 1, 0); // Fixes camera rotation.
RenderSystem.translated(-cameraX, -cameraY, -cameraZ);
setProjectionMatrix(partialTicks);
setupLighting(partialTicks);
// setupProjectionMatrix(partialTicks);
// setupLighting(partialTicks);
setupBufferThreads(lodArray);
@@ -338,32 +368,41 @@ public class LodRenderer
//===========//
// rendering //
//===========//
mc.mcProfiler.endStartSection("LOD build buffer");
profiler.endStartSection("LOD build buffer");
if (regen)
generateLodBuffers(lodArray, colorArray, LodConfig.fogDistance);
generateLodBuffers(lodArray, colorArray, LodConfig.COMMON.fogDistance.get());
switch(LodConfig.fogDistance)
profiler.endStartSection("LOD draw");
switch(LodConfig.COMMON.fogDistance.get())
{
case NEAR_AND_FAR:
mc.mcProfiler.endStartSection("LOD draw setup");
profiler.startSection("LOD draw near");
setupFog(FogDistance.NEAR, reflectionHandler.getFogQuality());
sendLodsToGpuAndDraw(nearBuffers);
profiler.endSection();
mc.mcProfiler.endStartSection("LOD draw setup");
setupFog(FogDistance.FAR, reflectionHandler.getFogQuality());
sendLodsToGpuAndDraw(farBuffers);
// profiler.startSection("LOD draw far");
// setupFog(FogDistance.FAR, reflectionHandler.getFogQuality());
// sendLodsToGpuAndDraw(farBuffers);
// profiler.endSection();
break;
case NEAR:
mc.mcProfiler.endStartSection("LOD draw setup");
profiler.endStartSection("LOD draw near");
setupFog(FogDistance.NEAR, reflectionHandler.getFogQuality());
sendLodsToGpuAndDraw(nearBuffers);
break;
case FAR:
mc.mcProfiler.endStartSection("LOD draw setup");
profiler.endStartSection("LOD draw far");
setupFog(FogDistance.FAR, reflectionHandler.getFogQuality());
sendLodsToGpuAndDraw(farBuffers);
break;
@@ -372,40 +411,37 @@ public class LodRenderer
//=========//
// cleanup //
//=========//
mc.mcProfiler.endStartSection("LOD cleanup");
profiler.endStartSection("LOD_cleanup");
// this must be done otherwise other parts of the screen may be drawn with a fog effect
// IE the GUI
GlStateManager.disableFog();
RenderSystem.disableFog();
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_LIGHT1);
GL11.glDisable(GL11.GL_LIGHT2);
GL11.glDisable(GL11.GL_COLOR_MATERIAL);
GL11.glDisable(GL11.GL_CULL_FACE);
// undo any projection matrix changes we did to prevent other renders
// from being corrupted
RenderSystem.popMatrix();
// change the perspective matrix back to prevent incompatibilities
// with other mods that may render during forgeRenderLast
Project.gluPerspective(reflectionHandler.getFov(mc, partialTicks, true), (float) this.mc.displayWidth / (float) this.mc.displayHeight, 0.05F, this.farPlaneDistance * MathHelper.SQRT_2);
// this can't be called until after the buffers are built
// because otherwise the buffers may be set to the wrong size
previousChunkRenderDistance = mc.gameSettings.renderDistanceChunks;
// This is about how long this whole process should take
// 16 ms = 60 hz
@SuppressWarnings("unused")
long endTime = System.nanoTime();
// end of profiler tracking
mc.mcProfiler.endSection();
}
@@ -416,6 +452,16 @@ public class LodRenderer
/**
* draw an array of cubes (or squares) with the given colors.
* @param lods bounding boxes to draw
@@ -431,11 +477,11 @@ public class LodRenderer
{
if (nearBuffers[i] == null || previousChunkRenderDistance != mc.gameSettings.renderDistanceChunks)
{
nearBuffers[i] = ByteBuffer.allocateDirect(bufferMaxCapacity);
nearBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
nearBuffers[i] = new BufferBuilder(bufferMaxCapacity); //ByteBuffer.allocateDirect(bufferMaxCapacity);
// nearBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
farBuffers[i] = ByteBuffer.allocateDirect(bufferMaxCapacity);
farBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
farBuffers[i] = new BufferBuilder(bufferMaxCapacity); //ByteBuffer.allocateDirect(bufferMaxCapacity);
// farBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
clearBytes = new byte[bufferMaxCapacity];
}
@@ -446,18 +492,18 @@ public class LodRenderer
// overwrite the old data
// (which needs to be done otherwise old
// LODs may be drawn)
nearBuffers[i].clear();
nearBuffers[i].put(clearBytes);
nearBuffers[i].clear();
nearBuffers[i].byteBuffer.clear();
nearBuffers[i].byteBuffer.put(clearBytes);
nearBuffers[i].byteBuffer.clear();
farBuffers[i].clear();
farBuffers[i].put(clearBytes);
farBuffers[i].clear();
farBuffers[i].byteBuffer.clear();
farBuffers[i].byteBuffer.put(clearBytes);
farBuffers[i].byteBuffer.clear();
}
int pos = bufferBuilder.getByteBuffer().position();
nearBuffers[i].position(pos);
farBuffers[i].position(pos);
// int pos = bufferBuilder.byteBuffer.position();
// nearBuffers[i].byteBuffer.position(pos);
// farBuffers[i].byteBuffer.position(pos);
bufferThreads.get(i).setNewData(nearBuffers[i], farBuffers[i], fogDistance, lods, colors, i, numbBufferThreads);
}
@@ -478,6 +524,9 @@ public class LodRenderer
{
nearBuffers[i] = bufferFutures.get(i).get().nearBuffer;
farBuffers[i] = bufferFutures.get(i).get().farBuffer;
nearBuffers[i].finishDrawing();
farBuffers[i].finishDrawing();
}
catch(CancellationException | ExecutionException| InterruptedException e)
{
@@ -488,22 +537,23 @@ public class LodRenderer
}
private void sendLodsToGpuAndDraw(ByteBuffer[] buffers)
private void sendLodsToGpuAndDraw(BufferBuilder[] nearBuffers)
{
for(int i = 0; i < numbBufferThreads; i++)
{
int pos = bufferBuilder.getByteBuffer().position();
buffers[i].position(pos);
profiler.startSection("LOD setup");
// int pos = bufferBuilder.byteBuffer.position();
// nearBuffers[i].byteBuffer.position(pos);
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
bufferBuilder.getByteBuffer().clear();
bufferBuilder.putBulkData(buffers[i]);
bufferBuilder.byteBuffer.clear();
bufferBuilder.putBulkData(nearBuffers[i].byteBuffer);
mc.mcProfiler.endStartSection("LOD draw");
profiler.endStartSection("LOD draw");
tessellator.draw();
mc.mcProfiler.endStartSection("LOD draw setup");
bufferBuilder.getByteBuffer().clear(); // this is required otherwise nothing is drawn
bufferBuilder.byteBuffer.clear(); // this is required otherwise nothing is drawn
profiler.endSection();
}
}
@@ -517,11 +567,12 @@ public class LodRenderer
// Setup Functions //
//=================//
@SuppressWarnings("deprecation")
private void setupFog(FogDistance fogDistance, FogQuality fogQuality)
{
if(fogQuality == FogQuality.OFF)
{
GlStateManager.disableFog();
RenderSystem.disableFog();
return;
}
@@ -542,8 +593,8 @@ public class LodRenderer
if (fogQuality == FogQuality.FANCY)
{
GlStateManager.setFogEnd(farPlaneDistance * 0.3f * LOD_CHUNK_DISTANCE_RADIUS);
GlStateManager.setFogStart(farPlaneDistance * 0.35f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogEnd(farPlaneDistance * 0.3f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogStart(farPlaneDistance * 0.35f * LOD_CHUNK_DISTANCE_RADIUS);
}
else if(fogQuality == FogQuality.FAST)
{
@@ -551,49 +602,55 @@ public class LodRenderer
// to start right where the LODs' end use:
// end = 0.8f, start = 1.5f
GlStateManager.setFogEnd(farPlaneDistance * 1.5f);
GlStateManager.setFogStart(farPlaneDistance * 2.0f);
RenderSystem.fogEnd(farPlaneDistance * 1.5f);
RenderSystem.fogStart(farPlaneDistance * 2.0f);
}
}
else if(fogDistance == FogDistance.FAR)
{
if (fogQuality == FogQuality.FANCY)
{
GlStateManager.setFogStart(farPlaneDistance * 0.78f * LOD_CHUNK_DISTANCE_RADIUS);
GlStateManager.setFogEnd(farPlaneDistance * 1.0f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogStart(farPlaneDistance * 0.78f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogEnd(farPlaneDistance * 1.0f * LOD_CHUNK_DISTANCE_RADIUS);
}
else if(fogQuality == FogQuality.FAST)
{
GlStateManager.setFogStart(farPlaneDistance * 0.5f * LOD_CHUNK_DISTANCE_RADIUS);
GlStateManager.setFogEnd(farPlaneDistance * 0.75f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogStart(farPlaneDistance * 0.5f * LOD_CHUNK_DISTANCE_RADIUS);
RenderSystem.fogEnd(farPlaneDistance * 0.75f * LOD_CHUNK_DISTANCE_RADIUS);
}
}
GlStateManager.setFogDensity(0.1f);
GlStateManager.enableFog();
RenderSystem.fogDensity(0.1f);
RenderSystem.enableFog();
}
/**
* create a new projection matrix and send it over to the GPU
* @param partialTicks how many ticks into the frame we are
* @return true if the matrix was successfully created and sent to the GPU, false otherwise
*/
private void setProjectionMatrix(float partialTicks)
private void setupProjectionMatrix(float partialTicks)
{
// create a new view frustum so that the squares can be drawn outside the normal view distance
GlStateManager.matrixMode(GL11.GL_PROJECTION);
GlStateManager.loadIdentity();
// Project.gluPerspective(getFov(partialTicks, true), (float) mc.currentScreen.width / (float) mc.currentScreen.height, 0.5F, farPlaneDistance * 12);
gameRender.resetProjectionMatrix(getCustomProjectionMatrix(partialTicks, false));
// only continue if we can get the FOV
if (reflectionHandler.fovMethod != null)
{
Project.gluPerspective(reflectionHandler.getFov(mc, partialTicks, true), (float) mc.displayWidth / (float) mc.displayHeight, 0.5F, farPlaneDistance * 12);
}
// we weren't able to set up the projection matrix
return;
}
/**
* Almost an exact copy of what is in GameRenderer
*/
public Matrix4f getCustomProjectionMatrix(float partialTicks, boolean useFovSetting)
{
ActiveRenderInfo activeRenderInfoIn = mc.gameRenderer.getActiveRenderInfo();
return Matrix4f.perspective(
gameRender.getFOVModifier(activeRenderInfoIn, partialTicks, useFovSetting),
(float)this.mc.getMainWindow().getFramebufferWidth() / (float)this.mc.getMainWindow().getFramebufferHeight(),
0.5F,
this.farPlaneDistance * LOD_CHUNK_DISTANCE_RADIUS * 2);
}
/**
@@ -604,18 +661,18 @@ public class LodRenderer
GL11.glEnable(GL11.GL_COLOR_MATERIAL); // set the color to be used as the material (this allows lighting to be enabled)
// this isn't perfect right now, but it looks pretty good at 50% brightness
float sunBrightness = mc.world.getSunBrightness(partialTicks) * mc.world.provider.getSunBrightnessFactor(partialTicks);
float skyHasLight = mc.world.provider.hasSkyLight()? 1.0f : 0.15f;
float gammaMultiplyer = (mc.gameSettings.gammaSetting * 0.5f + 0.5f);
float sunBrightness = mc.world.getSunBrightness(partialTicks);
float skyHasLight = 1.0f; //mc.world.provider.hasSkyLight()? 1.0f : 0.15f;
float gammaMultiplyer = ((float)mc.gameSettings.gamma * 0.5f + 0.5f);
float lightStrength = sunBrightness * skyHasLight * gammaMultiplyer;
float lightAmbient[] = {lightStrength, lightStrength, lightStrength, 1.0f};
ByteBuffer temp = ByteBuffer.allocateDirect(16);
temp.order(ByteOrder.nativeOrder());
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip());
GL11.glEnable(GL11.GL_LIGHT1); // Enable the above lighting
GL11.glLightfv(GL11.GL_LIGHT2, GL11.GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip());
GL11.glEnable(GL11.GL_LIGHT2); // Enable the above lighting
GlStateManager.enableLighting();
RenderSystem.enableLighting();
}
@@ -633,11 +690,11 @@ public class LodRenderer
for(int i = 0; i < maxNumbThreads; i++)
{
nearBuffers[i] = ByteBuffer.allocateDirect(bufferMaxCapacity);
nearBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
nearBuffers[i] = new BufferBuilder(bufferMaxCapacity); //ByteBuffer.allocateDirect(bufferMaxCapacity);
// nearBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
farBuffers[i] = ByteBuffer.allocateDirect(bufferMaxCapacity);
farBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
farBuffers[i] = new BufferBuilder(bufferMaxCapacity); //ByteBuffer.allocateDirect(bufferMaxCapacity);
// farBuffers[i].order(ByteOrder.LITTLE_ENDIAN);
}
}
}
@@ -646,6 +703,7 @@ public class LodRenderer
/**
* Returns -1 if there are no valid points
*/
@@ -661,6 +719,10 @@ public class LodRenderer
}
public double getFov(float partialTicks, boolean useFovSetting)
{
return mc.gameRenderer.getFOVModifier(mc.gameRenderer.getActiveRenderInfo(), partialTicks, useFovSetting);
}
@@ -1,6 +1,6 @@
package com.backsun.lod.renderer;
import java.nio.ByteBuffer;
import net.minecraft.client.renderer.BufferBuilder;
/**
* This object is just a replacement for an array
@@ -12,12 +12,12 @@ import java.nio.ByteBuffer;
*/
public class NearFarBuffer
{
public ByteBuffer nearBuffer;
public BufferBuilder nearBuffer;
public ByteBuffer farBuffer;
public BufferBuilder farBuffer;
NearFarBuffer(ByteBuffer newNearBuffer, ByteBuffer newFarBuffer)
NearFarBuffer(BufferBuilder newNearBuffer, BufferBuilder newFarBuffer)
{
nearBuffer = newNearBuffer;
farBuffer = newFarBuffer;
@@ -0,0 +1,82 @@
package com.backsun.lod.renderer;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.renderer.RenderType;
/**
* This code is used for drawing
* to the stencil buffer.
*
* @author James Seibel
* @version 02-17-2021
*/
public class RenderGlobalHook
{
/**
* this variable should be the same as the method name below.
* It is used when transforming the RenderGlobal class'
* renderBlockLayer method.
*/
public static final String START_STENCIL_METHOD_NAME = "startRenderingStencil";
/**
* This method tells OpenGL to start drawing everything to the stencil.
* This is done to prevent LODs from being rendered on top of the world.
* <br><br>
* Called in the order (as of minecraft 1.16.4): <br>
* RenderType.getSolid() <br>
* RenderType.getCutoutMipped() <br>
* RenderType.getCutout() <br>
* RenderType.getTranslucent() <br>
* RenderType.getTripwire() <br>
*/
public static void startRenderingStencil(RenderType blockLayerIn)
{
// we only enable drawing to the stencil once since
// we want to skip the rendering of the out of world fog
// but catch everything else
if (blockLayerIn == RenderType.getSolid())
{
// solid is the first layer rendered
// clear the buffer so we can start fresh.
// if this isn't cleared first we will have overlap with the fog
// outside the world
GL11.glClearStencil(0);
GL11.glStencilMask(0x11111111);
GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
GL11.glEnable(GL11.GL_STENCIL_TEST);
GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0x11111111);
GL11.glStencilMask(0b11111111);
GL11.glStencilOp(GL11.GL_KEEP, // this doesn't mater since GL_ALWAYS is being used
GL11.GL_KEEP, // stencil test passes
GL11.GL_REPLACE); // stencil + depth pass
}
}
/**
* this variable should be the same as the method name below.
* It is used when transforming the RenderGlobal class'
* renderBlockLayer method.
*/
public static final String END_STENCIL_METHOD_NAME = "endRenderingStencil";
/**
* Currently this method isn't used in any transformations since we end
* the stencil drawing in the ClientProxy right before we draw the LODs.
*/
public static void endRenderingStencil(RenderType blockLayerIn)
{
GL11.glStencilOp(GL11.GL_KEEP, // this doesn't mater since GL_ALWAYS is being used
GL11.GL_KEEP, // stencil test passes
GL11.GL_KEEP); // stencil + depth pass
}
public static void endRenderingStencil()
{
endRenderingStencil(null);
}
}
@@ -17,7 +17,7 @@ public class RenderUtil
*/
public static boolean isCoordinateInLoadedArea(int i, int j, int centerCoordinate)
{
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
return (i >= centerCoordinate - mc.gameSettings.renderDistanceChunks
&& i <= centerCoordinate + mc.gameSettings.renderDistanceChunks)
@@ -1,55 +1,65 @@
package com.backsun.lod.util;
import org.apache.commons.lang3.tuple.Pair;
import com.backsun.lod.ModInfo;
import com.backsun.lod.util.enums.FogDistance;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/**
*
* @author James Seibel
* @version 02-14-2021
*/
@Config(modid = Reference.MOD_ID)
@Mod.EventBusSubscriber
public class LodConfig
{
// save the config file when it is changed
@Mod.EventBusSubscriber(modid = Reference.MOD_ID)
private static class EventHandler
public static final LodConfig.Common COMMON;
public static final ForgeConfigSpec COMMON_SPEC;
// create the required variables
static
{
final Pair<Common, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(LodConfig.Common::new);
COMMON_SPEC = specPair.getRight();
COMMON = specPair.getLeft();
}
public static class Common
{
@SubscribeEvent
public static void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent event)
public ForgeConfigSpec.BooleanValue drawLODs;
public ForgeConfigSpec.EnumValue<FogDistance> fogDistance;
public ForgeConfigSpec.BooleanValue drawCheckerBoard;
Common(ForgeConfigSpec.Builder builder)
{
if (event.getModID().equals(Reference.MOD_ID))
{
ConfigManager.sync(Reference.MOD_ID, Config.Type.INSTANCE);
}
}
builder.comment(ModInfo.MODNAME + " configuration settings").push("common");
drawLODs = builder
.comment("If true LODs will be drawn, if false LODs will "
+ "not be rendered. However they will "
+ "still be generated.")
.define("drawLODs", true);
fogDistance = builder
.comment("At what distance should Fog be drawn on the LODs?")
.defineEnum("fogDistance", FogDistance.NEAR_AND_FAR);
drawCheckerBoard = builder
.comment("If false the LODs will draw with their normal world colors. "
+ "If true they will draw as a black and white checkerboard. "
+ "This can be used for debugging or imagining you are playing a "
+ "giant game of chess ;)")
.define("drawCheckerBoard", false);
builder.pop();
}
}
@Config.Comment(
{"Enable LODs",
"If true LODs will be drawn, if false LODs will "
+ "not be rendered. However they will "
+ "still be generated and stored in your world's save folder."})
public static boolean drawLODs = true;
@Config.Comment(
{"Fog Distance",
"What distance should Fog be drawn on the LODs?"})
public static FogDistance fogDistance = FogDistance.NEAR_AND_FAR;
@Config.Comment(
{"Draw Debugging Checkerboard",
"If false the LODs will draw with their normal world colors."
+ "If true they will draw as a black and white checkerboard."
+ "This can be used for debugging or imagining you are playing a "
+ "giant game of chess ;)"})
public static boolean drawCheckerBoard = false;
}
@@ -13,7 +13,6 @@ import com.backsun.lod.objects.LodDimension;
import com.backsun.lod.objects.LodRegion;
import net.minecraft.client.Minecraft;
import net.minecraft.world.storage.ISaveHandler;
/**
* This object handles creating LodRegions
@@ -25,34 +24,25 @@ import net.minecraft.world.storage.ISaveHandler;
*/
public class LodFileHandler
{
// TODO this object needs to be changed to use NBT data instead of writing to files
private static final boolean IMPLEMENTED = false;
private Minecraft mc = Minecraft.getInstance();
private LodDimension loadedRegion = null;
public long regionLastWriteTime[][];
// String s = Minecraft.getMinecraftDir().getCanonicalPath() + "/saves/" + world.getSaveHandler().getSaveDirectoryName() + "/data/AA/World" + world.provider.dimensionId + ".dat";
private String save_dir;
public ISaveHandler saveHandler;
private final String FILE_NAME_PREFIX = "lod";
private final String FILE_EXTENSION = ".txt";
private ExecutorService fileWritingThreadPool = Executors.newFixedThreadPool(1);
/** Is true if the readyToReadAndWrite is false */
private boolean waitingToSaveRegions = false;
private ExecutorService fileWritingThreadPool = Executors.newSingleThreadExecutor();
public LodFileHandler(ISaveHandler newSaveHandler, LodDimension newLoadedRegion)
public LodFileHandler(LodDimension newLoadedRegion)
{
saveHandler = newSaveHandler;
loadedRegion = newLoadedRegion;
// these two variable are used in sync with the LodDimension
regionLastWriteTime = new long[loadedRegion.getWidth()][loadedRegion.getWidth()];
for(int i = 0; i < loadedRegion.getWidth(); i++)
for(int j = 0; j < loadedRegion.getWidth(); j++)
regionLastWriteTime[i][j] = -1;
if (saveHandler != null && saveHandler.getWorldDirectory() != null)
save_dir = getWorldSaveDirectory();
}
@@ -71,15 +61,15 @@ public class LodFileHandler
*/
public LodRegion loadRegionFromFile(int regionX, int regionZ)
{
if (!IMPLEMENTED)
return null;
// we don't currently support reading or writing
// files when connected to a server
if (!Minecraft.getMinecraft().isIntegratedServerRunning())
if (!mc.isIntegratedServerRunning())
return null;
if (!readyToReadAndWrite())
return null;
String fileName = getFileNameForRegion(regionX, regionZ);
String fileName = "";
File f = new File(fileName);
@@ -144,50 +134,14 @@ public class LodFileHandler
public synchronized void saveDirtyRegionsToFile()
{
if (!IMPLEMENTED)
return;
// we don't currently support reading or writing
// files when connected to a server
if (!Minecraft.getMinecraft().isIntegratedServerRunning())
if (!mc.isIntegratedServerRunning())
return;
if (!readyToReadAndWrite())
{
// we aren't ready to read and write yet
if(!waitingToSaveRegions)
{
waitingToSaveRegions = true;
// retry until we are able to read and write
// then wake up the fileWritingThreadPool
Thread retryReady = new Thread(() ->
{
try
{
// check once every so often so see
// if anything has changed so we can
// start reading and writing files
while(!readyToReadAndWrite())
{
this.wait(1000);
// get the save handler again, if for some
// reason the original handler was null
saveHandler = Minecraft.getMinecraft().getIntegratedServer().getWorld(0).getSaveHandler();
save_dir = getWorldSaveDirectory();
}
// we can start writing files now
fileWritingThreadPool.execute(saveDirtyRegionsThread);
waitingToSaveRegions = false;
}
catch (InterruptedException e)
{ /* should never be called */}
});
retryReady.run();
}
return;
}
fileWritingThreadPool.execute(saveDirtyRegionsThread);
}
private Thread saveDirtyRegionsThread = new Thread(() ->
@@ -203,22 +157,21 @@ public class LodFileHandler
}
}
}
waitingToSaveRegions = false;
});
private void saveRegionToDisk(LodRegion region)
{
if (!readyToReadAndWrite() || region == null)
if (!IMPLEMENTED)
return;
// convert chunk coordinates to region
// coordinates
int x = region.x;
int z = region.z;
if (region == null)
return;
File f = new File(getFileNameForRegion(x, z));
// int x = region.x;
// int z = region.z;
File f = new File("");
try
{
@@ -254,34 +207,6 @@ public class LodFileHandler
//================//
/**
* Return the name of the file that should contain the
* region at the given x and z. <br>
* Returns null if this object isn't ready to read and write.
* @param regionX
* @param regionZ
*/
private String getFileNameForRegion(int regionX, int regionZ)
{
if (!readyToReadAndWrite())
return null;
return save_dir + "\\lod_data\\DIM" + loadedRegion.dimension.getId() + "\\" +
FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION;
}
/**
* Returns if this FileHandler is ready to read
* and write files.
*/
public boolean readyToReadAndWrite()
{
return saveHandler != null && saveHandler.getWorldDirectory() != null &&
save_dir != null && !save_dir.isEmpty();
}
/**
@@ -291,11 +216,11 @@ public class LodFileHandler
*/
public static String getWorldName()
{
Minecraft mc = Minecraft.getMinecraft();
Minecraft mc = Minecraft.getInstance();
if(mc.isIntegratedServerRunning())
{
return mc.getIntegratedServer().getWorldName();
return mc.getIntegratedServer().getName();
}
else
{
@@ -304,19 +229,4 @@ public class LodFileHandler
}
/**
* Returns null if there was an IO Exception
*/
private String getWorldSaveDirectory()
{
try
{
return saveHandler.getWorldDirectory().getCanonicalPath();
}
catch (IOException e)
{
return null;
}
}
}
@@ -1,9 +1,6 @@
package com.backsun.lod.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import com.backsun.lod.util.enums.FogQuality;
@@ -14,97 +11,27 @@ import net.minecraft.client.Minecraft;
* where they are private.
*
* @author James Seibel
* @version 09-21-2020
* @version 02-18-2021
*/
public class ReflectionHandler
{
public Method fovMethod = null;
private Minecraft mc = Minecraft.getInstance();
public Field ofFogField = null;
public ReflectionHandler()
{
setupFovMethod();
setupFogField();
}
/**
* This sets the "getFOVModifier" method from the
* minecraft "EntityRenderer" class, so that we can get
* the FOV of the player at any time.
*
* This is required since Minecraft is obfuscated so
* we can't just look for 'getFOVModifier'
* we have to search for it based on its parameters and
* return type; which luckily are unique in the EntityRenderer
* class.
*/
private void setupFovMethod()
{
// get every method from the entity renderer
Method[] methods = Minecraft.getMinecraft().entityRenderer.getClass().getDeclaredMethods();
Class<?> returnType;
Parameter[] params;
Method returnMethod = null;
for(Method m : methods)
{
returnType = m.getReturnType();
params = m.getParameters();
// see if this method has the same return type
// and parameters as the 'getFOVModifier' method.
if (returnType.equals(float.class) &&
params.length == 2 &&
params[0].getType().equals(float.class) &&
params[1].getType().equals(boolean.class))
{
// only accept the first method that we find
if (returnMethod == null)
{
returnMethod = m;
}
else
{
// we found a second method that matches the
// outline we were looking for,
// to prevent unexpected behavior
// dont't set fovMethod.
// Since we aren't sure that
// this method is the right
// one, we may accidently mess
// up the entityRender by invoking
// it and we probably wouldn't get
// the FOV from it anyway.
System.err.println("Error: a second method that matches the parameters and return typ of 'getFOVModifier' was found, LODs won't be rendered.");
return;
}
}
}
// only set the method once we have gone through
// the whole array of methods, just to
// make sure we have the right one.
fovMethod = returnMethod;
// set up the method so we can invoke it later
fovMethod.setAccessible(true);
}
/**
* Similar to setupFovMethod.
*/
private void setupFogField()
{
// get every variable from the entity renderer
Field[] vars = Minecraft.getMinecraft().gameSettings.getClass().getDeclaredFields();
Field[] vars = mc.gameSettings.getClass().getDeclaredFields();
// try and find the ofFogType variable in gameSettings
for(Field f : vars)
@@ -143,7 +70,7 @@ public class ReflectionHandler
try
{
returnNum = (int)ofFogField.get(Minecraft.getMinecraft().gameSettings);
returnNum = (int)ofFogField.get(mc.gameSettings);
}
catch (IllegalArgumentException | IllegalAccessException e)
{
@@ -166,22 +93,4 @@ public class ReflectionHandler
}
}
/**
* Gets the FOV used by the EntityRender.
*/
public float getFov(Minecraft mc, float partialTicks, boolean useFovSetting)
{
try
{
return (float)fovMethod.invoke(mc.entityRenderer, new Object[]{partialTicks, useFovSetting});
}
catch(InvocationTargetException | IllegalAccessException | IllegalArgumentException e)
{
e.printStackTrace();
}
return 0.0f;
}
}
@@ -0,0 +1,36 @@
# Note: to update code in eclipse run the "eclipse" commad in graldew
# make public the method getFOVModifier
public net.minecraft.client.renderer.GameRenderer func_215311_a(Lnet/minecraft/client/renderer/ActiveRenderInfo;FZ)D # getFOVModifier
# make public the byteBuffer in BufferBuilder
public net.minecraft.client.renderer.BufferBuilder field_179001_a # byteBuffer
# make public the cameraZoom in the GameRenderer
public net.minecraft.client.renderer.GameRenderer field_78503_V # cameraZoom
# make public the cameraYaw in the GameRenderer
public net.minecraft.client.renderer.GameRenderer field_228376_w_ # cameraYaw
# make public the cameraPitch in the GameRenderer
public net.minecraft.client.renderer.GameRenderer field_228377_x_ # cameraPitch
#=====================#
# Examples from Forge #
#=====================#
# Makes public the IScreenFactory class in ScreenManager
public net.minecraft.client.gui.ScreenManager$IScreenFactory
# Makes protected and removes the final modifier from 'random' in MinecraftServer
protected-f net.minecraft.server.MinecraftServer field_147146_q #random
# Makes public the 'createNamedService' method in Util,
# accepting a String and returns an ExecutorService
public net.minecraft.util.Util func_240979_a_(Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; #createNamedService
# Makes public the 'func_239776_a_' method in UUIDCodec,
# accepting two longs and returning an int[]
public net.minecraft.util.UUIDCodec func_239776_a_(JJ)[I #func_239776_a_
+40
View File
@@ -0,0 +1,40 @@
# This is an example mods.toml file. It contains the data relating to the loading mods.
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
# The overall format is standard TOML format, v0.5.0.
# Note that there are a couple of TOML lists in this file.
# Find more information on toml format here: https://github.com/toml-lang/toml
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml" #mandatory
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
loaderVersion="[35,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
license="All rights reserved"
# A URL to refer people to when problems occur with this mod
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]] #mandatory
# The modid of the mod
modId="lod" #mandatory
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
# see the associated build.gradle script for how to populate this completely automatically during a build
version="${file.jarVersion}" #mandatory
# A display name for the mod
displayName="Levels of Detail" #mandatory
# A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
# A URL for the "homepage" for this mod, displayed in the mod UI
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
# A file name (in the root of the mod JAR) containing a logo for display
#logoFile="examplemod.png" #optional
# A text field displayed in the mod UI
#credits="" #optional
# A text field displayed in the mod UI
authors="James Seibel" #optional
# The description text for the mod (multi line!) (#mandatory)
description='''
'''
+11
View File
@@ -0,0 +1,11 @@
{
"required": true,
"package": "com.backsun.lod.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "lod.refmap.json",
"mixins": [
"MixinItemEntity",
"MixinWorldRenderer"
],
"minVersion": "0.8"
}
+2 -2
View File
@@ -4,13 +4,13 @@
"name": "Level Of Details",
"description": "Generates and renders simplified chunks beyond the normal view distance, at a low performance cost.",
"version": "0.1",
"mcversion": "1.12.2",
"mcversion": "1.16.4",
"url": "",
"updateUrl": "",
"authorList": ["James Seibel"],
"credits": "TechnoVision and Vike for their modding tutorials.",
"logoFile": "",
"screenshots": [],
"dependencies": ["lodcore"]
"dependencies": []
}
]
+2 -2
View File
@@ -1,7 +1,7 @@
{
"pack": {
"description": "examplemod resources",
"pack_format": 3,
"_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)."
"pack_format": 6,
"_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods."
}
}