├── .github └── workflows │ └── gradle.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── me │ └── Deex │ └── SaltLib │ ├── Debug │ ├── Instrumentor.java │ └── PerformanceTimer.java │ ├── Mixin │ ├── BufferBuilderMixin.java │ ├── BufferRendererMixin.java │ ├── ChunkBuilderMixin.java │ ├── ChunkRenderHelperImplMixin.java │ ├── GLXMixin.java │ ├── GlStateManagerMixin.java │ ├── ListedChunkRenderManagerMixin.java │ ├── MinecraftClientMixin.java │ ├── ModelBoxAccessor.java │ ├── ModelPartMixin.java │ ├── ProjectMixin.java │ ├── RealmsNotificationScreenMixin.java │ ├── TextRendererMixin.java │ ├── TexturedQuadAccessor.java │ ├── VideoOptionsScreenMixin.java │ ├── WorldMixin.java │ └── WorldRendererMixin.java │ ├── Renderer │ ├── BufferBuilderRenderData.java │ ├── CustomBufferRenderer.java │ ├── GLShader.java │ └── MatrixStack.java │ ├── SaltLibMod.java │ └── Utils │ └── Util.java └── resources ├── assets └── saltlib │ ├── DefaultFragmentShader.glsl │ ├── DefaultVertexShader.glsl │ └── icon.png ├── fabric.mod.json └── saltlib.mixins.json /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # Automatically build the project and run any configured tests for every push 2 | # and submitted pull request. This can help catch issues that only occur on 3 | # certain Java versions, and provides a first line of defence against bad commits. 4 | 5 | name: Build 6 | 7 | on: [push, pull_request] 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | java: [ 14 | "17" # Latest version 15 | ] 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | - uses: gradle/wrapper-validation-action@v1 20 | - uses: actions/setup-java@v2 21 | with: 22 | distribution: "temurin" 23 | java-version: ${{ matrix.java }} 24 | 25 | - name: Grant execute permission 26 | run: chmod +x ./gradlew 27 | - name: Build with Gradle 28 | run: ./gradlew build 29 | 30 | - name: Upload a Build Artifact 31 | uses: actions/upload-artifact@v3.0.0 32 | with: 33 | # Artifact name 34 | name: build 35 | path: build/libs/*.jar 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | build/ 3 | classes/ 4 | out/ 5 | 6 | run/ 7 | 8 | #Visual Studio Code specific 9 | .settings/ 10 | .vscode/ 11 | .classpath/ 12 | .project/ 13 | bin/ 14 | 15 | #MacOS specific 16 | *.DS_Store -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Deex 2 | 3 | This software is provided 'as-is', without any express or implied warranty. In 4 | no event will the authors be held liable for any damages arising from the use of 5 | this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, including 8 | commercial applications, and to alter it and redistribute it freely, subject to 9 | the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not claim 12 | that you wrote the original software. If you use this software in a product, 13 | an acknowledgment in the product documentation would be appreciated but is 14 | not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source distribution. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The project is on a break, however I still check pull requests and issues once in a while. 2 | 3 | ![SaltLib](src/main/resources/assets/saltlib/icon.png) 4 | 5 | # SaltLib 6 | SaltLib aims to be an alternative of the Sodium mod for Minecraft, but for legacy versions (1.3.2-1.13.2) of the game. 7 | 8 | Might not compatible with Optifine in future 9 | 10 | **Performance:** 11 | idk try it out 12 | seems like only 10% with modern devices but might have more improvement with Intel Intergrated GPU 13 | 14 | **Requirements:** 15 | A gpu (can be integrated) made after 2008 16 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins 2 | { 3 | id 'java' 4 | id 'fabric-loom' version "1.0-SNAPSHOT" 5 | id 'maven-publish' 6 | id 'com.github.johnrengelman.shadow' version '7.1.2' 7 | } 8 | 9 | sourceCompatibility = JavaVersion.VERSION_1_8 10 | targetCompatibility = JavaVersion.VERSION_1_8 11 | 12 | archivesBaseName = project.archives_base_name 13 | version = project.mod_version 14 | group = project.maven_group 15 | 16 | repositories 17 | { 18 | mavenCentral() 19 | maven { url "https://jitpack.io" } 20 | maven 21 | { 22 | name = "legacy-fabric" 23 | url = "https://maven.legacyfabric.net" 24 | } 25 | // Fixed LWJGL on Linux 26 | maven 27 | { 28 | name = 'Babric' 29 | url = 'https://maven.glass-launcher.net/babric' 30 | } 31 | } 32 | 33 | loom 34 | { 35 | setIntermediaryUrl('https://maven.legacyfabric.net/net/legacyfabric/intermediary/%1$s/intermediary-%1$s-v2.jar'); 36 | 37 | // Only needed for versions not available from vanilla launcher by default. 38 | customMinecraftManifest.set("https://meta.legacyfabric.net/v2/manifest/${minecraft_version}") 39 | 40 | // Required by 1.7.x 41 | // runs 42 | // { 43 | // client 44 | // { 45 | // programArgs "--userProperties", "{}" 46 | // } 47 | // } 48 | } 49 | 50 | 51 | def lwjgl2 = !project.minecraft_version.startsWith("1.13") 52 | def currentOs = System.getProperty("os.name").toLowerCase(Locale.ENGLISH) 53 | 54 | dependencies 55 | { 56 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 57 | mappings "net.legacyfabric:yarn:${project.yarn_mappings}:v2" 58 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" 59 | 60 | // Fabric API provides hooks for events, item registration, and more. As most mods will need this, it's included by default. 61 | // If you know for a fact you don't, it's not required and can be safely removed. 62 | // modImplementation ("net.legacyfabric.legacy-fabric-api:legacy-fabric-api:${fabric_version}") 63 | // { 64 | // exclude module: "legacy-fabric-entity-events-v1" 65 | // } 66 | 67 | if (lwjgl2) 68 | { 69 | if (currentOs.contains("mac")) 70 | { 71 | implementation 'org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209' 72 | implementation 'org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209' 73 | implementation 'org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209' 74 | } 75 | else if (currentOs.contains("linux")) 76 | { 77 | implementation 'org.lwjgl.lwjgl:lwjgl_util:2.9.4-babric.1' 78 | implementation 'org.lwjgl.lwjgl:lwjgl:2.9.4-babric.1' 79 | implementation 'org.lwjgl.lwjgl:lwjgl-platform:2.9.4-babric.1' 80 | } 81 | } 82 | } 83 | 84 | if (lwjgl2) 85 | { 86 | if (currentOs.contains("mac")) 87 | { 88 | configurations.all 89 | { 90 | resolutionStrategy 91 | { 92 | dependencySubstitution 93 | { 94 | substitute module('org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-201408222') with module('org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209') 95 | substitute module('org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-201408222') with module('org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209') 96 | } 97 | force 'org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209' 98 | } 99 | } 100 | } else if (currentOs.contains("linux")) 101 | { 102 | configurations.all 103 | { 104 | resolutionStrategy 105 | { 106 | dependencySubstitution 107 | { 108 | substitute(module('org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209')) using module('org.lwjgl.lwjgl:lwjgl_util:2.9.4-babric.1') 109 | substitute module('org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209') using module('org.lwjgl.lwjgl:lwjgl:2.9.4-babric.1') 110 | } 111 | force 'org.lwjgl.lwjgl:lwjgl-platform:2.9.4-babric.1' 112 | } 113 | } 114 | } 115 | } 116 | 117 | processResources 118 | { 119 | inputs.property "version", project.version 120 | 121 | filesMatching("fabric.mod.json") 122 | { 123 | expand "version": project.version 124 | } 125 | } 126 | 127 | // ensure that the encoding is set to UTF-8, no matter what the system default is 128 | // this fixes some edge cases with special characters not displaying correctly 129 | // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html 130 | tasks.withType(JavaCompile).configureEach 131 | { 132 | it.options.encoding = "UTF-8" 133 | if (JavaVersion.current().isJava9Compatible()) it.options.release = 8 134 | } 135 | 136 | java 137 | { 138 | // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task 139 | // if it is present. 140 | // If you remove this line, sources will not be generated. 141 | withSourcesJar() 142 | } 143 | 144 | jar 145 | { 146 | from("LICENSE.txt") 147 | { 148 | rename { "${it}_${project.archivesBaseName}" } 149 | } 150 | } 151 | 152 | shadowJar 153 | { 154 | relocate 'org.lwjgl', "dependencies.org.lwjgl" 155 | } 156 | 157 | // configure the maven publication 158 | publishing 159 | { 160 | publications 161 | { 162 | mavenJava(MavenPublication) 163 | { 164 | from components.java 165 | } 166 | } 167 | 168 | // select the repositories you want to publish to 169 | repositories 170 | { 171 | // uncomment to publish to the local maven 172 | // mavenLocal() 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx1G 3 | 4 | 5 | # More versions available at: https://skyrising.xyz/legacy-quilt/ 6 | # Fabric Properties 7 | minecraft_version = 1.8.9 8 | yarn_mappings = 1.8.9+build.451 9 | loader_version = 0.14.12 10 | 11 | # Legacy Fabric API 12 | # fabric_version = 1.9.0+1.8.9 13 | 14 | # Mod Properties 15 | mod_version = 0.3.0 16 | maven_group = me.Deex 17 | archives_base_name = SaltLib 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeexCoding/SaltLib/26e220cb5923b84b78eeabb566195b03a5f3212c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 22 15:26:06 CEST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement 2 | { 3 | repositories 4 | { 5 | maven 6 | { 7 | name = 'Fabric' 8 | url = 'https://maven.fabricmc.net/' 9 | } 10 | gradlePluginPortal() 11 | maven 12 | { 13 | name = 'Jitpack' 14 | url = 'https://jitpack.io' 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Debug/Instrumentor.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Debug; 2 | 3 | import java.io.FileOutputStream; 4 | import java.util.concurrent.Semaphore; 5 | 6 | public class Instrumentor 7 | { 8 | private static FileOutputStream out; 9 | private static Semaphore profileWriteMutex = new Semaphore(1); 10 | private static boolean startWithComma = false; 11 | 12 | public static void BeginSession(String name) 13 | { 14 | new Thread(() -> 15 | { 16 | try 17 | { 18 | out = new FileOutputStream(name.concat(".json")); 19 | WriteHeader(); 20 | startWithComma = false; 21 | } 22 | catch (Exception e) 23 | { 24 | System.out.println("[SaltLib] Could not initalize a profiling session!"); 25 | e.printStackTrace(); 26 | } 27 | 28 | }).start(); 29 | } 30 | 31 | public static void EndSession() 32 | { 33 | try 34 | { 35 | WriteFooter(); 36 | out.close(); 37 | } 38 | catch (Exception e) 39 | { 40 | System.out.println("[SaltLib] Could not end a profiling session!"); 41 | e.printStackTrace(); 42 | } 43 | } 44 | 45 | private static void WriteHeader() 46 | { 47 | try 48 | { 49 | out.write("{\"otherData\": {},\"traceEvents\":[".getBytes()); 50 | out.flush(); 51 | } 52 | catch (Exception e) 53 | { 54 | System.out.println("[SaltLib] Error in WriteHeader!"); 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | private static void WriteFooter() 60 | { 61 | try 62 | { 63 | out.write("]}".getBytes()); 64 | out.flush(); 65 | } 66 | catch (Exception e) 67 | { 68 | System.out.println("[SaltLib] Error in WriteFooter!"); 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | public synchronized static void WriteProfile(String name, long start, long end, long threadID) 74 | { 75 | try 76 | { 77 | StringBuilder stringBuild = new StringBuilder(); 78 | 79 | if (startWithComma) 80 | { 81 | stringBuild.append(","); 82 | } 83 | 84 | stringBuild.append("{"); 85 | stringBuild.append("\"cat\":\"function\","); 86 | stringBuild.append("\"dur\":".concat(String.valueOf(end - start)).concat(",")); 87 | stringBuild.append("\"name\":\"".concat(name).concat("\",")); 88 | stringBuild.append("\"ph\":\"X\","); 89 | stringBuild.append("\"pid\":0,"); 90 | stringBuild.append("\"tid\":".concat(String.valueOf(threadID)).concat(",")); 91 | stringBuild.append("\"ts\":".concat(String.valueOf(start))); 92 | stringBuild.append("}"); 93 | 94 | profileWriteMutex.acquire(); 95 | 96 | try 97 | { 98 | out.write(stringBuild.toString().getBytes()); 99 | out.flush(); 100 | startWithComma = true; 101 | } 102 | catch (Exception e) 103 | { 104 | System.out.println("[SaltLib] Failed to write to the profiling output stream!"); 105 | e.printStackTrace(); 106 | } 107 | } 108 | catch (InterruptedException e) 109 | { 110 | System.out.println("[SaltLib] Failed to mutex!"); 111 | e.printStackTrace(); 112 | } 113 | finally 114 | { 115 | profileWriteMutex.release(); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Debug/PerformanceTimer.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Debug; 2 | 3 | import me.Deex.SaltLib.SaltLibMod; 4 | 5 | public class PerformanceTimer 6 | { 7 | private String name; 8 | private long start; 9 | 10 | private PerformanceTimer(String name) 11 | { 12 | this.name = name; 13 | start = System.nanoTime(); 14 | } 15 | 16 | private void StopAndWrite() 17 | { 18 | Instrumentor.WriteProfile(name, start / 1000, System.nanoTime() / 1000, Thread.currentThread().getId()); 19 | } 20 | 21 | public static PerformanceTimer Start(String name) 22 | { 23 | if (SaltLibMod.enableProfiling) 24 | { 25 | return new PerformanceTimer(name); 26 | } 27 | 28 | return null; 29 | } 30 | 31 | public static void StopAndWrite(PerformanceTimer timer) 32 | { 33 | if (timer != null) 34 | { 35 | timer.StopAndWrite(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/BufferBuilderMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import java.util.List; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Overwrite; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | 11 | import net.minecraft.client.render.BufferBuilder; 12 | import net.minecraft.client.render.VertexFormat; 13 | import net.minecraft.client.render.VertexFormatElement; 14 | 15 | @Mixin(BufferBuilder.class) 16 | public abstract class BufferBuilderMixin 17 | { 18 | @Shadow 19 | private ByteBuffer buffer; 20 | 21 | @Shadow 22 | private VertexFormat format; 23 | 24 | @Shadow 25 | private VertexFormatElement currentElement; 26 | 27 | @Shadow 28 | private int currentElementId; 29 | 30 | @Shadow 31 | private int vertexCount; 32 | 33 | @Shadow 34 | private double offsetX; 35 | 36 | @Shadow 37 | private double offsetY; 38 | 39 | @Shadow 40 | private double offsetZ; 41 | 42 | @Shadow 43 | private boolean building; 44 | 45 | public int method_9757() 46 | { 47 | return this.vertexCount * this.format.getVertexSizeInteger(); 48 | } 49 | 50 | /** 51 | * what is javadoc 52 | * @author me 53 | * @reason mod needs functionality 54 | */ 55 | @Overwrite 56 | private void nextElement() 57 | { 58 | List elements = format.getElements(); 59 | 60 | do 61 | { 62 | this.currentElementId++; 63 | if (this.currentElementId >= elements.size()) 64 | { 65 | this.currentElementId -= elements.size(); 66 | } 67 | 68 | currentElement = elements.get(currentElementId); 69 | 70 | } while (currentElement.getType() == VertexFormatElement.Type.PADDING); 71 | } 72 | 73 | @Shadow 74 | private int drawMode; 75 | 76 | @Shadow 77 | private boolean textured; 78 | 79 | @Shadow 80 | public abstract void reset(); 81 | 82 | @Overwrite 83 | public void begin(int drawMode, VertexFormat format) 84 | { 85 | if (this.building) 86 | { 87 | return; //Don't throw an error idiot 88 | } 89 | 90 | this.building = true; 91 | this.reset(); 92 | this.drawMode = drawMode; 93 | this.format = format; 94 | this.currentElement = format.get(this.currentElementId); 95 | this.textured = false; 96 | this.buffer.limit(this.buffer.capacity()); 97 | } 98 | 99 | @Overwrite 100 | public void end() 101 | { 102 | if (!this.building) 103 | { 104 | return; //Have you heard of assertions? 105 | } 106 | 107 | this.building = false; 108 | this.buffer.position(0); 109 | this.buffer.limit(this.method_9757() * 4); 110 | } 111 | 112 | 113 | //The matrix tranforms are not exact functionaltiy, since OpenGL transforms the verticies with the matrix stack once 114 | //it is requested to be drawn or glBegin has been called 115 | 116 | /*@Overwrite 117 | public BufferBuilder vertex(double x, double y, double z) 118 | { 119 | int i = this.vertexCount * this.format.getVertexSize() + this.format.getIndex(this.currentElementId); 120 | 121 | Vector4f vec = new Vector4f((float)x, (float)y, (float)z, 1.0f); 122 | 123 | //(m1*m2)*v is the same as m1*(m2*v) 124 | //Where m1 and m2 are matrices and v is a vector 125 | //projection * view -> view first thenprojection 126 | 127 | Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_MODELVIEW).GetTop(), vec, vec); 128 | Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_PROJECTION).GetTop(), vec, vec); 129 | 130 | x = (double)vec.x; 131 | y = (double)vec.y; 132 | z = (double)vec.z; 133 | 134 | switch (this.currentElement.getFormat()) 135 | { 136 | case FLOAT: 137 | { 138 | this.buffer.putFloat(i, (float)(x + this.offsetX)); 139 | this.buffer.putFloat(i + 4, (float)(y + this.offsetY)); 140 | this.buffer.putFloat(i + 8, (float)(z + this.offsetZ)); 141 | break; 142 | } 143 | case UNSIGNED_INT: 144 | case INT: 145 | { 146 | this.buffer.putInt(i, Float.floatToRawIntBits((float)(x + this.offsetX))); 147 | this.buffer.putInt(i + 4, Float.floatToRawIntBits((float)(y + this.offsetY))); 148 | this.buffer.putInt(i + 8, Float.floatToRawIntBits((float)(z + this.offsetZ))); 149 | break; 150 | } 151 | case UNSIGNED_SHORT: 152 | case SHORT: 153 | { 154 | this.buffer.putShort(i, (short)(x + this.offsetX)); 155 | this.buffer.putShort(i + 2, (short)(y + this.offsetY)); 156 | this.buffer.putShort(i + 4, (short)(z + this.offsetZ)); 157 | break; 158 | } 159 | case UNSIGNED_BYTE: 160 | case BYTE: 161 | { 162 | this.buffer.put(i, (byte)(x + this.offsetX)); 163 | this.buffer.put(i + 1, (byte)(y + this.offsetY)); 164 | this.buffer.put(i + 2, (byte)(z + this.offsetZ)); 165 | } 166 | } 167 | this.nextElement(); 168 | return (BufferBuilder)(Object)this; 169 | } 170 | 171 | public BufferBuilder texture(double u, double v) 172 | { 173 | int i = this.vertexCount * this.format.getVertexSize() + this.format.getIndex(this.currentElementId); 174 | 175 | Vector4f vec = new Vector4f((float)u, (float)v, 1.0f, 1.0f); 176 | 177 | Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_TEXTURE).GetTop(), vec, vec); 178 | 179 | u = (float)vec.x; 180 | v = (float)vec.y; 181 | 182 | switch (this.currentElement.getFormat()) 183 | { 184 | case FLOAT: 185 | { 186 | this.buffer.putFloat(i, (float)u); 187 | this.buffer.putFloat(i + 4, (float)v); 188 | break; 189 | } 190 | case UNSIGNED_INT: 191 | case INT: 192 | { 193 | this.buffer.putInt(i, (int)u); 194 | this.buffer.putInt(i + 4, (int)v); 195 | break; 196 | } 197 | case UNSIGNED_SHORT: 198 | case SHORT: 199 | { 200 | this.buffer.putShort(i, (short)v); 201 | this.buffer.putShort(i + 2, (short)u); 202 | break; 203 | } 204 | case UNSIGNED_BYTE: 205 | case BYTE: 206 | { 207 | this.buffer.put(i, (byte)v); 208 | this.buffer.put(i + 1, (byte)u); 209 | } 210 | } 211 | this.nextElement(); 212 | return (BufferBuilder)(Object)this; 213 | } 214 | 215 | @Overwrite 216 | public BufferBuilder texture2(int u, int v) 217 | { 218 | //TODO: Call to texture instead 219 | 220 | int i = this.vertexCount * this.format.getVertexSize() + this.format.getIndex(this.currentElementId); 221 | 222 | Vector4f vec = new Vector4f((float)u, (float)v, 1.0f, 1.0f); 223 | 224 | Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_TEXTURE).GetTop(), vec, vec); 225 | 226 | u = (int)vec.x; 227 | v = (int)vec.y; 228 | 229 | switch (this.currentElement.getFormat()) 230 | { 231 | case FLOAT: 232 | { 233 | this.buffer.putFloat(i, u); 234 | this.buffer.putFloat(i + 4, v); 235 | break; 236 | } 237 | case UNSIGNED_INT: 238 | case INT: 239 | { 240 | this.buffer.putInt(i, u); 241 | this.buffer.putInt(i + 4, v); 242 | break; 243 | } 244 | case UNSIGNED_SHORT: 245 | case SHORT: 246 | { 247 | this.buffer.putShort(i, (short)v); 248 | this.buffer.putShort(i + 2, (short)u); 249 | break; 250 | } 251 | case UNSIGNED_BYTE: 252 | case BYTE: 253 | { 254 | this.buffer.put(i, (byte)v); 255 | this.buffer.put(i + 1, (byte)u); 256 | } 257 | } 258 | this.nextElement(); 259 | return (BufferBuilder)(Object)this; 260 | } 261 | /**/ 262 | } 263 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/BufferRendererMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import me.Deex.SaltLib.Renderer.CustomBufferRenderer; 4 | 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Overwrite; 7 | 8 | import net.minecraft.client.render.BufferBuilder; 9 | import net.minecraft.client.render.BufferRenderer; 10 | 11 | @Mixin(BufferRenderer.class) 12 | public class BufferRendererMixin 13 | { 14 | /** 15 | * what is javadoc 16 | * @author me 17 | * @reason mod needs functionality 18 | */ 19 | @Overwrite 20 | public void draw(BufferBuilder builder) 21 | { 22 | CustomBufferRenderer.DrawAndReset(builder); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ChunkBuilderMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Overwrite; 5 | 6 | 7 | import net.minecraft.client.render.BufferBuilder; 8 | import net.minecraft.client.render.chunk.ChunkBuilder; 9 | import net.minecraft.client.world.BuiltChunk; 10 | 11 | @Mixin(ChunkBuilder.class) 12 | public class ChunkBuilderMixin 13 | { 14 | @Overwrite 15 | private void uploadGlList(BufferBuilder bufferBuilder, int i, BuiltChunk builtChunk) 16 | { 17 | //NOTE: To my knowledge, this function doesn't get called when VBOs are turned on. 18 | return; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ChunkRenderHelperImplMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.Redirect; 5 | import org.spongepowered.asm.mixin.injection.At; 6 | 7 | import net.minecraft.client.render.WorldRenderer; 8 | import net.minecraft.client.render.world.ChunkRenderHelperImpl; 9 | import net.minecraft.client.world.BuiltChunk; 10 | import net.minecraft.util.math.BlockPos; 11 | import net.minecraft.world.World; 12 | 13 | @Mixin(ChunkRenderHelperImpl.class) 14 | public abstract class ChunkRenderHelperImplMixin extends BuiltChunk 15 | { 16 | //TODO: Doesn't work, I am losing my mind 17 | @Redirect(method="", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/GlAllocationUtils;genLists(I)I")) 18 | private static synchronized int redirect(int i) 19 | { 20 | return -1; 21 | } 22 | 23 | //TODO: Ask someone smart what to do with the constructor when mixing in with an extends class 24 | public ChunkRenderHelperImplMixin(World world, WorldRenderer worldRenderer, BlockPos blockPos, int i) 25 | { 26 | super(world, worldRenderer, blockPos, i); 27 | } 28 | 29 | @Override 30 | public void delete() 31 | { 32 | return; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/GLXMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import com.mojang.blaze3d.platform.GLX; 4 | 5 | import me.Deex.SaltLib.SaltLibMod; 6 | import me.Deex.SaltLib.Renderer.CustomBufferRenderer; 7 | import me.Deex.SaltLib.Renderer.GLShader; 8 | import me.Deex.SaltLib.Renderer.MatrixStack; 9 | import net.fabricmc.loader.api.FabricLoader; 10 | 11 | import org.lwjgl.opengl.GL11; 12 | import org.lwjgl.opengl.GL15; 13 | import org.lwjgl.opengl.GL20; 14 | import org.lwjgl.opengl.GL30; 15 | import org.lwjgl.opengl.GL43; 16 | import org.lwjgl.opengl.KHRDebugCallback; 17 | import org.lwjgl.util.vector.Vector3f; 18 | import org.spongepowered.asm.mixin.Mixin; 19 | import org.spongepowered.asm.mixin.injection.At; 20 | import org.spongepowered.asm.mixin.injection.Inject; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 22 | 23 | @Mixin(GLX.class) 24 | public class GLXMixin 25 | { 26 | @Inject(method = "createContext", at = @At("TAIL")) 27 | private static void createContext(CallbackInfo ci) 28 | { 29 | //NOTE: Ground work for switching to VAOs from old vbo-only rendering 30 | 31 | if (FabricLoader.getInstance().isDevelopmentEnvironment()) 32 | { 33 | //GL11.glEnable(GL43.GL_DEBUG_OUTPUT); 34 | //GL43.glDebugMessageCallback(new KHRDebugCallback()); 35 | } 36 | 37 | SaltLibMod.defaultShader = new GLShader("/assets/saltlib/DefaultVertexShader.glsl", 38 | "/assets/saltlib/DefaultFragmentShader.glsl"); 39 | 40 | GL20.glUseProgram(0); 41 | 42 | CustomBufferRenderer.vao = GL30.glGenVertexArrays(); 43 | GL30.glBindVertexArray(CustomBufferRenderer.vao); 44 | 45 | CustomBufferRenderer.vbo = GL15.glGenBuffers(); 46 | GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, CustomBufferRenderer.vbo); 47 | 48 | GL30.glBindVertexArray(0); 49 | GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 50 | 51 | MatrixStack.CreateGLStacks(); 52 | //MatrixStack.GetGLStack(GL11.GL_PROJECTION).Translate(new Vector3f(1000000.0f, 0.0f, 0.0f)); 53 | 54 | System.out.println("[SaltLib] Initalized OpenGL stuff"); 55 | } 56 | } 57 | // -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/GlStateManagerMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import java.nio.FloatBuffer; 4 | 5 | import org.lwjgl.opengl.GL11; 6 | import org.lwjgl.util.vector.Vector3f; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Overwrite; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | import com.mojang.blaze3d.platform.GlStateManager; 14 | 15 | import me.Deex.SaltLib.Renderer.MatrixStack; 16 | import me.Deex.SaltLib.Utils.Util; 17 | import net.minecraft.client.util.GlAllocationUtils; 18 | import net.minecraft.client.util.math.Matrix4f; 19 | 20 | @Mixin(GlStateManager.class) 21 | public class GlStateManagerMixin 22 | { 23 | /** 24 | * what is javadoc 25 | * @author me 26 | * @reason mod needs functionality 27 | */ 28 | @Overwrite 29 | public static void matrixMode(int mode) 30 | { 31 | MatrixStack.SetCurrentStack(mode); 32 | } 33 | 34 | /** 35 | * what is javadoc 36 | * @author me 37 | * @reason mod needs functionality 38 | */ 39 | @Overwrite 40 | public static void loadIdentity() 41 | { 42 | MatrixStack.GetCurrentStack().SetIdentity(); 43 | } 44 | 45 | /** 46 | * what is javadoc 47 | * @author me 48 | * @reason mod needs functionality 49 | */ 50 | @Overwrite 51 | public static void pushMatrix() 52 | { 53 | MatrixStack.GetCurrentStack().Push(); 54 | } 55 | 56 | /** 57 | * what is javadoc 58 | * @author me 59 | * @reason mod needs functionality 60 | */ 61 | @Overwrite 62 | public static void popMatrix() 63 | { 64 | MatrixStack.GetCurrentStack().Pop(); 65 | } 66 | 67 | /** 68 | * what is javadoc 69 | * @author me 70 | * @reason mod needs functionality 71 | */ 72 | @Inject(at = @At("HEAD"), method = "getFloat", cancellable = true) 73 | private static void getFloat(int mode, FloatBuffer buffer, CallbackInfo ci) 74 | { 75 | switch (mode) 76 | { 77 | case GL11.GL_MODELVIEW: 78 | case GL11.GL_PROJECTION: 79 | case GL11.GL_TEXTURE: 80 | case GL11.GL_MODELVIEW_MATRIX: 81 | case GL11.GL_PROJECTION_MATRIX: 82 | case GL11.GL_TEXTURE_MATRIX: 83 | { 84 | int startPos = buffer.position(); 85 | 86 | Util.WriteMatrix4fIntoFloatBuffer(MatrixStack.GetGLStack(mode).GetTop(), buffer); 87 | 88 | buffer.position(startPos); 89 | ci.cancel(); 90 | } 91 | } 92 | 93 | } 94 | 95 | /** 96 | * what is javadoc 97 | * @author me 98 | * @reason mod needs functionality 99 | */ 100 | @Overwrite 101 | public static void ortho(double l, double r, double b, double t, double n, double f) 102 | { 103 | MatrixStack.GetCurrentStack().Ortho((float)l, (float)r, (float)b, (float)t, (float)n, (float)f); 104 | } 105 | 106 | /** 107 | * what is javadoc 108 | * @author me 109 | * @reason mod needs functionality 110 | */ 111 | @Overwrite 112 | public static void scalef(float x, float y, float z) 113 | { 114 | MatrixStack.GetCurrentStack().Scale(new Vector3f(x, y, z)); 115 | } 116 | 117 | /** 118 | * what is javadoc 119 | * @author me 120 | * @reason mod needs functionality 121 | */ 122 | @Overwrite 123 | public static void scaled(double x, double y, double z) 124 | { 125 | MatrixStack.GetCurrentStack().Scale(new Vector3f((float)x, (float)y, (float)z)); 126 | } 127 | 128 | /** 129 | * what is javadoc 130 | * @author me 131 | * @reason mod needs functionality 132 | */ 133 | @Overwrite 134 | public static void rotatef(float angle, float x, float y, float z) 135 | { 136 | MatrixStack.GetCurrentStack().Rotate(angle, new Vector3f(x, y, z)); 137 | } 138 | 139 | /** 140 | * what is javadoc 141 | * @author me 142 | * @reason mod needs functionality 143 | */ 144 | @Overwrite 145 | public static void translatef(float x, float y, float z) 146 | { 147 | MatrixStack.GetCurrentStack().Translate(new Vector3f(x, y, z)); 148 | } 149 | 150 | /** 151 | * what is javadoc 152 | * @author me 153 | * @reason mod needs functionality 154 | */ 155 | @Overwrite 156 | public static void translated(double x, double y, double z) 157 | { 158 | MatrixStack.GetCurrentStack().Translate(new Vector3f((float)x, (float)y, (float)z)); 159 | } 160 | 161 | /** 162 | * what is javadoc 163 | * @author me 164 | * @reason mod needs functionality 165 | */ 166 | @Overwrite 167 | public static void multiMatrix(FloatBuffer buffer) 168 | { 169 | Matrix4f mat = new Matrix4f(); 170 | int startPos = buffer.position(); 171 | mat.load(buffer); 172 | buffer.position(startPos); 173 | MatrixStack.GetCurrentStack().Multiply(mat); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ListedChunkRenderManagerMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | 5 | import net.minecraft.client.render.RenderLayer; 6 | import net.minecraft.client.render.world.AbstractChunkRenderManager; 7 | import net.minecraft.client.render.world.ListedChunkRenderManager; 8 | 9 | @Mixin(ListedChunkRenderManager.class) 10 | public class ListedChunkRenderManagerMixin extends AbstractChunkRenderManager 11 | { 12 | @Override 13 | public void render(RenderLayer layer) 14 | { 15 | //NOTE: To my knowledge, this function doesn't get called when VBOs are turned on. 16 | return; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/MinecraftClientMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Shadow; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | import me.Deex.SaltLib.SaltLibMod; 11 | 12 | import net.minecraft.client.MinecraftClient; 13 | 14 | @Mixin(MinecraftClient.class) 15 | public class MinecraftClientMixin 16 | { 17 | @Inject(at = @At("TAIL"), method = "initializeGame") 18 | private void initializeGame(CallbackInfo ci) 19 | { 20 | //This will make startup slower lol 21 | MinecraftClient.getInstance().options.vbo = true; 22 | MinecraftClient.getInstance().options.save(); 23 | MinecraftClient.getInstance().worldRenderer.reload(); 24 | } 25 | 26 | @Inject(at = @At("HEAD"), method = "stop") 27 | private void stop(CallbackInfo ci) 28 | { 29 | SaltLibMod.OnShutdown(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ModelBoxAccessor.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.gen.Accessor; 5 | 6 | import net.minecraft.client.render.ModelBox; 7 | import net.minecraft.client.util.TexturedQuad; 8 | 9 | @Mixin(ModelBox.class) 10 | public interface ModelBoxAccessor 11 | { 12 | @Accessor 13 | TexturedQuad[] getQuads(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ModelPartMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import java.util.List; 4 | 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Overwrite; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | 9 | import com.mojang.blaze3d.platform.GlStateManager; 10 | 11 | import me.Deex.SaltLib.Renderer.CustomBufferRenderer; 12 | import me.Deex.SaltLib.Renderer.BufferBuilderRenderData; 13 | import net.minecraft.client.render.BufferBuilder; 14 | import net.minecraft.client.render.ModelBox; 15 | import net.minecraft.client.render.Tessellator; 16 | import net.minecraft.client.render.VertexFormats; 17 | import net.minecraft.client.render.model.ModelPart; 18 | import net.minecraft.client.util.TexturedQuad; 19 | import net.minecraft.client.util.math.TexturePosition; 20 | import net.minecraft.util.math.Vec3d; 21 | 22 | @Mixin(ModelPart.class) 23 | public class ModelPartMixin 24 | { 25 | private BufferBuilderRenderData bufferBuilderData; 26 | 27 | @Shadow 28 | private boolean compiledList; 29 | 30 | @Shadow 31 | private int glList; 32 | 33 | @Shadow 34 | public List cuboids; 35 | 36 | @Shadow 37 | public List modelList; 38 | 39 | @Shadow 40 | public boolean hide; 41 | 42 | @Shadow 43 | public boolean visible; 44 | 45 | @Shadow 46 | public float pivotX; 47 | 48 | @Shadow 49 | public float pivotY; 50 | 51 | @Shadow 52 | public float pivotZ; 53 | 54 | @Shadow 55 | public float posX; 56 | 57 | @Shadow 58 | public float posY; 59 | 60 | @Shadow 61 | public float posZ; 62 | 63 | @Shadow 64 | public float offsetX; 65 | 66 | @Shadow 67 | public float offsetY; 68 | 69 | @Shadow 70 | public float offsetZ; 71 | 72 | //TODO: Works in runClient, doesnt work in release, why? 73 | public void render(float scale) 74 | { 75 | if (this.hide) 76 | { 77 | return; 78 | } 79 | if (!this.visible) 80 | { 81 | return; 82 | } 83 | if (!this.compiledList) 84 | { 85 | this.compileList(scale); 86 | } 87 | GlStateManager.translatef(this.offsetX, this.offsetY, this.offsetZ); 88 | if (this.posX != 0.0f || this.posY != 0.0f || this.posZ != 0.0f) 89 | { 90 | GlStateManager.pushMatrix(); 91 | GlStateManager.translatef(this.pivotX * scale, this.pivotY * scale, this.pivotZ * scale); 92 | if (this.posZ != 0.0f) 93 | { 94 | GlStateManager.rotatef(this.posZ * 57.295776f, 0.0f, 0.0f, 1.0f); 95 | } 96 | if (this.posY != 0.0f) 97 | { 98 | GlStateManager.rotatef(this.posY * 57.295776f, 0.0f, 1.0f, 0.0f); 99 | } 100 | if (this.posX != 0.0f) 101 | { 102 | GlStateManager.rotatef(this.posX * 57.295776f, 1.0f, 0.0f, 0.0f); 103 | } 104 | //GlStateManager.callList(this.glList); 105 | CallListField1612(); 106 | if (this.modelList != null) 107 | { 108 | for (int i = 0; i < this.modelList.size(); ++i) 109 | { 110 | this.modelList.get(i).render(scale); 111 | } 112 | } 113 | GlStateManager.popMatrix(); 114 | } 115 | else if (this.pivotX != 0.0f || this.pivotY != 0.0f || this.pivotZ != 0.0f) 116 | { 117 | GlStateManager.translatef(this.pivotX * scale, this.pivotY * scale, this.pivotZ * scale); 118 | //GlStateManager.callList(this.glList); 119 | CallListField1612(); 120 | if (this.modelList != null) 121 | { 122 | for (int i = 0; i < this.modelList.size(); ++i) 123 | { 124 | this.modelList.get(i).render(scale); 125 | } 126 | } 127 | GlStateManager.translatef(-this.pivotX * scale, -this.pivotY * scale, -this.pivotZ * scale); 128 | } 129 | else 130 | { 131 | //GlStateManager.callList(this.glList); 132 | CallListField1612(); 133 | if (this.modelList != null) 134 | { 135 | for (int i = 0; i < this.modelList.size(); ++i) 136 | { 137 | this.modelList.get(i).render(scale); 138 | } 139 | } 140 | } 141 | GlStateManager.translatef(-this.offsetX, -this.offsetY, -this.offsetZ); 142 | } 143 | 144 | public void method_1193(float f) 145 | { 146 | if (this.hide) 147 | { 148 | return; 149 | } 150 | if (!this.visible) 151 | { 152 | return; 153 | } 154 | if (!this.compiledList) 155 | { 156 | this.compileList(f); 157 | } 158 | GlStateManager.pushMatrix(); 159 | GlStateManager.translatef(this.pivotX * f, this.pivotY * f, this.pivotZ * f); 160 | if (this.posY != 0.0f) 161 | { 162 | GlStateManager.rotatef(this.posY * 57.295776f, 0.0f, 1.0f, 0.0f); 163 | } 164 | if (this.posX != 0.0f) 165 | { 166 | GlStateManager.rotatef(this.posX * 57.295776f, 1.0f, 0.0f, 0.0f); 167 | } 168 | if (this.posZ != 0.0f) 169 | { 170 | GlStateManager.rotatef(this.posZ * 57.295776f, 0.0f, 0.0f, 1.0f); 171 | } 172 | //GlStateManager.callList(this.glList); 173 | CallListField1612(); 174 | GlStateManager.popMatrix(); 175 | } 176 | 177 | @Overwrite 178 | private void compileList(float scale) 179 | { 180 | this.glList = 4; 181 | 182 | BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer(); 183 | bufferBuilder.begin(7, VertexFormats.ENTITY); 184 | for (int i = 0; i < this.cuboids.size(); ++i) 185 | { 186 | ModelBox currentCuboid = cuboids.get(i); 187 | 188 | for (int i2 = 0; i2 < ((ModelBoxAccessor)currentCuboid).getQuads().length; ++i2) 189 | { 190 | TexturedQuad currentQuad = ((ModelBoxAccessor)currentCuboid).getQuads()[i2]; 191 | 192 | Vec3d vec3d = ((TexturedQuadAccessor)currentQuad).getPositions()[1].position.reverseSubtract(((TexturedQuadAccessor)currentQuad).getPositions()[0].position); 193 | Vec3d vec3d2 = ((TexturedQuadAccessor)currentQuad).getPositions()[1].position.reverseSubtract(((TexturedQuadAccessor)currentQuad).getPositions()[2].position); 194 | Vec3d vec3d3 = vec3d2.crossProduct(vec3d).normalize(); 195 | float f = (float)vec3d3.x; 196 | float g = (float)vec3d3.y; 197 | float h = (float)vec3d3.z; 198 | if (((TexturedQuadAccessor)currentQuad).getField_1507()) 199 | { 200 | f = -f; 201 | g = -g; 202 | h = -h; 203 | } 204 | for (int i3 = 0; i3 < 4; ++i3) 205 | { 206 | TexturePosition texturePosition = ((TexturedQuadAccessor)currentQuad).getPositions()[i3]; 207 | bufferBuilder.vertex(texturePosition.position.x * (double)scale, texturePosition.position.y * (double)scale, texturePosition.position.z * (double)scale).texture(texturePosition.u, texturePosition.v).normal(f, g, h).next(); 208 | } 209 | } 210 | } 211 | 212 | bufferBuilder.end(); 213 | 214 | if (bufferBuilderData == null) 215 | { 216 | bufferBuilderData = new BufferBuilderRenderData(bufferBuilder); 217 | } 218 | else 219 | { 220 | bufferBuilderData.SetData(bufferBuilder); 221 | } 222 | 223 | bufferBuilder.reset(); 224 | 225 | this.compiledList = true; 226 | } 227 | 228 | private void CallListField1612() 229 | { 230 | CustomBufferRenderer.DrawNoReset(bufferBuilderData); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/ProjectMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.lwjgl.util.glu.Project; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Overwrite; 6 | 7 | import me.Deex.SaltLib.Renderer.MatrixStack; 8 | 9 | @Mixin(Project.class) 10 | public class ProjectMixin 11 | { 12 | @Overwrite(remap = false) 13 | public static void gluPerspective(float fovy, float aspect, float zNear, float zFar) 14 | { 15 | MatrixStack.GetCurrentStack().Perspective(fovy, aspect, zNear, zFar); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/RealmsNotificationScreenMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.Overwrite; 5 | 6 | import com.mojang.realmsclient.gui.screens.RealmsNotificationsScreen; 7 | 8 | @Mixin(RealmsNotificationsScreen.class) 9 | public class RealmsNotificationScreenMixin 10 | { 11 | //Stub function to remove random crash when starting up. 12 | //I'm 99% sure it's a problem with fabric. 13 | @Overwrite 14 | public void init() 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/TextRendererMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | import org.lwjgl.util.vector.Matrix4f; 5 | import org.lwjgl.util.vector.Vector3f; 6 | import org.lwjgl.util.vector.Vector4f; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Overwrite; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | 12 | import com.mojang.blaze3d.platform.GlStateManager; 13 | 14 | import me.Deex.SaltLib.Renderer.MatrixStack; 15 | import net.minecraft.client.font.TextRenderer; 16 | import net.minecraft.client.texture.TextureManager; 17 | import net.minecraft.util.Identifier; 18 | 19 | @Mixin(TextRenderer.class) 20 | public class TextRendererMixin 21 | { 22 | @Shadow 23 | private int[] characterWidths; 24 | 25 | @Shadow 26 | private byte[] glyphWidths; 27 | 28 | @Shadow 29 | @Final 30 | private Identifier fontTexture; 31 | 32 | @Shadow 33 | @Final 34 | private TextureManager textureManager; 35 | 36 | @Shadow 37 | private float x; 38 | 39 | @Shadow 40 | private float y; 41 | 42 | //TODO: Speed this up with vaos and batching!!!!!!!!!!!!!!!!!! 43 | 44 | @Overwrite 45 | private float drawLayerNormal(int characterIndex, boolean italic) 46 | { 47 | Vector3f pos; 48 | 49 | GlStateManager.matrixMode(GL11.GL_MODELVIEW); 50 | GlStateManager.pushMatrix(); 51 | 52 | int i = characterIndex % 16 * 8; 53 | int j = characterIndex / 16 * 8; 54 | float k = italic ? 1.0f : 0.0f; 55 | this.textureManager.bindTexture(this.fontTexture); 56 | int l = this.characterWidths[characterIndex]; 57 | float f = (float)l - 0.01f; 58 | GL11.glBegin(5); 59 | 60 | GL11.glTexCoord2f((float)i / 128.0f, (float)j / 128.0f); 61 | pos = new Vector3f(this.x + k, this.y, 0.0f); 62 | MatrixStack.TransformWorldPoint(pos); 63 | GL11.glVertex3f(pos.x, pos.y, pos.z); 64 | 65 | GL11.glTexCoord2f((float)i / 128.0f, ((float)j + 7.99f) / 128.0f); 66 | pos = new Vector3f(this.x - k, this.y + 7.99f, 0.0f); 67 | MatrixStack.TransformWorldPoint(pos); 68 | GL11.glVertex3f(pos.x, pos.y, pos.z); 69 | 70 | GL11.glTexCoord2f(((float)i + f - 1.0f) / 128.0f, (float)j / 128.0f); 71 | pos = new Vector3f(this.x + f - 1.0f + k, this.y, 0.0f); 72 | MatrixStack.TransformWorldPoint(pos); 73 | GL11.glVertex3f(pos.x, pos.y, pos.z); 74 | 75 | GL11.glTexCoord2f(((float)i + f - 1.0f) / 128.0f, ((float)j + 7.99f) / 128.0f); 76 | pos = new Vector3f(this.x + (float)f - 1.0f - k, this.y + 7.99f, 0.0f); 77 | MatrixStack.TransformWorldPoint(pos); 78 | GL11.glVertex3f(pos.x, pos.y, pos.z); 79 | 80 | GL11.glEnd(); 81 | 82 | GlStateManager.popMatrix(); 83 | 84 | return l; 85 | } 86 | 87 | @Overwrite 88 | private float drawLayerUnicode(char character, boolean italic) 89 | { 90 | if (this.glyphWidths[character] == 0) { 91 | return 0.0f; 92 | } 93 | int i = character / 256; 94 | this.bindPageTexture(i); 95 | int j = this.glyphWidths[character] >>> 4; 96 | int k = this.glyphWidths[character] & 0xF; 97 | float f = j; 98 | float g = k + 1; 99 | float h = (float)(character % 16 * 16) + f; 100 | float l = (character & 0xFF) / 16 * 16; 101 | float m = g - f - 0.02f; 102 | float n = italic ? 1.0f : 0.0f; 103 | GL11.glBegin(5); 104 | GL11.glTexCoord2f(h / 256.0f, l / 256.0f); 105 | GL11.glVertex3f(this.x + n, this.y, 0.0f); 106 | GL11.glTexCoord2f(h / 256.0f, (l + 15.98f) / 256.0f); 107 | GL11.glVertex3f(this.x - n, this.y + 7.99f, 0.0f); 108 | GL11.glTexCoord2f((h + m) / 256.0f, l / 256.0f); 109 | GL11.glVertex3f(this.x + m / 2.0f + n, this.y, 0.0f); 110 | GL11.glTexCoord2f((h + m) / 256.0f, (l + 15.98f) / 256.0f); 111 | GL11.glVertex3f(this.x + m / 2.0f - n, this.y + 7.99f, 0.0f); 112 | GL11.glEnd(); 113 | return (g - f) / 2.0f + 1.0f; 114 | } 115 | 116 | @Shadow 117 | private void bindPageTexture(int index) {} 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/TexturedQuadAccessor.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.gen.Accessor; 5 | 6 | import net.minecraft.client.util.TexturedQuad; 7 | import net.minecraft.client.util.math.TexturePosition; 8 | 9 | @Mixin(TexturedQuad.class) 10 | public interface TexturedQuadAccessor 11 | { 12 | @Accessor 13 | TexturePosition[] getPositions(); 14 | 15 | @Accessor 16 | boolean getField_1507(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/VideoOptionsScreenMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.Final; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Overwrite; 6 | import org.spongepowered.asm.mixin.Shadow; 7 | 8 | import net.minecraft.client.gui.screen.Screen; 9 | import net.minecraft.client.gui.screen.VideoOptionsScreen; 10 | import net.minecraft.client.gui.widget.ButtonWidget; 11 | import net.minecraft.client.gui.widget.EntryListWidget; 12 | import net.minecraft.client.gui.widget.OptionPairWidget; 13 | import net.minecraft.client.options.GameOptions; 14 | import net.minecraft.client.resource.language.I18n; 15 | 16 | @Mixin(VideoOptionsScreen.class) 17 | public class VideoOptionsScreenMixin extends Screen 18 | { 19 | @Shadow 20 | private Screen parent; 21 | 22 | @Shadow 23 | protected String title; 24 | 25 | @Shadow 26 | private GameOptions options; 27 | 28 | @Shadow 29 | private EntryListWidget list; 30 | 31 | @Shadow 32 | @Final 33 | private static GameOptions.Option[] OPTIONS; 34 | 35 | /* 36 | @Overwrite 37 | public void init() { 38 | this.title = I18n.translate("options.videoTitle", new Object[0]); 39 | this.buttons.clear(); 40 | this.buttons.add(new ButtonWidget(200, this.width / 2 - 100, this.height - 27, I18n.translate("gui.done", new Object[0]))); 41 | GameOptions.Option[] options = new GameOptions.Option[OPTIONS.length - 1]; 42 | int i = 0; 43 | for (GameOptions.Option option : OPTIONS) 44 | { 45 | if (option == GameOptions.Option.USE_VBO) continue; //Bug in the original version? This breaks out ouf the loop when it sees USE_VBO, however, there are options after that, which will not get added 46 | options[i] = option; 47 | ++i; 48 | } 49 | this.list = new OptionPairWidget(this.client, this.width, this.height, 32, this.height - 32, 25, options); 50 | }*/ 51 | // This overwrite seems useless and might be improved in the future. 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/WorldMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import org.spongepowered.asm.mixin.injection.Inject; 4 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 5 | 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | 9 | import net.minecraft.block.AirBlock; 10 | import net.minecraft.block.BlockState; 11 | import net.minecraft.block.RedstoneWireBlock; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.util.math.Direction; 14 | import net.minecraft.world.World; 15 | 16 | @Mixin(World.class) 17 | public abstract class WorldMixin 18 | { 19 | private static final int MIN_POWER_LEVEL = 0; 20 | private static final int MAX_POWER_LEVEL = 15; 21 | private static final int MAX_POWER_FROM_OTHER_WIRE = 14; 22 | 23 | @Inject(method = "getReceivedRedstonePower", cancellable = true, at = @At(value = "HEAD")) 24 | private void getReceivedRedstonePower(BlockPos pos, CallbackInfoReturnable returnValue) 25 | { 26 | returnValue.setReturnValue(CalculatePower(pos)); 27 | } 28 | 29 | private int CalculatePower(BlockPos pos) 30 | { 31 | World world = ((World)(Object)this); 32 | int power = MIN_POWER_LEVEL; 33 | 34 | for (Direction dir : Direction.DirectionType.VERTICAL) 35 | { 36 | BlockPos side = pos.offset(dir); 37 | BlockState neighbor = world.getBlockState(side); 38 | 39 | if (!(neighbor.getBlock() instanceof AirBlock) && !(neighbor.getBlock() instanceof RedstoneWireBlock)) 40 | { 41 | power = Math.max(power, GetPowerFromVertical(world, side, neighbor, dir)); 42 | 43 | if (power >= MAX_POWER_LEVEL) 44 | { 45 | return MAX_POWER_LEVEL; 46 | } 47 | } 48 | } 49 | 50 | BlockPos up = pos.up(); 51 | 52 | for (Direction dir : Direction.DirectionType.HORIZONTAL) { 53 | 54 | power = Math.max(power, GetPowerFromHorizontal(world, pos.offset(dir), dir, !world.getBlockAt(up).isNormalBlock())); //May need to use isFullCube() 55 | 56 | if (power >= MAX_POWER_LEVEL) 57 | { 58 | return MAX_POWER_LEVEL; 59 | } 60 | } 61 | 62 | return power; 63 | } 64 | 65 | private int GetPowerFromVertical(World world, BlockPos pos, BlockState state, Direction dir) 66 | { 67 | int power = state.getBlock().getWeakRedstonePower(world, pos, state, dir); 68 | 69 | if (power >= MAX_POWER_LEVEL) 70 | { 71 | return MAX_POWER_LEVEL; 72 | } 73 | 74 | if (state.getBlock().isNormalBlock()) 75 | { 76 | return Math.max(power, GetStrongPowerTo(world, pos, state, dir.getOpposite())); 77 | } 78 | 79 | return power; 80 | } 81 | 82 | private int GetPowerFromHorizontal(World world, BlockPos pos, Direction toDir, boolean checkWiresAbove) 83 | { 84 | BlockState state = world.getBlockState(pos); 85 | 86 | if (state.getBlock() instanceof RedstoneWireBlock) 87 | { 88 | return ((RedstoneWireBlock)state.getBlock()).getData(state) - 1; 89 | } 90 | 91 | int power = state.getBlock().getWeakRedstonePower(world, pos, state, toDir); 92 | 93 | if (power >= MAX_POWER_LEVEL) 94 | { 95 | return MAX_POWER_LEVEL; 96 | } 97 | 98 | if (state.getBlock().isNormalBlock()) //May need to use isFullCube() 99 | { 100 | power = Math.max(power, GetStrongPowerTo(world, pos, state, toDir.getOpposite())); 101 | 102 | if (power >= MAX_POWER_LEVEL) 103 | { 104 | return MAX_POWER_LEVEL; 105 | } 106 | 107 | if (checkWiresAbove && power < MAX_POWER_FROM_OTHER_WIRE) 108 | { 109 | BlockPos up = pos.up(); 110 | BlockState aboveState = world.getBlockState(up); 111 | 112 | if (aboveState.getBlock() instanceof RedstoneWireBlock) 113 | { 114 | power = Math.max(power, ((RedstoneWireBlock)aboveState.getBlock()).getData(aboveState) - 1); 115 | } 116 | } 117 | } 118 | else if (power < MAX_POWER_FROM_OTHER_WIRE) 119 | { 120 | BlockPos down = pos.down(); 121 | BlockState belowState = world.getBlockState(down); 122 | 123 | if (belowState.getBlock() instanceof RedstoneWireBlock) 124 | { 125 | power = Math.max(power, ((RedstoneWireBlock)belowState.getBlock()).getData(belowState) - 1); 126 | } 127 | } 128 | 129 | return power; 130 | } 131 | 132 | private int GetStrongPowerTo(World world, BlockPos pos, BlockState state, Direction ignore) 133 | { 134 | int power = MIN_POWER_LEVEL; 135 | 136 | for (Direction dir : Direction.values()) 137 | { 138 | if (dir != ignore) 139 | { 140 | BlockPos side = pos.offset(dir); 141 | BlockState neighbor = world.getBlockState(side); 142 | 143 | if (!(neighbor.getBlock() instanceof AirBlock) && 144 | !(neighbor.getBlock() instanceof RedstoneWireBlock)) 145 | { 146 | power = Math.max(power, state.getBlock().getStrongRedstonePower(world, side, neighbor, dir)); 147 | 148 | if (power >= MAX_POWER_LEVEL) 149 | { 150 | return MAX_POWER_LEVEL; 151 | } 152 | } 153 | } 154 | } 155 | 156 | return power; 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Mixin/WorldRendererMixin.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Mixin; 2 | 3 | import java.util.Random; 4 | 5 | import org.lwjgl.opengl.GL11; 6 | import org.spongepowered.asm.mixin.Final; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Overwrite; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | 11 | import com.mojang.blaze3d.platform.GlStateManager; 12 | 13 | import net.minecraft.client.MinecraftClient; 14 | import net.minecraft.client.render.BufferBuilder; 15 | import net.minecraft.client.render.DiffuseLighting; 16 | import net.minecraft.client.render.Tessellator; 17 | import net.minecraft.client.render.VertexBuffer; 18 | import net.minecraft.client.render.VertexFormat; 19 | import net.minecraft.client.render.VertexFormats; 20 | import net.minecraft.client.render.WorldRenderer; 21 | import net.minecraft.client.texture.TextureManager; 22 | import net.minecraft.client.world.ClientWorld; 23 | import net.minecraft.util.Identifier; 24 | import net.minecraft.util.math.MathHelper; 25 | import net.minecraft.util.math.Vec3d; 26 | 27 | @Mixin(WorldRenderer.class) 28 | public class WorldRendererMixin 29 | { 30 | @Shadow 31 | private void renderEndSky() {} 32 | 33 | @Shadow 34 | @Final 35 | private MinecraftClient client; 36 | 37 | @Shadow 38 | private ClientWorld world; 39 | 40 | @Shadow 41 | private boolean vbo; 42 | 43 | @Shadow 44 | private VertexBuffer lightSkyBuffer; 45 | 46 | @Shadow 47 | private int lightSkyList = -1; 48 | 49 | @Shadow 50 | @Final 51 | private static Identifier SUN; 52 | 53 | @Shadow 54 | @Final 55 | private TextureManager textureManager; 56 | 57 | @Shadow 58 | @Final 59 | private static Identifier MOON_PHASES; 60 | 61 | @Shadow 62 | private VertexBuffer darkSkyBuffer; 63 | 64 | @Shadow 65 | private VertexBuffer starsBuffer; 66 | 67 | @Shadow 68 | private int darkSkyList; 69 | 70 | @Shadow 71 | private int starsList; //Render command list for stars 72 | 73 | @Shadow 74 | private VertexFormat skyVertexFormat; 75 | 76 | @Overwrite 77 | public void renderSky(float f, int i) 78 | { 79 | float w; 80 | float v; 81 | int u; 82 | int t; 83 | float s; 84 | float o; 85 | float n; 86 | if (this.client.world.dimension.getType() == 1) 87 | { 88 | this.renderEndSky(); 89 | return; 90 | } 91 | if (!this.client.world.dimension.canPlayersSleep()) 92 | { 93 | return; 94 | } 95 | GlStateManager.disableTexture(); 96 | Vec3d vec3d = this.world.method_3631(this.client.getCameraEntity(), f); 97 | float g = (float)vec3d.x; 98 | float h = (float)vec3d.y; 99 | float j = (float)vec3d.z; 100 | if (i != 2) { 101 | float k = (g * 30.0f + h * 59.0f + j * 11.0f) / 100.0f; 102 | float l = (g * 30.0f + h * 70.0f) / 100.0f; 103 | float m = (g * 30.0f + j * 70.0f) / 100.0f; 104 | g = k; 105 | h = l; 106 | j = m; 107 | } 108 | GlStateManager.color3f(g, h, j); 109 | Tessellator tessellator = Tessellator.getInstance(); 110 | BufferBuilder bufferBuilder = tessellator.getBuffer(); 111 | GlStateManager.depthMask(false); 112 | GlStateManager.enableFog(); 113 | GlStateManager.color3f(g, h, j); //Not sure 114 | if (this.vbo) 115 | { 116 | this.lightSkyBuffer.bind(); 117 | //GL11.glEnableClientState(32884); //Position 118 | GL11.glVertexPointer(3, 5126, 12, 0L); 119 | this.lightSkyBuffer.draw(7); 120 | this.lightSkyBuffer.unbind(); 121 | //GL11.glDisableClientState(32884); //Position 122 | } 123 | else 124 | { 125 | //GlStateManager.callList(this.lightSkyList); 126 | CallListField1924(); 127 | } 128 | GlStateManager.disableFog(); 129 | GlStateManager.disableAlphaTest(); 130 | GlStateManager.enableBlend(); 131 | GlStateManager.blendFuncSeparate(770, 771, 1, 0); 132 | DiffuseLighting.disable(); 133 | float[] fs = this.world.dimension.getBackgroundColor(this.world.getSkyAngle(f), f); 134 | if (fs != null) { 135 | GlStateManager.disableTexture(); 136 | GlStateManager.shadeModel(7425); 137 | GlStateManager.pushMatrix(); 138 | GlStateManager.rotatef(90.0f, 1.0f, 0.0f, 0.0f); 139 | GlStateManager.rotatef(MathHelper.sin(this.world.getSkyAngleRadians(f)) < 0.0f ? 180.0f : 0.0f, 0.0f, 0.0f, 1.0f); 140 | GlStateManager.rotatef(90.0f, 0.0f, 0.0f, 1.0f); 141 | n = fs[0]; 142 | o = fs[1]; 143 | float p = fs[2]; 144 | if (i != 2) { 145 | float q = (n * 30.0f + o * 59.0f + p * 11.0f) / 100.0f; 146 | float r = (n * 30.0f + o * 70.0f) / 100.0f; 147 | s = (n * 30.0f + p * 70.0f) / 100.0f; 148 | n = q; 149 | o = r; 150 | p = s; 151 | } 152 | bufferBuilder.begin(6, VertexFormats.POSITION_COLOR); 153 | bufferBuilder.vertex(0.0, 100.0, 0.0).color(n, o, p, fs[3]).next(); 154 | t = 16; 155 | for (u = 0; u <= 16; ++u) { 156 | s = (float)u * (float)Math.PI * 2.0f / 16.0f; 157 | v = MathHelper.sin(s); 158 | w = MathHelper.cos(s); 159 | bufferBuilder.vertex(v * 120.0f, w * 120.0f, -w * 40.0f * fs[3]).color(fs[0], fs[1], fs[2], 0.0f).next(); 160 | } 161 | tessellator.draw(); 162 | GlStateManager.popMatrix(); 163 | GlStateManager.shadeModel(7424); 164 | } 165 | GlStateManager.enableTexture(); 166 | GlStateManager.blendFuncSeparate(770, 1, 1, 0); 167 | GlStateManager.pushMatrix(); 168 | n = 1.0f - this.world.getRainGradient(f); 169 | GlStateManager.color4f(1.0f, 1.0f, 1.0f, n); 170 | GlStateManager.rotatef(-90.0f, 0.0f, 1.0f, 0.0f); 171 | GlStateManager.rotatef(this.world.getSkyAngle(f) * 360.0f, 1.0f, 0.0f, 0.0f); 172 | o = 30.0f; 173 | this.textureManager.bindTexture(SUN); 174 | bufferBuilder.begin(7, VertexFormats.POSITION_TEXTURE); 175 | bufferBuilder.vertex(-o, 100.0, -o).texture(0.0, 0.0).next(); 176 | bufferBuilder.vertex(o, 100.0, -o).texture(1.0, 0.0).next(); 177 | bufferBuilder.vertex(o, 100.0, o).texture(1.0, 1.0).next(); 178 | bufferBuilder.vertex(-o, 100.0, o).texture(0.0, 1.0).next(); 179 | tessellator.draw(); 180 | o = 20.0f; 181 | this.textureManager.bindTexture(MOON_PHASES); 182 | int x = this.world.getMoonPhase(); 183 | t = x % 4; 184 | u = x / 4 % 2; 185 | s = (float)(t + 0) / 4.0f; 186 | v = (float)(u + 0) / 2.0f; 187 | w = (float)(t + 1) / 4.0f; 188 | float y = (float)(u + 1) / 2.0f; 189 | bufferBuilder.begin(7, VertexFormats.POSITION_TEXTURE); 190 | bufferBuilder.vertex(-o, -100.0, o).texture(w, y).next(); 191 | bufferBuilder.vertex(o, -100.0, o).texture(s, y).next(); 192 | bufferBuilder.vertex(o, -100.0, -o).texture(s, v).next(); 193 | bufferBuilder.vertex(-o, -100.0, -o).texture(w, v).next(); 194 | tessellator.draw(); 195 | GlStateManager.disableTexture(); 196 | float z = this.world.method_3707(f) * n; 197 | if (z > 0.0f) 198 | { 199 | GlStateManager.color4f(z, z, z, z); 200 | if (this.vbo) 201 | { 202 | this.starsBuffer.bind(); 203 | //GL11.glEnableClientState(32884); //Position 204 | GL11.glVertexPointer(3, 5126, 12, 0L); 205 | this.starsBuffer.draw(7); 206 | this.starsBuffer.unbind(); 207 | //GL11.glDisableClientState(32884); //Position 208 | } 209 | else 210 | { 211 | //GlStateManager.callList(this.starsList); 212 | CallListField1923(); 213 | } 214 | } 215 | GlStateManager.color4f(1.0f, 1.0f, 1.0f, 1.0f); 216 | GlStateManager.disableBlend(); 217 | GlStateManager.enableAlphaTest(); 218 | GlStateManager.enableFog(); 219 | GlStateManager.popMatrix(); 220 | GlStateManager.disableTexture(); 221 | GlStateManager.color3f(0.0f, 0.0f, 0.0f); 222 | double d = this.client.player.getCameraPosVec((float)f).y - this.world.getHorizonHeight(); 223 | if (d < 0.0) 224 | { 225 | GlStateManager.pushMatrix(); 226 | GlStateManager.translatef(0.0f, 12.0f, 0.0f); 227 | if (this.vbo) 228 | { 229 | this.darkSkyBuffer.bind(); 230 | //GL11.glEnableClientState(32884); //Position 231 | GL11.glVertexPointer(3, 5126, 12, 0L); 232 | this.darkSkyBuffer.draw(7); 233 | this.darkSkyBuffer.unbind(); 234 | //GL11.glDisableClientState(32884); //Position 235 | } 236 | else 237 | { 238 | //GlStateManager.callList(this.darkSkyList); 239 | CallListField1925(); 240 | } 241 | GlStateManager.popMatrix(); 242 | //float p = 1.0f; 243 | float q = -((float)(d + 65.0)); 244 | //float r = -1.0f; 245 | s = q; 246 | bufferBuilder.begin(7, VertexFormats.POSITION_COLOR); 247 | bufferBuilder.vertex(-1.0, s, 1.0).color(0, 0, 0, 255).next(); 248 | bufferBuilder.vertex(1.0, s, 1.0).color(0, 0, 0, 255).next(); 249 | bufferBuilder.vertex(1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 250 | bufferBuilder.vertex(-1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 251 | bufferBuilder.vertex(-1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 252 | bufferBuilder.vertex(1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 253 | bufferBuilder.vertex(1.0, s, -1.0).color(0, 0, 0, 255).next(); 254 | bufferBuilder.vertex(-1.0, s, -1.0).color(0, 0, 0, 255).next(); 255 | bufferBuilder.vertex(1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 256 | bufferBuilder.vertex(1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 257 | bufferBuilder.vertex(1.0, s, 1.0).color(0, 0, 0, 255).next(); 258 | bufferBuilder.vertex(1.0, s, -1.0).color(0, 0, 0, 255).next(); 259 | bufferBuilder.vertex(-1.0, s, -1.0).color(0, 0, 0, 255).next(); 260 | bufferBuilder.vertex(-1.0, s, 1.0).color(0, 0, 0, 255).next(); 261 | bufferBuilder.vertex(-1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 262 | bufferBuilder.vertex(-1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 263 | bufferBuilder.vertex(-1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 264 | bufferBuilder.vertex(-1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 265 | bufferBuilder.vertex(1.0, -1.0, 1.0).color(0, 0, 0, 255).next(); 266 | bufferBuilder.vertex(1.0, -1.0, -1.0).color(0, 0, 0, 255).next(); 267 | tessellator.draw(); 268 | } 269 | if (this.world.dimension.hasGround()) { 270 | GlStateManager.color3f(g * 0.2f + 0.04f, h * 0.2f + 0.04f, j * 0.6f + 0.1f); 271 | } else { 272 | GlStateManager.color3f(g, h, j); 273 | } 274 | GlStateManager.pushMatrix(); 275 | GlStateManager.translatef(0.0f, -((float)(d - 16.0)), 0.0f); 276 | //GlStateManager.callList(this.darkSkyList); 277 | CallListField1925(); 278 | GlStateManager.popMatrix(); 279 | GlStateManager.enableTexture(); 280 | GlStateManager.depthMask(true); 281 | 282 | } 283 | 284 | @Shadow 285 | private void renderDarkSky() 286 | { 287 | Tessellator tessellator = Tessellator.getInstance(); 288 | BufferBuilder bufferBuilder = tessellator.getBuffer(); 289 | if (this.darkSkyBuffer == null) 290 | { 291 | this.darkSkyBuffer = new VertexBuffer(this.skyVertexFormat); 292 | } 293 | if (this.darkSkyList >= 0) 294 | { 295 | //GlAllocationUtils.deleteSingletonList(this.darkSkyList); 296 | this.darkSkyList = -1; 297 | } 298 | if (this.vbo) 299 | { 300 | this.renderSkyHalf(bufferBuilder, -16.0f, true); 301 | bufferBuilder.end(); 302 | bufferBuilder.reset(); 303 | this.darkSkyBuffer.data(bufferBuilder.getByteBuffer()); 304 | } else { 305 | this.darkSkyList = 3; 306 | //GL11.glNewList(this.darkSkyList, 4864); //GL_COMPILE 307 | //this.renderSkyHalf(bufferBuilder, -16.0f, true); //Doesn't contain gl calls? 308 | //tessellator.draw(); 309 | //GL11.glEndList(); 310 | } 311 | 312 | } 313 | 314 | private void CallListField1925() 315 | { 316 | Tessellator tessellator = Tessellator.getInstance(); 317 | //BufferBuilder bufferBuilder = tessellator.getBuffer(); 318 | //this.renderSkyHalf(bufferBuilder, -16.0f, true); //Doesn't contain gl calls? 319 | tessellator.draw(); 320 | } 321 | 322 | @Overwrite 323 | private void renderLightSky() 324 | { 325 | Tessellator tessellator = Tessellator.getInstance(); 326 | BufferBuilder bufferBuilder = tessellator.getBuffer(); 327 | if (this.lightSkyBuffer == null) 328 | { 329 | this.lightSkyBuffer = new VertexBuffer(this.skyVertexFormat); 330 | } 331 | if (this.lightSkyList >= 0) 332 | { 333 | //GlAllocationUtils.deleteSingletonList(this.lightSkyList); 334 | this.lightSkyList = -1; 335 | } 336 | if (this.vbo) 337 | { 338 | this.renderSkyHalf(bufferBuilder, 16.0f, false); 339 | bufferBuilder.end(); 340 | bufferBuilder.reset(); 341 | this.lightSkyBuffer.data(bufferBuilder.getByteBuffer()); 342 | } else 343 | { 344 | this.lightSkyList = 2; 345 | //GL11.glNewList(this.lightSkyList, 4864); //GL_COMPILE 346 | //this.renderSkyHalf(bufferBuilder, 16.0f, false); //Doesn't contain gl calls? 347 | //tessellator.draw(); 348 | //GL11.glEndList(); 349 | } 350 | } 351 | 352 | private void CallListField1924() 353 | { 354 | Tessellator tessellator = Tessellator.getInstance(); 355 | //BufferBuilder bufferBuilder = tessellator.getBuffer(); 356 | //this.renderSkyHalf(bufferBuilder, 16.0f, false); //Doesn't contain gl calls? 357 | tessellator.draw(); 358 | } 359 | 360 | @Shadow 361 | private void renderStars() 362 | { 363 | Tessellator tessellator = Tessellator.getInstance(); 364 | BufferBuilder bufferBuilder = tessellator.getBuffer(); 365 | 366 | if (this.starsBuffer == null) 367 | { 368 | this.starsBuffer = new VertexBuffer(this.skyVertexFormat); 369 | } 370 | if (this.starsList >= 0) 371 | { 372 | //GlAllocationUtils.deleteSingletonList(this.starsList); 373 | this.starsList = -1; 374 | } 375 | if (this.vbo) 376 | { 377 | this.renderStars(bufferBuilder); 378 | bufferBuilder.end(); 379 | bufferBuilder.reset(); 380 | this.starsBuffer.data(bufferBuilder.getByteBuffer()); 381 | } 382 | else 383 | { 384 | this.starsList = 5; 385 | //GlStateManager.pushMatrix(); 386 | //GL11.glNewList(this.starsList, 4864); //GL_COMPILE 387 | //this.renderStars(bufferBuilder); //Doesn't contain gl calls? 388 | //tessellator.draw(); 389 | //GL11.glEndList(); 390 | //GlStateManager.popMatrix(); 391 | } 392 | 393 | } 394 | 395 | private void CallListField1923() 396 | { 397 | Tessellator tessellator = Tessellator.getInstance(); 398 | //this.renderStars(bufferBuilder); //Doesn't contain gl calls? 399 | tessellator.draw(); 400 | } 401 | 402 | @Overwrite 403 | private void renderStars(BufferBuilder buffer) 404 | { 405 | Random random = new Random(10842L); 406 | buffer.begin(7, VertexFormats.POSITION); 407 | for (int i = 0; i < 1500; ++i) { 408 | double d = random.nextFloat() * 2.0f - 1.0f; 409 | double e = random.nextFloat() * 2.0f - 1.0f; 410 | double f = random.nextFloat() * 2.0f - 1.0f; 411 | double g = 0.15f + random.nextFloat() * 0.1f; 412 | double h = d * d + e * e + f * f; 413 | if (!(h < 1.0) || !(h > 0.01)) continue; 414 | h = 1.0 / Math.sqrt(h); 415 | double j = (d *= h) * 100.0; 416 | double k = (e *= h) * 100.0; 417 | double l = (f *= h) * 100.0; 418 | double m = Math.atan2(d, f); 419 | double n = Math.sin(m); 420 | double o = Math.cos(m); 421 | double p = Math.atan2(Math.sqrt(d * d + f * f), e); 422 | double q = Math.sin(p); 423 | double r = Math.cos(p); 424 | double s = random.nextDouble() * Math.PI * 2.0; 425 | double t = Math.sin(s); 426 | double u = Math.cos(s); 427 | for (int v = 0; v < 4; ++v) 428 | { 429 | double x = (double)((v & 2) - 1) * g; 430 | double y = (double)((v + 1 & 2) - 1) * g; 431 | double aa = x * u - y * t; 432 | double ac = y * u + x * t; 433 | double ad = aa * q + 0.0 * r; 434 | double ae = 0.0 * q - aa * r; 435 | double af = ae * n - ac * o; 436 | double ag = ad; 437 | double ah = ac * n + ae * o; 438 | buffer.vertex(j + af, k + ag, l + ah).next(); 439 | } 440 | } 441 | } 442 | 443 | @Shadow 444 | private void renderSkyHalf(BufferBuilder buffer, float y, boolean bottom) {} 445 | } 446 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Renderer/BufferBuilderRenderData.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Renderer; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import me.Deex.SaltLib.Utils.Util; 6 | import net.minecraft.client.render.BufferBuilder; 7 | import net.minecraft.client.render.VertexFormat; 8 | 9 | public class BufferBuilderRenderData 10 | { 11 | public ByteBuffer byteBuffer; 12 | public VertexFormat format; 13 | public int vertexCount; 14 | public int drawMode; 15 | 16 | public BufferBuilderRenderData(BufferBuilder builder) 17 | { 18 | SetData(builder); 19 | } 20 | 21 | public void SetData(BufferBuilder builder) 22 | { 23 | byteBuffer = ByteBuffer.allocateDirect(builder.getByteBuffer().capacity()); 24 | Util.CopyBuffer(builder.getByteBuffer(), byteBuffer); 25 | format = new VertexFormat(builder.getFormat()); 26 | vertexCount = builder.getVertexCount(); 27 | drawMode = builder.getDrawMode(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Renderer/CustomBufferRenderer.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Renderer; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.util.List; 5 | 6 | import org.lwjgl.opengl.GL11; 7 | import org.lwjgl.opengl.GL20; 8 | import org.lwjgl.opengl.GL30; 9 | import org.lwjgl.util.vector.Matrix; 10 | import org.lwjgl.util.vector.Matrix4f; 11 | import org.lwjgl.util.vector.Vector4f; 12 | 13 | import com.mojang.blaze3d.platform.GLX; 14 | 15 | import me.Deex.SaltLib.SaltLibMod; 16 | import net.minecraft.client.render.BufferBuilder; 17 | import net.minecraft.client.render.VertexFormat; 18 | import net.minecraft.client.render.VertexFormatElement; 19 | 20 | public class CustomBufferRenderer 21 | { 22 | public static int vao; 23 | public static int vbo; 24 | 25 | private static void InternalDraw(ByteBuffer byteBuffer, VertexFormat vertexFormat, int vertexCount, int drawMode) 26 | { 27 | if (vertexCount <= 0) 28 | { 29 | return; 30 | } 31 | 32 | int stride = vertexFormat.getVertexSize(); 33 | List list = vertexFormat.getElements(); 34 | 35 | for (int i = 0; i < list.size(); ++i) 36 | { 37 | VertexFormatElement vertexFormatElement = list.get(i); 38 | VertexFormatElement.Type type = vertexFormatElement.getType(); 39 | int vertexTypeID = vertexFormatElement.getFormat().getGlId(); 40 | byteBuffer.position(vertexFormat.getIndex(i)); 41 | 42 | switch (type) 43 | { 44 | case POSITION: 45 | { 46 | int startPos = byteBuffer.position(); 47 | 48 | float x = 0.0f; 49 | float y = 0.0f; 50 | float z = 0.0f; 51 | 52 | for (int v = 0; v < vertexCount; ++v) 53 | { 54 | byteBuffer.position(startPos + v * stride); 55 | 56 | switch(vertexFormatElement.getFormat()) 57 | { 58 | case UNSIGNED_INT: 59 | case INT: 60 | case FLOAT: 61 | { 62 | x = byteBuffer.getFloat(); 63 | y = byteBuffer.getFloat(); 64 | z = byteBuffer.getFloat(); 65 | } break; 66 | 67 | case UNSIGNED_SHORT: 68 | case SHORT: 69 | { 70 | x = (float)byteBuffer.getShort(); 71 | y = (float)byteBuffer.getShort(); 72 | z = (float)byteBuffer.getShort(); 73 | } break; 74 | 75 | case UNSIGNED_BYTE: 76 | case BYTE: 77 | { 78 | x = (float)byteBuffer.get(); 79 | y = (float)byteBuffer.get(); 80 | z = (float)byteBuffer.get(); 81 | } break; 82 | } 83 | 84 | Vector4f point = new Vector4f(x, y, z, 1.0f); 85 | point = Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_MODELVIEW).GetTop(), point, point); 86 | point = Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_PROJECTION).GetTop(), point, point); 87 | x = point.x / point.w; 88 | y = point.y / point.w; 89 | z = point.z / point.w; 90 | 91 | byteBuffer.position(startPos + v * stride); 92 | byteBuffer.putFloat(x); 93 | byteBuffer.putFloat(y); 94 | byteBuffer.putFloat(z); 95 | } 96 | 97 | byteBuffer.position(startPos); 98 | 99 | GL11.glVertexPointer(vertexFormatElement.getCount(), vertexTypeID, stride, byteBuffer); 100 | GL11.glEnableClientState(32884); 101 | break; 102 | } 103 | case UV: 104 | { 105 | int startPos = byteBuffer.position(); 106 | 107 | float x = 0.0f; 108 | float y = 0.0f; 109 | 110 | for (int v = 0; v < vertexCount; ++v) 111 | { 112 | byteBuffer.position(startPos + v * stride); 113 | 114 | x = byteBuffer.getFloat(); 115 | y = byteBuffer.getFloat(); 116 | 117 | Vector4f point = new Vector4f(x, y, 0.0f, 1.0f); 118 | point = Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_TEXTURE).GetTop(), point, point); 119 | x = point.x / point.w; 120 | y = point.y / point.w; 121 | 122 | byteBuffer.position(startPos + v * stride); 123 | byteBuffer.putFloat(x); 124 | byteBuffer.putFloat(y); 125 | } 126 | 127 | byteBuffer.position(startPos); 128 | 129 | GLX.gl13ClientActiveTexture(GLX.textureUnit + vertexFormatElement.getIndex()); 130 | GL11.glTexCoordPointer(vertexFormatElement.getCount(), vertexTypeID, stride, byteBuffer); 131 | GL11.glEnableClientState(32888); 132 | GLX.gl13ClientActiveTexture(GLX.textureUnit); 133 | break; 134 | } 135 | case COLOR: 136 | { 137 | GL11.glColorPointer(vertexFormatElement.getCount(), vertexTypeID, stride, byteBuffer); 138 | GL11.glEnableClientState(32886); 139 | break; 140 | } 141 | case NORMAL: 142 | { 143 | GL11.glNormalPointer(vertexTypeID, stride, byteBuffer); 144 | GL11.glEnableClientState(32885); 145 | break; 146 | } 147 | case BLEND_WEIGHT: 148 | case MATRIX: 149 | case PADDING: 150 | break; 151 | } 152 | } 153 | 154 | //GL20.glUseProgram(SaltLibMod.defaultShader.glProgram); 155 | //GL30.glBindVertexArray(vao); 156 | GL11.glDrawArrays(drawMode, 0, vertexCount); 157 | //GL30.glBindVertexArray(0); 158 | //GL20.glUseProgram(0); 159 | 160 | //No need to unbind textures, clear colors, they will get set once we need them 161 | //NOTE: Altough we need to disable coloring, texturing and everything else, because the next Draw won't disable it for itself 162 | //We technically don't need to disable positions, because we can't render anyting without a position 163 | //GL11.glDisableClientState(32884); 164 | GL11.glDisableClientState(32888); 165 | GL11.glDisableClientState(32886); 166 | GL11.glDisableClientState(32885); 167 | } 168 | 169 | public static void DrawNoReset(BufferBuilder builder) 170 | { 171 | InternalDraw(builder.getByteBuffer(), builder.getFormat(), builder.getVertexCount(), builder.getDrawMode()); 172 | } 173 | 174 | public static void DrawNoReset(BufferBuilderRenderData builder) 175 | { 176 | InternalDraw(builder.byteBuffer, builder.format, builder.vertexCount, builder.drawMode); 177 | } 178 | 179 | public static void DrawAndReset(BufferBuilder builder) 180 | { 181 | DrawNoReset(builder); 182 | builder.reset(); 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Renderer/GLShader.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Renderer; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | 6 | import org.lwjgl.opengl.GL20; 7 | 8 | import me.Deex.SaltLib.SaltLibMod; 9 | 10 | public class GLShader 11 | { 12 | public int glProgram; 13 | 14 | public GLShader(String vertexShaderPath, String fragmentShaderPath) 15 | { 16 | byte[] vshBytes = new byte[4096]; 17 | byte[] fshBytes = new byte[4096]; 18 | 19 | try 20 | { 21 | //TODO: Slow, but it's only load code, so it's not suuuuper important 22 | SaltLibMod.class.getResourceAsStream(vertexShaderPath).read(vshBytes, 0, 4096); 23 | SaltLibMod.class.getResourceAsStream(fragmentShaderPath).read(fshBytes, 0, 4096); 24 | } 25 | catch (IOException e) 26 | { 27 | e.printStackTrace(); 28 | return; 29 | } 30 | 31 | int vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); 32 | ByteBuffer buffer = ByteBuffer.allocateDirect(4096); 33 | buffer.put(vshBytes); 34 | buffer.position(0); 35 | GL20.glShaderSource(vertexShader, buffer); 36 | GL20.glCompileShader(vertexShader); 37 | 38 | int success = GL20.glGetShaderi(vertexShader, GL20.GL_COMPILE_STATUS); 39 | if (success == 0) 40 | { 41 | String infoLog = GL20.glGetShaderInfoLog(vertexShader, 512); 42 | System.err.println("Could not compile vertex shader: " + infoLog); 43 | } 44 | 45 | int fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER); 46 | buffer = ByteBuffer.allocateDirect(4096); 47 | buffer.put(fshBytes); 48 | buffer.position(0); 49 | GL20.glShaderSource(fragmentShader, buffer); 50 | GL20.glCompileShader(fragmentShader); 51 | 52 | success = GL20.glGetShaderi(fragmentShader, GL20.GL_COMPILE_STATUS); 53 | if (success == 0) 54 | { 55 | String infoLog = GL20.glGetShaderInfoLog(fragmentShader, 512); 56 | System.err.println("Could not compile fragment shader: " + infoLog); 57 | } 58 | 59 | glProgram = GL20.glCreateProgram(); 60 | GL20.glAttachShader(glProgram, vertexShader); 61 | GL20.glAttachShader(glProgram, fragmentShader); 62 | GL20.glLinkProgram(glProgram); 63 | 64 | success = GL20.glGetProgrami(glProgram, GL20.GL_LINK_STATUS); 65 | if (success == 0) 66 | { 67 | String infoLog = GL20.glGetProgramInfoLog(glProgram, 512); 68 | System.err.println("Could not link shader: " + infoLog); 69 | } 70 | 71 | GL20.glDeleteShader(vertexShader); 72 | GL20.glDeleteShader(fragmentShader); 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Renderer/MatrixStack.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Renderer; 2 | 3 | import java.util.List; 4 | 5 | import com.google.common.collect.Lists; 6 | 7 | import org.lwjgl.opengl.GL11; 8 | import org.lwjgl.util.vector.Matrix4f; 9 | import org.lwjgl.util.vector.Vector3f; 10 | import org.lwjgl.util.vector.Vector4f; 11 | 12 | public class MatrixStack 13 | { 14 | private static int currentStackId; 15 | 16 | private static MatrixStack modelview; 17 | private static MatrixStack projection; 18 | private static MatrixStack texture; 19 | 20 | public static void CreateGLStacks() 21 | { 22 | modelview = new MatrixStack(); 23 | projection = new MatrixStack(); 24 | texture = new MatrixStack(); 25 | } 26 | 27 | public static MatrixStack GetGLStack(int glId) 28 | { 29 | switch (glId) 30 | { 31 | case GL11.GL_MODELVIEW_MATRIX: 32 | case GL11.GL_MODELVIEW: 33 | { 34 | return modelview; 35 | } 36 | 37 | case GL11.GL_PROJECTION_MATRIX: 38 | case GL11.GL_PROJECTION: 39 | { 40 | return projection; 41 | } 42 | 43 | case GL11.GL_TEXTURE_MATRIX: 44 | case GL11.GL_TEXTURE: 45 | { 46 | return texture; 47 | } 48 | } 49 | 50 | throw new IllegalStateException("Invalid [glId] in [MatrixStack.GetGLStack]!"); 51 | } 52 | 53 | public static void TransformWorldPoint(Vector3f point) 54 | { 55 | Vector4f pos = new Vector4f(point.x, point.y, point.z, 1.0f); 56 | pos = Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_MODELVIEW).GetTop(), pos, pos); 57 | pos = Matrix4f.transform(MatrixStack.GetGLStack(GL11.GL_PROJECTION).GetTop(), pos, pos); 58 | point.x = pos.x / pos.w; 59 | point.y = pos.y / pos.w; 60 | point.z = pos.z / pos.w; 61 | } 62 | 63 | public static void SetCurrentStack(int id) 64 | { 65 | currentStackId = id; 66 | } 67 | 68 | public static MatrixStack GetCurrentStack() 69 | { 70 | return GetGLStack(currentStackId); 71 | } 72 | 73 | private List stack; 74 | 75 | MatrixStack() 76 | { 77 | stack = Lists.newArrayList(); 78 | stack.add(new Matrix4f()); 79 | } 80 | 81 | public Matrix4f GetTop() 82 | { 83 | return stack.get(0); 84 | } 85 | 86 | public void SetIdentity() 87 | { 88 | stack.set(0, new Matrix4f()); 89 | } 90 | 91 | public void Push() 92 | { 93 | Matrix4f newMat = new Matrix4f(stack.get(0)); 94 | stack.add(0, newMat); 95 | } 96 | 97 | public void Pop() 98 | { 99 | stack.remove(0); 100 | } 101 | 102 | public void Ortho(float l, float r, float b, float t, float n, float f) 103 | { 104 | Matrix4f orthoMat = new Matrix4f(); 105 | orthoMat.m00 = 2.0f / (r - l); 106 | orthoMat.m11 = 2.0f / (t - b); 107 | orthoMat.m22 = -2.0f / (f - n); //Could do 2.0f / (n - f) 108 | 109 | orthoMat.m30 = -((r + l) / (r - l)); 110 | orthoMat.m31 = -((t + b) / (t - b)); 111 | orthoMat.m32 = -((f + n) / (f - n)); 112 | 113 | Matrix4f.mul(stack.get(0), orthoMat, stack.get(0)); 114 | } 115 | 116 | public void Perspective(float fovy, float aspect, float zNear, float zFar) 117 | { 118 | float sine, cotangent, deltaZ; 119 | float radians = fovy / 2 * (float)Math.PI / 180; 120 | 121 | deltaZ = zFar - zNear; 122 | sine = (float) Math.sin(radians); 123 | 124 | if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { 125 | return; 126 | } 127 | 128 | cotangent = (float) Math.cos(radians) / sine; 129 | 130 | Matrix4f mat = new Matrix4f(); 131 | 132 | mat.m00 = cotangent / aspect; 133 | mat.m11 = cotangent; 134 | mat.m22 = - (zFar + zNear) / deltaZ; 135 | mat.m23 = -1; 136 | mat.m32 = -2 * zNear * zFar / deltaZ; 137 | mat.m33 = 0; 138 | 139 | Matrix4f.mul(stack.get(0), mat, stack.get(0)); 140 | } 141 | 142 | public void Rotate(float angle, Vector3f axis) 143 | { 144 | Matrix4f.rotate((float)Math.toRadians((double)angle), (Vector3f)axis.normalise(), stack.get(0), stack.get(0)); 145 | } 146 | 147 | public void Scale(Vector3f scale) 148 | { 149 | stack.get(0).scale(scale); 150 | } 151 | 152 | public void Translate(Vector3f translate) 153 | { 154 | stack.get(0).translate(translate); 155 | } 156 | 157 | public void Multiply(Matrix4f mat) 158 | { 159 | Matrix4f.mul(stack.get(0), mat, stack.get(0)); 160 | } 161 | } -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/SaltLibMod.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib; 2 | 3 | import me.Deex.SaltLib.Debug.Instrumentor; 4 | import me.Deex.SaltLib.Renderer.GLShader; 5 | import net.fabricmc.api.ClientModInitializer; 6 | import net.fabricmc.loader.api.FabricLoader; 7 | 8 | public class SaltLibMod implements ClientModInitializer 9 | { 10 | public static boolean enableProfiling; 11 | public static GLShader defaultShader; 12 | 13 | @Override 14 | public void onInitializeClient() 15 | { 16 | // This code runs as soon as Minecraft is in a mod-load-ready state. 17 | // However, some things (like resources) may still be uninitialized. 18 | // Proceed with mild caution. 19 | 20 | OnStartup(); 21 | 22 | System.out.println("[SaltLib] Initalized successfully"); 23 | } 24 | 25 | private static void OnStartup() 26 | { 27 | enableProfiling = FabricLoader.getInstance().isDevelopmentEnvironment(); 28 | 29 | if (enableProfiling) 30 | { 31 | Instrumentor.BeginSession("SaltLib-profile"); 32 | } 33 | } 34 | 35 | public static void OnShutdown() 36 | { 37 | if (enableProfiling) 38 | { 39 | Instrumentor.EndSession(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/Deex/SaltLib/Utils/Util.java: -------------------------------------------------------------------------------- 1 | package me.Deex.SaltLib.Utils; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.FloatBuffer; 5 | 6 | import org.lwjgl.util.vector.Matrix4f; 7 | 8 | public class Util 9 | { 10 | public static void CopyBuffer(ByteBuffer from, ByteBuffer to) 11 | { 12 | from.position(0); 13 | 14 | while (from.remaining() > 0) 15 | { 16 | to.put(from.get()); 17 | } 18 | } 19 | 20 | public static void CopyBuffer(FloatBuffer from, FloatBuffer to) 21 | { 22 | from.position(0); 23 | 24 | while (from.remaining() > 0) 25 | { 26 | to.put(from.get()); 27 | } 28 | } 29 | 30 | 31 | public static void WriteMatrix4fIntoFloatBuffer(Matrix4f mat, FloatBuffer buffer) 32 | { 33 | if (buffer.remaining() < 16) 34 | { 35 | throw new IllegalStateException("Not enough bytes remaining in buffer!"); 36 | } 37 | 38 | buffer.put(mat.m00); 39 | buffer.put(mat.m01); 40 | buffer.put(mat.m02); 41 | buffer.put(mat.m03); 42 | buffer.put(mat.m10); 43 | buffer.put(mat.m11); 44 | buffer.put(mat.m12); 45 | buffer.put(mat.m13); 46 | buffer.put(mat.m20); 47 | buffer.put(mat.m21); 48 | buffer.put(mat.m22); 49 | buffer.put(mat.m23); 50 | buffer.put(mat.m30); 51 | buffer.put(mat.m31); 52 | buffer.put(mat.m32); 53 | buffer.put(mat.m33); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/resources/assets/saltlib/DefaultFragmentShader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec2 vTexCoord; 4 | in vec4 vColor; 5 | in vec3 vNormal; 6 | 7 | uniform sampler2D tex; 8 | 9 | void main() 10 | { 11 | gl_FragColor = vColor * texture(tex, vTexCoord); 12 | } -------------------------------------------------------------------------------- /src/main/resources/assets/saltlib/DefaultVertexShader.glsl: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout(location = 0) in vec3 aPosition; 4 | layout(location = 1) in vec2 aTexCoord; 5 | layout(location = 2) in vec4 aColor; 6 | layout(location = 3) in vec3 aNormal; 7 | 8 | out vec2 vTexCoord; 9 | out vec4 vColor; 10 | out vec3 vNormal; 11 | 12 | void main() 13 | { 14 | vTexCoord = aTexCoord; 15 | vColor = aColor; 16 | vNormal = aNormal; 17 | 18 | gl_Position = vec4(aPosition, 1.0); 19 | } -------------------------------------------------------------------------------- /src/main/resources/assets/saltlib/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeexCoding/SaltLib/26e220cb5923b84b78eeabb566195b03a5f3212c/src/main/resources/assets/saltlib/icon.png -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "saltlib", 4 | "version": "${version}", 5 | "name": "SaltLib", 6 | "description": "Sodium alternative for legacy versions (1.3.2-1.13.2)", 7 | "authors": 8 | [ 9 | "Deex" 10 | ], 11 | "contact": 12 | { 13 | "issues": "https://github.com/DeexCoding/SaltLib/issues", 14 | "sources": "https://github.com/DeexCoding/SaltLib" 15 | }, 16 | "license": "zlib", 17 | "icon": "assets/saltlib/icon.png", 18 | "environment": "client", 19 | "entrypoints": 20 | { 21 | "client": 22 | [ 23 | "me.Deex.SaltLib.SaltLibMod" 24 | ] 25 | }, 26 | "mixins": 27 | [ 28 | "saltlib.mixins.json" 29 | ], 30 | "depends": 31 | { 32 | "fabricloader": ">=0.14.0", 33 | "minecraft": "1.8.9" 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/resources/saltlib.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "me.Deex.SaltLib.Mixin", 5 | "compatibilityLevel": "JAVA_8", 6 | "mixins": 7 | [ 8 | ], 9 | "client": 10 | [ 11 | "BufferBuilderMixin", 12 | "BufferRendererMixin", 13 | "GlStateManagerMixin", 14 | "GLXMixin", 15 | "MinecraftClientMixin", 16 | "ModelBoxAccessor", 17 | "ProjectMixin", 18 | "RealmsNotificationScreenMixin", 19 | "TextRendererMixin", 20 | "TexturedQuadAccessor", 21 | "WorldMixin" 22 | ], 23 | "injectors": 24 | { 25 | "defaultRequire": 1 26 | }, 27 | "refmap": "SaltLib-refmap.json" 28 | } 29 | --------------------------------------------------------------------------------