mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-11-15 01:34:48 +00:00
Compare commits
93
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
701f55b5a5 | ||
|
|
5afb5d8f5a | ||
|
|
c353c83cf3 | ||
|
|
6563c7c0ce | ||
|
|
78072236d2 | ||
|
|
52dae51121 | ||
|
|
b42eb9a6b2 | ||
|
|
5925c28d29 | ||
|
|
fedabd0fb6 | ||
|
|
350fdcd7e4 | ||
|
|
3d98e57178 | ||
|
|
55c1786811 | ||
|
|
356d826387 | ||
|
|
c34d8548a5 | ||
|
|
81a000af75 | ||
|
|
711c23c722 | ||
|
|
5aa1d504b0 | ||
|
|
60ab3b7900 | ||
|
|
912e0e83b8 | ||
|
|
104eda0b51 | ||
|
|
7fb8cde66d | ||
|
|
0e4421f2ce | ||
|
|
3cf3d096fd | ||
|
|
ffa1193dd2 | ||
|
|
d180023469 | ||
|
|
762275a6da | ||
|
|
0e66bcf42f | ||
|
|
979ad344a1 | ||
|
|
5f328e9b57 | ||
|
|
2dba62bf20 | ||
|
|
0fd4d457e2 | ||
|
|
b56e803622 | ||
|
|
3ab965ded7 | ||
|
|
538b38898c | ||
|
|
e43cd6f18e | ||
|
|
38285087c9 | ||
|
|
deb6c2b6e5 | ||
|
|
e11985a913 | ||
|
|
4bbf39eb4d | ||
|
|
8c90f79c17 | ||
|
|
e4e657846d | ||
|
|
2dace708b4 | ||
|
|
1df1ec3530 | ||
|
|
d96ac28043 | ||
|
|
72c13cff67 | ||
|
|
f233ba65e3 | ||
|
|
c0d636d4f7 | ||
|
|
bd5cd350c3 | ||
|
|
88936d3713 | ||
|
|
cf5bf2e2e7 | ||
|
|
cfd2388c85 | ||
|
|
fd78f63f12 | ||
|
|
6cf119dfee | ||
|
|
8c5f4d2543 | ||
|
|
9e1fa7b80f | ||
|
|
6c99872459 | ||
|
|
f0809410ee | ||
|
|
98299b69d2 | ||
|
|
fed0aa77c5 | ||
|
|
f7fb3186c8 | ||
|
|
ab243bb936 | ||
|
|
60cce7ea1d | ||
|
|
b837b0571d | ||
|
|
7abc6213f5 | ||
|
|
b46643ae8c | ||
|
|
e3d1fedd48 | ||
|
|
ebcee499eb | ||
|
|
ad26b1ad6f | ||
|
|
73338e3c3e | ||
|
|
2c89244fbe | ||
|
|
991f658819 | ||
|
|
1588c7000d | ||
|
|
260d57e308 | ||
|
|
3a1d1b03b3 | ||
|
|
66563f41c8 | ||
|
|
a52adb9190 | ||
|
|
1c6f9aa131 | ||
|
|
8c584fed05 | ||
|
|
558ea0fe12 | ||
|
|
1315d8971a | ||
|
|
e33f2ff7e3 | ||
|
|
29072ee3f8 | ||
|
|
ff8315270b | ||
|
|
54f276a460 | ||
|
|
feef745722 | ||
|
|
88cb3faf47 | ||
|
|
f477675ee9 | ||
|
|
4294059fbe | ||
|
|
e40c9f2441 | ||
|
|
52e886adcc | ||
|
|
f38fcd1d82 | ||
|
|
fbebbd4049 | ||
|
|
03a0406199 |
No files matched your search
@@ -18,6 +18,14 @@ body:
|
||||
placeholder: "Example: 1.0.0-alpha1"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: report
|
||||
attributes:
|
||||
label: Bug Report
|
||||
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
|
||||
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: java
|
||||
attributes:
|
||||
@@ -48,12 +56,25 @@ body:
|
||||
- Mesa/Software
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: report
|
||||
- type: dropdown
|
||||
id: shaders
|
||||
attributes:
|
||||
label: Bug Report
|
||||
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
|
||||
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
|
||||
label: Shaders
|
||||
description: Do you have a shaderpack enabled?
|
||||
options:
|
||||
- "No"
|
||||
- "Yes: Please put relevant information about shaderpack in the report(what shaderpack, any special settings of note, etc)"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: mcpf
|
||||
attributes:
|
||||
label: MCPF or other features disabled by default
|
||||
description: Do you have MCPF or any other features that are disabled by default enabled?
|
||||
options:
|
||||
- "No: Go ahead and create an issue"
|
||||
- "Yes: I will not create an issue"
|
||||
- "Yes: I don't read and shouldn't be creating an issue"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -76,6 +97,5 @@ body:
|
||||
required: true
|
||||
- label: "I am running an officially released version. (Or, if I've compiled it myself I plan to fix the issue)"
|
||||
required: true
|
||||
- label: "This issue is not related to a feature that is disabed by default - Shaders, MCPF, etc. [They'll be enabled when they're ready for testing]"
|
||||
required: true
|
||||
|
||||
|
||||
|
||||
@@ -29,5 +29,5 @@ body:
|
||||
required: true
|
||||
- label: "I have read the known incompatibilities and this is not related to one of those."
|
||||
required: true
|
||||
- label: "This issue is not related to a feature that is disabed by default - Shaders, MCPF, etc. [They'll be enabled when they're ready for testing]"
|
||||
required: true
|
||||
- label: "This issue is not related to a feature that is disabed by default - MCPF, etc. [They'll be enabled when they're ready for testing]"
|
||||
required: true
|
||||
@@ -31,3 +31,10 @@ src/main/resources/mixins.*([!.]).json
|
||||
*.bat
|
||||
*.DS_Store
|
||||
!gradlew.bat
|
||||
layout.json
|
||||
addon.local.gradle
|
||||
addon.local.gradle.kts
|
||||
addon.late.local.gradle
|
||||
addon.late.local.gradle.kts
|
||||
/*.csv
|
||||
!gl_functions.csv
|
||||
@@ -5,8 +5,9 @@
|
||||
* The little Angle [sic] that supports shaders while saving your fps from a certain death -boubou
|
||||
* Is it obtuse, or accute? -Caedis
|
||||
* It's a cute angle -mitchej123
|
||||
* It's the angel that pulls you out of OptiFine's hell -Roadhog360
|
||||
|
||||
## **Beta Quality - Here there be Dragons**
|
||||
## **Beta Quality - Here there be Dragons**
|
||||
* Shaders sneak preview - Please don't report issues yet, but please do submit fixes
|
||||
* Complementary & BSL mostly function, but have some bugs
|
||||
* Sildurs, Seus, and any other shader probably doesn't work
|
||||
@@ -14,7 +15,7 @@
|
||||
|
||||
# Required Dependencies
|
||||
* [UniMixins](https://github.com/LegacyModdingMC/UniMixins/releases) >= 0.1.14
|
||||
* [GTNHLib](https://github.com/GTNewHorizons/GTNHLib/releases) >= 0.3.2
|
||||
* [GTNHLib](https://github.com/GTNewHorizons/GTNHLib/releases) >= 0.4.2
|
||||
* NOTE: Some mods are not required, but a specific version is required if present - see: `Permanent Incompatibilities` below.
|
||||
|
||||
# Known (temporary) Incompatibilities
|
||||
@@ -30,14 +31,16 @@
|
||||
* RPLE - Not currently planned (Looking for volunteers)
|
||||
|
||||
# Permanent Incompatibilities
|
||||
* Optifine [Disabled, won't fix]
|
||||
* Fastcraft [Disable, won't fix]
|
||||
* BetterFPS [Won't fix]
|
||||
* LWJGL3ify 1.5.4 and below - Use the latest version available, 1.5.7+
|
||||
* ArchaicFix 0.6.2 and below - Use 0.7.0 or above
|
||||
* Hodgepodge 2.4.3 and below - [Use 2.4.4 or above](https://github.com/GTNewHorizons/Hodgepodge/releases)
|
||||
* OptiFine [Disabled, won't fix]
|
||||
* FastCraft [Disabled, won't fix]
|
||||
* BetterFPS [Disabled, won't fix]
|
||||
* OptimizationsAndTweaks [Disabled, won't fix]
|
||||
* [Amazing Trophies 1.2.1 and below](https://github.com/GTNewHorizons/Amazing-Trophies/releases) - use 1.2.2+
|
||||
* [LWJGL3ify 1.5.4 and below](https://github.com/GTNewHorizons/lwjgl3ify/releases/) - Use the latest version available, 1.5.7+
|
||||
* [ArchaicFix 0.6.2 and below](https://www.curseforge.com/minecraft/mc-mods/archaicfix/files/all?page=1&pageSize=20) - Use 0.7.0 or above
|
||||
* [Hodgepodge 2.4.3 and below](https://github.com/GTNewHorizons/Hodgepodge/releases) - Use 0.4.5 or above
|
||||
* CodeChicken[Core](https://github.com/GTNewHorizons/CodeChickenCore/releases)/[Lib](https://github.com/GTNewHorizons/CodeChickenLib/releases) <1.2.0 - Threading issues, use 1.3.0+
|
||||
* Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config)
|
||||
* Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config)
|
||||
|
||||
# Credits
|
||||
* ShadersMod
|
||||
@@ -65,7 +68,7 @@
|
||||
* HUDCaching
|
||||
* Created by [Moulberry](https://github.com/Moulberry/MCHUDCaching), backported from [Patcher](https://github.com/Sk1erLLC/Patcher) mod by Alexdoru under the CC-BY-SA-NC 4.0 license
|
||||
* Angelica
|
||||
* mitchej123, Omni, Makamys, Embeddedt, NanoLive, Caedis, Cardinalstar, Alexdoru, Eigenraven, mist475, Clepto for helping get Angelica up and running!
|
||||
* mitchej123, Omni, Makamys, Embeddedt, NanoLive, Caedis, Cardinalstar, Alexdoru, Eigenraven, mist475, Clepto, kurrycat for helping get Angelica up and running!
|
||||
* IMS, jss2a98aj, || dbp ||, roadhog360 for advice and moral support
|
||||
* Forge 1.12+
|
||||
* Some files have been taken from Minecraft Forge under the LGPL 2.1 license and are marked as such
|
||||
@@ -74,4 +77,8 @@
|
||||
license, see LICENSE in `com.gtnewhorizons.angelica.models`
|
||||
* Dynamic Lights
|
||||
* LambdAurora for [LambDynamicLights](https://github.com/LambdAurora/LambDynamicLights) under the MIT license, and the Forge port anthxnymc for [DynamicLightsReforged](https://github.com/anthxnymc/DynamicLightsReforged), also under the MIT license
|
||||
|
||||
* Embeddedt and Ferri_Arnus for [glsl-transformation-lib](https://github.com/TauMC/glsl-transformation-lib)
|
||||
* Also for work on [Monocle](https://github.com/ferriarnus/Monocle) which was used as a reference for implementing glsl-transformation-lib
|
||||
* Code from both glsl-transformation-lib and Monocle taken under their respective LGPL 3.0 licenses
|
||||
* FalseTweaks
|
||||
* FalsePattern for [FalseTweaks](https://github.com/falsepattern/falsetweaks) - Item Rendering Optimizations taken from FalseTweaks under the LGPL 3.0 license
|
||||
+21
-18
@@ -49,39 +49,41 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.4.31")
|
||||
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.5.78")
|
||||
|
||||
compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:0.4.0") { transitive = false }
|
||||
|
||||
compileOnly("org.projectlombok:lombok:1.18.22") { transitive = false }
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.22")
|
||||
|
||||
// Use modern models+textures to inject QuadProviders
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:TX-Loader:1.7.2:dev')
|
||||
|
||||
// Iris Shaders
|
||||
compileOnly('org.jetbrains:annotations:24.0.1')
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.3.2:dev")
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.5.20:dev")
|
||||
shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0
|
||||
implementation("io.github.douira:glsl-transformer:1.0.0")
|
||||
shadowImplementation("io.github.douira:glsl-transformer:1.0.0") { // glsl-transformer Noncommercial License 1.0.0
|
||||
shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-4.g6b42bca") {
|
||||
exclude module: "antlr4" // we only want to shadow the runtime module
|
||||
}
|
||||
shadowImplementation("org.antlr:antlr4-runtime:4.13.2")
|
||||
compileOnly "org.apache.ant:ant:1.8.2"
|
||||
|
||||
// Because who doesn't want NEI
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.4.9-GTNH:dev')
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.2.0:dev')
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.6.45-GTNH:dev')
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.3.10:dev')
|
||||
|
||||
// Notfine Deps
|
||||
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev")
|
||||
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")
|
||||
compileOnly("com.github.GTNewHorizons:twilightforest:2.5.16:dev") { transitive = false }
|
||||
devOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")
|
||||
compileOnly("com.github.GTNewHorizons:twilightforest:2.6.35:dev") { transitive = false }
|
||||
compileOnly(rfg.deobf('curse.maven:witchery-69673:2234410'))
|
||||
compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.0-GTNH:dev")
|
||||
compileOnly("com.github.GTNewHorizons:Natura:2.6.1:dev")
|
||||
compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.14-GTNH:dev") { transitive = false }
|
||||
compileOnly("com.github.GTNewHorizons:Natura:2.7.5:dev")
|
||||
|
||||
compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.0:dev") { transitive = false }
|
||||
compileOnly(rfg.deobf('maven.modrinth:backhand:1.4.1')) { transitive = false }
|
||||
compileOnly("com.github.GTNewHorizons:ThaumicHorizons:1.6.4:dev")
|
||||
|
||||
compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.0:dev") { transitive = false }
|
||||
compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.1:dev") { transitive = false }
|
||||
compileOnly(rfg.deobf('maven.modrinth:backhand:1.4.1')) { transitive = false }
|
||||
|
||||
compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.5.1:api") { transitive = false }
|
||||
@@ -92,15 +94,13 @@ dependencies {
|
||||
|
||||
compileOnly("curse.maven:minefactory-reloaded-66672:2277486")
|
||||
|
||||
compileOnly("com.github.GTNewHorizons:NotEnoughIds:2.0.3:dev") // Mixin Version
|
||||
compileOnly("com.github.GTNewHorizons:NotEnoughIds:2.1.6:dev") // Mixin Version
|
||||
compileOnly("com.github.GTNewHorizons:NotEnoughIds-Legacy:1.4.7:dev") // ASM Version
|
||||
|
||||
compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675"))
|
||||
// HMMMMM
|
||||
compileOnly(rfg.deobf("curse.maven:journeymap-32274:2367915"))
|
||||
compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684"))
|
||||
|
||||
compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.4-GTNH:dev")
|
||||
compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.13-GTNH:dev")
|
||||
|
||||
runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2"))
|
||||
|
||||
@@ -110,10 +110,13 @@ dependencies {
|
||||
// Better Crashes
|
||||
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.0-GTNH:dev")
|
||||
|
||||
|
||||
// Tests
|
||||
testImplementation(platform('org.junit:junit-bom:5.9.2'))
|
||||
testImplementation('org.junit.jupiter:junit-jupiter')
|
||||
testImplementation("org.mockito:mockito-core:3.+")
|
||||
testImplementation("org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209")
|
||||
|
||||
devOnlyNonPublishable("com.github.javaparser:javaparser-symbol-solver-core:3.26.2") {
|
||||
exclude module: "guava"
|
||||
}
|
||||
}
|
||||
+2084
File diff suppressed because it is too large.
Load diff
+12
-1
@@ -85,6 +85,11 @@ accessTransformersFile = angelica_at.cfg notfine_at.cfg archaicfix_at.cfg mcpatc
|
||||
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
|
||||
usesMixins = true
|
||||
|
||||
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
|
||||
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
|
||||
# Mixin classes will have access to "main" classes, but not the other way around.
|
||||
separateMixinSourceSet = mixin
|
||||
|
||||
# Adds some debug arguments like verbose output and class export.
|
||||
usesMixinDebug = false
|
||||
|
||||
@@ -117,9 +122,15 @@ minimizeShadowedDependencies = true
|
||||
# If disabled, won't rename the shadowed classes.
|
||||
relocateShadowedDependencies = true
|
||||
|
||||
# Adds the GTNH maven, CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
|
||||
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
|
||||
includeWellKnownRepositories = true
|
||||
|
||||
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
|
||||
# list of strings, with the acceptable keys being(case does not matter):
|
||||
# cursemaven
|
||||
# modrinth
|
||||
excludeWellKnownRepositories =
|
||||
|
||||
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
|
||||
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
|
||||
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -84,7 +86,8 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
Vendored
+2
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
|
||||
@@ -25,5 +25,12 @@ repositories {
|
||||
includeGroup('CoreTweaks')
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = 'taumc'
|
||||
url = 'https://maven.taumc.org/releases'
|
||||
content {
|
||||
includeGroup 'org.taumc'
|
||||
}
|
||||
}
|
||||
mavenLocal()
|
||||
}
|
||||
+1
-1
@@ -16,5 +16,5 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.23'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.29'
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import com.github.javaparser.StaticJavaParser;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Used to generate gl_functions.csv. Which contains a mapping of OpenGL functions provided by LWJGL
|
||||
* corresponding to the earliest GL version they appear in.
|
||||
*/
|
||||
public class GLFunctionParser {
|
||||
final static String glPath = "util/gl"; // Path to LWJGL OpenGL bindings source code
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
HashMap<String, Set<String>> byFunction = new HashMap<>();
|
||||
File dir = new File(glPath);
|
||||
for (File file : dir.listFiles()) {
|
||||
final String filename = file.getName();
|
||||
if (filename.endsWith(".java") && filename.startsWith("GL") && Character.isDigit(filename.charAt(2))) {
|
||||
Path p = Paths.get(filename);
|
||||
|
||||
String parsedFile = removeFileExtension(p.getFileName().toString());
|
||||
|
||||
CompilationUnit cu = StaticJavaParser.parse(file);
|
||||
cu.accept(new VoidVisitorWithDefaults<>() {
|
||||
|
||||
@Override
|
||||
public void defaultAction(Node n, Object arg) {
|
||||
for( Node child : n.getChildNodes()) {
|
||||
if(child instanceof ClassOrInterfaceDeclaration cd) {
|
||||
for (MethodDeclaration md : cd.getMethods()) {
|
||||
String methodName = md.getNameAsString() + "(";
|
||||
for (Parameter p : md.getParameters()) {
|
||||
methodName = methodName + p.getTypeAsString();
|
||||
}
|
||||
methodName = methodName + ")";
|
||||
if(methodName.startsWith("n")) continue;
|
||||
|
||||
Set<String> functionSet = byFunction.computeIfAbsent(methodName, k -> new HashSet<>());
|
||||
functionSet.add(parsedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> functionVersionMap = new HashMap<>();
|
||||
|
||||
for(String function : byFunction.keySet()) {
|
||||
|
||||
Set<String> versionsForFunction = byFunction.get(function);
|
||||
int lowestInt = 46;
|
||||
String lowestString = "GL46";
|
||||
for(String version : versionsForFunction) {
|
||||
int i = Integer.parseInt(version.substring(2, 4));
|
||||
if (i < lowestInt) {
|
||||
lowestInt = i;
|
||||
lowestString = version;
|
||||
}
|
||||
}
|
||||
functionVersionMap.put(function, lowestString);
|
||||
}
|
||||
|
||||
List<String[]> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : functionVersionMap.entrySet()) {
|
||||
outputLines.add(new String[] {entry.getKey(), entry.getValue()});
|
||||
}
|
||||
|
||||
File output = new File("output.csv");
|
||||
try (PrintWriter writer = new PrintWriter(output)) {
|
||||
outputLines.stream().map(GLSMFunctionComparison::convertToCSV).forEach(writer::println);
|
||||
}
|
||||
}
|
||||
|
||||
public static String convertToCSV(String[] data) {
|
||||
return Stream.of(data).map(GLSMFunctionComparison::escapeSpecialCharacters).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
public static String escapeSpecialCharacters(String data) {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Input data cannot be null");
|
||||
}
|
||||
String escapedData = data.replaceAll("\\R", " ");
|
||||
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
|
||||
data = data.replace("\"", "\"\"");
|
||||
escapedData = "\"" + data + "\"";
|
||||
}
|
||||
return escapedData;
|
||||
}
|
||||
|
||||
public static String removeFileExtension(String filename) {
|
||||
if (filename == null || filename.isEmpty()) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
String extPattern = "(?<!^)[.]" + "[^.]*$";
|
||||
return filename.replaceAll(extPattern, "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import com.github.javaparser.ParserConfiguration;
|
||||
import com.github.javaparser.StaticJavaParser;
|
||||
import com.github.javaparser.ast.CompilationUnit;
|
||||
import com.github.javaparser.ast.Node;
|
||||
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
|
||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||
import com.github.javaparser.ast.body.Parameter;
|
||||
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Used to compare OpenGL functions from gl_functions.csv to current GLStateManager
|
||||
* source code to determine what functions have an implementation in GLSM, and what ones don't.
|
||||
* Only considers functions which appear in GL 2.1 and lower
|
||||
*/
|
||||
public class GLSMFunctionComparison {
|
||||
|
||||
/**
|
||||
* If set to true, then the outputted CSV will show functions which do have an implementation in GLSM
|
||||
*/
|
||||
final static boolean INCLUDE_TRUE = false;
|
||||
|
||||
final static String glFunctionsCsvPath = "gl_functions.csv";
|
||||
final static String glsmPath = "src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java";
|
||||
|
||||
public static Map<String, String> parseGLFunctions() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(glFunctionsCsvPath))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] values = line.split(",");
|
||||
if (values.length == 2) {
|
||||
String key = values[0].trim();
|
||||
String value = values[1].trim();
|
||||
int versionInt = Integer.parseInt(value.substring(2, 4));
|
||||
if (versionInt < 30) map.put(key, value);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
//GLSM will fail to parse without increasing language level
|
||||
StaticJavaParser.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17);
|
||||
|
||||
Map<String, String> functionMap = parseGLFunctions();
|
||||
Set<String> glsmFunctions = new HashSet<>();
|
||||
|
||||
File glsmFile = new File(glsmPath);
|
||||
CompilationUnit cu = StaticJavaParser.parse(glsmFile);
|
||||
cu.accept(new VoidVisitorWithDefaults<>() {
|
||||
|
||||
@Override
|
||||
public void defaultAction(Node n, Object arg) {
|
||||
for (Node child : n.getChildNodes()) {
|
||||
if (child instanceof ClassOrInterfaceDeclaration cd) {
|
||||
for (MethodDeclaration md : cd.getMethods()) {
|
||||
String methodName = md.getNameAsString() + "(";
|
||||
for (Parameter p : md.getParameters()) {
|
||||
methodName = methodName + p.getTypeAsString();
|
||||
}
|
||||
methodName = methodName + ")";
|
||||
glsmFunctions.add(methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
|
||||
Map<String, String> functionGLSMMap = new HashMap<>();
|
||||
|
||||
for(String function : functionMap.keySet()) {
|
||||
if (!glsmFunctions.contains(function)) {
|
||||
functionGLSMMap.put(function, "false");
|
||||
} else if (INCLUDE_TRUE) {
|
||||
functionGLSMMap.put(function, "true");
|
||||
}
|
||||
}
|
||||
|
||||
List<String[]> outputLines = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : functionGLSMMap.entrySet()) {
|
||||
outputLines.add(new String[] {entry.getKey(), functionMap.get(entry.getKey()), entry.getValue()});
|
||||
}
|
||||
|
||||
File output = new File("glsm_function_comparison.csv");
|
||||
try (PrintWriter writer = new PrintWriter(output)) {
|
||||
outputLines.stream().map(GLSMFunctionComparison::convertToCSV).forEach(writer::println);
|
||||
}
|
||||
}
|
||||
|
||||
public static String convertToCSV(String[] data) {
|
||||
return Stream.of(data).map(GLSMFunctionComparison::escapeSpecialCharacters).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
public static String escapeSpecialCharacters(String data) {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Input data cannot be null");
|
||||
}
|
||||
String escapedData = data.replaceAll("\\R", " ");
|
||||
if (data.contains(",") || data.contains("\"") || data.contains("'")) {
|
||||
data = data.replace("\"", "\"\"");
|
||||
escapedData = "\"" + data + "\"";
|
||||
}
|
||||
return escapedData;
|
||||
}
|
||||
|
||||
public static String removeFileExtension(String filename) {
|
||||
if (filename == null || filename.isEmpty()) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
String extPattern = "(?<!^)[.]" + "[^.]*$";
|
||||
return filename.replaceAll(extPattern, "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica;
|
||||
|
||||
import com.gtnewhorizons.angelica.common.BlockError;
|
||||
import com.gtnewhorizons.angelica.compat.ModStatus;
|
||||
import com.gtnewhorizons.angelica.proxy.CommonProxy;
|
||||
import com.gtnewhorizons.angelica.utils.AnimationMode;
|
||||
@@ -15,7 +16,7 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
name = "Angelica",
|
||||
version = Tags.VERSION,
|
||||
dependencies = " before:lwjgl3ify@[1.5.3,);" + " after:hodgepodge@[2.4.4,);" + " after:CodeChickenCore@[1.2.0,);"
|
||||
+ " after:archaicfix@[0.7.0,);" + " required-after:gtnhlib@[0.3.2,);",
|
||||
+ " after:archaicfix@[0.7.0,);" + " required-after:gtnhlib@[0.4.2,);",
|
||||
acceptedMinecraftVersions = "[1.7.10]",
|
||||
acceptableRemoteVersions = "*",
|
||||
guiFactory = "com.gtnewhorizons.angelica.config.AngelicaGuiConfigFactory")
|
||||
@@ -27,10 +28,13 @@ public class AngelicaMod {
|
||||
|
||||
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
|
||||
|
||||
public static BlockError blockError;
|
||||
|
||||
@Mod.EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
ModStatus.preInit();
|
||||
proxy.preInit(event);
|
||||
blockError = new BlockError();
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
- [x] Frustum (Seems related to Frustrum)
|
||||
- [X] NativeImage
|
||||
- [ ] PoseStack
|
||||
- [ ] RenderType
|
||||
- [ ] MultiBufferSource.BufferSource
|
||||
- [ ] VertexBuffer
|
||||
- [ ] VertexConsumer
|
||||
- [ ] VertextFormat
|
||||
- [ ] TextureAtlas (Seems related to TextureManager) - PBR related
|
||||
- [ ] GUI
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.util.CoordinatePacker;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public interface BlockPos {
|
||||
int getX();
|
||||
int getY();
|
||||
int getZ();
|
||||
BlockPosImpl offset(ForgeDirection d);
|
||||
BlockPosImpl down();
|
||||
BlockPosImpl up();
|
||||
long asLong();
|
||||
|
||||
static long asLong(int x, int y, int z) {
|
||||
return CoordinatePacker.pack(x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
/**
|
||||
* To be used for modded items that don't have blocks. Baubles for example.
|
||||
*/
|
||||
public interface IDynamicLightProducer {
|
||||
int getLuminance();
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
public interface MutableBlockPos extends BlockPos {
|
||||
|
||||
MutableBlockPos set(int x, int y, int z);
|
||||
|
||||
MutableBlockPos set(long packedPos);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface QuadProvider {
|
||||
|
||||
int R_MASK = 0xFF << 16;
|
||||
int G_MASK = 0xFF << 8;
|
||||
int B_MASK = 0xFF;
|
||||
|
||||
/**
|
||||
* Returns the color packed as ABGR. If you want to vary colors within a block, just ignore the color passed into
|
||||
* {@link #getQuads} and use whatever you want. You might want to override this to return a constant if you're
|
||||
* extending a block with an expensive color call, like leaves.
|
||||
*/
|
||||
default int getColor(IBlockAccess world, BlockPos pos, Block block, int meta, Random random) {
|
||||
|
||||
final int cin = block.colorMultiplier(world, pos.getX(), pos.getY(), pos.getZ());
|
||||
return (0xFF << 24) | ((cin & B_MASK) << 16) | (cin & G_MASK) | ((cin & R_MASK) >>> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* If you need to allocate new quads, set this to true. If true, the quads returned by {@link #getQuads} are
|
||||
* recycled, and you should not keep a reference to them. Example: stone can return a static list every time, but a
|
||||
* modded block which adds or removes quads based on location would need dynamic quads.
|
||||
*/
|
||||
default boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide quads to render. If you need new quads, they should be obtained with the passed supplier and
|
||||
* {@link #isDynamic} overridden to return true. If so, all quads in the list are recycled and references to them
|
||||
* should not be kept.
|
||||
*/
|
||||
List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable;
|
||||
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface QuadView extends ModelQuadViewMutable {
|
||||
|
||||
boolean isShade();
|
||||
boolean isDeleted();
|
||||
ForgeDirection getFace();
|
||||
void copyFrom(QuadView src);
|
||||
void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags);
|
||||
int[] getRawVertexes();
|
||||
|
||||
/**
|
||||
* Present for compatibility with the Tesselator, not recommended for general use.
|
||||
*/
|
||||
void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ);
|
||||
}
|
||||
@@ -20,8 +20,6 @@ import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
/**
|
||||
* A batching replacement for {@code FontRenderer}
|
||||
*
|
||||
@@ -255,15 +253,15 @@ public class BatchingFontRenderer {
|
||||
GLStateManager.enableTexture();
|
||||
GLStateManager.enableAlphaTest();
|
||||
GLStateManager.enableBlend();
|
||||
GLStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
GLStateManager.glShadeModel(GL_FLAT);
|
||||
GLStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
|
||||
GLStateManager.glShadeModel(GL11.GL_FLAT);
|
||||
|
||||
glTexCoordPointer(2, 0, batchVtxTexCoords);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, batchVtxColors);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(2, 0, batchVtxPositions);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
GL11.glTexCoordPointer(2, 0, batchVtxTexCoords);
|
||||
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
|
||||
GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, batchVtxColors);
|
||||
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
|
||||
GL11.glVertexPointer(2, 0, batchVtxPositions);
|
||||
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
|
||||
GLStateManager.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
// Use plain for loop to avoid allocations
|
||||
@@ -285,12 +283,12 @@ public class BatchingFontRenderer {
|
||||
}
|
||||
batchIndices.limit(cmd.startVtx + cmd.idxCount);
|
||||
batchIndices.position(cmd.startVtx);
|
||||
glDrawElements(GL_TRIANGLES, batchIndices);
|
||||
GL11.glDrawElements(GL11.GL_TRIANGLES, batchIndices);
|
||||
}
|
||||
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
|
||||
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
|
||||
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
|
||||
|
||||
if (isTextureEnabledBefore) {
|
||||
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
|
||||
@@ -359,7 +357,7 @@ public class BatchingFontRenderer {
|
||||
final float underlineY = anchorY + underlying.FONT_HEIGHT - 1.0f;
|
||||
float underlineStartX = 0.0f;
|
||||
float underlineEndX = 0.0f;
|
||||
final float strikethroughY = anchorY + (float) (underlying.FONT_HEIGHT / 2);
|
||||
final float strikethroughY = anchorY + (float) (underlying.FONT_HEIGHT / 2) - 1.0F;
|
||||
float strikethroughStartX = 0.0f;
|
||||
float strikethroughEndX = 0.0f;
|
||||
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.client.renderer;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.Vector3dStack;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ITessellatorInstance;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static net.minecraft.util.MathHelper.clamp_int;
|
||||
|
||||
/*
|
||||
* To be used in conjunction with the TessellatorManager
|
||||
*
|
||||
* Used to capture the quads generated by the Tessellator across multiple draw calls and make the quad
|
||||
* list available for usage.
|
||||
*
|
||||
* NOTE: This will _not_ (currently) capture, integrate, or stop any GL calls made around the tessellator draw calls.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class CapturingTessellator extends Tessellator implements ITessellatorInstance {
|
||||
|
||||
// Access Transformers don't work on Forge Fields :rage:
|
||||
private static final MethodHandle sRawBufferSize;
|
||||
private static final MethodHandle gRawBufferSize;
|
||||
private final BlockRenderer.Flags FLAGS = new BlockRenderer.Flags(true, true, true, true);
|
||||
private final ObjectPooler<QuadView> quadBuf = new ObjectPooler<>(Quad::new);
|
||||
private final List<QuadView> collectedQuads = new ObjectArrayList<>();
|
||||
|
||||
// Any offset we need to the Tesselator's offset!
|
||||
private final BlockPosImpl offset = new BlockPosImpl();
|
||||
|
||||
private final Vector3dStack storedTranslation = new Vector3dStack();
|
||||
|
||||
public void setOffset(BlockPosImpl pos) {
|
||||
this.offset.set(pos);
|
||||
}
|
||||
public void resetOffset() {
|
||||
this.offset.zero();
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
final Field rbs = ReflectionHelper.findField(Tessellator.class, "rawBufferSize");
|
||||
rbs.setAccessible(true);
|
||||
try {
|
||||
sRawBufferSize = MethodHandles.lookup().unreflectSetter(rbs);
|
||||
gRawBufferSize = MethodHandles.lookup().unreflectGetter(rbs);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRawBufferSize(int size) {
|
||||
try {
|
||||
sRawBufferSize.invokeExact((Tessellator)this, size);
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
public int getRawBufferSize() {
|
||||
try {
|
||||
return (int) gRawBufferSize.invokeExact((Tessellator)this);
|
||||
} catch (Throwable throwable) {
|
||||
throw new RuntimeException(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int draw() {
|
||||
// Adapted from Neodymium
|
||||
|
||||
FLAGS.hasBrightness = this.hasBrightness;
|
||||
FLAGS.hasColor = this.hasColor;
|
||||
FLAGS.hasNormals = this.hasNormals;
|
||||
|
||||
final int verticesPerPrimitive = this.drawMode == GL11.GL_QUADS ? 4 : 3;
|
||||
|
||||
|
||||
for(int quadI = 0; quadI < this.vertexCount / verticesPerPrimitive; quadI++) {
|
||||
final QuadView quad = quadBuf.getInstance();
|
||||
quad.setState(this.rawBuffer, quadI * (verticesPerPrimitive * 8), FLAGS, this.drawMode, -offset.x, -offset.y, -offset.z);
|
||||
|
||||
if(quad.isDeleted()) {
|
||||
quadBuf.releaseInstance(quad);
|
||||
} else {
|
||||
this.collectedQuads.add(quad);
|
||||
}
|
||||
}
|
||||
|
||||
final int i = this.rawBufferIndex * 4;
|
||||
this.discard();
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void discard() {
|
||||
isDrawing = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
public List<QuadView> getQuads() {
|
||||
return collectedQuads;
|
||||
}
|
||||
|
||||
public void clearQuads() {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for(int i = 0; i < this.collectedQuads.size(); i++) {
|
||||
this.quadBuf.releaseInstance(this.collectedQuads.get(i));
|
||||
}
|
||||
this.collectedQuads.clear();
|
||||
}
|
||||
|
||||
public static ByteBuffer quadsToBuffer(List<QuadView> quads, VertexFormat format) {
|
||||
if(!format.canWriteQuads()) {
|
||||
throw new IllegalStateException("Vertex format has no quad writer: " + format);
|
||||
}
|
||||
final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(format.getVertexSize() * quads.size() * 4);
|
||||
// noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, quadsSize = quads.size(); i < quadsSize; i++) {
|
||||
format.writeQuad(quads.get(i), byteBuffer);
|
||||
}
|
||||
byteBuffer.rewind();
|
||||
return byteBuffer;
|
||||
}
|
||||
|
||||
public void storeTranslation() {
|
||||
storedTranslation.push();
|
||||
|
||||
this.storedTranslation.set(xOffset, yOffset, zOffset);
|
||||
}
|
||||
|
||||
public void restoreTranslation() {
|
||||
|
||||
xOffset = storedTranslation.x;
|
||||
yOffset = storedTranslation.y;
|
||||
zOffset = storedTranslation.z;
|
||||
storedTranslation.pop();
|
||||
}
|
||||
|
||||
public static int createBrightness(int sky, int block) {
|
||||
return sky << 20 | block << 4;
|
||||
}
|
||||
|
||||
// API from newer MC
|
||||
public CapturingTessellator pos(double x, double y, double z) {
|
||||
ensureBuffer();
|
||||
|
||||
this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float)(x + this.xOffset));
|
||||
this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float)(y + this.yOffset));
|
||||
this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float)(z + this.zOffset));
|
||||
|
||||
return this;
|
||||
}
|
||||
public CapturingTessellator tex(double u, double v) {
|
||||
this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float)u);
|
||||
this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float)v);
|
||||
this.hasTexture = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CapturingTessellator color(float red, float green, float blue, float alpha) {
|
||||
return this.color((int)(red * 255.0F), (int)(green * 255.0F), (int)(blue * 255.0F), (int)(alpha * 255.0F));
|
||||
}
|
||||
|
||||
public CapturingTessellator color(int red, int green, int blue, int alpha) {
|
||||
if(this.isColorDisabled) return this;
|
||||
red = clamp_int(red, 0, 255);
|
||||
green = clamp_int(green, 0, 255);
|
||||
blue = clamp_int(blue, 0, 255);
|
||||
alpha = clamp_int(alpha, 0, 255);
|
||||
|
||||
final int color;
|
||||
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
|
||||
color = alpha << 24 | blue << 16 | green << 8 | red;
|
||||
} else {
|
||||
color = red << 24 | green << 16 | blue << 8 | alpha;
|
||||
}
|
||||
this.rawBuffer[this.rawBufferIndex + 5] = color;
|
||||
this.hasColor = true;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
public CapturingTessellator normal(float x, float y, float z) {
|
||||
final byte b0 = (byte)((int)(x * 127.0F));
|
||||
final byte b1 = (byte)((int)(y * 127.0F));
|
||||
final byte b2 = (byte)((int)(z * 127.0F));
|
||||
|
||||
this.rawBuffer[this.rawBufferIndex + 6] = b0 & 255 | (b1 & 255) << 8 | (b2 & 255) << 16;
|
||||
this.hasNormals = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CapturingTessellator lightmap(int skyLight, int blockLight) {
|
||||
return brightness(createBrightness(skyLight, blockLight));
|
||||
}
|
||||
|
||||
public CapturingTessellator brightness(int brightness) {
|
||||
this.rawBuffer[this.rawBufferIndex + 7] = brightness;
|
||||
this.hasBrightness = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CapturingTessellator endVertex() {
|
||||
this.rawBufferIndex += 8;
|
||||
++this.vertexCount;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ensureBuffer() {
|
||||
int rawBufferSize = getRawBufferSize();
|
||||
if (rawBufferIndex >= rawBufferSize - 32) {
|
||||
if (rawBufferSize == 0) {
|
||||
rawBufferSize = 0x10000;
|
||||
setRawBufferSize(rawBufferSize);
|
||||
rawBuffer = new int[rawBufferSize];
|
||||
} else {
|
||||
rawBufferSize *= 2;
|
||||
setRawBufferSize(rawBufferSize);
|
||||
rawBuffer = Arrays.copyOf(rawBuffer, rawBufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.gtnewhorizons.angelica.common;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
/**
|
||||
* This Block is not actually getting registered. A static instance is created in AngelicaMod.
|
||||
* Actually registering the block on the client but not the server can cause block IDs to
|
||||
* different between client/server, which is not good.
|
||||
|
||||
* We're essentially injecting the block's texture, so that we may use this block as if it were
|
||||
* any normal block for rendering purposes with RenderBlocks and such, but not have to actually
|
||||
* register it as a block.
|
||||
*/
|
||||
|
||||
public class BlockError extends Block {
|
||||
|
||||
public static final IIcon[] icons = new IIcon[2];
|
||||
|
||||
public BlockError() {
|
||||
super(Material.rock);
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void onTextureStitch(TextureStitchEvent.Pre event) {
|
||||
if (event.map.getTextureType() == 0) {
|
||||
for (int i = 0; i < icons.length; i++) {
|
||||
icons[i] = event.map.registerIcon("angelica:error_block_" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public IIcon getIcon(int side, int meta) {
|
||||
return meta >= 0 && meta < icons.length ? icons[meta] : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +1,34 @@
|
||||
package com.gtnewhorizons.angelica.common;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.json.JsonModel;
|
||||
import com.gtnewhorizons.angelica.models.json.Loader;
|
||||
import com.gtnewhorizons.angelica.models.json.Variant;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadProvider;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.util.DirectionUtil;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ModeledBlock;
|
||||
import com.gtnewhorizons.angelica.utils.AssetLoader;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
import static com.gtnewhorizons.angelica.models.VanillaModels.LECTERN;
|
||||
|
||||
public class BlockTest extends Block implements QuadProvider {
|
||||
public class BlockTest extends Block implements ModeledBlock {
|
||||
|
||||
public static final Variant[] modelId = {
|
||||
new Variant(
|
||||
new ResourceLocation("blocks/lectern"),
|
||||
0,
|
||||
0,
|
||||
false
|
||||
),
|
||||
new Variant(
|
||||
new ResourceLocation("blocks/lectern"),
|
||||
180,
|
||||
0,
|
||||
false
|
||||
),
|
||||
new Variant(
|
||||
new ResourceLocation("blocks/lectern"),
|
||||
90,
|
||||
0,
|
||||
false
|
||||
),
|
||||
new Variant(
|
||||
new ResourceLocation("blocks/lectern"),
|
||||
270,
|
||||
0,
|
||||
false
|
||||
),
|
||||
};
|
||||
private static final List<QuadView> EMPTY = ObjectImmutableList.of();
|
||||
private static final JsonModel[] model = new JsonModel[4];
|
||||
@Getter
|
||||
@Setter
|
||||
private QuadProvider model;
|
||||
|
||||
public BlockTest() {
|
||||
|
||||
super(Material.rock);
|
||||
}
|
||||
|
||||
public static void loadModel() {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
model[i] = Loader.getModel(modelId[i]);
|
||||
this.setBlockTextureName("missingno");
|
||||
this.setModel((world, pos, block, meta, dir, random, color, quadPool) -> {
|
||||
if (meta < 2 || meta > 5) meta = 2;
|
||||
return LECTERN.models[meta - 2].getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,21 +38,9 @@ public class BlockTest extends Block implements QuadProvider {
|
||||
|
||||
@Override
|
||||
public void registerBlockIcons(IIconRegister reg) {
|
||||
|
||||
reg.registerIcon("angelica:test_block");
|
||||
reg.registerIcon("lectern_base");
|
||||
reg.registerIcon("lectern_front");
|
||||
reg.registerIcon("lectern_sides");
|
||||
reg.registerIcon("lectern_top");
|
||||
reg.registerIcon("oak_planks");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
|
||||
if (meta < 2 || meta > 5) meta = 2;
|
||||
|
||||
return (model[meta - 2] != null) ? model[meta - 2].getQuads(world, pos, block, meta, dir, random, color, quadPool) : EMPTY;
|
||||
for (String s : AssetLoader.testTexs) {
|
||||
reg.registerIcon(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +50,7 @@ public class BlockTest extends Block implements QuadProvider {
|
||||
public int onBlockPlaced(@NotNull World worldIn, int x, int y, int z, int side, float subX, float subY, float subZ, int meta) {
|
||||
|
||||
// Face NORTH if placed up or down
|
||||
final ForgeDirection s = ForgeDirection.values()[side];
|
||||
final ForgeDirection s = DirectionUtil.ALL_DIRECTIONS[side];
|
||||
if (s == ForgeDirection.UP || s == ForgeDirection.DOWN)
|
||||
return 2;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat;
|
||||
|
||||
import com.falsepattern.chunk.api.DataRegistry;
|
||||
import com.gtnewhorizons.angelica.mixins.early.sodium.MixinExtendedBlockStorage;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedBlockStorageAccessor;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedNibbleArray;
|
||||
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
|
||||
}
|
||||
|
||||
public ExtendedBlockStorageExt(Chunk chunk, ExtendedBlockStorage storage) {
|
||||
super(((MixinExtendedBlockStorage) storage).getYBase(), storage.getSkylightArray() != null);
|
||||
super(((ExtendedBlockStorageAccessor) storage).getYBase(), storage.getSkylightArray() != null);
|
||||
|
||||
if (ModStatus.isChunkAPILoaded) {
|
||||
if (storage.getSkylightArray() != null) {
|
||||
@@ -68,7 +68,7 @@ public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
|
||||
copyNibbleArray((ExtendedNibbleArray) storage.getSkylightArray(), (ExtendedNibbleArray) this.getSkylightArray());
|
||||
}
|
||||
}
|
||||
((MixinExtendedBlockStorage) this).setBlockRefCount(((MixinExtendedBlockStorage) storage).getBlockRefCount());
|
||||
((ExtendedBlockStorageAccessor) this).setBlockRefCount(((ExtendedBlockStorageAccessor) storage).getBlockRefCount());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.gtnewhorizons.angelica.helpers.LoadControllerHelper;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import mods.battlegear2.Battlegear;
|
||||
import net.dries007.holoInventory.HoloInventory;
|
||||
import xonin.backhand.Backhand;
|
||||
|
||||
@@ -26,6 +27,9 @@ public class ModStatus {
|
||||
public static boolean isHoloInventoryLoaded;
|
||||
public static boolean isBattlegearLoaded;
|
||||
public static boolean isBackhandLoaded;
|
||||
public static boolean isThaumcraftLoaded;
|
||||
public static boolean isThaumicHorizonsLoaded;
|
||||
public static boolean isBaublesLoaded;
|
||||
|
||||
public static void preInit(){
|
||||
isBetterCrashesLoaded = Loader.isModLoaded("bettercrashes");
|
||||
@@ -38,6 +42,9 @@ public class ModStatus {
|
||||
isHoloInventoryLoaded = Loader.isModLoaded("holoinventory");
|
||||
isBattlegearLoaded = Loader.isModLoaded("battlegear2");
|
||||
isBackhandLoaded = Loader.isModLoaded("backhand");
|
||||
isThaumcraftLoaded = Loader.isModLoaded("Thaumcraft");
|
||||
isThaumicHorizonsLoaded = Loader.isModLoaded("ThaumicHorizons");
|
||||
isBaublesLoaded = Loader.isModLoaded("Baubles");
|
||||
|
||||
if (isHoloInventoryLoaded){
|
||||
isHoloInventoryLoaded = new DefaultArtifactVersion("2.4.4-GTNH")
|
||||
@@ -46,6 +53,14 @@ public class ModStatus {
|
||||
) <= 0;
|
||||
}
|
||||
|
||||
// remove compat with original release of BG2
|
||||
if (isBattlegearLoaded){
|
||||
isBattlegearLoaded = new DefaultArtifactVersion("1.2.0")
|
||||
.compareTo(
|
||||
LoadControllerHelper.getOwningMod(Battlegear.class).getProcessedVersion()
|
||||
) <= 0;
|
||||
}
|
||||
|
||||
if (isBackhandLoaded){
|
||||
isBackhandLoaded = new DefaultArtifactVersion("1.4.1")
|
||||
.compareTo(
|
||||
|
||||
@@ -1,12 +1,58 @@
|
||||
package com.gtnewhorizons.angelica.compat.lwjgl;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.Pointer.BITS64;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongPredicate;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
/**
|
||||
* Backported from LWJGL3 under the BSD 3-Clause "New" or "Revised" License license
|
||||
*
|
||||
* <p>This class provides functionality for managing native memory.
|
||||
*
|
||||
* <p>All methods in this class will make use of {@link sun.misc.Unsafe} if it's available, for performance. If Unsafe is not available, the fallback
|
||||
* implementations make use of reflection and, in the worst-case, JNI.</p>
|
||||
*
|
||||
* <p>Method names in this class are prefixed with {@code mem} to avoid ambiguities when used with static imports.</p>
|
||||
*/
|
||||
public class CompatMemoryUtil {
|
||||
public static final long NULL = 0;
|
||||
|
||||
static final sun.misc.Unsafe UNSAFE;
|
||||
|
||||
private static final Class<? extends ByteBuffer> BUFFER_BYTE;
|
||||
private static final Class<? extends IntBuffer> BUFFER_INT;
|
||||
private static final Class<? extends FloatBuffer> BUFFER_FLOAT;
|
||||
|
||||
private static final long MARK;
|
||||
private static final long POSITION;
|
||||
private static final long LIMIT;
|
||||
private static final long CAPACITY;
|
||||
|
||||
private static final long ADDRESS;
|
||||
|
||||
static {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
|
||||
BUFFER_BYTE = bb.getClass();
|
||||
BUFFER_INT = bb.asIntBuffer().getClass();
|
||||
BUFFER_FLOAT = bb.asFloatBuffer().getClass();
|
||||
|
||||
UNSAFE = getUnsafeInstance();
|
||||
|
||||
MARK = getMarkOffset();
|
||||
POSITION = getPositionOffset();
|
||||
LIMIT = getLimitOffset();
|
||||
CAPACITY = getCapacityOffset();
|
||||
|
||||
ADDRESS = getAddressOffset();
|
||||
}
|
||||
|
||||
public static ByteBuffer memReallocDirect(ByteBuffer old, int capacity) {
|
||||
ByteBuffer newBuf = BufferUtils.createByteBuffer(capacity);
|
||||
int oldPos = old.position();
|
||||
@@ -34,22 +80,100 @@ public class CompatMemoryUtil {
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
/* -------------------------------------
|
||||
-------------------------------------
|
||||
UNSAFE MEMORY ACCESS API
|
||||
-------------------------------------
|
||||
------------------------------------- */
|
||||
|
||||
private static final int FILL_PATTERN_32 = Integer.divideUnsigned(-1, 255);
|
||||
private static final long FILL_PATTERN_64 = Long.divideUnsigned(-1L, 255L);
|
||||
|
||||
/**
|
||||
* Backported from LWJGL3 under the BSD 3-Clause "New" or "Revised" License license
|
||||
* Sets all bytes in a specified block of memory to a fixed value (usually zero).
|
||||
*
|
||||
* <p>This class provides functionality for managing native memory.
|
||||
*
|
||||
* <p>All methods in this class will make use of {@link sun.misc.Unsafe} if it's available, for performance. If Unsafe is not available, the fallback
|
||||
* implementations make use of reflection and, in the worst-case, JNI.</p>
|
||||
*
|
||||
* <p>Method names in this class are prefixed with {@code mem} to avoid ambiguities when used with static imports.</p>
|
||||
* @param ptr the starting memory address
|
||||
* @param value the value to set (memSet will convert it to unsigned byte)
|
||||
* @param bytes the number of bytes to set
|
||||
*/
|
||||
public static void memSet(long ptr, int value, long bytes) {
|
||||
if (/*DEBUG*/ false && (ptr == NULL || bytes < 0)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
static final sun.misc.Unsafe UNSAFE;
|
||||
/*
|
||||
- Unsafe.setMemory is very slow.
|
||||
- A custom Java loop is fastest at small sizes, approximately up to 256 bytes.
|
||||
- The native memset becomes fastest at bigger sizes, when the JNI overhead becomes negligible.
|
||||
TODO: verify this
|
||||
*/
|
||||
|
||||
static {
|
||||
UNSAFE = getUnsafeInstance();
|
||||
//UNSAFE.setMemory(ptr, bytes, (byte)(value & 0xFF));
|
||||
//if (bytes < 256L) {
|
||||
int p = (int)ptr;
|
||||
if (BITS64) {
|
||||
if ((p & 7) == 0) {
|
||||
memSet64(ptr, value, (int)bytes & 0xFF);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ((p & 3) == 0) {
|
||||
memSet32(p, value, (int)bytes & 0xFF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//}
|
||||
//nmemset(ptr, value, bytes);
|
||||
}
|
||||
private static void memSet64(long ptr, int value, int bytes) {
|
||||
int aligned = bytes & ~7;
|
||||
|
||||
// Aligned body
|
||||
long valuel = (value & 0xFF) * FILL_PATTERN_64;
|
||||
for (int i = 0; i < aligned; i += 8) {
|
||||
UNSAFE.putLong(null, ptr + i, valuel);
|
||||
}
|
||||
|
||||
// Unaligned tail
|
||||
byte valueb = (byte)(value & 0xFF);
|
||||
for (int i = aligned; i < bytes; i++) {
|
||||
UNSAFE.putByte(null, ptr + i, valueb);
|
||||
}
|
||||
}
|
||||
private static void memSet32(int ptr, int value, int bytes) {
|
||||
int aligned = bytes & ~3;
|
||||
|
||||
// Aligned body
|
||||
int vi = (value & 0xFF) * FILL_PATTERN_32;
|
||||
for (int i = 0; i < aligned; i += 4) {
|
||||
UNSAFE.putInt(null, (ptr + i) & 0xFFFF_FFFFL, vi);
|
||||
}
|
||||
|
||||
// Unaligned tail
|
||||
byte vb = (byte)(value & 0xFF);
|
||||
for (int i = aligned; i < bytes; i++) {
|
||||
UNSAFE.putByte(null, (ptr + i) & 0xFFFF_FFFFL, vb);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean memGetBoolean(long ptr) { return UNSAFE.getByte(null, ptr) != 0; }
|
||||
public static byte memGetByte(long ptr) { return UNSAFE.getByte(null, ptr); }
|
||||
public static short memGetShort(long ptr) { return UNSAFE.getShort(null, ptr); }
|
||||
public static int memGetInt(long ptr) { return UNSAFE.getInt(null, ptr); }
|
||||
public static long memGetLong(long ptr) { return UNSAFE.getLong(null, ptr); }
|
||||
public static float memGetFloat(long ptr) { return UNSAFE.getFloat(null, ptr); }
|
||||
public static double memGetDouble(long ptr) { return UNSAFE.getDouble(null, ptr); }
|
||||
|
||||
public static void memPutByte(long ptr, byte value) { UNSAFE.putByte(null, ptr, value); }
|
||||
public static void memPutShort(long ptr, short value) { UNSAFE.putShort(null, ptr, value); }
|
||||
public static void memPutInt(long ptr, int value) { UNSAFE.putInt(null, ptr, value); }
|
||||
public static void memPutLong(long ptr, long value) { UNSAFE.putLong(null, ptr, value); }
|
||||
public static void memPutFloat(long ptr, float value) { UNSAFE.putFloat(null, ptr, value); }
|
||||
public static void memPutDouble(long ptr, double value) { UNSAFE.putDouble(null, ptr, value); }
|
||||
|
||||
// -------------------------------------------------
|
||||
// -------------------------------------------------
|
||||
// -------------------------------------------------
|
||||
|
||||
private static sun.misc.Unsafe getUnsafeInstance() {
|
||||
java.lang.reflect.Field[] fields = sun.misc.Unsafe.class.getDeclaredFields();
|
||||
@@ -83,20 +207,121 @@ public class CompatMemoryUtil {
|
||||
throw new UnsupportedOperationException("LWJGL requires sun.misc.Unsafe to be available.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively searches an object and its superclasses for a field with the same name and type. If the field isn't
|
||||
* public, it may not be stable across library/JVM versions, and these calls are likely not portable. You have been
|
||||
* warned!
|
||||
*/
|
||||
private static long getFieldOffset(Class<?> containerType, Class<?> fieldType, String name) {
|
||||
Class<?> c = containerType;
|
||||
while (c != Object.class) {
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if (!field.getType().isAssignableFrom(fieldType) || Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
public static void memPutByte(long ptr, byte value) { UNSAFE.putByte(null, ptr, value); }
|
||||
public static void memPutShort(long ptr, short value) { UNSAFE.putShort(null, ptr, value); }
|
||||
public static void memPutInt(long ptr, int value) { UNSAFE.putInt(null, ptr, value); }
|
||||
public static void memPutLong(long ptr, long value) { UNSAFE.putLong(null, ptr, value); }
|
||||
public static void memPutFloat(long ptr, float value) { UNSAFE.putFloat(null, ptr, value); }
|
||||
public static void memPutDouble(long ptr, double value) { UNSAFE.putDouble(null, ptr, value); }
|
||||
long offset = UNSAFE.objectFieldOffset(field);
|
||||
if (field.getName().equals(name)) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
throw new UnsupportedOperationException("Failed to find field offset in class.");
|
||||
}
|
||||
|
||||
public static boolean memGetBoolean(long ptr) { return UNSAFE.getByte(null, ptr) != 0; }
|
||||
public static byte memGetByte(long ptr) { return UNSAFE.getByte(null, ptr); }
|
||||
public static short memGetShort(long ptr) { return UNSAFE.getShort(null, ptr); }
|
||||
public static int memGetInt(long ptr) { return UNSAFE.getInt(null, ptr); }
|
||||
public static long memGetLong(long ptr) { return UNSAFE.getLong(null, ptr); }
|
||||
public static float memGetFloat(long ptr) { return UNSAFE.getFloat(null, ptr); }
|
||||
public static double memGetDouble(long ptr) { return UNSAFE.getDouble(null, ptr); }
|
||||
private static long getFieldOffset(Class<?> containerType, Class<?> fieldType, LongPredicate predicate) {
|
||||
Class<?> c = containerType;
|
||||
while (c != Object.class) {
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if (!field.getType().isAssignableFrom(fieldType) || Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long offset = UNSAFE.objectFieldOffset(field);
|
||||
if (predicate.test(offset)) {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
throw new UnsupportedOperationException("Failed to find field offset in class.");
|
||||
}
|
||||
|
||||
private static long getFieldOffsetInt(Object container, int value) {
|
||||
return getFieldOffset(container.getClass(), int.class, offset -> UNSAFE.getInt(container, offset) == value);
|
||||
}
|
||||
|
||||
private static long getAddressOffset() {
|
||||
final ByteBuffer bb = ByteBuffer.allocateDirect(0);
|
||||
return getFieldOffset(bb.getClass(), long.class, "address");
|
||||
|
||||
// TODO: do this portably
|
||||
// long MAGIC_ADDRESS = 0xDEADBEEF8BADF00DL & (BITS32 ? 0xFFFF_FFFFL : 0xFFFF_FFFF_FFFF_FFFFL);
|
||||
// ByteBuffer bb = Objects.requireNonNull(NewDirectByteBuffer(MAGIC_ADDRESS, 0));
|
||||
//return getFieldOffset(bb.getClass(), long.class, offset -> UNSAFE.getLong(bb, offset) == MAGIC_ADDRESS);
|
||||
}
|
||||
|
||||
private static final int MAGIC_CAPACITY = 0x0D15EA5E;
|
||||
private static final int MAGIC_POSITION = 0x00FACADE;
|
||||
|
||||
private static long getMarkOffset() {
|
||||
// TODO: is this actually reliable without NewDirectByteBuffer?
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(0);
|
||||
return getFieldOffsetInt(bb, -1);
|
||||
// ByteBuffer bb = Objects.requireNonNull(NewDirectByteBuffer(1L, 0));
|
||||
// return getFieldOffsetInt(bb, -1);
|
||||
}
|
||||
|
||||
private static long getPositionOffset() {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
|
||||
bb.position(MAGIC_POSITION);
|
||||
return getFieldOffsetInt(bb, MAGIC_POSITION);
|
||||
}
|
||||
|
||||
private static long getLimitOffset() {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
|
||||
bb.limit(MAGIC_POSITION);
|
||||
return getFieldOffsetInt(bb, MAGIC_POSITION);
|
||||
}
|
||||
|
||||
private static long getCapacityOffset() {
|
||||
ByteBuffer bb = ByteBuffer.allocateDirect(MAGIC_CAPACITY);
|
||||
bb.limit(0);
|
||||
return getFieldOffsetInt(bb, MAGIC_CAPACITY);
|
||||
}
|
||||
|
||||
static IntBuffer wrapBufferInt(long address, int capacity) {
|
||||
IntBuffer buffer;
|
||||
try {
|
||||
buffer = (IntBuffer)UNSAFE.allocateInstance(BUFFER_INT);
|
||||
} catch (InstantiationException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
|
||||
UNSAFE.putLong(buffer, ADDRESS, address);
|
||||
UNSAFE.putInt(buffer, MARK, -1);
|
||||
UNSAFE.putInt(buffer, LIMIT, capacity);
|
||||
UNSAFE.putInt(buffer, CAPACITY, capacity);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static FloatBuffer wrapBufferFloat(long address, int capacity) {
|
||||
FloatBuffer buffer;
|
||||
try {
|
||||
buffer = (FloatBuffer)UNSAFE.allocateInstance(BUFFER_FLOAT);
|
||||
} catch (InstantiationException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
|
||||
UNSAFE.putLong(buffer, ADDRESS, address);
|
||||
UNSAFE.putInt(buffer, MARK, -1);
|
||||
UNSAFE.putInt(buffer, LIMIT, capacity);
|
||||
UNSAFE.putInt(buffer, CAPACITY, capacity);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* This class is backported from LWJGL3 under the BSD 3-clause "New" or "Revised" License
|
||||
*/
|
||||
|
||||
package com.gtnewhorizons.angelica.compat.lwjgl;
|
||||
|
||||
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutDouble;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutFloat;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutInt;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutLong;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memPutShort;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.memSet;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.wrapBufferFloat;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.wrapBufferInt;
|
||||
|
||||
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.MemoryUtil;
|
||||
|
||||
/**
|
||||
* An off-heap memory stack.
|
||||
*
|
||||
* <p>This class should be used in a thread-local manner for stack allocations.</p>
|
||||
*
|
||||
* @ see Configuration#STACK_SIZE
|
||||
* @ see Configuration#DEBUG_STACK
|
||||
*/
|
||||
@SuppressWarnings("LombokGetterMayBeUsed")
|
||||
public class MemoryStack extends Pointer.Default implements AutoCloseable {
|
||||
|
||||
private static final int DEFAULT_STACK_SIZE = /*Configuration.STACK_SIZE.get(64)*/ 64 * 1024;
|
||||
private static final int DEFAULT_STACK_FRAMES = 8;
|
||||
|
||||
private static final ThreadLocal<MemoryStack> TLS = ThreadLocal.withInitial(MemoryStack::create);
|
||||
|
||||
static {
|
||||
if (DEFAULT_STACK_SIZE < 0) {
|
||||
throw new IllegalStateException("Invalid stack size.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final @Nullable ByteBuffer container;
|
||||
|
||||
private final int size;
|
||||
|
||||
private int pointer;
|
||||
|
||||
private int[] frames;
|
||||
protected int frameIndex;
|
||||
|
||||
/**
|
||||
* Creates a new {@code MemoryStack} backed by the specified memory region.
|
||||
*
|
||||
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
|
||||
*
|
||||
* @param container the backing memory buffer, may be null
|
||||
* @param address the backing memory address
|
||||
* @param size the backing memory size
|
||||
*/
|
||||
protected MemoryStack(@Nullable ByteBuffer container, long address, int size) {
|
||||
super(address);
|
||||
this.container = container;
|
||||
|
||||
this.size = size;
|
||||
this.pointer = size;
|
||||
|
||||
this.frames = new int[DEFAULT_STACK_FRAMES];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code MemoryStack} with the default size.
|
||||
*
|
||||
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
|
||||
*/
|
||||
public static MemoryStack create() {
|
||||
return create(DEFAULT_STACK_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code MemoryStack} with the specified size.
|
||||
*
|
||||
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
|
||||
*
|
||||
* @param capacity the maximum number of bytes that may be allocated on the stack
|
||||
*/
|
||||
public static MemoryStack create(int capacity) {
|
||||
return create(BufferUtils.createByteBuffer(capacity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code MemoryStack} backed by the specified memory buffer.
|
||||
*
|
||||
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
|
||||
*
|
||||
* @param buffer the backing memory buffer
|
||||
*/
|
||||
public static MemoryStack create(ByteBuffer buffer) {
|
||||
long address = MemoryUtil.getAddress(buffer);
|
||||
int size = buffer.remaining();
|
||||
return new MemoryStack(buffer, address, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code MemoryStack} backed by the specified memory region.
|
||||
*
|
||||
* <p>In the initial state, there is no active stack frame. The {@link #push} method must be used before any allocations.</p>
|
||||
*
|
||||
* @param address the backing memory address
|
||||
* @param size the backing memory size
|
||||
*/
|
||||
public static MemoryStack ncreate(long address, int size) {
|
||||
return new MemoryStack(null, address, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the current stack pointer and pushes a new frame to the stack.
|
||||
*
|
||||
* <p>This method should be called when entering a method, before doing any stack allocations. When exiting a method, call the {@link #pop} method to
|
||||
* restore the previous stack frame.</p>
|
||||
*
|
||||
* <p>Pairs of push/pop calls may be nested. Care must be taken to:</p>
|
||||
* <ul>
|
||||
* <li>match every push with a pop</li>
|
||||
* <li>not call pop before push has been called at least once</li>
|
||||
* <li>not nest push calls to more than the maximum supported depth</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return this stack
|
||||
*/
|
||||
public MemoryStack push() {
|
||||
if (frameIndex == frames.length) {
|
||||
frameOverflow();
|
||||
}
|
||||
|
||||
frames[frameIndex++] = pointer;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void frameOverflow() {
|
||||
if (/*DEBUG*/ false) {
|
||||
AngelicaTweaker.LOGGER.warn("[WARNING] Out of frame stack space (" + frames.length + ") in thread: " + Thread.currentThread());
|
||||
}
|
||||
frames = Arrays.copyOf(frames, frames.length * 3 / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the current stack frame and moves the stack pointer to the end of the previous stack frame.
|
||||
*
|
||||
* @return this stack
|
||||
*/
|
||||
public MemoryStack pop() {
|
||||
pointer = frames[--frameIndex];
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #pop} on this {@code MemoryStack}.
|
||||
*
|
||||
* <p>This method should not be used directly. It is called automatically when the {@code MemoryStack} is used as a resource in a try-with-resources
|
||||
* statement.</p>
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
//noinspection resource
|
||||
pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the backing off-heap memory.
|
||||
*
|
||||
* <p>The stack grows "downwards", so the bottom of the stack is at {@code address + size}, while the top is at {@code address}.</p>
|
||||
*/
|
||||
public long getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the backing off-heap memory.
|
||||
*
|
||||
* <p>This is the maximum number of bytes that may be allocated on the stack.</p>
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current frame index.
|
||||
*
|
||||
* <p>This is the current number of nested {@link #push} calls.</p>
|
||||
*/
|
||||
public int getFrameIndex() {
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
/** Returns the memory address at the current stack pointer. */
|
||||
public long getPointerAddress() {
|
||||
return address + (pointer & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current stack pointer.
|
||||
*
|
||||
* <p>The stack grows "downwards", so when the stack is empty {@code pointer} is equal to {@code size}. On every allocation {@code pointer} is reduced by
|
||||
* the allocated size (after alignment) and {@code address + pointer} points to the first byte of the last allocation.</p>
|
||||
*
|
||||
* <p>Effectively, this methods returns how many more bytes may be allocated on the stack.</p>
|
||||
*/
|
||||
public int getPointer() {
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current stack pointer.
|
||||
*
|
||||
* <p>This method directly manipulates the stack pointer. Using it irresponsibly may break the internal state of the stack. It should only be used in rare
|
||||
* cases or in auto-generated code.</p>
|
||||
*/
|
||||
public void setPointer(int pointer) {
|
||||
if (/*CHECKS*/ false) {
|
||||
checkPointer(pointer);
|
||||
}
|
||||
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
||||
private void checkPointer(int pointer) {
|
||||
if (pointer < 0 || size < pointer) {
|
||||
throw new IndexOutOfBoundsException("Invalid stack pointer");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAlignment(int alignment) {
|
||||
if (Integer.bitCount(alignment) != 1) {
|
||||
throw new IllegalArgumentException("Alignment must be a power-of-two value.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #nmalloc(int, int)} with {@code alignment} equal to {@link Pointer#POINTER_SIZE POINTER_SIZE}.
|
||||
*
|
||||
* @param size the allocation size
|
||||
*
|
||||
* @return the memory address on the stack for the requested allocation
|
||||
*/
|
||||
public long nmalloc(int size) {
|
||||
return nmalloc(POINTER_SIZE, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a block of {@code size} bytes of memory on the stack. The content of the newly allocated block of memory is not initialized, remaining with
|
||||
* indeterminate values.
|
||||
*
|
||||
* @param alignment the required alignment
|
||||
* @param size the allocation size
|
||||
*
|
||||
* @return the memory address on the stack for the requested allocation
|
||||
*/
|
||||
public long nmalloc(int alignment, int size) {
|
||||
// Align address to the specified alignment
|
||||
long address = (this.address + pointer - size) & ~Integer.toUnsignedLong(alignment - 1);
|
||||
|
||||
pointer = (int)(address - this.address);
|
||||
if (/*CHECKS*/ false && pointer < 0) {
|
||||
throw new OutOfMemoryError("Out of stack space.");
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a block of memory on the stack for an array of {@code num} elements, each of them {@code size} bytes long, and initializes all its bits to
|
||||
* zero.
|
||||
*
|
||||
* @param alignment the required element alignment
|
||||
* @param num num the number of elements to allocate
|
||||
* @param size the size of each element
|
||||
*
|
||||
* @return the memory address on the stack for the requested allocation
|
||||
*/
|
||||
public long ncalloc(int alignment, int num, int size) {
|
||||
int bytes = num * size;
|
||||
long address = nmalloc(alignment, bytes);
|
||||
memSet(address, 0, bytes);
|
||||
return address;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/** Unsafe version of {@link #shorts(short)}. */
|
||||
public long nshort(short value) {
|
||||
long a = nmalloc(2, 2);
|
||||
memPutShort(a, value);
|
||||
return a;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/** Int version of {@link #malloc(int)}. */
|
||||
public IntBuffer mallocInt(int size) { return wrapBufferInt(nmalloc(4, size << 2), size); }
|
||||
|
||||
/** Unsafe version of {@link #ints(int)}. */
|
||||
public long nint(int value) {
|
||||
long a = nmalloc(4, 4);
|
||||
memPutInt(a, value);
|
||||
return a;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/** Unsafe version of {@link #longs(long)}. */
|
||||
public long nlong(long value) {
|
||||
long a = nmalloc(8, 8);
|
||||
memPutLong(a, value);
|
||||
return a;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/** Float version of {@link #malloc(int)}. */
|
||||
public FloatBuffer mallocFloat(int size) { return wrapBufferFloat(nmalloc(4, size << 2), size); }
|
||||
|
||||
/** Unsafe version of {@link #floats(float)}. */
|
||||
public long nfloat(float value) {
|
||||
long a = nmalloc(4, 4);
|
||||
memPutFloat(a, value);
|
||||
return a;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/** Unsafe version of {@link #doubles(double)}. */
|
||||
public long ndouble(double value) {
|
||||
long a = nmalloc(8, 8);
|
||||
memPutDouble(a, value);
|
||||
return a;
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// -------------------------------------------------
|
||||
// -------------------------------------------------
|
||||
|
||||
|
||||
/** Returns the stack of the current thread. */
|
||||
public static MemoryStack stackGet() {
|
||||
return TLS.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #push} on the stack of the current thread.
|
||||
*
|
||||
* @return the stack of the current thread.
|
||||
*/
|
||||
public static MemoryStack stackPush() {
|
||||
return stackGet().push();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link #pop} on the stack of the current thread.
|
||||
*
|
||||
* @return the stack of the current thread.
|
||||
*/
|
||||
public static MemoryStack stackPop() {
|
||||
return stackGet().pop();
|
||||
}
|
||||
|
||||
/** Thread-local version of {@link #nmalloc(int)}. */
|
||||
public static long nstackMalloc(int size) { return stackGet().nmalloc(size); }
|
||||
/** Thread-local version of {@link #nmalloc(int, int)}. */
|
||||
public static long nstackMalloc(int alignment, int size) { return stackGet().nmalloc(alignment, size); }
|
||||
/** Thread-local version of {@link #ncalloc}. */
|
||||
public static long nstackCalloc(int alignment, int num, int size) { return stackGet().ncalloc(alignment, num, size); }
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This class is backported from LWJGL3 under the BSD 3-clause "New" or "Revised" License
|
||||
*/
|
||||
package com.gtnewhorizons.angelica.compat.lwjgl;
|
||||
|
||||
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.NULL;
|
||||
import static com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil.UNSAFE;
|
||||
import static org.lwjgl.LWJGLUtil.CHECKS;
|
||||
|
||||
import net.minecraft.util.Util;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Pointer interface.
|
||||
*
|
||||
* <p>LWJGL can run on both 32bit and 64bit architectures. Since LWJGL applications deal with native memory directly, this interface provides necessary
|
||||
* information about the underlying architecture of the running JVM process.</p>
|
||||
*
|
||||
* <p>When interacting with native functions, pointer values are mapped to Java {@code long}. LWJGL automatically converts long values to the correct pointer
|
||||
* addresses when used in native code. Native functions sometimes require arrays of pointer values; the {@link PointerBuffer} class may be used for that
|
||||
* purpose. It has an API similar to a {@link java.nio.LongBuffer} but handles pointer casts automatically.</p>
|
||||
*/
|
||||
public interface Pointer {
|
||||
|
||||
/** The pointer size in bytes. Will be 4 on a 32bit JVM and 8 on a 64bit one. */
|
||||
int POINTER_SIZE = UNSAFE.addressSize();
|
||||
|
||||
/** The pointer size power-of-two. Will be 2 on a 32bit JVM and 3 on a 64bit one. */
|
||||
int POINTER_SHIFT = POINTER_SIZE == 8 ? 3 : 2;
|
||||
|
||||
/** The value of {@code sizeof(long)} for the current platform. */
|
||||
int CLONG_SIZE = POINTER_SIZE == 8 && Util.getOSType() == Util.EnumOS.WINDOWS ? 4 : POINTER_SIZE;
|
||||
|
||||
/** The value of {@code sizeof(long)} as a power-of-two. */
|
||||
int CLONG_SHIFT = CLONG_SIZE == 8 ? 3 : 2;
|
||||
|
||||
/** Will be true on a 32bit JVM. */
|
||||
boolean BITS32 = POINTER_SIZE * 8 == 32;
|
||||
|
||||
/** Will be true on a 64bit JVM. */
|
||||
boolean BITS64 = POINTER_SIZE * 8 == 64;
|
||||
|
||||
/**
|
||||
* Returns the raw pointer address as a {@code long} value.
|
||||
*
|
||||
* @return the pointer address
|
||||
*/
|
||||
long address();
|
||||
|
||||
/** Default {@link Pointer} implementation. */
|
||||
abstract class Default implements Pointer {
|
||||
|
||||
// Removed final due to JDK-8139758. TODO: Restore if the fix is backported to JDK 8.
|
||||
protected long address;
|
||||
|
||||
protected Default(long address) {
|
||||
if (CHECKS && address == NULL) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long address() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Pointer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Pointer that = (Pointer)o;
|
||||
|
||||
return address == that.address();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (int)(address ^ (address >>> 32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s pointer [0x%X]", getClass().getSimpleName(), address);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public enum Axis {
|
||||
X,
|
||||
Y,
|
||||
Z;
|
||||
|
||||
public static Axis fromDirection(ModelQuadFacing dir) {
|
||||
return switch (dir) {
|
||||
case DOWN, UP -> Y;
|
||||
case NORTH, SOUTH -> Z;
|
||||
case WEST, EAST -> X;
|
||||
case UNASSIGNED -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static Axis fromDirection(ForgeDirection dir) {
|
||||
return switch (dir) {
|
||||
case DOWN, UP -> Y;
|
||||
case NORTH, SOUTH -> Z;
|
||||
case WEST, EAST -> X;
|
||||
case UNKNOWN -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static Axis fromName(String dir) {
|
||||
return switch (dir) {
|
||||
case "y" -> Y;
|
||||
case "z" -> Z;
|
||||
case "x" -> X;
|
||||
default -> null;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public enum Direction {
|
||||
POSITIVE,
|
||||
NEGATIVE;
|
||||
|
||||
public static Direction fromDirection(ForgeDirection dir) {
|
||||
return switch (dir) {
|
||||
case DOWN, NORTH, WEST -> NEGATIVE;
|
||||
case UP, SOUTH, EAST -> POSITIVE;
|
||||
case UNKNOWN -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.util.CoordinatePacker;
|
||||
import com.gtnewhorizons.angelica.api.MutableBlockPos;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
|
||||
// Should we keep this?
|
||||
public class BlockPosImpl extends Vector3i implements MutableBlockPos {
|
||||
|
||||
public BlockPosImpl() {
|
||||
super();
|
||||
}
|
||||
public BlockPosImpl(int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
public BlockPosImpl(ChunkPosition chunkPosition) {
|
||||
super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
@Override
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
@Override
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl offset(ForgeDirection d) {
|
||||
return new BlockPosImpl(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl down() {
|
||||
return offset(ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl up() {
|
||||
return offset(ForgeDirection.UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long asLong() {
|
||||
return CoordinatePacker.pack(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl set(int x, int y, int z) {
|
||||
super.set(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl set(long packedPos) {
|
||||
CoordinatePacker.unpack(packedPos, this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
import com.gtnewhorizons.angelica.rendering.RenderingState;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -13,7 +14,7 @@ import org.joml.Vector4f;
|
||||
@Getter
|
||||
public class Camera {
|
||||
final Vector3d pos = new Vector3d();
|
||||
final BlockPosImpl blockPos = new BlockPosImpl();
|
||||
final BlockPos blockPos = new BlockPos();
|
||||
float pitch;
|
||||
float yaw;
|
||||
EntityLivingBase entity;
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue;
|
||||
import it.unimi.dsi.fastutil.ints.IntPriorityQueue;
|
||||
import me.jellysquid.mods.sodium.common.util.DirectionUtil;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.BitSet;
|
||||
@@ -17,7 +17,7 @@ public class ChunkOcclusionDataBuilder {
|
||||
private static final int STEP_X = (int)Math.pow(16.0, 0.0);
|
||||
private static final int STEP_Z = (int)Math.pow(16.0, 1.0);
|
||||
private static final int STEP_Y = (int)Math.pow(16.0, 2.0);
|
||||
private static final ForgeDirection[] DIRECTIONS = DirectionUtil.ALL_DIRECTIONS;
|
||||
private static final ForgeDirection[] DIRECTIONS = ForgeDirection.VALID_DIRECTIONS;
|
||||
private final BitSet closed = new BitSet(4096);
|
||||
private static final int[] EDGE_POINTS = new int[1352];
|
||||
|
||||
@@ -36,12 +36,12 @@ public class ChunkOcclusionDataBuilder {
|
||||
}
|
||||
private int openCount = 4096;
|
||||
|
||||
public void markClosed(BlockPosImpl pos) {
|
||||
public void markClosed(BlockPos pos) {
|
||||
this.closed.set(pack(pos), true);
|
||||
--this.openCount;
|
||||
}
|
||||
|
||||
private static int pack(BlockPosImpl pos) {
|
||||
private static int pack(BlockPos pos) {
|
||||
return pack(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
|
||||
// See if we can merge/mixin/extend ChunkCoordIntPair?
|
||||
public class ChunkPos {
|
||||
public static long INT_MASK = (1L << Integer.SIZE) - 1;
|
||||
@@ -12,7 +14,7 @@ public class ChunkPos {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public ChunkPos(BlockPosImpl pos) {
|
||||
public ChunkPos(BlockPos pos) {
|
||||
this.x = pos.getX() >> 4;
|
||||
this.z = pos.getZ() >> 4;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
// See if we can merge/mixin/extend ChunkPosition maybe?
|
||||
@@ -19,7 +20,7 @@ public class ChunkSectionPos extends Vector3i {
|
||||
return new ChunkSectionPos(x, y, z);
|
||||
}
|
||||
|
||||
public static ChunkSectionPos from(BlockPosImpl pos) {
|
||||
public static ChunkSectionPos from(BlockPos pos) {
|
||||
return new ChunkSectionPos(getSectionCoord(pos.getX()), getSectionCoord(pos.getY()), getSectionCoord(pos.getZ()));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Type;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Usage;
|
||||
import com.gtnewhorizons.angelica.compat.nd.writers.ItemVBOQuadWriter;
|
||||
import com.gtnewhorizons.angelica.compat.nd.writers.PositionColorTextureQuadWriter;
|
||||
import com.gtnewhorizons.angelica.compat.nd.writers.PositionQuadWriter;
|
||||
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureColorQuadWriter;
|
||||
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureQuadWriter;
|
||||
|
||||
public class DefaultVertexFormat {
|
||||
|
||||
public static final VertexFormatElement POSITION_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.POSITION, 3);
|
||||
public static final VertexFormatElement COLOR_ELEMENT = new VertexFormatElement(0, Type.UBYTE, Usage.COLOR, 4);
|
||||
public static final VertexFormatElement TEXTURE_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.UV, 2);
|
||||
public static final VertexFormatElement LIGHT_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
|
||||
// TODO: The overlay element index is wrong, need to find a 1.7.10 equivalent
|
||||
public static final VertexFormatElement OVERLAY_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
|
||||
public static final VertexFormatElement NORMAL_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.NORMAL, 3);
|
||||
public static final VertexFormatElement PADDING_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.PADDING, 1);
|
||||
public static final VertexFormat POSITION_TEXTURE_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build(), new ItemVBOQuadWriter());
|
||||
public static final VertexFormat POSITION_COLOR_TEXTURE_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(OVERLAY_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_TEXTURE_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
|
||||
public static final VertexFormat POSITION = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).build(), new PositionQuadWriter());
|
||||
public static final VertexFormat POSITION_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionTextureQuadWriter());
|
||||
public static final VertexFormat POSITION_COLOR_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionColorTextureQuadWriter());
|
||||
public static final VertexFormat POSITION_TEXTURE_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).build(), new PositionTextureColorQuadWriter());
|
||||
public static final VertexFormat POSITION_COLOR_TEX_LIGHTMAP = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_TEXTURE_LIGHT_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(COLOR_ELEMENT).build());
|
||||
public static final VertexFormat POSITION_TEXTURE_COLOR_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.Iris;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import javax.imageio.ImageIO;
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.Iris;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
// TBD
|
||||
public class NativeImage extends BufferedImage {
|
||||
@@ -59,12 +58,14 @@ public class NativeImage extends BufferedImage {
|
||||
|
||||
// final int width = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_WIDTH);
|
||||
// final int height = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_HEIGHT);
|
||||
IntBuffer buffer = BufferUtils.createIntBuffer(size);
|
||||
int[] data = new int[size];
|
||||
try (final MemoryStack stack = MemoryStack.stackPush()) {
|
||||
final IntBuffer buffer = stack.mallocInt(size);
|
||||
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, format.glFormat, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
|
||||
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, format.glFormat, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
buffer.get(data);
|
||||
setRGB(0, 0, width, height, data, 0, width);
|
||||
int[] data = new int[size];
|
||||
buffer.get(data);
|
||||
setRGB(0, 0, width, height, data, 0, width);
|
||||
}
|
||||
}
|
||||
public void writeToFile(File file) throws IOException{
|
||||
try {
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
|
||||
public class VertexBuffer implements AutoCloseable {
|
||||
private int id;
|
||||
private int vertexCount;
|
||||
private VertexFormat format;
|
||||
private int drawMode;
|
||||
|
||||
public VertexBuffer() {
|
||||
this.id = GL15.glGenBuffers();
|
||||
}
|
||||
|
||||
public VertexBuffer(VertexFormat format, int drawMode) {
|
||||
this();
|
||||
this.format = format;
|
||||
this.drawMode = drawMode;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.id);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
public void upload(ByteBuffer buffer, int vertexCount) {
|
||||
if (this.id == -1) return;
|
||||
this.vertexCount = vertexCount;
|
||||
this.bind();
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
|
||||
this.unbind();
|
||||
}
|
||||
|
||||
public VertexBuffer upload(ByteBuffer buffer) {
|
||||
if(format == null) throw new IllegalStateException("No format specified for VBO upload");
|
||||
upload(buffer, buffer.remaining() / format.getVertexSize());
|
||||
return this;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (this.id >= 0) {
|
||||
GL15.glDeleteBuffers(this.id);
|
||||
this.id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(FloatBuffer floatBuffer) {
|
||||
GL11.glPushMatrix();
|
||||
GL11.glLoadIdentity();
|
||||
GL11.glMultMatrix(floatBuffer);
|
||||
draw();
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
GL11.glDrawArrays(drawMode, 0, this.vertexCount);
|
||||
}
|
||||
|
||||
public void setupState() {
|
||||
if(format == null) throw new IllegalStateException("No format specified for VBO setup");
|
||||
bind();
|
||||
format.setupBufferState(0L);
|
||||
}
|
||||
|
||||
public void cleanupState() {
|
||||
format.clearBufferState();
|
||||
unbind();
|
||||
}
|
||||
public void render() {
|
||||
setupState();
|
||||
draw();
|
||||
cleanupState();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
|
||||
import net.coderbot.iris.vertices.ImmediateState;
|
||||
import net.coderbot.iris.vertices.IrisVertexFormats;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
public class VertexFormat {
|
||||
@Getter
|
||||
protected final ImmutableList<VertexFormatElement> elements;
|
||||
protected final IntList offsets = new IntArrayList();
|
||||
@Getter
|
||||
protected final int vertexSize;
|
||||
|
||||
protected IWriteQuads quadWriter;
|
||||
|
||||
public VertexFormat(ImmutableList<VertexFormatElement> elements) {
|
||||
this(elements, null);
|
||||
}
|
||||
|
||||
public VertexFormat(ImmutableList<VertexFormatElement> elements, IWriteQuads quadWriter) {
|
||||
this.elements = elements;
|
||||
int i = 0;
|
||||
for (VertexFormatElement element : elements) {
|
||||
offsets.add(i);
|
||||
i += element.getByteSize();
|
||||
}
|
||||
vertexSize = i;
|
||||
this.quadWriter = quadWriter;
|
||||
}
|
||||
|
||||
public void setupBufferState(long l) {
|
||||
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
|
||||
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
|
||||
IrisVertexFormats.TERRAIN.setupBufferState(l);
|
||||
return;
|
||||
} else if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
|
||||
IrisVertexFormats.ENTITY.setupBufferState(l);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final int i = this.getVertexSize();
|
||||
final List<VertexFormatElement> list = this.getElements();
|
||||
final int listSize = list.size();
|
||||
|
||||
for(int j = 0; j < listSize; ++j) {
|
||||
list.get(j).setupBufferState(l + this.offsets.getInt(j), i);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearBufferState() {
|
||||
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
|
||||
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
|
||||
IrisVertexFormats.TERRAIN.clearBufferState();
|
||||
return;
|
||||
} else if ( this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
|
||||
IrisVertexFormats.ENTITY.clearBufferState();
|
||||
return;
|
||||
}
|
||||
}
|
||||
final List<VertexFormatElement> list = this.getElements();
|
||||
final int listSize = list.size();
|
||||
|
||||
for(int i = 0 ; i < listSize; ++i) {
|
||||
list.get(i).clearBufferState();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canWriteQuads() {
|
||||
return quadWriter != null;
|
||||
}
|
||||
|
||||
public void writeQuad(QuadView quad, ByteBuffer byteBuffer) {
|
||||
if(quadWriter == null) {
|
||||
throw new IllegalStateException("No quad writer set");
|
||||
}
|
||||
quadWriter.writeQuad(quad, byteBuffer);
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
|
||||
@Getter
|
||||
public class VertexFormatElement {
|
||||
protected final Type type;
|
||||
protected final Usage usage;
|
||||
protected final int index;
|
||||
protected final int count;
|
||||
protected final int byteSize;
|
||||
|
||||
public VertexFormatElement(int index, Type type, Usage usage, int count) {
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.usage = usage;
|
||||
this.count = count;
|
||||
this.byteSize = type.getSize() * count;
|
||||
}
|
||||
|
||||
public void setupBufferState(long offset, int stride) {
|
||||
this.usage.setupBufferState(this.count, this.type.getGlType(), stride, offset, this.index);
|
||||
}
|
||||
|
||||
public void clearBufferState() {
|
||||
this.usage.clearBufferState(this.index);
|
||||
}
|
||||
|
||||
public enum Usage {
|
||||
POSITION("Position", (size, type, stride, pointer, index) -> {
|
||||
GL11.glVertexPointer(size, type, stride, pointer);
|
||||
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
|
||||
}, index -> GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY)),
|
||||
NORMAL("Normal", (size, type, stride, pointer, index) -> {
|
||||
GL11.glNormalPointer(type, stride, pointer);
|
||||
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
|
||||
}, index -> GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY)),
|
||||
COLOR("Vertex Color", (size, type, stride, pointer, index) -> {
|
||||
GL11.glColorPointer(size, type, stride, pointer);
|
||||
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
|
||||
}, index -> GL11.glDisableClientState(GL11.GL_COLOR_ARRAY)),
|
||||
UV("UV", (size, type, stride, pointer, index) -> {
|
||||
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + index);
|
||||
GL11.glTexCoordPointer(size, type, stride, pointer);
|
||||
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
|
||||
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
|
||||
}, index -> {
|
||||
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + index);
|
||||
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
|
||||
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
|
||||
}),
|
||||
PADDING("Padding", (size, type, stride, pointer, index) -> {}, index-> {}),
|
||||
GENERIC("Generic", (size, type, stride, pointer, index) -> {
|
||||
GL20.glEnableVertexAttribArray(index);
|
||||
GL20.glVertexAttribPointer(index, size, type, false, stride, pointer);
|
||||
}, GL20::glDisableVertexAttribArray);
|
||||
|
||||
@Getter private final String name;
|
||||
private final SetupState setupState;
|
||||
private final IntConsumer clearState;
|
||||
|
||||
Usage(String name, SetupState setupState, IntConsumer clearState) {
|
||||
this.name = name;
|
||||
this.setupState = setupState;
|
||||
this.clearState = clearState;
|
||||
}
|
||||
|
||||
private void setupBufferState(int size, int type, int stride, long pointer, int index) {
|
||||
this.setupState.setupBufferState(size, type, stride, pointer, index);
|
||||
}
|
||||
|
||||
public void clearBufferState(int index) {
|
||||
this.clearState.accept(index);
|
||||
}
|
||||
|
||||
interface SetupState {
|
||||
void setupBufferState(int size, int type, int stride, long pointer, int index);
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public enum Type {
|
||||
FLOAT(4, "Float", GL11.GL_FLOAT),
|
||||
UBYTE(1, "Unsigned Byte", GL11.GL_UNSIGNED_BYTE),
|
||||
BYTE(1, "Byte", GL11.GL_BYTE),
|
||||
USHORT(2, "Unsigned Short", GL11.GL_UNSIGNED_SHORT),
|
||||
SHORT(2, "Short", GL11.GL_SHORT),
|
||||
UINT(4, "Unsigned Int", GL11.GL_UNSIGNED_INT),
|
||||
INT(4, "Int", GL11.GL_INT);
|
||||
|
||||
private final int size;
|
||||
private final String name;
|
||||
private final int glType;
|
||||
|
||||
Type(int size, String name, int glType) {
|
||||
this.size = size;
|
||||
this.name = name;
|
||||
this.glType = glType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface IWriteQuads {
|
||||
void writeQuad(QuadView quad, ByteBuffer buf);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.QuadView;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.quad.writers.IWriteQuads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.gtnewhorizons.angelica.compat.toremove;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.DefaultVertexFormat;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat;
|
||||
import it.unimi.dsi.fastutil.Hash;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
|
||||
import lombok.Getter;
|
||||
@@ -58,7 +60,7 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
}
|
||||
|
||||
public static RenderLayer getOutline(ResourceLocation texture, RenderPhase.Cull cull) {
|
||||
return of("outline", DefaultVertexFormat.POSITION_COLOR_TEXTURE, 7, 256, RenderLayer.MultiPhaseParameters.builder().texture(new RenderPhase.Texture(texture, false, false)).cull(cull).depthTest(ALWAYS_DEPTH_TEST).alpha(ONE_TENTH_ALPHA).texturing(OUTLINE_TEXTURING).fog(NO_FOG).target(OUTLINE_TARGET).build(RenderLayer.OutlineMode.IS_OUTLINE));
|
||||
return of("outline", DefaultVertexFormat.POSITION_COLOR_TEXTURE, 7, 256, RenderLayer.MultiPhaseParameters.builder().texture(new RenderPhase.Texture(texture, false, false)).cull(cull).depthTest(ALWAYS_DEPTH_TEST).alpha(ONE_TENTH_ALPHA).fog(NO_FOG).target(OUTLINE_TARGET).build(RenderLayer.OutlineMode.IS_OUTLINE));
|
||||
}
|
||||
|
||||
public int mode() {
|
||||
@@ -145,11 +147,10 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
private final RenderPhase.Target target;
|
||||
private final RenderPhase.Texturing texturing;
|
||||
private final RenderPhase.WriteMaskState writeMaskState;
|
||||
private final RenderPhase.LineWidth lineWidth;
|
||||
private final OutlineMode outlineMode;
|
||||
private final ImmutableList<RenderPhase> phases;
|
||||
|
||||
private MultiPhaseParameters(RenderPhase.Texture texture, RenderPhase.Transparency transparency, RenderPhase.DiffuseLighting diffuseLighting, RenderPhase.ShadeModel shadeModel, RenderPhase.Alpha alpha, RenderPhase.DepthTest depthTest, RenderPhase.Cull cull, RenderPhase.Lightmap lightmap, RenderPhase.Fog fog, RenderPhase.Layering layering, RenderPhase.Target target, RenderPhase.Texturing texturing, RenderPhase.WriteMaskState writeMaskState, RenderPhase.LineWidth lineWidth, OutlineMode outlineMode) {
|
||||
private MultiPhaseParameters(RenderPhase.Texture texture, RenderPhase.Transparency transparency, RenderPhase.DiffuseLighting diffuseLighting, RenderPhase.ShadeModel shadeModel, RenderPhase.Alpha alpha, RenderPhase.DepthTest depthTest, RenderPhase.Cull cull, RenderPhase.Lightmap lightmap, RenderPhase.Fog fog, RenderPhase.Layering layering, RenderPhase.Target target, RenderPhase.Texturing texturing, RenderPhase.WriteMaskState writeMaskState, OutlineMode outlineMode) {
|
||||
this.texture = texture;
|
||||
this.transparency = transparency;
|
||||
this.diffuseLighting = diffuseLighting;
|
||||
@@ -163,9 +164,8 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
this.target = target;
|
||||
this.texturing = texturing;
|
||||
this.writeMaskState = writeMaskState;
|
||||
this.lineWidth = lineWidth;
|
||||
this.outlineMode = outlineMode;
|
||||
this.phases = ImmutableList.of(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState, this.lineWidth);
|
||||
this.phases = ImmutableList.of(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState);
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@@ -205,7 +205,6 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
private RenderPhase.Target target;
|
||||
private RenderPhase.Texturing texturing;
|
||||
private RenderPhase.WriteMaskState writeMaskState;
|
||||
private RenderPhase.LineWidth lineWidth;
|
||||
|
||||
private Builder() {
|
||||
this.texture = RenderPhase.NO_TEXTURE ;
|
||||
@@ -221,7 +220,6 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
this.target = RenderPhase.MAIN_TARGET;
|
||||
this.texturing = RenderPhase.DEFAULT_TEXTURING;
|
||||
this.writeMaskState = RenderPhase.ALL_MASK;
|
||||
this.lineWidth = RenderPhase.FULL_LINE_WIDTH;
|
||||
}
|
||||
|
||||
public Builder texture(RenderPhase.Texture texture) {
|
||||
@@ -279,7 +277,7 @@ public abstract class RenderLayer extends RenderPhase { // Aka: RenderType (Iris
|
||||
}
|
||||
|
||||
public MultiPhaseParameters build(OutlineMode outlineMode) {
|
||||
return new MultiPhaseParameters(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState, this.lineWidth, outlineMode);
|
||||
return new MultiPhaseParameters(this.texture, this.transparency, this.diffuseLighting, this.shadeModel, this.alpha, this.depthTest, this.cull, this.lightmap, this.fog, this.layering, this.target, this.texturing, this.writeMaskState, outlineMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,9 +64,6 @@ public abstract class RenderPhase {
|
||||
protected static final Texture BLOCK_ATLAS_TEXTURE;
|
||||
protected static final Texture NO_TEXTURE;
|
||||
protected static final Texturing DEFAULT_TEXTURING;
|
||||
protected static final Texturing OUTLINE_TEXTURING;
|
||||
protected static final Texturing GLINT_TEXTURING;
|
||||
protected static final Texturing ENTITY_GLINT_TEXTURING;
|
||||
protected static final Lightmap ENABLE_LIGHTMAP;
|
||||
protected static final Lightmap DISABLE_LIGHTMAP;
|
||||
protected static final DiffuseLighting ENABLE_DIFFUSE_LIGHTING;
|
||||
@@ -80,19 +77,12 @@ public abstract class RenderPhase {
|
||||
protected static final WriteMaskState COLOR_MASK;
|
||||
protected static final WriteMaskState DEPTH_MASK;
|
||||
protected static final Layering NO_LAYERING;
|
||||
protected static final Layering POLYGON_OFFSET_LAYERING;
|
||||
protected static final Layering VIEW_OFFSET_Z_LAYERING;
|
||||
protected static final Fog NO_FOG;
|
||||
protected static final Fog FOG;
|
||||
protected static final Fog BLACK_FOG;
|
||||
protected static final Target MAIN_TARGET;
|
||||
protected static final Target OUTLINE_TARGET;
|
||||
protected static final Target TRANSLUCENT_TARGET;
|
||||
protected static final Target PARTICLES_TARGET;
|
||||
protected static final Target WEATHER_TARGET;
|
||||
protected static final Target CLOUDS_TARGET;
|
||||
protected static final Target ITEM_TARGET;
|
||||
protected static final LineWidth FULL_LINE_WIDTH;
|
||||
|
||||
public RenderPhase(String name, Runnable beginAction, Runnable endAction) {
|
||||
this.name = name;
|
||||
@@ -127,20 +117,6 @@ public abstract class RenderPhase {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
private static void setupGlintTexturing(float scale) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.pushMatrix();
|
||||
// RenderSystem.loadIdentity();
|
||||
// long l = Util.getMeasuringTimeMs() * 8L;
|
||||
// float g = (float)(l % 110000L) / 110000.0F;
|
||||
// float h = (float)(l % 30000L) / 30000.0F;
|
||||
// RenderSystem.translatef(-g, h, 0.0F);
|
||||
// RenderSystem.rotatef(10.0F, 0.0F, 0.0F, 1.0F);
|
||||
// RenderSystem.scalef(scale, scale, scale);
|
||||
// RenderSystem.matrixMode(5888);
|
||||
}
|
||||
|
||||
private static ResourceLocation ATLAS = TextureMap.locationBlocksTexture;
|
||||
static {
|
||||
// TODO: Sodium - SpriteAtlasTexture
|
||||
@@ -149,29 +125,6 @@ public abstract class RenderPhase {
|
||||
NO_TEXTURE = new Texture();
|
||||
DEFAULT_TEXTURING = new Texturing("default_texturing", () -> {
|
||||
}, () -> {
|
||||
});
|
||||
OUTLINE_TEXTURING = new Texturing("outline_texturing", () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.setupOutline();
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.teardownOutline();
|
||||
});
|
||||
GLINT_TEXTURING = new Texturing("glint_texturing", () -> {
|
||||
setupGlintTexturing(8.0F);
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.popMatrix();
|
||||
// RenderSystem.matrixMode(5888);
|
||||
});
|
||||
ENTITY_GLINT_TEXTURING = new Texturing("entity_glint_texturing", () -> {
|
||||
setupGlintTexturing(0.16F);
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.popMatrix();
|
||||
// RenderSystem.matrixMode(5888);
|
||||
});
|
||||
ENABLE_LIGHTMAP = new Lightmap(true);
|
||||
DISABLE_LIGHTMAP = new Lightmap(false);
|
||||
@@ -185,26 +138,7 @@ public abstract class RenderPhase {
|
||||
ALL_MASK = new WriteMaskState(true, true);
|
||||
COLOR_MASK = new WriteMaskState(true, false);
|
||||
DEPTH_MASK = new WriteMaskState(false, true);
|
||||
NO_LAYERING = new Layering("no_layering", () -> {
|
||||
}, () -> {
|
||||
});
|
||||
POLYGON_OFFSET_LAYERING = new Layering("polygon_offset_layering", () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.polygonOffset(-1.0F, -10.0F);
|
||||
// RenderSystem.enablePolygonOffset();
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.polygonOffset(0.0F, 0.0F);
|
||||
// RenderSystem.disablePolygonOffset();
|
||||
});
|
||||
VIEW_OFFSET_Z_LAYERING = new Layering("view_offset_z_layering", () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.pushMatrix();
|
||||
// RenderSystem.scalef(0.99975586F, 0.99975586F, 0.99975586F);
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem::popMatrix();
|
||||
});
|
||||
NO_LAYERING = new Layering("no_layering", () -> {}, () -> {});
|
||||
NO_FOG = new Fog("no_fog", () -> {
|
||||
}, () -> {
|
||||
});
|
||||
@@ -246,103 +180,6 @@ public abstract class RenderPhase {
|
||||
}
|
||||
|
||||
});
|
||||
PARTICLES_TARGET = new Target("particles_target", () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// MinecraftClient.getInstance().worldRenderer.getParticlesFramebuffer().beginWrite(false);
|
||||
}
|
||||
|
||||
}, () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
|
||||
}
|
||||
|
||||
});
|
||||
WEATHER_TARGET = new Target("weather_target", () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// MinecraftClient.getInstance().worldRenderer.getWeatherFramebuffer().beginWrite(false);
|
||||
}
|
||||
|
||||
}, () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
|
||||
}
|
||||
|
||||
});
|
||||
CLOUDS_TARGET = new Target("clouds_target", () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// MinecraftClient.getInstance().worldRenderer.getCloudsFramebuffer().beginWrite(false);
|
||||
}
|
||||
|
||||
}, () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
|
||||
}
|
||||
|
||||
});
|
||||
ITEM_TARGET = new Target("item_entity_target", () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// MinecraftClient.getInstance().worldRenderer.getEntityFramebuffer().beginWrite(false);
|
||||
}
|
||||
|
||||
}, () -> {
|
||||
if (Minecraft.isFancyGraphicsEnabled()) {
|
||||
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
|
||||
}
|
||||
|
||||
});
|
||||
FULL_LINE_WIDTH = new LineWidth(OptionalDouble.of(1.0));
|
||||
}
|
||||
|
||||
|
||||
public static class LineWidth extends RenderPhase {
|
||||
private final OptionalDouble width;
|
||||
|
||||
public LineWidth(OptionalDouble optionalDouble) {
|
||||
super("line_width", () -> {
|
||||
if (!Objects.equals(optionalDouble, OptionalDouble.of(1.0))) {
|
||||
if (optionalDouble.isPresent()) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.lineWidth((float)optionalDouble.getAsDouble());
|
||||
} else {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.lineWidth(Math.max(2.5F, (float)MinecraftClient.getInstance().getWindow().getFramebufferWidth() / 1920.0F * 2.5F));
|
||||
}
|
||||
}
|
||||
|
||||
}, () -> {
|
||||
if (!Objects.equals(optionalDouble, OptionalDouble.of(1.0))) {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.lineWidth(1.0F);
|
||||
}
|
||||
|
||||
});
|
||||
this.width = optionalDouble;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object != null && this.getClass() == object.getClass()) {
|
||||
return !super.equals(object) ? false : Objects.equals(this.width, ((LineWidth)object).width);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), this.width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name + '[' + (this.width.isPresent() ? this.width.getAsDouble() : "window_scale") + ']';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -557,93 +394,6 @@ public abstract class RenderPhase {
|
||||
}
|
||||
|
||||
|
||||
public static final class PortalTexturing extends Texturing {
|
||||
private final int layer;
|
||||
|
||||
public PortalTexturing(int layer) {
|
||||
super("portal_texturing", () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.pushMatrix();
|
||||
// RenderSystem.loadIdentity();
|
||||
// RenderSystem.translatef(0.5F, 0.5F, 0.0F);
|
||||
// RenderSystem.scalef(0.5F, 0.5F, 1.0F);
|
||||
// RenderSystem.translatef(17.0F / (float)layer, (2.0F + (float)layer / 1.5F) * ((float)(Util.getMeasuringTimeMs() % 800000L) / 800000.0F), 0.0F);
|
||||
// RenderSystem.rotatef(((float)(layer * layer) * 4321.0F + (float)layer * 9.0F) * 2.0F, 0.0F, 0.0F, 1.0F);
|
||||
// RenderSystem.scalef(4.5F - (float)layer / 4.0F, 4.5F - (float)layer / 4.0F, 1.0F);
|
||||
// RenderSystem.mulTextureByProjModelView();
|
||||
// RenderSystem.matrixMode(5888);
|
||||
// RenderSystem.setupEndPortalTexGen();
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.popMatrix();
|
||||
// RenderSystem.matrixMode(5888);
|
||||
// RenderSystem.clearTexGen();
|
||||
});
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object != null && this.getClass() == object.getClass()) {
|
||||
PortalTexturing lv = (PortalTexturing)object;
|
||||
return this.layer == lv.layer;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Integer.hashCode(this.layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final class OffsetTexturing extends Texturing {
|
||||
private final float x;
|
||||
private final float y;
|
||||
|
||||
public OffsetTexturing(float x, float y) {
|
||||
super("offset_texturing", () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.pushMatrix();
|
||||
// RenderSystem.loadIdentity();
|
||||
// RenderSystem.translatef(x, y, 0.0F);
|
||||
// RenderSystem.matrixMode(5888);
|
||||
}, () -> {
|
||||
throw new RuntimeException("Not Implemented Yet");
|
||||
// RenderSystem.matrixMode(5890);
|
||||
// RenderSystem.popMatrix();
|
||||
// RenderSystem.matrixMode(5888);
|
||||
});
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object != null && this.getClass() == object.getClass()) {
|
||||
OffsetTexturing lv = (OffsetTexturing)object;
|
||||
return Float.compare(lv.x, this.x) == 0 && Float.compare(lv.y, this.y) == 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.x, this.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Texturing extends RenderPhase {
|
||||
public Texturing(String string, Runnable runnable, Runnable runnable2) {
|
||||
super(string, runnable, runnable2);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class AngelicaConfig {
|
||||
public static boolean enableTestBlocks;
|
||||
|
||||
@Config.Comment("Enable Iris Shaders [Requires Sodium]")
|
||||
@Config.DefaultBoolean(false)
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean enableIris;
|
||||
|
||||
@@ -72,6 +72,10 @@ public class AngelicaConfig {
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean enableHudCaching;
|
||||
@Config.Comment("Inject a conditional early return into all RenderGameOverlayEvent receivers; Requires enableHudCaching")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean enableHudCachingEventTransformer;
|
||||
|
||||
@Config.Comment("The amount of frames to wait before updating the HUD elements. [Experimental]")
|
||||
@Config.DefaultInt(20)
|
||||
@@ -103,28 +107,45 @@ public class AngelicaConfig {
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean optimizeTextureLoading;
|
||||
|
||||
@Config.Comment("Fix thread-safety in lotrs rendering")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixLotrSodiumCompat;
|
||||
|
||||
@Config.Comment("Fix thread-safety in Extra Utilities rendering")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixExtraUtilsSodiumCompat;
|
||||
|
||||
@Config.Comment("Fix thread-safety issues in MineFactory Reloaded")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixMineFactoryReloadedSodiumCompat;
|
||||
|
||||
@Config.Comment("Fix RenderBlockFluid reading the block type from the world access multiple times")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixFluidRendererCheckingBlockAgain;
|
||||
|
||||
@Config.Comment("Dynamically modifies the render distance of dropped items entities to preserve performance."
|
||||
+ " It starts reducing the render distance when exceeding the threshold set below.")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean dynamicItemRenderDistance;
|
||||
|
||||
@Config.Comment("Max amount of dropped item rendered")
|
||||
@Config.DefaultInt(256)
|
||||
@Config.RangeInt(min = 32, max = 2048)
|
||||
public static int droppedItemLimit;
|
||||
|
||||
@Config.Comment("Use total world time instead of normal world time. Allows most shader animations to play when "
|
||||
+ "doDaylightCycle is off, but causes shader animations to desync from time of day.")
|
||||
@Config.DefaultBoolean(false)
|
||||
public static boolean useTotalWorldTime;
|
||||
|
||||
@Config.Comment("Enable Debug Logging")
|
||||
@Config.DefaultBoolean(false)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean enableDebugLogging;
|
||||
|
||||
@Config.Comment("Enable Zoom")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean enableZoom;
|
||||
|
||||
@Config.Comment("Optimizes in-world item rendering")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean optimizeInWorldItemRendering;
|
||||
|
||||
@Config.Comment("Max amount of display lists to cache for optimized item rendering. Higher number will use more VRAM")
|
||||
@Config.DefaultInt(256)
|
||||
@Config.RangeInt(min = 64, max = 1024)
|
||||
public static int itemRendererDisplayListCacheSize;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.gtnewhorizons.angelica.config;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.config.Config;
|
||||
|
||||
@Config(modid = "angelica", filename = "angelica-compat")
|
||||
public class CompatConfig {
|
||||
|
||||
@Config.Comment("Apply fixes to the LOTR mod")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixLotr;
|
||||
|
||||
@Config.Comment("Apply fixes to Extra Utilities")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixExtraUtils;
|
||||
|
||||
@Config.Comment("Apply fixes to Stacks on Stacks")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixStacksOnStacks;
|
||||
|
||||
@Config.Comment("Apply fixes to Minefactory Reloaded")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixMinefactoryReloaded;
|
||||
|
||||
@Config.Comment("Apply fixes to Thaumcraft")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixThaumcraft;
|
||||
|
||||
@Config.Comment("Apply fixes to ThaumicHorizons")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixThaumicHorizons;
|
||||
|
||||
@Config.Comment("Apply fixes to Immersive Engineering")
|
||||
@Config.DefaultBoolean(true)
|
||||
@Config.RequiresMcRestart
|
||||
public static boolean fixImmersiveEngineering;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.gtnewhorizons.angelica.debug;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class F3Direction {
|
||||
public static void renderWorldDirectionsEvent(Minecraft mc, RenderGameOverlayEvent.Pre event) {
|
||||
if (mc.gameSettings.showDebugInfo && mc.gameSettings.thirdPersonView == 0) {
|
||||
ScaledResolution scaledresolution = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
|
||||
int width = scaledresolution.getScaledWidth();
|
||||
int height = scaledresolution.getScaledHeight();
|
||||
|
||||
GL11.glPushMatrix();
|
||||
|
||||
GL11.glTranslatef((float) (width / 2), (float) (height / 2), -90);
|
||||
|
||||
Entity entity = mc.renderViewEntity;
|
||||
GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * event.partialTicks, -1.0F, 0.0F, 0.0F);
|
||||
GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * event.partialTicks, 0.0F, 1.0F, 0.0F);
|
||||
|
||||
GL11.glScalef(-1.0F, -1.0F, -1.0F);
|
||||
|
||||
renderWorldDirections();
|
||||
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
public static void renderWorldDirections() {
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDepthMask(false);
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
GL11.glLineWidth(2.0F);
|
||||
tessellator.startDrawing(GL11.GL_LINES);
|
||||
|
||||
//X
|
||||
tessellator.setColorRGBA_F(255, 0, 0, 1);
|
||||
tessellator.addVertex(0.0D, 0.0D, 0.0D);
|
||||
tessellator.addVertex(10, 0.0D, 0.0D);
|
||||
|
||||
//Z
|
||||
tessellator.setColorRGBA_F(0, 0, 255, 1);
|
||||
tessellator.addVertex(0.0D, 0.0D, 0.0D);
|
||||
tessellator.addVertex(0.0D, 0.0D, 10);
|
||||
|
||||
//Y
|
||||
tessellator.setColorRGBA_F(0, 255, 0, 1);
|
||||
tessellator.addVertex(0.0D, 0.0D, 0.0D);
|
||||
tessellator.addVertex(0.0D, 10, 0.0D);
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
GL11.glLineWidth(1.0F);
|
||||
GL11.glDepthMask(true);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package com.gtnewhorizons.angelica.debug;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP;
|
||||
import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY;
|
||||
import static org.lwjgl.opengl.GL11.glBlendFunc;
|
||||
import static org.lwjgl.opengl.GL11.glColor4f;
|
||||
import static org.lwjgl.opengl.GL11.glDisable;
|
||||
import static org.lwjgl.opengl.GL11.glDisableClientState;
|
||||
import static org.lwjgl.opengl.GL11.glDrawArrays;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
import static org.lwjgl.opengl.GL11.glEnableClientState;
|
||||
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
||||
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
||||
import static org.lwjgl.opengl.GL15.glBufferData;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1f;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram;
|
||||
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
|
||||
import java.nio.FloatBuffer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
public abstract class F3Graph {
|
||||
private static final int NUM_SAMPLES = 240;
|
||||
// Two floats (x,y)
|
||||
private static final int VERT_FLOATS = 2;
|
||||
private static final int VERT_COUNT = 4;
|
||||
private static final int BORDER = 1;
|
||||
private static final int HEIGHT = 60;
|
||||
private static final int WIDTH = NUM_SAMPLES;
|
||||
private static final int FONT_COLOR = 0xFFE0E0E0;
|
||||
// Due to GLSL 120 limitations, it's just easier to use floats
|
||||
private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES);
|
||||
private final long[] samples = new long[NUM_SAMPLES]; // long version for calculations
|
||||
// Circular buffer holding the last 240 samples, in nanoseconds
|
||||
private int samplesHead = 0; // one ahead of the position of the last sample
|
||||
private boolean initialized = false;
|
||||
private ShaderProgram shader;
|
||||
private int aPos;
|
||||
private int uFBWidth;
|
||||
private int uFBHeight;
|
||||
private int uScaleFactor;
|
||||
private int uHeadIdx;
|
||||
private int uSamples;
|
||||
private int vertBuf;
|
||||
private final ResourceLocation texture;
|
||||
private final float pxPerNs;
|
||||
private final boolean left;
|
||||
private long sum;
|
||||
|
||||
protected F3Graph(ResourceLocation texture, float pxPerNs, boolean left) {
|
||||
this.texture = texture;
|
||||
this.pxPerNs = pxPerNs;
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public void putSample(long time) {
|
||||
// Manage running trackers
|
||||
sum -= samples[samplesHead];
|
||||
sum += time;
|
||||
samples[samplesHead] = time;
|
||||
|
||||
sampleBuf.put(samplesHead, (float) time);
|
||||
samplesHead = (samplesHead + 1) % NUM_SAMPLES;
|
||||
}
|
||||
|
||||
private int getVertX(ScaledResolution sres, int idx) {
|
||||
if (left) {
|
||||
return switch (idx) {
|
||||
case 0, 3 -> WIDTH + BORDER * 2;
|
||||
case 1, 2 -> 0;
|
||||
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
|
||||
};
|
||||
}
|
||||
|
||||
final int displayWidth = sres.getScaledWidth();
|
||||
return switch (idx) {
|
||||
case 0, 3 -> displayWidth;
|
||||
case 1, 2 -> displayWidth - WIDTH - BORDER * 2;
|
||||
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
|
||||
};
|
||||
}
|
||||
|
||||
private int getVertY(ScaledResolution sres, int idx) {
|
||||
final int displayHeight = sres.getScaledHeight();
|
||||
return switch (idx) {
|
||||
case 0, 1 -> displayHeight - HEIGHT - BORDER * 2;
|
||||
case 2, 3 -> displayHeight;
|
||||
default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!");
|
||||
};
|
||||
}
|
||||
|
||||
private void init() {
|
||||
shader = new ShaderProgram(
|
||||
"angelica",
|
||||
"shaders/debug_graph.vert.glsl",
|
||||
"shaders/debug_graph.frag.glsl");
|
||||
shader.use();
|
||||
|
||||
// Register attributes
|
||||
aPos = shader.getAttribLocation("pos");
|
||||
|
||||
// Register uniforms
|
||||
uFBWidth = shader.getUniformLocation("fbWidth");
|
||||
uFBHeight = shader.getUniformLocation("fbHeight");
|
||||
uScaleFactor = shader.getUniformLocation("scaleFactor");
|
||||
uSamples = shader.getUniformLocation("samples");
|
||||
uHeadIdx = shader.getUniformLocation("headIdx");
|
||||
final int uPxPerNs = shader.getUniformLocation("pxPerNs");
|
||||
final int uLeft = shader.getUniformLocation("left");
|
||||
|
||||
// Load vertex buffer
|
||||
vertBuf = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
|
||||
try (final MemoryStack stack = MemoryStack.stackPush()) {
|
||||
final FloatBuffer vertices = stack.mallocFloat(VERT_COUNT * VERT_FLOATS);
|
||||
// Since we use a triangle strip, we only need 4 vertices. The quad extends to the top of the screen so spikes
|
||||
// don't get truncated. The max height is replaced in the vert shader, no need to be precise.
|
||||
vertices.put(new float[]{
|
||||
BORDER, BORDER,
|
||||
WIDTH + BORDER, BORDER,
|
||||
BORDER, Float.MAX_VALUE,
|
||||
WIDTH + BORDER, Float.MAX_VALUE
|
||||
});
|
||||
vertices.rewind();
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
final Minecraft mc = Minecraft.getMinecraft();
|
||||
final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
|
||||
|
||||
// Load initial value for uniforms
|
||||
glUniform1f(uFBWidth, mc.displayWidth);
|
||||
glUniform1f(uFBHeight, mc.displayHeight);
|
||||
glUniform1f(uScaleFactor, sr.getScaleFactor());
|
||||
glUniform1i(uHeadIdx, samplesHead);
|
||||
glUniform1(uSamples, sampleBuf);
|
||||
glUniform1f(uPxPerNs, pxPerNs);
|
||||
glUniform1i(uLeft, left ? 1 : 0); // this is how you load bool uniforms
|
||||
|
||||
ShaderProgram.clear();
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (!initialized) {
|
||||
init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to copy modern vanilla's tracker.
|
||||
* It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders.
|
||||
* We instead make it 242x62 including borders to prevent the borders from overlapping the samples.
|
||||
* The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0.
|
||||
* First the background is rendered, then the samples, then the foreground texture and the text.
|
||||
* The background is drawn via a 242x62 translucent rect.
|
||||
* Next, the samples are rendered by a shader on a transparent 240x60 rect.
|
||||
* Finally, the foreground texture and the text is rendered on top.
|
||||
* The shader pipeline is only needed for the sample draw.
|
||||
*/
|
||||
|
||||
final Minecraft mc = Minecraft.getMinecraft();
|
||||
final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
|
||||
|
||||
// Setup GL state
|
||||
final Tessellator tess = Tessellator.instance;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Draw background
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F);
|
||||
tess.startDrawingQuads();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
tess.addVertex(getVertX(sr, i), getVertY(sr, i), 0);
|
||||
}
|
||||
tess.draw();
|
||||
glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
// Draw samples
|
||||
shader.use();
|
||||
|
||||
// Load uniforms
|
||||
glUniform1f(uFBWidth, mc.displayWidth);
|
||||
glUniform1f(uFBHeight, mc.displayHeight);
|
||||
glUniform1f(uScaleFactor, sr.getScaleFactor());
|
||||
glUniform1i(uHeadIdx, samplesHead);
|
||||
glUniform1(uSamples, sampleBuf);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
|
||||
glEnableVertexAttribArray(aPos);
|
||||
glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
// Left side graphs are inverted, so temporarily disable culling
|
||||
if (!left) glDisable(GL_CULL_FACE);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT);
|
||||
|
||||
if (!left) glEnable(GL_CULL_FACE);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableVertexAttribArray(aPos);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
ShaderProgram.clear();
|
||||
|
||||
// Draw foreground
|
||||
|
||||
mc.getTextureManager().bindTexture(texture);
|
||||
tess.startDrawingQuads();
|
||||
tess.addVertexWithUV(getVertX(sr, 0), getVertY(sr, 0), 0.0D, 1, 0);
|
||||
tess.addVertexWithUV(getVertX(sr, 1), getVertY(sr, 1), 0.0D, 0, 0);
|
||||
tess.addVertexWithUV(getVertX(sr, 2), getVertY(sr, 2), 0.0D, 0, 1);
|
||||
tess.addVertexWithUV(getVertX(sr, 3), getVertY(sr, 3), 0.0D, 1, 1);
|
||||
tess.draw();
|
||||
|
||||
// Reset GL state
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
// Draw text
|
||||
// Ensure running counters are reset on first sample
|
||||
long min = Long.MAX_VALUE;
|
||||
long max = Long.MIN_VALUE;
|
||||
for (int i = 0; i < NUM_SAMPLES; ++i) {
|
||||
min = Math.min(min, samples[i]);
|
||||
max = Math.max(max, samples[i]);
|
||||
}
|
||||
String minStr = String.format("%.1f ms min", min / 1_000_000D);
|
||||
String avgStr = String.format("%.1f ms avg", sum / 1_000_000 / (double) NUM_SAMPLES);
|
||||
String maxStr = String.format("%.1f ms max", max / 1_000_000D);
|
||||
final FontRenderer fr = mc.fontRenderer;
|
||||
final int top = sr.getScaledHeight() - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT;
|
||||
final int scaledWidth = sr.getScaledWidth();
|
||||
|
||||
if (left) {
|
||||
fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true);
|
||||
fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true);
|
||||
fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true);
|
||||
} else {
|
||||
fr.drawString(minStr, scaledWidth - (BORDER * 2 + WIDTH), top, FONT_COLOR, true);
|
||||
fr.drawString(avgStr, scaledWidth - (BORDER + WIDTH / 2 + fr.getStringWidth(avgStr) / 2), top, FONT_COLOR, true);
|
||||
fr.drawString(maxStr, scaledWidth - (BORDER * 2 + fr.getStringWidth(maxStr)), top, FONT_COLOR, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.gtnewhorizons.angelica.debug;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class FrametimeGraph extends F3Graph {
|
||||
public FrametimeGraph() {
|
||||
// At 1x scale, 30 FPS should be 60 px. 30 FPS = 33_333_333ns per frame, 60px/33_333_333ns = 0.0000018f px/ns
|
||||
super(
|
||||
new ResourceLocation("angelica:textures/frametimes_fg.png"),
|
||||
0.0000018f,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.gtnewhorizons.angelica.debug;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class TPSGraph extends F3Graph {
|
||||
public TPSGraph() {
|
||||
// At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns
|
||||
super(
|
||||
new ResourceLocation("angelica:textures/tps_fg.png"),
|
||||
0.0000012f,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.gtnewhorizons.angelica.dynamiclights;
|
||||
|
||||
import baubles.common.lib.PlayerHandler;
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.BlockPos;
|
||||
import com.gtnewhorizon.gtnhlib.blockpos.IBlockPos;
|
||||
import com.gtnewhorizon.gtnhlib.util.CoordinatePacker;
|
||||
import com.gtnewhorizons.angelica.api.IDynamicLightProducer;
|
||||
import com.gtnewhorizons.angelica.compat.ModStatus;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
@@ -15,6 +18,7 @@ import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.monster.EntityCreeper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -25,7 +29,6 @@ import net.minecraft.util.MathHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import xonin.backhand.api.core.BackhandUtils;
|
||||
import xonin.backhand.api.core.IBackhandPlayer;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@@ -34,6 +37,7 @@ import java.util.function.Predicate;
|
||||
public class DynamicLights {
|
||||
private static DynamicLights instance;
|
||||
public static DynamicLightsMode Mode = DynamicLightsMode.OFF;
|
||||
public static boolean ShaderForce = false;
|
||||
|
||||
private static final double MAX_RADIUS = 7.75;
|
||||
private static final double MAX_RADIUS_SQUARED = MAX_RADIUS * MAX_RADIUS;
|
||||
@@ -49,7 +53,11 @@ public class DynamicLights {
|
||||
}
|
||||
|
||||
public static boolean isEnabled() {
|
||||
return AngelicaConfig.enableDynamicLights && Mode.isEnabled() && !IrisApi.getInstance().isShaderPackInUse();
|
||||
return AngelicaConfig.enableDynamicLights &&
|
||||
Mode.isEnabled() &&
|
||||
// if shader force is enabled then true
|
||||
// if not, then true when shaders are not in use
|
||||
(ShaderForce || !IrisApi.getInstance().isShaderPackInUse());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +70,7 @@ public class DynamicLights {
|
||||
return;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (now >= this.lastUpdate + 50) {
|
||||
if (now >= this.lastUpdate + Mode.getDelay()) {
|
||||
this.lastUpdate = now;
|
||||
this.lastUpdateCount = 0;
|
||||
|
||||
@@ -195,7 +203,7 @@ public class DynamicLights {
|
||||
return MathHelper.clamp_double(result, 0, 15);
|
||||
}
|
||||
|
||||
public double getDynamicLightLevel(@NotNull BlockPosImpl pos) {
|
||||
public double getDynamicLightLevel(@NotNull BlockPos pos) {
|
||||
return this.getDynamicLightLevel(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
@@ -229,7 +237,7 @@ public class DynamicLights {
|
||||
* @param currentLightLevel the current surrounding dynamic light level
|
||||
* @return the dynamic light level at the specified position
|
||||
*/
|
||||
public static double maxDynamicLightLevel(@NotNull BlockPosImpl pos, @NotNull IDynamicLightSource lightSource, double currentLightLevel) {
|
||||
public static double maxDynamicLightLevel(@NotNull BlockPos pos, @NotNull IDynamicLightSource lightSource, double currentLightLevel) {
|
||||
return maxDynamicLightLevel(pos.getX(), pos.getY(), pos.getZ(), lightSource, currentLightLevel);
|
||||
}
|
||||
|
||||
@@ -267,7 +275,7 @@ public class DynamicLights {
|
||||
* @param renderer the renderer
|
||||
* @param chunkPos the chunk position
|
||||
*/
|
||||
public static void scheduleChunkRebuild(@NotNull SodiumWorldRenderer renderer, @NotNull BlockPosImpl chunkPos) {
|
||||
public static void scheduleChunkRebuild(@NotNull SodiumWorldRenderer renderer, @NotNull IBlockPos chunkPos) {
|
||||
scheduleChunkRebuild(renderer, chunkPos.getX(), chunkPos.getY(), chunkPos.getZ());
|
||||
}
|
||||
|
||||
@@ -292,7 +300,7 @@ public class DynamicLights {
|
||||
* @param old the set of old chunk coordinates to remove this chunk from it
|
||||
* @param newPos the set of new chunk coordinates to add this chunk to it
|
||||
*/
|
||||
public static void updateTrackedChunks(@NotNull BlockPosImpl chunkPos, @Nullable LongOpenHashSet old, @Nullable LongOpenHashSet newPos) {
|
||||
public static void updateTrackedChunks(@NotNull IBlockPos chunkPos, @Nullable LongOpenHashSet old, @Nullable LongOpenHashSet newPos) {
|
||||
if (old != null || newPos != null) {
|
||||
final long pos = chunkPos.asLong();
|
||||
if (old != null)
|
||||
@@ -335,6 +343,8 @@ public class DynamicLights {
|
||||
if (block != null) {
|
||||
return block.getLightValue();
|
||||
}
|
||||
} else if (item instanceof IDynamicLightProducer lightProducer){
|
||||
return lightProducer.getLuminance();
|
||||
}
|
||||
|
||||
if (item == Items.lava_bucket) return Blocks.lava.getLightValue();
|
||||
@@ -380,6 +390,18 @@ public class DynamicLights {
|
||||
}
|
||||
}
|
||||
|
||||
if (ModStatus.isBaublesLoaded && living instanceof EntityPlayer player){
|
||||
var playerBaubles = PlayerHandler.getPlayerBaubles(player);
|
||||
if (playerBaubles != null){
|
||||
for (int i = 0; i < playerBaubles.getSizeInventory(); i++){
|
||||
var stack = playerBaubles.getStackInSlot(i);
|
||||
if (stack != null){
|
||||
luminance = Math.max(luminance, getLuminanceFromItemStack(stack, inWater));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return luminance;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ public enum DynamicLightsMode
|
||||
OFF("Off", 0),
|
||||
FASTEST("Fastest", 500),
|
||||
FAST("Fast", 250),
|
||||
FANCY("Fancy", 0);
|
||||
FANCY("Fancy", 50),
|
||||
REALTIME("Realtime", 0);
|
||||
|
||||
private final String name;
|
||||
private final int delay;
|
||||
|
||||
@@ -73,13 +73,6 @@ public interface IDynamicLightSource {
|
||||
*/
|
||||
void angelica$dynamicLightTick();
|
||||
|
||||
/**
|
||||
* Returns whether this dynamic light source should update.
|
||||
*
|
||||
* @return {@code true} if this dynamic light source should update, else {@code false}
|
||||
*/
|
||||
boolean angelica$shouldUpdateDynamicLight();
|
||||
|
||||
boolean angelica$updateDynamicLight(@NotNull SodiumWorldRenderer renderer);
|
||||
|
||||
void angelica$scheduleTrackedChunksRebuild(@NotNull SodiumWorldRenderer renderer);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.IStateStack;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -77,7 +77,7 @@ public class Feature {
|
||||
// GL_AUTO_NORMAL flag
|
||||
, GLStateManager.blendMode // GL_BLEND flag
|
||||
// Enable bits for the user-definable clipping planes
|
||||
// GL_COLOR_MATERIAL
|
||||
, GLStateManager.colorMaterial // GL_COLOR_MATERIAL
|
||||
, GLStateManager.cullState // GL_CULL_FACE flag
|
||||
, GLStateManager.depthTest // GL_DEPTH_TEST flag
|
||||
// GL_DITHER flag
|
||||
@@ -148,13 +148,11 @@ public class Feature {
|
||||
// GL_TEXTURE_COMPRESSION_HINT setting
|
||||
));
|
||||
attribToFeatures.put(GL11.GL_LIGHTING_BIT, ImmutableSet.of(
|
||||
// GL_COLOR_MATERIAL enable bit
|
||||
// GL_COLOR_MATERIAL_FACE value
|
||||
// Color material parameters that are tracking the current color
|
||||
// Ambient scene color
|
||||
// GL_LIGHT_MODEL_LOCAL_VIEWER value
|
||||
// GL_LIGHT_MODEL_TWO_SIDE setting
|
||||
GLStateManager.lightingState // GL_LIGHTING enable bit
|
||||
GLStateManager.colorMaterial // GL_COLOR_MATERIAL enable bit
|
||||
, GLStateManager.colorMaterialFace // GL_COLOR_MATERIAL_FACE value
|
||||
, GLStateManager.colorMaterialParameter // Color material parameters that are tracking the current color
|
||||
, GLStateManager.lightModel // Ambient scene color, GL_LIGHT_MODEL_LOCAL_VIEWER, GL_LIGHT_MODEL_TWO_SIDE
|
||||
, GLStateManager.lightingState // GL_LIGHTING enable bit
|
||||
// Enable bit for each light
|
||||
, GLStateManager.lightStates[0] // GL_LIGHT0
|
||||
, GLStateManager.lightStates[1] // GL_LIGHT1
|
||||
@@ -178,6 +176,8 @@ public class Feature {
|
||||
// Ambient, diffuse, specular, and emissive color for each material
|
||||
// Ambient, diffuse, and specular color indices for each material
|
||||
// Specular exponent for each material
|
||||
, GLStateManager.frontMaterial
|
||||
, GLStateManager.backMaterial
|
||||
, GLStateManager.shadeModelState // GL_SHADE_MODEL setting
|
||||
));
|
||||
attribToFeatures.put(GL11.GL_LINE_BIT, ImmutableSet.of(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.vbo.VBOManager;
|
||||
import com.gtnewhorizons.angelica.AngelicaMod;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.AlphaStateStack;
|
||||
@@ -9,9 +11,10 @@ import com.gtnewhorizons.angelica.glsm.stacks.Color4Stack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.ColorMaskStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.DepthStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.FogStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.IntegerStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.LightModelStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.LightStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.MaterialStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.MatrixModeStack;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.ViewPortStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.states.Color4;
|
||||
@@ -94,13 +97,9 @@ public class GLStateManager {
|
||||
|
||||
// GLStateManager State Trackers
|
||||
private static final IntStack attribs = new IntArrayList(MAX_ATTRIB_STACK_DEPTH);
|
||||
protected static final IntegerStateStack activeTextureUnit = new IntegerStateStack();
|
||||
protected static final IntegerStateStack shadeModelState = new IntegerStateStack();
|
||||
protected static final IntegerStateStack activeTextureUnit = new IntegerStateStack(0);
|
||||
protected static final IntegerStateStack shadeModelState = new IntegerStateStack(GL11.GL_SMOOTH);
|
||||
|
||||
static {
|
||||
activeTextureUnit.setValue(0); // GL_TEXTURE0
|
||||
shadeModelState.setValue(GL11.GL_SMOOTH);
|
||||
}
|
||||
@Getter protected static final TextureUnitArray textures = new TextureUnitArray();
|
||||
@Getter protected static final BlendStateStack blendState = new BlendStateStack();
|
||||
@Getter protected static final BooleanStateStack blendMode = new BooleanStateStack(GL11.GL_BLEND);
|
||||
@@ -126,6 +125,14 @@ public class GLStateManager {
|
||||
|
||||
@Getter protected static final BooleanStateStack[] lightStates = new BooleanStateStack[8];
|
||||
@Getter protected static final LightStateStack[] lightDataStates = new LightStateStack[8];
|
||||
@Getter protected static final BooleanStateStack colorMaterial = new BooleanStateStack(GL11.GL_COLOR_MATERIAL);
|
||||
@Getter protected static final IntegerStateStack colorMaterialFace = new IntegerStateStack(GL11.GL_FRONT_AND_BACK);
|
||||
@Getter protected static final IntegerStateStack colorMaterialParameter = new IntegerStateStack(GL11.GL_AMBIENT_AND_DIFFUSE);
|
||||
@Getter protected static final LightModelStateStack lightModel = new LightModelStateStack();
|
||||
|
||||
@Getter protected static final MaterialStateStack frontMaterial = new MaterialStateStack(GL11.GL_FRONT);
|
||||
@Getter protected static final MaterialStateStack backMaterial = new MaterialStateStack(GL11.GL_BACK);
|
||||
|
||||
static {
|
||||
for (int i = 0; i < lightStates.length; i ++) {
|
||||
lightStates[i] = new BooleanStateStack(GL11.GL_LIGHT0 + i);
|
||||
@@ -165,6 +172,7 @@ public class GLStateManager {
|
||||
@Setter @Getter private static boolean runningSplash = true;
|
||||
|
||||
private static int glListMode = 0;
|
||||
private static int glListNesting = 0;
|
||||
private static int glListId = -1;
|
||||
private static final Map<IStateStack<?>, ISettableState<?>> glListStates = new Object2ObjectArrayMap<>();
|
||||
private static final Int2ObjectMap<Set<Map.Entry<IStateStack<?>, ISettableState<?>>>> glListChanges = new Int2ObjectOpenHashMap<>();
|
||||
@@ -280,6 +288,7 @@ public class GLStateManager {
|
||||
case GL11.GL_LIGHT5 -> enableLight(5);
|
||||
case GL11.GL_LIGHT6 -> enableLight(6);
|
||||
case GL11.GL_LIGHT7 -> enableLight(7);
|
||||
case GL11.GL_COLOR_MATERIAL -> enableColorMaterial();
|
||||
case GL11.GL_SCISSOR_TEST -> enableScissorTest();
|
||||
case GL11.GL_TEXTURE_2D -> enableTexture();
|
||||
case GL12.GL_RESCALE_NORMAL -> enableRescaleNormal();
|
||||
@@ -303,6 +312,7 @@ public class GLStateManager {
|
||||
case GL11.GL_LIGHT5 -> disableLight(5);
|
||||
case GL11.GL_LIGHT6 -> disableLight(6);
|
||||
case GL11.GL_LIGHT7 -> disableLight(7);
|
||||
case GL11.GL_COLOR_MATERIAL -> disableColorMaterial();
|
||||
case GL11.GL_SCISSOR_TEST -> disableScissorTest();
|
||||
case GL11.GL_TEXTURE_2D -> disableTexture();
|
||||
case GL12.GL_RESCALE_NORMAL -> disableRescaleNormal();
|
||||
@@ -329,6 +339,7 @@ public class GLStateManager {
|
||||
case GL11.GL_LIGHT5 -> lightStates[5].isEnabled();
|
||||
case GL11.GL_LIGHT6 -> lightStates[6].isEnabled();
|
||||
case GL11.GL_LIGHT7 -> lightStates[7].isEnabled();
|
||||
case GL11.GL_COLOR_MATERIAL -> colorMaterial.isEnabled();
|
||||
case GL11.GL_SCISSOR_TEST -> scissorTest.isEnabled();
|
||||
case GL11.GL_TEXTURE_2D -> textures.getTextureUnitStates(activeTextureUnit.getValue()).isEnabled();
|
||||
case GL12.GL_RESCALE_NORMAL -> rescaleNormalState.isEnabled();
|
||||
@@ -356,6 +367,7 @@ public class GLStateManager {
|
||||
case GL11.GL_LIGHT5 -> lightStates[5].isEnabled();
|
||||
case GL11.GL_LIGHT6 -> lightStates[6].isEnabled();
|
||||
case GL11.GL_LIGHT7 -> lightStates[7].isEnabled();
|
||||
case GL11.GL_COLOR_MATERIAL -> colorMaterial.isEnabled();
|
||||
case GL11.GL_SCISSOR_TEST -> scissorTest.isEnabled();
|
||||
case GL11.GL_TEXTURE_2D -> textures.getTextureUnitStates(activeTextureUnit.getValue()).isEnabled();
|
||||
case GL12.GL_RESCALE_NORMAL -> rescaleNormalState.isEnabled();
|
||||
@@ -402,6 +414,8 @@ public class GLStateManager {
|
||||
case GL14.GL_BLEND_DST_RGB -> blendState.getDstRgb();
|
||||
case GL14.GL_BLEND_SRC_ALPHA -> blendState.getSrcAlpha();
|
||||
case GL14.GL_BLEND_SRC_RGB -> blendState.getSrcRgb();
|
||||
case GL11.GL_COLOR_MATERIAL_FACE -> colorMaterialFace.getValue();
|
||||
case GL11.GL_COLOR_MATERIAL_PARAMETER -> colorMaterialParameter.getValue();
|
||||
case GL20.GL_CURRENT_PROGRAM -> activeProgram;
|
||||
|
||||
default -> GL11.glGetInteger(pname);
|
||||
@@ -426,6 +440,32 @@ public class GLStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void glGetMaterial(int face, int pname, FloatBuffer params) {
|
||||
if (shouldBypassCache()) {
|
||||
GL11.glGetMaterial(face, pname, params);
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialStateStack state;
|
||||
if (face == GL11.GL_FRONT) {
|
||||
state = frontMaterial;
|
||||
} else if (face == GL11.GL_BACK) {
|
||||
state = backMaterial;
|
||||
} else {
|
||||
throw new RuntimeException("Invalid face parameter specified to glGetMaterial: " + face);
|
||||
}
|
||||
|
||||
switch (pname) {
|
||||
case GL11.GL_AMBIENT -> state.ambient.get(0, params);
|
||||
case GL11.GL_DIFFUSE -> state.diffuse.get(0, params);
|
||||
case GL11.GL_SPECULAR -> state.specular.get(0, params);
|
||||
case GL11.GL_EMISSION -> state.emission.get(0, params);
|
||||
case GL11.GL_SHININESS -> params.put(state.shininess);
|
||||
case GL11.GL_COLOR_INDEXES -> state.colorIndexes.get(0, params);
|
||||
default -> GL11.glGetMaterial(face, pname, params);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glGetLight(int light, int pname, FloatBuffer params) {
|
||||
if (shouldBypassCache()) {
|
||||
GL11.glGetLight(light, pname, params);
|
||||
@@ -444,8 +484,8 @@ public class GLStateManager {
|
||||
case GL11.GL_CONSTANT_ATTENUATION -> params.put(state.constantAttenuation);
|
||||
case GL11.GL_LINEAR_ATTENUATION -> params.put(state.linearAttenuation);
|
||||
case GL11.GL_QUADRATIC_ATTENUATION -> params.put(state.quadraticAttenuation);
|
||||
default -> GL11.glGetLight(light, pname, params);
|
||||
}
|
||||
GL11.glGetLight(light, pname, params);
|
||||
}
|
||||
|
||||
public static void glGetFloat(int pname, FloatBuffer params) {
|
||||
@@ -932,6 +972,20 @@ public class GLStateManager {
|
||||
GL11.glDrawBuffer(mode);
|
||||
}
|
||||
|
||||
public static void glDrawElements(int mode, IntBuffer indices) {
|
||||
if(AngelicaConfig.enableIris) {
|
||||
Iris.getPipelineManager().getPipeline().ifPresent(WorldRenderingPipeline::syncProgram);
|
||||
}
|
||||
GL11.glDrawElements(mode, indices);
|
||||
}
|
||||
|
||||
public static void glBegin(int mode) {
|
||||
if (AngelicaConfig.enableIris) {
|
||||
Iris.getPipelineManager().getPipeline().ifPresent(WorldRenderingPipeline::syncProgram);
|
||||
}
|
||||
GL11.glBegin(mode);
|
||||
}
|
||||
|
||||
public static void glLogicOp(int opcode) {
|
||||
GL11.glLogicOp(opcode);
|
||||
}
|
||||
@@ -964,6 +1018,42 @@ public class GLStateManager {
|
||||
lightStates[light].enable();
|
||||
}
|
||||
|
||||
public static void enableColorMaterial() {
|
||||
colorMaterial.enable();
|
||||
float r = getColor().getRed();
|
||||
float g = getColor().getGreen();
|
||||
float b = getColor().getBlue();
|
||||
float a = getColor().getAlpha();
|
||||
if (colorMaterialFace.getValue() == GL11.GL_FRONT || colorMaterialFace.getValue() == GL11.GL_FRONT_AND_BACK) {
|
||||
switch (colorMaterialParameter.getValue()) {
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
frontMaterial.ambient.set(r, g, b, a);
|
||||
frontMaterial.diffuse.set(r, g, b, a);
|
||||
}
|
||||
case GL11.GL_AMBIENT -> frontMaterial.ambient.set(r, g, b, a);
|
||||
case GL11.GL_DIFFUSE -> frontMaterial.diffuse.set(r, g, b, a);
|
||||
case GL11.GL_SPECULAR -> frontMaterial.specular.set(r, g, b, a);
|
||||
case GL11.GL_EMISSION -> frontMaterial.emission.set(r, g, b, a);
|
||||
}
|
||||
}
|
||||
if (colorMaterialFace.getValue() == GL11.GL_BACK || colorMaterialFace.getValue() == GL11.GL_FRONT_AND_BACK) {
|
||||
switch (colorMaterialParameter.getValue()) {
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
backMaterial.ambient.set(r, g, b, a);
|
||||
backMaterial.diffuse.set(r, g, b, a);
|
||||
}
|
||||
case GL11.GL_AMBIENT -> backMaterial.ambient.set(r, g, b, a);
|
||||
case GL11.GL_DIFFUSE -> backMaterial.diffuse.set(r, g, b, a);
|
||||
case GL11.GL_SPECULAR -> backMaterial.specular.set(r, g, b, a);
|
||||
case GL11.GL_EMISSION -> backMaterial.emission.set(r, g, b, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void disableColorMaterial() {
|
||||
colorMaterial.disable();
|
||||
}
|
||||
|
||||
public static void disableLighting() {
|
||||
lightingState.disable();
|
||||
}
|
||||
@@ -1098,7 +1188,8 @@ public class GLStateManager {
|
||||
|
||||
public static void glNewList(int list, int mode) {
|
||||
if(glListMode > 0) {
|
||||
throw new RuntimeException("glNewList called inside of a display list!");
|
||||
glListNesting += 1;
|
||||
return;
|
||||
}
|
||||
glListId = list;
|
||||
glListMode = mode;
|
||||
@@ -1113,6 +1204,11 @@ public class GLStateManager {
|
||||
}
|
||||
|
||||
public static void glEndList() {
|
||||
if (glListNesting > 0) {
|
||||
glListNesting -= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(glListMode == 0) {
|
||||
throw new RuntimeException("glEndList called outside of a display list!");
|
||||
}
|
||||
@@ -1215,10 +1311,6 @@ public class GLStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static Matrix4f getModelviewMatrix() {
|
||||
return modelViewMatrix;
|
||||
}
|
||||
|
||||
public static void glLoadIdentity() {
|
||||
GL11.glLoadIdentity();
|
||||
getMatrixStack().identity();
|
||||
@@ -1489,6 +1581,115 @@ public class GLStateManager {
|
||||
};
|
||||
}
|
||||
|
||||
private static void glMaterialFront(int pname, FloatBuffer params) {
|
||||
switch (pname) {
|
||||
case GL11.GL_AMBIENT -> frontMaterial.setAmbient(params);
|
||||
case GL11.GL_DIFFUSE -> frontMaterial.setDiffuse(params);
|
||||
case GL11.GL_SPECULAR -> frontMaterial.setSpecular(params);
|
||||
case GL11.GL_EMISSION -> frontMaterial.setEmission(params);
|
||||
case GL11.GL_SHININESS -> frontMaterial.setShininess(params);
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
frontMaterial.setAmbient(params);
|
||||
frontMaterial.setDiffuse(params);
|
||||
}
|
||||
case GL11.GL_COLOR_INDEXES -> frontMaterial.setColorIndexes(params);
|
||||
}
|
||||
}
|
||||
|
||||
private static void glMaterialBack(int pname, FloatBuffer params) {
|
||||
switch (pname) {
|
||||
case GL11.GL_AMBIENT -> backMaterial.setAmbient(params);
|
||||
case GL11.GL_DIFFUSE -> backMaterial.setDiffuse(params);
|
||||
case GL11.GL_SPECULAR -> backMaterial.setSpecular(params);
|
||||
case GL11.GL_EMISSION -> backMaterial.setEmission(params);
|
||||
case GL11.GL_SHININESS -> backMaterial.setShininess(params);
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
backMaterial.setAmbient(params);
|
||||
backMaterial.setDiffuse(params);
|
||||
}
|
||||
case GL11.GL_COLOR_INDEXES -> backMaterial.setColorIndexes(params);
|
||||
}
|
||||
}
|
||||
|
||||
private static void glMaterialFront(int pname, IntBuffer params) {
|
||||
switch (pname) {
|
||||
case GL11.GL_AMBIENT -> frontMaterial.setAmbient(params);
|
||||
case GL11.GL_DIFFUSE -> frontMaterial.setDiffuse(params);
|
||||
case GL11.GL_SPECULAR -> frontMaterial.setSpecular(params);
|
||||
case GL11.GL_EMISSION -> frontMaterial.setEmission(params);
|
||||
case GL11.GL_SHININESS -> frontMaterial.setShininess(params);
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
frontMaterial.setAmbient(params);
|
||||
frontMaterial.setDiffuse(params);
|
||||
}
|
||||
case GL11.GL_COLOR_INDEXES -> frontMaterial.setColorIndexes(params);
|
||||
}
|
||||
}
|
||||
|
||||
private static void glMaterialBack(int pname, IntBuffer params) {
|
||||
switch (pname) {
|
||||
case GL11.GL_AMBIENT -> backMaterial.setAmbient(params);
|
||||
case GL11.GL_DIFFUSE -> backMaterial.setDiffuse(params);
|
||||
case GL11.GL_SPECULAR -> backMaterial.setSpecular(params);
|
||||
case GL11.GL_EMISSION -> backMaterial.setEmission(params);
|
||||
case GL11.GL_SHININESS -> backMaterial.setShininess(params);
|
||||
case GL11.GL_AMBIENT_AND_DIFFUSE -> {
|
||||
backMaterial.setAmbient(params);
|
||||
backMaterial.setDiffuse(params);
|
||||
}
|
||||
case GL11.GL_COLOR_INDEXES -> backMaterial.setColorIndexes(params);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glMaterial(int face, int pname, FloatBuffer params) {
|
||||
if (face == GL11.GL_FRONT) {
|
||||
glMaterialFront(pname, params);
|
||||
} else if (face == GL11.GL_BACK) {
|
||||
glMaterialBack(pname, params);
|
||||
} else if (face == GL11.GL_FRONT_AND_BACK) {
|
||||
glMaterialFront(pname, params);
|
||||
glMaterialBack(pname, params);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glMaterial(int face, int pname, IntBuffer params) {
|
||||
if (face == GL11.GL_FRONT) {
|
||||
glMaterialFront(pname, params);
|
||||
} else if (face == GL11.GL_BACK) {
|
||||
glMaterialBack(pname, params);
|
||||
} else if (face == GL11.GL_FRONT_AND_BACK) {
|
||||
glMaterialFront(pname, params);
|
||||
glMaterialBack(pname, params);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glMaterialf(int face, int pname, float val) {
|
||||
if (pname != GL11.GL_SHININESS) {
|
||||
// it is only valid to call glMaterialf for the GL_SHININESS parameter
|
||||
return;
|
||||
}
|
||||
|
||||
if (face == GL11.GL_FRONT) {
|
||||
frontMaterial.setShininess(val);
|
||||
} else if (face == GL11.GL_BACK) {
|
||||
backMaterial.setShininess(val);
|
||||
} else if (face == GL11.GL_FRONT_AND_BACK) {
|
||||
frontMaterial.setShininess(val);
|
||||
backMaterial.setShininess(val);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported face value for glMaterial: " + face);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glMateriali(int face, int pname, int val) {
|
||||
// This will end up no-opping if pname != GL_SHININESS, it is invalid to call this with another pname
|
||||
glMaterialf(face, pname, (float) val);
|
||||
}
|
||||
|
||||
public static void glLight(int light, int pname, FloatBuffer params) {
|
||||
LightStateStack lightState = lightDataStates[light - GL11.GL_LIGHT0];
|
||||
switch (pname) {
|
||||
@@ -1548,20 +1749,44 @@ public class GLStateManager {
|
||||
}
|
||||
|
||||
public static void glLightModel(int pname, FloatBuffer params) {
|
||||
GL11.glLightModel(pname, params);
|
||||
switch (pname) {
|
||||
case GL11.GL_LIGHT_MODEL_AMBIENT -> lightModel.setAmbient(params);
|
||||
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> lightModel.setLocalViewer(params);
|
||||
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> lightModel.setTwoSide(params);
|
||||
default -> GL11.glLightModel(pname, params);
|
||||
}
|
||||
}
|
||||
public static void glLightModel(int pname, IntBuffer params) {
|
||||
GL11.glLightModel(pname, params);
|
||||
switch (pname) {
|
||||
case GL11.GL_LIGHT_MODEL_AMBIENT -> lightModel.setAmbient(params);
|
||||
case GL12.GL_LIGHT_MODEL_COLOR_CONTROL -> lightModel.setColorControl(params);
|
||||
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> lightModel.setLocalViewer(params);
|
||||
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> lightModel.setTwoSide(params);
|
||||
default -> GL11.glLightModel(pname, params);
|
||||
}
|
||||
}
|
||||
public static void glLightModelf(int pname, float param) {
|
||||
GL11.glLightModelf(pname, param);
|
||||
switch (pname) {
|
||||
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> lightModel.setLocalViewer(param);
|
||||
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> lightModel.setTwoSide(param);
|
||||
default -> GL11.glLightModelf(pname, param);
|
||||
}
|
||||
}
|
||||
public static void glLightModeli(int pname, int param) {
|
||||
GL11.glLightModeli(pname, param);
|
||||
switch (pname) {
|
||||
case GL12.GL_LIGHT_MODEL_COLOR_CONTROL -> lightModel.setColorControl(param);
|
||||
case GL11.GL_LIGHT_MODEL_LOCAL_VIEWER -> lightModel.setLocalViewer(param);
|
||||
case GL11.GL_LIGHT_MODEL_TWO_SIDE -> lightModel.setTwoSide(param);
|
||||
default -> GL11.glLightModeli(pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glColorMaterial(int face, int mode) {
|
||||
GL11.glColorMaterial(face, mode);
|
||||
if (shouldBypassCache() || (colorMaterialFace.getValue() != face || colorMaterialParameter.getValue() != mode)) {
|
||||
colorMaterialFace.setValue(face);
|
||||
colorMaterialParameter.setValue(mode);
|
||||
GL11.glColorMaterial(face, mode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void glDepthRange(double near, double far) {
|
||||
|
||||
@@ -239,7 +239,7 @@ public class RenderSystem {
|
||||
dsaState.bindTextureToUnit(unit, texture);
|
||||
}
|
||||
|
||||
public static FloatBuffer PROJECTION_MATRIX_BUFFER = BufferUtils.createFloatBuffer(16);
|
||||
public static final FloatBuffer PROJECTION_MATRIX_BUFFER = BufferUtils.createFloatBuffer(16);
|
||||
public static void setupProjectionMatrix(Matrix4f matrix) {
|
||||
GL11.glMatrixMode(GL11.GL_PROJECTION);
|
||||
GL11.glPushMatrix();
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class TessellatorManager {
|
||||
private static final ThreadLocal<CapturingTessellator> capturingTessellator = ThreadLocal.withInitial(CapturingTessellator::new);
|
||||
|
||||
private static final ThreadLocal<Boolean> currentlyCapturing = ThreadLocal.withInitial(() -> Boolean.FALSE);
|
||||
private static final Thread mainThread = Thread.currentThread();
|
||||
|
||||
public static Tessellator get() {
|
||||
if(currentlyCapturing.get()) {
|
||||
return capturingTessellator.get();
|
||||
} else if(isOnMainThread()) {
|
||||
return Tessellator.instance;
|
||||
} else {
|
||||
// TODO: Verify this works correctly and nothing unexpected is grabbing a tessellator off the main thread
|
||||
// when not capturing
|
||||
throw new IllegalStateException("Tried to get the Tessellator off the main thread when not capturing!");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isOnMainThread() {
|
||||
return Thread.currentThread() == mainThread;
|
||||
}
|
||||
|
||||
public static boolean isMainInstance(Object instance) {
|
||||
return instance == Tessellator.instance || isOnMainThread();
|
||||
}
|
||||
|
||||
public static void startCapturing() {
|
||||
if(currentlyCapturing.get()) throw new IllegalStateException("Tried to start capturing when already capturing!");
|
||||
final CapturingTessellator tess = capturingTessellator.get();
|
||||
if(tess.getQuads().size() > 0) throw new IllegalStateException("Tried to start capturing with existing collected Quads!");
|
||||
tess.storeTranslation();
|
||||
|
||||
currentlyCapturing.set(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop the CapturingTessellator and return the pooled quads. The quads are valid until clearQuads() is
|
||||
* called on the CapturingTesselator, which must be done before starting capturing again.
|
||||
*/
|
||||
public static List<QuadView> stopCapturingToPooledQuads() {
|
||||
if(!currentlyCapturing.get()) throw new IllegalStateException("Tried to stop capturing when not capturing!");
|
||||
currentlyCapturing.set(false);
|
||||
final CapturingTessellator tess = capturingTessellator.get();
|
||||
|
||||
// Be sure we got all the quads
|
||||
if(tess.isDrawing) tess.draw();
|
||||
|
||||
final List<QuadView> quads = tess.getQuads();
|
||||
tess.discard();
|
||||
tess.restoreTranslation();
|
||||
|
||||
return quads;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stops the CapturingTessellator, stores the quads in a buffer (based on the VertexFormat provided),
|
||||
* and clears the quads.
|
||||
*/
|
||||
public static ByteBuffer stopCapturingToBuffer(VertexFormat format) {
|
||||
final ByteBuffer buf = CapturingTessellator.quadsToBuffer(stopCapturingToPooledQuads(), format);
|
||||
capturingTessellator.get().clearQuads();
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stops the CapturingTessellator, stores the quads in a buffer (based on the VertexFormat provided),
|
||||
* uploads the buffer to a new VertexBuffer, and clears the quads.
|
||||
*/
|
||||
public static VertexBuffer stopCapturingToVBO(VertexFormat format) {
|
||||
return new VertexBuffer(format, GL11.GL_QUADS).upload(stopCapturingToBuffer(format));
|
||||
}
|
||||
|
||||
static {
|
||||
System.out.println("[TessellatorManager] Initialized on thread " + mainThread.getName());
|
||||
}
|
||||
|
||||
public static void cleanup() {
|
||||
// Ensure we've cleaned everything up
|
||||
final CapturingTessellator tessellator = capturingTessellator.get();
|
||||
|
||||
currentlyCapturing.set(false);
|
||||
tessellator.discard();
|
||||
tessellator.clearQuads();
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
public class VBOManager {
|
||||
// Not thread safe, only expected to be called from the main thread
|
||||
|
||||
private static int nextDisplayList = Integer.MIN_VALUE;
|
||||
|
||||
private static int getNextDisplayList() {
|
||||
return nextDisplayList++;
|
||||
}
|
||||
|
||||
private static Int2ObjectMap<VertexBuffer> vertexBuffers = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
/*
|
||||
* Allocate a (range) of "display list IDs" that will refer to a VBO in the arraylist of vertex buffers.
|
||||
*/
|
||||
public static int generateDisplayLists(int range) {
|
||||
if(range < 1) throw new IllegalArgumentException("Range must be at least 1!");
|
||||
|
||||
final int id = getNextDisplayList();
|
||||
for (int i = 1; i < range; i++) {
|
||||
// Reserve, but don't use, the rest in the range
|
||||
getNextDisplayList();
|
||||
}
|
||||
// Return the first in the range
|
||||
return id;
|
||||
}
|
||||
|
||||
public static VertexBuffer registerVBO(int displayList, VertexBuffer vertexBuffer) {
|
||||
if(displayList > 0) throw new IllegalArgumentException("Display list must be negative!");
|
||||
displayList -= Integer.MIN_VALUE;
|
||||
|
||||
vertexBuffers.put(displayList, vertexBuffer);
|
||||
return vertexBuffer;
|
||||
}
|
||||
|
||||
public static VertexBuffer get(int list) {
|
||||
list -= Integer.MIN_VALUE;
|
||||
return vertexBuffers.getOrDefault(list, null);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.AlphaState;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.BlendState;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.BooleanState;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.Color4;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.ColorMask;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.DepthState;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.FogState;
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
public interface IStateStack<T>{
|
||||
|
||||
T push();
|
||||
|
||||
T pop();
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.IntegerState;
|
||||
|
||||
@@ -9,10 +10,12 @@ public class IntegerStateStack extends IntegerState implements IStateStack<Integ
|
||||
|
||||
protected int pointer;
|
||||
|
||||
public IntegerStateStack() {
|
||||
public IntegerStateStack(int val) {
|
||||
setValue(val);
|
||||
stack = new IntegerState[GLStateManager.MAX_ATTRIB_STACK_DEPTH];
|
||||
for (int i = 0; i < GLStateManager.MAX_ATTRIB_STACK_DEPTH; i++) {
|
||||
stack[i] = new IntegerState();
|
||||
stack[i].setValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.LightModelState;
|
||||
|
||||
public class LightModelStateStack extends LightModelState implements IStateStack<LightModelStateStack> {
|
||||
|
||||
protected final LightModelState[] stack;
|
||||
|
||||
protected int pointer;
|
||||
|
||||
public LightModelStateStack() {
|
||||
super();
|
||||
stack = new LightModelState[GLStateManager.MAX_ATTRIB_STACK_DEPTH];
|
||||
for (int i = 0; i < GLStateManager.MAX_ATTRIB_STACK_DEPTH; i++) {
|
||||
stack[i] = new LightModelState();
|
||||
}
|
||||
}
|
||||
|
||||
public LightModelStateStack push() {
|
||||
if (pointer == stack.length) {
|
||||
throw new IllegalStateException("Stack overflow size " + (pointer + 1) + " reached");
|
||||
}
|
||||
|
||||
stack[pointer++].set(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LightModelStateStack pop() {
|
||||
if (pointer == 0) {
|
||||
throw new IllegalStateException("Stack underflow");
|
||||
}
|
||||
|
||||
set(stack[--pointer]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() { return pointer == 0; }
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.LightState;
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.MaterialState;
|
||||
|
||||
public class MaterialStateStack extends MaterialState implements IStateStack<MaterialStateStack> {
|
||||
|
||||
protected final MaterialState[] stack;
|
||||
|
||||
protected int pointer;
|
||||
|
||||
public MaterialStateStack(int face) {
|
||||
super(face);
|
||||
stack = new MaterialState[GLStateManager.MAX_ATTRIB_STACK_DEPTH];
|
||||
for (int i = 0; i < GLStateManager.MAX_ATTRIB_STACK_DEPTH; i++) {
|
||||
stack[i] = new MaterialState(face);
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialStateStack push() {
|
||||
if (pointer == stack.length) {
|
||||
throw new IllegalStateException("Stack overflow size " + (pointer + 1) + " reached");
|
||||
}
|
||||
|
||||
stack[pointer++].set(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MaterialStateStack pop() {
|
||||
if (pointer == 0) {
|
||||
throw new IllegalStateException("Stack underflow");
|
||||
}
|
||||
|
||||
set(stack[--pointer]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() { return pointer == 0; }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.MatrixMode;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.TextureBinding;
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
public class Vector3dStack extends Vector3d implements IStateStack<Vector3dStack> {
|
||||
protected final Vector3d[] stack;
|
||||
|
||||
protected int pointer;
|
||||
|
||||
public Vector3dStack() {
|
||||
stack = new Vector3d[GLStateManager.MAX_ATTRIB_STACK_DEPTH];
|
||||
for (int i = 0; i < GLStateManager.MAX_ATTRIB_STACK_DEPTH; i++) {
|
||||
stack[i] = new Vector3d();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3dStack push() {
|
||||
if(pointer == stack.length) {
|
||||
throw new IllegalStateException("Stack overflow size " + (pointer + 1) + " reached");
|
||||
}
|
||||
stack[pointer++].set(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3dStack pop() {
|
||||
if(pointer == 0) {
|
||||
throw new IllegalStateException("Stack underflow");
|
||||
}
|
||||
set(stack[--pointer]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return pointer == 0;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gtnewhorizons.angelica.glsm.stacks;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.stacks.IStateStack;
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.states.ViewportState;
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.gtnewhorizons.angelica.glsm.states;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4i;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static com.gtnewhorizons.angelica.glsm.GLStateManager.i2f;
|
||||
|
||||
public class LightModelState implements ISettableState<LightModelState> {
|
||||
|
||||
private static final Vector4f vector4f = new Vector4f();
|
||||
private static final Vector4i vector4i = new Vector4i();
|
||||
|
||||
public final Vector4f ambient;
|
||||
public int colorControl;
|
||||
public float localViewer;
|
||||
public float twoSide;
|
||||
|
||||
public LightModelState() {
|
||||
ambient = new Vector4f(0.2F, 0.2F, 0.2F, 1.0F);
|
||||
colorControl = GL12.GL_SINGLE_COLOR;
|
||||
localViewer = 0.0F;
|
||||
twoSide = 0.0F;
|
||||
}
|
||||
|
||||
public void setAmbient(FloatBuffer newBuffer) {
|
||||
vector4f.set(newBuffer);
|
||||
if (GLStateManager.shouldBypassCache() || !this.ambient.equals(vector4f)) {
|
||||
this.ambient.set(vector4f);
|
||||
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAmbient(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
vector4f.set(i2f(vector4i.x), i2f(vector4i.y), i2f(vector4i.z), i2f(vector4i.w));
|
||||
if (GLStateManager.shouldBypassCache() || !this.ambient.equals(vector4f)) {
|
||||
this.ambient.set(vector4f);
|
||||
GL11.glLightModel(GL11.GL_LIGHT_MODEL_AMBIENT, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColorControl(int val) {
|
||||
if (GLStateManager.shouldBypassCache() || this.colorControl != val) {
|
||||
this.colorControl = val;
|
||||
GL11.glLightModeli(GL12.GL_LIGHT_MODEL_COLOR_CONTROL, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColorControl(IntBuffer newBuffer) {
|
||||
setColorControl(newBuffer.get());
|
||||
}
|
||||
|
||||
public void setLocalViewer(float val) {
|
||||
if (GLStateManager.shouldBypassCache() || Float.compare(this.localViewer, val) != 0) {
|
||||
this.localViewer = val;
|
||||
GL11.glLightModelf(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLocalViewer(FloatBuffer newBuffer) {
|
||||
setLocalViewer(newBuffer.get());
|
||||
}
|
||||
|
||||
public void setLocalViewer(IntBuffer newBuffer) {
|
||||
setLocalViewer((float) newBuffer.get());
|
||||
}
|
||||
|
||||
public void setLocalViewer(int val) {
|
||||
setLocalViewer((float) val);
|
||||
}
|
||||
|
||||
public void setTwoSide(float val) {
|
||||
if (GLStateManager.shouldBypassCache() || Float.compare(this.twoSide, val) != 0) {
|
||||
this.twoSide = val;
|
||||
GL11.glLightModelf(GL11.GL_LIGHT_MODEL_TWO_SIDE, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTwoSide(FloatBuffer newBuffer) {
|
||||
setTwoSide(newBuffer.get());
|
||||
}
|
||||
|
||||
public void setTwoSide(IntBuffer newBuffer) {
|
||||
setTwoSide((float) newBuffer.get());
|
||||
}
|
||||
|
||||
public void setTwoSide(int val) {
|
||||
setTwoSide((float) val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightModelState set(LightModelState state) {
|
||||
this.ambient.set(state.ambient);
|
||||
this.colorControl = state.colorControl;
|
||||
this.localViewer = state.localViewer;
|
||||
this.twoSide = state.twoSide;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameAs(Object state) {
|
||||
if (this == state) return true;
|
||||
if (!(state instanceof LightModelState lightModelState)) return false;
|
||||
return this.ambient.equals(lightModelState.ambient)
|
||||
&& this.colorControl == lightModelState.colorControl
|
||||
&& Float.compare(lightModelState.localViewer, this.localViewer) == 0
|
||||
&& Float.compare(lightModelState.twoSide, this.twoSide) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LightModelState copy() {
|
||||
return new LightModelState().set(this);
|
||||
}
|
||||
}
|
||||
@@ -66,10 +66,10 @@ public class LightState implements ISettableState<LightState> {
|
||||
this.quadraticAttenuation = quadraticAttenuation;
|
||||
|
||||
this.position = position;
|
||||
this.position.mul(GLStateManager.getModelviewMatrix());
|
||||
this.position.mul(GLStateManager.getModelViewMatrix());
|
||||
|
||||
this.spotDirection = spotDirection;
|
||||
GLStateManager.getModelviewMatrix().get3x3(matrix3f);
|
||||
GLStateManager.getModelViewMatrix().get3x3(matrix3f);
|
||||
this.spotDirection.mul(matrix3f);
|
||||
}
|
||||
|
||||
@@ -129,14 +129,14 @@ public class LightState implements ISettableState<LightState> {
|
||||
// are big and probably more than just bypassing. We would need to track the modelview matrix it was transformed
|
||||
// with and the untransformed coordinates in addition to the final transformation.
|
||||
this.position.set(newBuffer);
|
||||
this.position.mul(GLStateManager.getModelviewMatrix());
|
||||
this.position.mul(GLStateManager.getModelViewMatrix());
|
||||
GL11.glLight(this.light, GL11.GL_POSITION, newBuffer);
|
||||
}
|
||||
|
||||
public void setPosition(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
this.position.set((float) vector4i.x, (float) vector4i.y, (float) vector4i.z, (float) vector4i.w);
|
||||
this.position.mul(GLStateManager.getModelviewMatrix());
|
||||
this.position.mul(GLStateManager.getModelViewMatrix());
|
||||
GL11.glLight(this.light, GL11.GL_POSITION, newBuffer);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class LightState implements ISettableState<LightState> {
|
||||
// We are bypassing cache everytime for spot direction, because the necessary components to enable tracking the cache
|
||||
// are big and probably more than just bypassing. We would need to track the modelview matrix it was transformed
|
||||
// with and the untransformed coordinates in addition to the final transformation.
|
||||
GLStateManager.getModelviewMatrix().get3x3(matrix3f);
|
||||
GLStateManager.getModelViewMatrix().get3x3(matrix3f);
|
||||
this.spotDirection.set(newBuffer);
|
||||
this.spotDirection.mul(matrix3f);
|
||||
GL11.glLight(this.light, GL11.GL_SPOT_DIRECTION, newBuffer);
|
||||
@@ -152,7 +152,7 @@ public class LightState implements ISettableState<LightState> {
|
||||
|
||||
public void setSpotDirection(IntBuffer newBuffer) {
|
||||
vector3i.set(newBuffer);
|
||||
GLStateManager.getModelviewMatrix().get3x3(matrix3f);
|
||||
GLStateManager.getModelViewMatrix().get3x3(matrix3f);
|
||||
this.spotDirection.set((float) vector3i.x, (float) vector3i.y, (float) vector3i.z);
|
||||
this.spotDirection.mul(matrix3f);
|
||||
GL11.glLight(this.light, GL11.GL_SPOT_DIRECTION, newBuffer);
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.gtnewhorizons.angelica.glsm.states;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4i;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static com.gtnewhorizons.angelica.glsm.GLStateManager.i2f;
|
||||
|
||||
public class MaterialState implements ISettableState<MaterialState> {
|
||||
|
||||
private static final Vector4f vector4f = new Vector4f();
|
||||
private static final Vector4i vector4i = new Vector4i();
|
||||
private static final Vector3f vector3f = new Vector3f();
|
||||
private static final Vector3i vector3i = new Vector3i();
|
||||
|
||||
public int face;
|
||||
|
||||
public final Vector4f ambient;
|
||||
public final Vector4f diffuse;
|
||||
public final Vector4f specular;
|
||||
public final Vector4f emission;
|
||||
public float shininess;
|
||||
public final Vector3f colorIndexes;
|
||||
|
||||
public MaterialState(int face) {
|
||||
this.face = face;
|
||||
ambient = new Vector4f(0.2F, 0.2F, 0.2F, 1.0F);
|
||||
diffuse = new Vector4f(0.8F, 0.8F, 0.8F, 1.0F);
|
||||
specular = new Vector4f(0.0F, 0.0F, 0.0F, 1.0F);
|
||||
emission = new Vector4f(0.0F, 0.0F, 0.0F, 1.0F);
|
||||
shininess = 0.0F;
|
||||
colorIndexes = new Vector3f(0.0F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
public void setAmbient(FloatBuffer newBuffer) {
|
||||
vector4f.set(newBuffer);
|
||||
if (GLStateManager.shouldBypassCache() || !this.ambient.equals(vector4f)) {
|
||||
this.ambient.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_AMBIENT, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAmbient(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
vector4f.set(i2f(vector4i.x), i2f(vector4i.y), i2f(vector4i.z), i2f(vector4i.w));
|
||||
if (GLStateManager.shouldBypassCache() || !this.ambient.equals(vector4f)) {
|
||||
this.ambient.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_AMBIENT, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDiffuse(FloatBuffer newBuffer) {
|
||||
vector4f.set(newBuffer);
|
||||
if (GLStateManager.shouldBypassCache() || !this.diffuse.equals(vector4f)) {
|
||||
this.diffuse.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_DIFFUSE, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDiffuse(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
vector4f.set(i2f(vector4i.x), i2f(vector4i.y), i2f(vector4i.z), i2f(vector4i.w));
|
||||
if (GLStateManager.shouldBypassCache() || !this.diffuse.equals(vector4f)) {
|
||||
this.diffuse.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_DIFFUSE, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpecular(FloatBuffer newBuffer) {
|
||||
vector4f.set(newBuffer);
|
||||
if (GLStateManager.shouldBypassCache() || !this.specular.equals(vector4f)) {
|
||||
this.specular.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_SPECULAR, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpecular(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
vector4f.set(i2f(vector4i.x), i2f(vector4i.y), i2f(vector4i.z), i2f(vector4i.w));
|
||||
if (GLStateManager.shouldBypassCache() || !this.specular.equals(vector4f)) {
|
||||
this.specular.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_SPECULAR, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setEmission(FloatBuffer newBuffer) {
|
||||
vector4f.set(newBuffer);
|
||||
if (GLStateManager.shouldBypassCache() || !this.emission.equals(vector4f)) {
|
||||
this.emission.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_EMISSION, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setEmission(IntBuffer newBuffer) {
|
||||
vector4i.set(newBuffer);
|
||||
vector4f.set(i2f(vector4i.x), i2f(vector4i.y), i2f(vector4i.z), i2f(vector4i.w));
|
||||
if (GLStateManager.shouldBypassCache() || !this.emission.equals(vector4f)) {
|
||||
this.emission.set(vector4f);
|
||||
GL11.glMaterial(face, GL11.GL_EMISSION, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setShininess(float val) {
|
||||
if (GLStateManager.shouldBypassCache() || Float.compare(this.shininess, val) != 0) {
|
||||
this.shininess = val;
|
||||
GL11.glMaterialf(face, GL11.GL_SHININESS, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void setShininess(FloatBuffer newBuffer) { setShininess(newBuffer.get()); }
|
||||
|
||||
public void setShininess(IntBuffer newBuffer) { setShininess((float) newBuffer.get());}
|
||||
|
||||
public void setShininess(int val) { setShininess((float) val);}
|
||||
|
||||
public void setColorIndexes(FloatBuffer newBuffer) {
|
||||
// You are reading this correctly, nvidia drivers flip the y and z values in
|
||||
// glMaterial specifically for GL_COLOR_INDEXES. Other drivers do not do this.
|
||||
// This probably breaks things but who knows, GLSM is setup to track to what the
|
||||
// driver is doing for it right now.
|
||||
if (GLStateManager.isNVIDIA()) {
|
||||
vector3f.set(newBuffer.get(0), newBuffer.get(2), newBuffer.get(1));
|
||||
} else {
|
||||
vector3f.set(newBuffer);
|
||||
}
|
||||
|
||||
if (GLStateManager.shouldBypassCache() || !this.colorIndexes.equals(vector3f)) {
|
||||
this.colorIndexes.set(vector3f);
|
||||
GL11.glMaterial(face, GL11.GL_COLOR_INDEXES, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColorIndexes(IntBuffer newBuffer) {
|
||||
vector3i.set(newBuffer.get(0), newBuffer.get(2), newBuffer.get(1));
|
||||
vector3f.set((float) vector3i.x, (float) vector3i.y, (float) vector3i.z);
|
||||
if (GLStateManager.shouldBypassCache() || !this.colorIndexes.equals(vector3f)) {
|
||||
this.colorIndexes.set(vector3f);
|
||||
GL11.glMaterial(face, GL11.GL_COLOR_INDEXES, newBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialState set(MaterialState state) {
|
||||
this.ambient.set(state.ambient);
|
||||
this.diffuse.set(state.diffuse);
|
||||
this.specular.set(state.specular);
|
||||
this.emission.set(state.emission);
|
||||
this.shininess = state.shininess;
|
||||
this.colorIndexes.set(state.colorIndexes);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameAs(Object state) {
|
||||
if (this == state) return true;
|
||||
if (!(state instanceof MaterialState materialState)) return false;
|
||||
return this.ambient.equals(materialState.ambient)
|
||||
&& this.diffuse.equals(materialState.diffuse)
|
||||
&& this.specular.equals(materialState.specular)
|
||||
&& this.emission.equals(materialState.emission)
|
||||
&& Float.compare(materialState.shininess, this.shininess) == 0
|
||||
&& this.colorIndexes.equals(materialState.colorIndexes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialState copy() { return new MaterialState(this.face).set(this); }
|
||||
}
|
||||
@@ -3,9 +3,13 @@ package com.gtnewhorizons.angelica.hudcaching;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
|
||||
import com.gtnewhorizons.angelica.compat.ModStatus;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.mixins.early.angelica.hudcaching.RenderGameOverlayEventAccessor;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.GuiIngameAccessor;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.GuiIngameForgeAccessor;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.RenderGameOverlayEventAccessor;
|
||||
import com.kentington.thaumichorizons.common.ThaumicHorizons;
|
||||
import cpw.mods.fml.common.eventhandler.EventPriority;
|
||||
import net.dries007.holoInventory.client.Renderer;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
@@ -14,14 +18,8 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import com.gtnewhorizons.angelica.glsm.GLStateManager;
|
||||
import com.gtnewhorizons.angelica.glsm.TessellatorManager;
|
||||
import com.gtnewhorizons.angelica.mixins.early.angelica.hudcaching.GuiIngameAccessor;
|
||||
import com.gtnewhorizons.angelica.mixins.early.angelica.hudcaching.GuiIngameForgeAccessor;
|
||||
|
||||
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.gameevent.InputEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.GuiIngame;
|
||||
@@ -29,10 +27,9 @@ import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraftforge.client.GuiIngameForge;
|
||||
import thaumcraft.common.Thaumcraft;
|
||||
import xaero.common.core.XaeroMinimapCore;
|
||||
|
||||
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
|
||||
@@ -61,53 +58,14 @@ public class HUDCaching {
|
||||
// Crosshairs need to be blended with the scene
|
||||
public static boolean renderCrosshairsCaptured;
|
||||
|
||||
private static RenderGameOverlayEvent fakeHoloInventoryEvent = new RenderGameOverlayEvent.Pre(new RenderGameOverlayEvent(0, null, 0, 0), RenderGameOverlayEvent.ElementType.HELMET);
|
||||
private final static RenderGameOverlayEvent fakeTextEvent = new RenderGameOverlayEvent.Text(new RenderGameOverlayEvent(0, null, 0, 0), null, null);
|
||||
private final static RenderGameOverlayEvent fakePreEvent = new RenderGameOverlayEvent.Pre(new RenderGameOverlayEvent(0, null, 0, 0), RenderGameOverlayEvent.ElementType.HELMET);
|
||||
|
||||
public static final HUDCaching INSTANCE = new HUDCaching();
|
||||
|
||||
|
||||
private HUDCaching() {}
|
||||
|
||||
/* TODO START REMOVE DEBUG STUFF */
|
||||
|
||||
private final List<Long> updateTimeList = new ArrayList<>(21);
|
||||
private static boolean isEnabled = true;
|
||||
|
||||
// moved initialization to when its registered to avoid an empty Debug category, which can cause crashes when
|
||||
// opening the controls menu and hudcaching is disabled in the config
|
||||
private static KeyBinding toggle;
|
||||
|
||||
public static void registerKeyBindings() {
|
||||
toggle = new KeyBinding("Toggle HUDCaching", 0, "Debug");
|
||||
ClientRegistry.registerKeyBinding(toggle);
|
||||
}
|
||||
|
||||
// @SubscribeEvent
|
||||
// public void onFrame(RenderGameOverlayEvent.Post event) {
|
||||
// if (event.type == RenderGameOverlayEvent.ElementType.TEXT) {
|
||||
// final long currentTimeMillis = System.currentTimeMillis();
|
||||
// updateTimeList.removeIf(time -> currentTimeMillis - time > 1000L);
|
||||
// String text = EnumChatFormatting.GREEN + "HUD Fps : " + updateTimeList.size();
|
||||
// mc.fontRenderer.drawStringWithShadow(
|
||||
// text,
|
||||
// event.resolution.getScaledWidth() / 4,
|
||||
// event.resolution.getScaledHeight() / 4,
|
||||
// 0xFFFFFF);
|
||||
// updateTimeList.add(currentTimeMillis);
|
||||
// }
|
||||
// }
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeypress(InputEvent.KeyInputEvent event) {
|
||||
if (toggle != null && toggle.isPressed()) {
|
||||
isEnabled = !isEnabled;
|
||||
final String msg = isEnabled ? "Enabled HUDCaching" : "Disabled HUDCaching";
|
||||
if (mc.thePlayer != null) mc.thePlayer.addChatMessage(new ChatComponentText(msg));
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO END REMOVE DEBUG STUFF */
|
||||
|
||||
// highest so it runs before the GLSM load event
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public void onJoinWorld(WorldEvent.Load event) {
|
||||
@@ -120,13 +78,12 @@ public class HUDCaching {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void renderCachedHud(EntityRenderer renderer, GuiIngame ingame, float partialTicks, boolean hasScreen, int mouseX, int mouseY) {
|
||||
|
||||
if (ModStatus.isXaerosMinimapLoaded && ingame instanceof GuiIngameForge) {
|
||||
// this used to be called by asming into renderGameOverlay, but we removed it
|
||||
XaeroMinimapCore.beforeIngameGuiRender(partialTicks);
|
||||
}
|
||||
|
||||
if (!OpenGlHelper.isFramebufferEnabled() || !isEnabled || framebuffer == null) {
|
||||
if (!OpenGlHelper.isFramebufferEnabled() || framebuffer == null) {
|
||||
ingame.renderGameOverlay(partialTicks, hasScreen, mouseX, mouseY);
|
||||
return;
|
||||
}
|
||||
@@ -171,8 +128,8 @@ public class HUDCaching {
|
||||
if (ModStatus.isHoloInventoryLoaded){
|
||||
Renderer.INSTANCE.angelicaOverride = false;
|
||||
// only settings the partial ticks as mouseX and mouseY are not used in renderEvent
|
||||
((RenderGameOverlayEventAccessor) fakeHoloInventoryEvent).setPartialTicks(partialTicks);
|
||||
Renderer.INSTANCE.renderEvent(fakeHoloInventoryEvent);
|
||||
((RenderGameOverlayEventAccessor) fakePreEvent).setPartialTicks(partialTicks);
|
||||
Renderer.INSTANCE.renderEvent(fakePreEvent);
|
||||
}
|
||||
}
|
||||
if (renderPortalCapturedTicks > 0) {
|
||||
@@ -181,7 +138,18 @@ public class HUDCaching {
|
||||
if (renderCrosshairsCaptured) {
|
||||
guiForge.callRenderCrosshairs(width, height);
|
||||
}
|
||||
|
||||
if (ModStatus.isThaumcraftLoaded || ModStatus.isThaumicHorizonsLoaded){
|
||||
((RenderGameOverlayEventAccessor) fakeTextEvent).setPartialTicks(partialTicks);
|
||||
((RenderGameOverlayEventAccessor) fakeTextEvent).setResolution(resolution);
|
||||
((RenderGameOverlayEventAccessor) fakeTextEvent).setMouseX(mouseX);
|
||||
((RenderGameOverlayEventAccessor) fakeTextEvent).setMouseY(mouseY);
|
||||
if (ModStatus.isThaumcraftLoaded){
|
||||
Thaumcraft.instance.renderEventHandler.renderOverlay(fakeTextEvent);
|
||||
}
|
||||
if (ModStatus.isThaumicHorizonsLoaded){
|
||||
ThaumicHorizons.instance.renderEventHandler.renderOverlay(fakeTextEvent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (renderHelmetCaptured)
|
||||
{
|
||||
@@ -247,9 +215,15 @@ public class HUDCaching {
|
||||
|
||||
// moved to here due to the method being called from a mixin
|
||||
public static void disableHoloInventory() {
|
||||
if (ModStatus.isHoloInventoryLoaded){
|
||||
Renderer.INSTANCE.angelicaOverride = isEnabled;
|
||||
if (ModStatus.isHoloInventoryLoaded) {
|
||||
Renderer.INSTANCE.angelicaOverride = true;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") // called via ASM
|
||||
public static class HUDCachingHooks {
|
||||
public static boolean shouldReturnEarly() {
|
||||
return renderingCacheOverride;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,21 @@
|
||||
package com.gtnewhorizons.angelica.loading;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.gtnewhorizon.gtnhlib.asm.ASMUtil;
|
||||
import com.gtnewhorizon.gtnhlib.config.ConfigException;
|
||||
import com.gtnewhorizon.gtnhlib.config.ConfigurationManager;
|
||||
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.config.CompatConfig;
|
||||
import com.gtnewhorizons.angelica.mixins.Mixins;
|
||||
import com.gtnewhorizons.angelica.mixins.TargetedMod;
|
||||
import com.gtnewhorizons.angelica.transform.compat.CompatASMTransformers;
|
||||
import com.gtnewhorizons.angelica.transform.compat.GenericCompatTransformer;
|
||||
import com.gtnewhorizons.angelica.transform.compat.handlers.CompatHandler;
|
||||
import com.gtnewhorizons.angelica.transform.compat.handlers.CompatHandlers;
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
import jss.notfine.asm.AsmTransformers;
|
||||
import jss.notfine.asm.mappings.Namer;
|
||||
import jss.notfine.config.MCPatcherForgeConfig;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -21,17 +26,28 @@ import org.spongepowered.asm.launch.GlobalProperties;
|
||||
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
// ================== Important ==================
|
||||
// Due to a bug caused by this class both implementing
|
||||
// IFMLLoadingPlugin and IEarlyMixinLoader,
|
||||
// the IClassTransformer registered in this class
|
||||
// will not respect the sorting index defined.
|
||||
// They will instead use default index 0 which means they will see
|
||||
// obfuscated mappings and not SRG mappings when running outside of dev env.
|
||||
// ===============================================
|
||||
//@IFMLLoadingPlugin.SortingIndex(Integer.MAX_VALUE - 5)
|
||||
@IFMLLoadingPlugin.MCVersion("1.7.10")
|
||||
@IFMLLoadingPlugin.TransformerExclusions("com.gtnewhorizons.angelica.transform.RedirectorTransformer")
|
||||
@IFMLLoadingPlugin.SortingIndex(Integer.MAX_VALUE - 5)
|
||||
@IFMLLoadingPlugin.TransformerExclusions({
|
||||
"com.gtnewhorizons.angelica.transform.RedirectorTransformer",
|
||||
"com.gtnewhorizons.angelica.glsm.GLStateManager"})
|
||||
public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
|
||||
private static final boolean DUMP_CLASSES = Boolean.parseBoolean(System.getProperty("angelica.dumpClass", "false"));
|
||||
private static boolean OBF_ENV;
|
||||
public static final Logger LOGGER = LogManager.getLogger("Angelica");
|
||||
|
||||
private String[] transformerClasses;
|
||||
@@ -40,9 +56,11 @@ public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
try {
|
||||
// Angelica Config
|
||||
ConfigurationManager.registerConfig(AngelicaConfig.class);
|
||||
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||
Configuration config = ctx.getConfiguration();
|
||||
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
||||
ConfigurationManager.registerConfig(CompatConfig.class);
|
||||
MCPatcherForgeConfig.registerConfig();
|
||||
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||
final Configuration config = ctx.getConfiguration();
|
||||
final LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
||||
if (AngelicaConfig.enableDebugLogging) {
|
||||
loggerConfig.setLevel(Level.DEBUG);
|
||||
}
|
||||
@@ -59,21 +77,28 @@ public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
@Override
|
||||
public String[] getASMTransformerClass() {
|
||||
// Directly add this to the MixinServiceLaunchWrapper tweaker's list of Tweak Classes
|
||||
List<String> mixinTweakClasses = GlobalProperties.get(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKCLASSES);
|
||||
final List<String> mixinTweakClasses = GlobalProperties.get(MixinServiceLaunchWrapper.BLACKBOARD_KEY_TWEAKCLASSES);
|
||||
if (mixinTweakClasses != null) {
|
||||
mixinTweakClasses.add(MixinCompatHackTweaker.class.getName());
|
||||
}
|
||||
|
||||
// Return any others here
|
||||
if (transformerClasses == null) {
|
||||
final List<String> transformers = new ArrayList<>();
|
||||
|
||||
//Mod Compat transformers
|
||||
List<String> transformers = new ArrayList<String>();
|
||||
transformers.addAll(CompatASMTransformers.getTransformers());
|
||||
// Regsiter compat handlers, and add extra specific transformers, then build and register the generic transformer
|
||||
for (CompatHandler handler : CompatHandlers.getHandlers()) {
|
||||
GenericCompatTransformer.register(handler);
|
||||
if (handler.extraTransformers() != null) {
|
||||
transformers.addAll(handler.extraTransformers());
|
||||
}
|
||||
}
|
||||
|
||||
//NotFine transformers
|
||||
Namer.initNames();
|
||||
transformers.addAll(Arrays.asList(AsmTransformers.getTransformers()));
|
||||
GenericCompatTransformer.build();
|
||||
transformers.add(GenericCompatTransformer.class.getName());
|
||||
|
||||
// Add NotFine transformers
|
||||
final List<String> notFineTransformers = AsmTransformers.getTransformers();
|
||||
if (!notFineTransformers.isEmpty()) Namer.initNames();
|
||||
transformers.addAll(notFineTransformers);
|
||||
|
||||
transformerClasses = transformers.toArray(new String[0]);
|
||||
}
|
||||
@@ -92,7 +117,7 @@ public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
|
||||
@Override
|
||||
public void injectData(Map<String, Object> data) {
|
||||
// no-op
|
||||
OBF_ENV = (boolean) data.get("runtimeDeobfuscationEnabled");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,12 +132,27 @@ public class AngelicaTweaker implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
|
||||
@Override
|
||||
public List<String> getMixins(Set<String> loadedCoreMods) {
|
||||
// TODO: Sodium
|
||||
// mixins.addAll(getNotFineMixins(loadedCoreMods));
|
||||
// mixins.addAll(getArchaicMixins(loadedCoreMods));
|
||||
return Mixins.getEarlyMixins(loadedCoreMods);
|
||||
}
|
||||
|
||||
public static boolean DUMP_CLASSES() {
|
||||
return DUMP_CLASSES || !OBF_ENV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we are in an obfuscated environment, returns false in dev environment.
|
||||
*/
|
||||
public static boolean isObfEnv() {
|
||||
return OBF_ENV;
|
||||
}
|
||||
|
||||
public static void dumpClass(String className, byte[] originalBytes, byte[] transformedBytes, Object transformer) {
|
||||
if (AngelicaTweaker.DUMP_CLASSES()) {
|
||||
ASMUtil.saveAsRawClassFile(originalBytes, className + "_PRE", transformer);
|
||||
ASMUtil.saveAsRawClassFile(transformedBytes, className + "_POST", transformer);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ImmutableMap<String, TargetedMod> MODS_BY_CLASS = ImmutableMap.<String, TargetedMod>builder()
|
||||
.put("optifine.OptiFineForgeTweaker", TargetedMod.OPTIFINE)
|
||||
.put("fastcraft.Tweaker", TargetedMod.FASTCRAFT)
|
||||
|
||||
@@ -4,27 +4,36 @@ import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.transform.BlockTransformer;
|
||||
import com.gtnewhorizons.angelica.transform.RedirectorTransformer;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.relauncher.CoreModManager;
|
||||
import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import net.minecraft.launchwrapper.ITweaker;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
import org.spongepowered.asm.launch.platform.MixinContainer;
|
||||
import org.spongepowered.asm.launch.platform.MixinPlatformManager;
|
||||
import org.spongepowered.asm.launch.platform.container.IContainerHandle;
|
||||
import org.spongepowered.asm.mixin.transformer.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
|
||||
|
||||
public class MixinCompatHackTweaker implements ITweaker {
|
||||
public static final boolean DISABLE_OPTIFINE_AND_FASTCRAFT = true;
|
||||
public static final boolean DISABLE_OPTIFINE_FASTCRAFT_BETTERFPS = true;
|
||||
@Override
|
||||
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
||||
verifyDependencies();
|
||||
|
||||
if(DISABLE_OPTIFINE_AND_FASTCRAFT) {
|
||||
LOGGER.info("Disabling Optifine and Fastcraft (if present)");
|
||||
disableOptifineAndFastcraft();
|
||||
if(DISABLE_OPTIFINE_FASTCRAFT_BETTERFPS) {
|
||||
LOGGER.info("Disabling Optifine, Fastcraft, BetterFPS, and other incompatible mods (if present)");
|
||||
disableIncompatibleMods();
|
||||
}
|
||||
|
||||
if (AngelicaConfig.enableHudCaching){
|
||||
@@ -40,8 +49,8 @@ public class MixinCompatHackTweaker implements ITweaker {
|
||||
|
||||
private void disableXaerosMinimapWaypointTransformer(){
|
||||
try {
|
||||
LaunchClassLoader lcl = Launch.classLoader;
|
||||
Field xformersField = lcl.getClass().getDeclaredField("transformers");
|
||||
final LaunchClassLoader lcl = Launch.classLoader;
|
||||
final Field xformersField = lcl.getClass().getDeclaredField("transformers");
|
||||
xformersField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IClassTransformer> xformers = (List<IClassTransformer>) xformersField.get(lcl);
|
||||
@@ -57,17 +66,17 @@ public class MixinCompatHackTweaker implements ITweaker {
|
||||
}
|
||||
}
|
||||
|
||||
private void disableOptifineAndFastcraft() {
|
||||
// Remove Optifine and Fastcraft transformers & Mod Containers
|
||||
@SuppressWarnings("unchecked")
|
||||
private void disableIncompatibleMods() {
|
||||
// Remove transformers, Mod Containers, and mixins for Optifine, Fastcraft, BetterFPS and other incompatible mods
|
||||
try {
|
||||
LaunchClassLoader lcl = Launch.classLoader;
|
||||
Field xformersField = lcl.getClass().getDeclaredField("transformers");
|
||||
final LaunchClassLoader lcl = Launch.classLoader;
|
||||
final Field xformersField = lcl.getClass().getDeclaredField("transformers");
|
||||
xformersField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IClassTransformer> xformers = (List<IClassTransformer>) xformersField.get(lcl);
|
||||
final List<IClassTransformer> xformers = (List<IClassTransformer>) xformersField.get(lcl);
|
||||
for (int idx = xformers.size() - 1; idx >= 0; idx--) {
|
||||
final String name = xformers.get(idx).getClass().getName();
|
||||
if (name.startsWith("optifine") || name.startsWith("fastcraft")) {
|
||||
if (name.startsWith("optifine") || name.startsWith("fastcraft") || name.startsWith("me.guichaguri.betterfps")) {
|
||||
LOGGER.info("Removing transformer " + name);
|
||||
xformers.remove(idx);
|
||||
}
|
||||
@@ -76,17 +85,72 @@ public class MixinCompatHackTweaker implements ITweaker {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
Field injectedContainersField = Loader.class.getDeclaredField("injectedContainers");
|
||||
final Field injectedContainersField = Loader.class.getDeclaredField("injectedContainers");
|
||||
injectedContainersField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> containers = (List<String> ) injectedContainersField.get(Loader.class);
|
||||
final List<String> containers = (List<String> ) injectedContainersField.get(Loader.class);
|
||||
for (int idx = containers.size() - 1; idx >= 0; idx--) {
|
||||
final String name = containers.get(idx);
|
||||
final String name = containers.get(idx);
|
||||
if (name.startsWith("optifine") || name.startsWith("fastcraft")) {
|
||||
LOGGER.info("Removing mod container " + name);
|
||||
containers.remove(idx);
|
||||
}
|
||||
}
|
||||
|
||||
final Field reparsedCoremodsField = CoreModManager.class.getDeclaredField("reparsedCoremods");
|
||||
final Field loadedCoremodsField = CoreModManager.class.getDeclaredField("loadedCoremods");
|
||||
reparsedCoremodsField.setAccessible(true);
|
||||
loadedCoremodsField.setAccessible(true);
|
||||
final ArrayList<String> reparsedCoremods = (ArrayList<String>) reparsedCoremodsField.get(CoreModManager.class);
|
||||
final ArrayList<String> loadedCoremods = (ArrayList<String>) loadedCoremodsField.get(CoreModManager.class);
|
||||
for (int idx = reparsedCoremods.size() - 1; idx >= 0; idx--) {
|
||||
final String coreMod = reparsedCoremods.get(idx);
|
||||
if (coreMod.startsWith("optimizationsandtweaks")) {
|
||||
LOGGER.info("Removing reparsed coremod " + coreMod);
|
||||
// Fool the CoreModManager into not checking for a mod container again later
|
||||
loadedCoremods.add(reparsedCoremods.remove(idx));
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
final ArrayList<String> mixinConfigsDefault = (ArrayList<String>) Launch.blackboard.get("mixin.configs.default");
|
||||
if (mixinConfigsDefault != null) {
|
||||
for (int idx = mixinConfigsDefault.size() - 1; idx >= 0; idx--) {
|
||||
final String name = mixinConfigsDefault.get(idx);
|
||||
if (name != null && name.contains("optimizationsandtweaks")) {
|
||||
LOGGER.info("Removing mixin config " + name);
|
||||
mixinConfigsDefault.remove(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
final Set<Config> mixinConfigs = (Set<Config>) Launch.blackboard.get("mixin.configs.queue");
|
||||
final Set<Config> toRemove = new HashSet<>();
|
||||
if (mixinConfigs != null) {
|
||||
for (Config config : mixinConfigs) {
|
||||
final String name = config.getName();
|
||||
if (name != null && name.contains("optimizationsandtweaks")) {
|
||||
LOGGER.info("Removing queued mixin config " + config.getName());
|
||||
toRemove.add(config);
|
||||
}
|
||||
}
|
||||
mixinConfigs.removeAll(toRemove);
|
||||
}
|
||||
final MixinPlatformManager platformManager = (MixinPlatformManager) Launch.blackboard.get("mixin.platform");
|
||||
if (platformManager != null) {
|
||||
final Field containersField = platformManager.getClass().getDeclaredField("containers");
|
||||
containersField.setAccessible(true);
|
||||
final Map<IContainerHandle, MixinContainer> containers = (Map<IContainerHandle, MixinContainer>) containersField.get(platformManager);
|
||||
for (Map.Entry<IContainerHandle, MixinContainer> entry : containers.entrySet()) {
|
||||
final String attribute = entry.getKey().getAttribute("MixinConfigs");
|
||||
if(attribute != null && attribute.contains("optimizationsandtweaks")) {
|
||||
LOGGER.info("Removing mixin container " + entry.getKey().toString());
|
||||
containers.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.mixins;
|
||||
|
||||
import com.gtnewhorizons.angelica.AngelicaMod;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.config.CompatConfig;
|
||||
import com.gtnewhorizons.angelica.loading.AngelicaTweaker;
|
||||
import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
import jss.notfine.config.MCPatcherForgeConfig;
|
||||
@@ -26,9 +27,12 @@ public enum Mixins {
|
||||
.setPhase(Phase.EARLY).addMixinClasses(
|
||||
"angelica.MixinActiveRenderInfo"
|
||||
,"angelica.MixinEntityRenderer"
|
||||
,"angelica.MixinGameSettings"
|
||||
,"angelica.MixinMinecraft"
|
||||
,"angelica.MixinMinecraftServer"
|
||||
,"angelica.optimizations.MixinRendererLivingEntity"
|
||||
,"angelica.MixinFMLClientHandler"
|
||||
,"angelica.bugfixes.MixinRenderGlobal_DestroyBlock"
|
||||
)
|
||||
),
|
||||
ANGELICA_VBO(
|
||||
@@ -69,6 +73,16 @@ public enum Mixins {
|
||||
.setApplyIf(() -> AngelicaConfig.fixFluidRendererCheckingBlockAgain)
|
||||
.addTargetedMod(TargetedMod.VANILLA)),
|
||||
|
||||
ANGELICA_LIMIT_DROPPED_ITEM_ENTITIES(new Builder("Dynamically modifies the render distance of dropped items entities to preserve performance")
|
||||
.setPhase(Phase.EARLY).addMixinClasses("angelica.optimizations.MixinRenderGlobal_ItemRenderDist").setSide(Side.CLIENT)
|
||||
.setApplyIf(() -> AngelicaConfig.dynamicItemRenderDistance)
|
||||
.addTargetedMod(TargetedMod.VANILLA)),
|
||||
|
||||
ANGELICA_ITEM_DISPLAY_LIST_OPTIMIZATION(new Builder("Optimized item rendering by wrapping them with display lists")
|
||||
.setPhase(Phase.EARLY).addMixinClasses("angelica.itemrenderer.MixinItemRenderer").setSide(Side.CLIENT)
|
||||
.setApplyIf(() -> AngelicaConfig.optimizeInWorldItemRendering)
|
||||
.addTargetedMod(TargetedMod.VANILLA)),
|
||||
|
||||
// Not compatible with the lwjgl debug callbacks, so disable if that's enabled
|
||||
ARCHAIC_SPLASH(new Builder("ArchaicFix Splash").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.showSplashMemoryBar && !AngelicaMod.lwjglDebug).addMixinClasses(
|
||||
@@ -100,15 +114,15 @@ public enum Mixins {
|
||||
|
||||
SODIUM(new Builder("Sodium").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableSodium).addMixinClasses(
|
||||
"sodium.MixinChunkProviderClient"
|
||||
,"sodium.MixinBlock"
|
||||
"sodium.MixinBlock"
|
||||
,"sodium.MixinBlockFluidBase"
|
||||
,"sodium.AccessorBiomeColorEvent"
|
||||
,"sodium.MixinBiomeGenBase"
|
||||
,"sodium.MixinChunk"
|
||||
,"sodium.MixinChunkProviderServer"
|
||||
,"sodium.MixinClientRegistry"
|
||||
,"sodium.MixinEntity"
|
||||
,"sodium.MixinEntity_RenderDist"
|
||||
,"sodium.MixinEntityItem_RenderDist"
|
||||
,"sodium.MixinRenderManager"
|
||||
,"sodium.MixinExtendedBlockStorage"
|
||||
,"sodium.MixinEntityRenderer"
|
||||
@@ -122,7 +136,6 @@ public enum Mixins {
|
||||
,"sodium.MixinRenderBlocks"
|
||||
,"sodium.MixinRenderGlobal"
|
||||
,"sodium.MixinWorldClient"
|
||||
,"sodium.MixinTessellator"
|
||||
,"sodium.MixinTileEntity"
|
||||
,"sodium.MixinEffectRenderer"
|
||||
,"sodium.MixinTileEntityRendererDispatcher"
|
||||
@@ -132,37 +145,30 @@ public enum Mixins {
|
||||
)
|
||||
),
|
||||
|
||||
// Required for Sodium's FluidRenderer, so it treats vanilla liquids as IFluidBlocks
|
||||
SODIUM_WISHLIST(new Builder("Sodiumer").addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableSodiumFluidRendering).addMixinClasses(
|
||||
"sodium.MixinBlockLiquid")),
|
||||
|
||||
IRIS_RENDERING(new Builder("Iris Shaders").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableIris).addMixinClasses(
|
||||
"shaders.MixinEntityRenderer"
|
||||
,"shaders.MixinGuiIngameForge"
|
||||
,"shaders.MixinFramebuffer"
|
||||
,"shaders.MixinItem"
|
||||
,"shaders.MixinItemRenderer"
|
||||
,"shaders.MixinLocale"
|
||||
,"shaders.MixinOpenGlHelper"
|
||||
,"shaders.MixinRender"
|
||||
,"shaders.MixinRenderDragon"
|
||||
,"shaders.MixinRenderEnderman"
|
||||
,"shaders.MixinRendererLivingEntity"
|
||||
,"shaders.MixinRenderGlobal"
|
||||
,"shaders.MixinRenderSpider"
|
||||
,"shaders.MixinTileEntityBeaconRenderer"
|
||||
)
|
||||
),
|
||||
|
||||
IRIS_ACCESSORS(new Builder("Iris Accessors").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableIris).addMixinClasses(
|
||||
"shaders.accessors.MinecraftAccessor"
|
||||
,"shaders.accessors.EntityRendererAccessor"
|
||||
,"shaders.accessors.SimpleTextureAccessor"
|
||||
,"shaders.accessors.TextureAtlasSpriteAccessor"
|
||||
,"shaders.accessors.TextureMapAccessor"
|
||||
,"shaders.accessors.AnimationMetadataSectionAccessor"
|
||||
"shaders.accessors.MixinMinecraft"
|
||||
,"shaders.accessors.MixinEntityRenderer"
|
||||
,"shaders.accessors.MixinSimpleTexture"
|
||||
,"shaders.accessors.MixinTextureAtlasSprite"
|
||||
,"shaders.accessors.MixinTextureMap"
|
||||
,"shaders.accessors.MixinAnimationMetadataSection"
|
||||
)
|
||||
),
|
||||
|
||||
@@ -172,12 +178,20 @@ public enum Mixins {
|
||||
,"angelica.textures.MixinTextureUtil"
|
||||
)),
|
||||
|
||||
ANGELICA_ZOOM(new Builder("Zoom").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableZoom)
|
||||
.addMixinClasses(
|
||||
"angelica.zoom.MixinEntityRenderer_Zoom",
|
||||
"angelica.zoom.MixinMinecraft_Zoom",
|
||||
"angelica.zoom.MixinMouseFilter"
|
||||
)),
|
||||
|
||||
HUD_CACHING(new Builder("Renders the HUD elements 20 times per second maximum to improve performance")
|
||||
.addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableHudCaching).addMixinClasses(
|
||||
"angelica.hudcaching.GuiIngameAccessor",
|
||||
"angelica.hudcaching.GuiIngameForgeAccessor",
|
||||
"angelica.hudcaching.RenderGameOverlayEventAccessor",
|
||||
"angelica.hudcaching.MixinGuiIngame",
|
||||
"angelica.hudcaching.MixinGuiIngameForge",
|
||||
"angelica.hudcaching.MixinRenderGameOverlayEvent",
|
||||
"angelica.hudcaching.MixinEntityRenderer_HUDCaching",
|
||||
"angelica.hudcaching.MixinFramebuffer_HUDCaching",
|
||||
"angelica.hudcaching.MixinGuiIngame_HUDCaching",
|
||||
@@ -206,7 +220,7 @@ public enum Mixins {
|
||||
|
||||
EXTRA_UTILITIES_THREAD_SAFETY(new Builder("Enable thread safety fixes in Extra Utilities").setPhase(Phase.LATE)
|
||||
.addTargetedMod(TargetedMod.EXTRAUTILS).setSide(Side.CLIENT)
|
||||
.setApplyIf(() -> AngelicaConfig.fixExtraUtilsSodiumCompat)
|
||||
.setApplyIf(() -> CompatConfig.fixExtraUtils)
|
||||
.addMixinClasses(
|
||||
"client.extrautils.MixinRenderBlockConnectedTextures",
|
||||
"client.extrautils.MixinRenderBlockConnectedTexturesEthereal",
|
||||
@@ -214,7 +228,7 @@ public enum Mixins {
|
||||
|
||||
MFR_THREAD_SAFETY(new Builder("Enable thread safety fixes for MineFactory Reloaded").setPhase(Phase.LATE)
|
||||
.addTargetedMod(TargetedMod.MINEFACTORY_RELOADED).setSide(Side.CLIENT)
|
||||
.setApplyIf(() -> AngelicaConfig.fixMineFactoryReloadedSodiumCompat)
|
||||
.setApplyIf(() -> CompatConfig.fixMinefactoryReloaded)
|
||||
.addMixinClasses("client.minefactoryreloaded.MixinRedNetCableRenderer")),
|
||||
|
||||
SPEEDUP_CAMPFIRE_BACKPORT_ANIMATIONS(new Builder("Add animation speedup support to Campfire Backport").setPhase(Phase.LATE)
|
||||
@@ -293,7 +307,7 @@ public enum Mixins {
|
||||
),
|
||||
NOTFINE_NO_CUSTOM_ITEM_TEXTURES(new Builder("NotFine no Custom Item Textures")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> !AngelicaConfig.enableMCPatcherForgeFeatures || !MCPatcherForgeConfig.instance().customItemTexturesEnabled)
|
||||
.setApplyIf(() -> !AngelicaConfig.enableMCPatcherForgeFeatures || !MCPatcherForgeConfig.CustomItemTextures.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("notfine.glint.",
|
||||
"MixinItemRenderer",
|
||||
@@ -377,7 +391,7 @@ public enum Mixins {
|
||||
),
|
||||
MCPATCHER_FORGE_CUSTOM_COLORS(new Builder("MCP:F Custom Colors")
|
||||
.setSide(Mixins.Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().customColorsEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.CustomColors.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("mcpatcherforge.cc.",
|
||||
"block.material.MixinMapColor",
|
||||
@@ -433,7 +447,7 @@ public enum Mixins {
|
||||
),
|
||||
MCPATCHER_FORGE_CUSTOM_ITEM_TEXTURES(new Builder("MCP:F Custom Item Textures")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().customItemTexturesEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.CustomItemTextures.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("mcpatcherforge.cit.",
|
||||
"client.renderer.entity.MixinRenderBiped",
|
||||
@@ -452,13 +466,13 @@ public enum Mixins {
|
||||
),
|
||||
MCPATCHER_FORGE_CONNECTED_TEXTURES(new Builder("MCP:F Connected Textures")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().connectedTexturesEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.ConnectedTextures.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses("mcpatcherforge.ctm.MixinRenderBlocks")
|
||||
),
|
||||
MCPATCHER_FORGE_EXTENDED_HD(new Builder("MCP:F Extended hd")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().extendedHDEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.ExtendedHD.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("mcpatcherforge.hd.",
|
||||
"MixinTextureClock",
|
||||
@@ -468,14 +482,14 @@ public enum Mixins {
|
||||
),
|
||||
MCPATCHER_FORGE_EXTENDED_HD_FONT(new Builder("MCP:F Extended HD Font")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> (AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().extendedHDEnabled && MCPatcherForgeConfig.instance().hdFont))
|
||||
.setApplyIf(() -> (AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.ExtendedHD.enabled && MCPatcherForgeConfig.ExtendedHD.hdFont))
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addExcludedMod(TargetedMod.COFHCORE)
|
||||
.addMixinClasses("mcpatcherforge.hd.MixinFontRenderer")
|
||||
),
|
||||
MCPATCHER_FORGE_RANDOM_MOBS(new Builder("MCP:F Random Mobs")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().randomMobsEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.RandomMobs.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("mcpatcherforge.mob.",
|
||||
"MixinRender",
|
||||
@@ -492,7 +506,7 @@ public enum Mixins {
|
||||
),
|
||||
MCPATCHER_FORGE_SKY(new Builder("MCP:F Sky")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.instance().betterSkiesEnabled)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures && MCPatcherForgeConfig.BetterSkies.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(addPrefix("mcpatcherforge.sky.",
|
||||
"MixinEffectRenderer",
|
||||
@@ -502,47 +516,45 @@ public enum Mixins {
|
||||
MCPATCHER_FORGE_CC_NO_CTM(new Builder("MCP:F Custom Colors, no Connected Textures")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
|
||||
&& !MCPatcherForgeConfig.instance().connectedTexturesEnabled
|
||||
&& MCPatcherForgeConfig.instance().customColorsEnabled)
|
||||
&& !MCPatcherForgeConfig.ConnectedTextures.enabled
|
||||
&& MCPatcherForgeConfig.CustomColors.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses("mcpatcherforge.cc_ctm.MixinRenderBlocksNoCTM")
|
||||
),
|
||||
MCPATCHER_FORGE_CTM_NO_CC(new Builder("MCP:F Connected Textures, no Custom Colours")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
|
||||
&& MCPatcherForgeConfig.instance().connectedTexturesEnabled
|
||||
&& !MCPatcherForgeConfig.instance().customColorsEnabled)
|
||||
&& MCPatcherForgeConfig.ConnectedTextures.enabled
|
||||
&& !MCPatcherForgeConfig.CustomColors.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses("mcpatcherforge.ctm_cc.MixinRenderBlocksNoCC")
|
||||
),
|
||||
MCPATCHER_FORGE_CTM_AND_CC(new Builder("MCP:F Connected Textures and Custom Colors")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
|
||||
&& MCPatcherForgeConfig.instance().connectedTexturesEnabled
|
||||
&& MCPatcherForgeConfig.instance().customColorsEnabled)
|
||||
&& MCPatcherForgeConfig.ConnectedTextures.enabled
|
||||
&& MCPatcherForgeConfig.CustomColors.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses("mcpatcherforge.ctm_cc.MixinRenderBlocks")
|
||||
),
|
||||
MCPATCHER_FORGE_CTM_OR_CC(new Builder("MCP:F Connected Textures or Custom Colors")
|
||||
.setSide(Side.CLIENT).setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.enableMCPatcherForgeFeatures
|
||||
&& MCPatcherForgeConfig.instance().connectedTexturesEnabled
|
||||
|| MCPatcherForgeConfig.instance().customColorsEnabled)
|
||||
&& MCPatcherForgeConfig.ConnectedTextures.enabled
|
||||
|| MCPatcherForgeConfig.CustomColors.enabled)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses("mcpatcherforge.ctm_cc.MixinTextureMap")
|
||||
),
|
||||
//End from NotFine
|
||||
|
||||
NOVIS_OCULIS(new Builder("Non-Tessellator Quad provider")
|
||||
QPR(new Builder("Adds a QuadProvider field to blocks without populating it")
|
||||
.setSide(Side.CLIENT)
|
||||
.setPhase(Phase.EARLY)
|
||||
.setApplyIf(() -> AngelicaConfig.injectQPRendering)
|
||||
.setApplyIf(() -> true)
|
||||
.addTargetedMod(TargetedMod.VANILLA)
|
||||
.addMixinClasses(
|
||||
"angelica.models.MixinBlockStone",
|
||||
"angelica.models.MixinBlockAir",
|
||||
"angelica.models.MixinBlockWorkbench",
|
||||
"angelica.models.MixinBlockLeaves")),
|
||||
"angelica.models.MixinBlock",
|
||||
"angelica.models.MixinBlockOldLeaf")),
|
||||
|
||||
;
|
||||
|
||||
@@ -572,7 +584,7 @@ public enum Mixins {
|
||||
NotFineConfig.loadSettings();
|
||||
//This may be possible to handle differently or fix.
|
||||
if(loadedCoreMods.contains("cofh.asm.LoadingPlugin")) {
|
||||
MCPatcherForgeConfig.instance().hdFont = false;
|
||||
MCPatcherForgeConfig.ExtendedHD.hdFont = false;
|
||||
}
|
||||
final List<String> mixins = new ArrayList<>();
|
||||
final List<String> notLoading = new ArrayList<>();
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft {
|
||||
|
||||
@Inject(
|
||||
method = "runGameLoop",
|
||||
at = @At(value = "INVOKE", target = "Lcpw/mods/fml/common/FMLCommonHandler;onRenderTickEnd(F)V", shift = At.Shift.AFTER, remap = false)
|
||||
)
|
||||
private void angelica$injectLightingFixPostRenderTick(CallbackInfo ci) {
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.hudcaching;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.gui.GuiIngame;
|
||||
|
||||
@Mixin(GuiIngame.class)
|
||||
public interface GuiIngameAccessor {
|
||||
@Invoker
|
||||
void callRenderVignette(float brightness, int width, int height);
|
||||
|
||||
@Invoker
|
||||
void callRenderPumpkinBlur(int width, int height);
|
||||
|
||||
@Invoker("func_130015_b")
|
||||
void callRenderPortal(float partialTicks, int width, int height);
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.hudcaching;
|
||||
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.event.terraingen.BiomeEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(RenderGameOverlayEvent.class)
|
||||
public interface RenderGameOverlayEventAccessor {
|
||||
@Accessor(value = "partialTicks", remap = false)
|
||||
void setPartialTicks(float value);
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockAir.class)
|
||||
public abstract class MixinBlockAir implements QuadProvider {
|
||||
|
||||
@Unique
|
||||
private static final List<QuadView> angelica$EMPTY = ObjectImmutableList.of();
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return angelica$EMPTY;
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLeaves;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.gtnewhorizons.angelica.models.CubeModel.INSTANCE;
|
||||
|
||||
@Mixin(BlockLeaves.class)
|
||||
public abstract class MixinBlockLeaves extends Block implements QuadProvider {
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
|
||||
private MixinBlockLeaves(Material materialIn) {
|
||||
super(materialIn);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.VanillaModels;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockStone;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockStone.class)
|
||||
public abstract class MixinBlockStone implements QuadProvider {
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return VanillaModels.stoneModel.getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.CubeModel;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockWorkbench;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockWorkbench.class)
|
||||
public class MixinBlockWorkbench implements QuadProvider {
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return CubeModel.INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.vbo;
|
||||
|
||||
import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.DefaultVertexFormat;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
import com.gtnewhorizons.angelica.glsm.TessellatorManager;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.IModelCustomExt;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraftforge.client.model.obj.GroupObject;
|
||||
import net.minecraftforge.client.model.obj.WavefrontObject;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
@Mixin(value = WavefrontObject.class, remap = false)
|
||||
public abstract class MixinWavefrontObject implements IModelCustomExt {
|
||||
@Unique private VertexBuffer vertexBuffer;
|
||||
|
||||
@Shadow private GroupObject currentGroupObject;
|
||||
|
||||
@Shadow public abstract void tessellateAll(Tessellator tessellator);
|
||||
|
||||
@Unique VertexFormat format = DefaultVertexFormat.POSITION_TEXTURE_NORMAL;
|
||||
|
||||
@Override
|
||||
public void rebuildVBO() {
|
||||
if(currentGroupObject == null) {
|
||||
throw new RuntimeException("No group object selected");
|
||||
}
|
||||
if (this.vertexBuffer != null) {
|
||||
this.vertexBuffer.close();
|
||||
}
|
||||
TessellatorManager.startCapturing();
|
||||
final CapturingTessellator tess = (CapturingTessellator) TessellatorManager.get();
|
||||
tess.startDrawing(currentGroupObject.glDrawingMode);
|
||||
tessellateAll(tess);
|
||||
|
||||
this.vertexBuffer = TessellatorManager.stopCapturingToVBO(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAllVBO() {
|
||||
if(vertexBuffer == null) {
|
||||
rebuildVBO();
|
||||
}
|
||||
vertexBuffer.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author mitchej123
|
||||
* @reason Force all models to use VBOs
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Overwrite
|
||||
public void renderAll() {
|
||||
renderAllVBO();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.shaders;
|
||||
|
||||
import net.coderbot.iris.gbuffer_overrides.matching.SpecialCondition;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.minecraft.client.renderer.entity.RenderDragon;
|
||||
import net.minecraft.entity.boss.EntityDragon;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RenderDragon.class)
|
||||
public class MixinRenderDragon {
|
||||
@Inject(method = "Lnet/minecraft/client/renderer/entity/RenderDragon;shouldRenderPass(Lnet/minecraft/entity/boss/EntityDragon;IF)I", at = @At(value="RETURN", ordinal = 1))
|
||||
private void onShouldRenderPass(EntityDragon entity, int pass, float partialTicks, CallbackInfoReturnable<Integer> cir) {
|
||||
GbufferPrograms.setupSpecialRenderCondition(SpecialCondition.ENTITY_EYES);
|
||||
}
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.shaders;
|
||||
|
||||
import net.coderbot.iris.gbuffer_overrides.matching.SpecialCondition;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.minecraft.client.renderer.entity.RenderEnderman;
|
||||
import net.minecraft.entity.monster.EntityEnderman;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RenderEnderman.class)
|
||||
public class MixinRenderEnderman {
|
||||
@Inject(method = "Lnet/minecraft/client/renderer/entity/RenderEnderman;shouldRenderPass(Lnet/minecraft/entity/monster/EntityEnderman;IF)I", at = @At(value="RETURN", ordinal = 1))
|
||||
private void onShouldRenderPass(EntityEnderman entity, int pass, float partialTicks, CallbackInfoReturnable<Integer> cir) {
|
||||
GbufferPrograms.setupSpecialRenderCondition(SpecialCondition.ENTITY_EYES);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.shaders;
|
||||
|
||||
import net.coderbot.iris.gbuffer_overrides.matching.SpecialCondition;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.minecraft.client.renderer.entity.RenderSpider;
|
||||
import net.minecraft.entity.monster.EntitySpider;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RenderSpider.class)
|
||||
public class MixinRenderSpider {
|
||||
@Inject(method = "Lnet/minecraft/client/renderer/entity/RenderSpider;shouldRenderPass(Lnet/minecraft/entity/monster/EntitySpider;IF)I", at = @At(value="RETURN", ordinal = 1))
|
||||
private void onShouldRenderPass(EntitySpider entity, int pass, float partialTicks, CallbackInfoReturnable<Integer> cir) {
|
||||
GbufferPrograms.setupSpecialRenderCondition(SpecialCondition.ENTITY_EYES);
|
||||
}
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.shaders;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.coderbot.iris.layer.GbufferPrograms;
|
||||
import net.coderbot.iris.uniforms.CapturedRenderingState;
|
||||
import net.minecraft.client.renderer.entity.RendererLivingEntity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RendererLivingEntity.class)
|
||||
public class MixinRendererLivingEntity {
|
||||
|
||||
@WrapOperation(
|
||||
method="doRender",
|
||||
at=@At(value="INVOKE", target="Lnet/minecraft/client/renderer/entity/RendererLivingEntity;getColorMultiplier(Lnet/minecraft/entity/EntityLivingBase;FF)I")
|
||||
)
|
||||
private int iris$setEntityColor(RendererLivingEntity instance, EntityLivingBase elb, float f0, float f1, Operation<Integer> original) {
|
||||
final int j = original.call(instance, elb, f0, f1);
|
||||
final float a = (j >> 24 & 255) / 255.0F;
|
||||
final float r = (j >> 16 & 255) / 255.0F;
|
||||
final float g = (j >> 8 & 255) / 255.0F;
|
||||
final float b = (j & 255) / 255.0F;
|
||||
CapturedRenderingState.INSTANCE.setCurrentEntityColor(r, g, b, 1.0F - a);
|
||||
return j;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method="Lnet/minecraft/client/renderer/entity/RendererLivingEntity;doRender(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V", at=@At(value="INVOKE",
|
||||
target="Lnet/minecraft/client/renderer/entity/RendererLivingEntity;renderEquippedItems(Lnet/minecraft/entity/EntityLivingBase;F)V", shift=At.Shift.BEFORE)
|
||||
)
|
||||
private void iris$teardownSpecialRenderConditions(EntityLivingBase entity, double x, double y, double z, float entityYaw, float partialTicks, CallbackInfo ci) {
|
||||
GbufferPrograms.teardownSpecialRenderCondition();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.sodium;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.IFluidBlock;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(BlockLiquid.class)
|
||||
public abstract class MixinBlockLiquid implements IFluidBlock {
|
||||
|
||||
@Shadow
|
||||
public abstract int getBlockColor();
|
||||
|
||||
@Override
|
||||
public Fluid getFluid() {
|
||||
return ((Block) (Object) this).getMaterial() == Material.water ? FluidRegistry.WATER : FluidRegistry.LAVA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFilledPercentage(World world, int x, int y, int z) {
|
||||
return getFluid() == null ? 0 : 1 - BlockLiquid.getLiquidHeightPercent(world.getBlockMetadata(x, y, z));
|
||||
}
|
||||
}
|
||||
Loaded 100 of 572 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user