Compare commits

..
75 changed files with 3518 additions and 651 deletions

No files matched your search

+2
View File
@@ -36,3 +36,5 @@ addon.local.gradle
addon.local.gradle.kts
addon.late.local.gradle
addon.late.local.gradle.kts
/*.csv
!gl_functions.csv
+4 -4
View File
@@ -8,19 +8,19 @@
* It's the angel that pulls you out of OptiFine's hell -Roadhog360
## **Beta Quality - Here there be Dragons**
* Shaders - Beta
* 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
# Required Dependencies
* [UniMixins](https://github.com/LegacyModdingMC/UniMixins/releases) >= 0.1.19
* [GTNHLib](https://github.com/GTNewHorizons/GTNHLib/releases) >= 0.5.20
* [UniMixins](https://github.com/LegacyModdingMC/UniMixins/releases) >= 0.1.14
* [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
* Forge Relocation - Currently non Thread Safe; safe if not in use
* ProjectRed Frames - Currently non Thread Safe; safe if not in use
* ProjectRed Frames - Currently non Thread Safe; safe if not in use'
# Potential Incompatibilities
* EndlessIDs - Compat commits have been made, might work, might not - not fully tested
+21 -17
View File
@@ -49,19 +49,19 @@ configurations {
}
dependencies {
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.6.23")
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.5.78")
compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:1.0.7") { transitive = false }
compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:0.4.0") { transitive = false }
compileOnly("org.projectlombok:lombok:1.18.34") { transitive = false }
annotationProcessor("org.projectlombok:lombok:1.18.34")
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.8.0:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:TX-Loader:1.7.2:dev')
// Iris Shaders
compileOnly('org.jetbrains:annotations:26.0.2')
api("com.github.GTNewHorizons:GTNHLib:0.6.8:dev")
compileOnly('org.jetbrains:annotations:24.0.1')
api("com.github.GTNewHorizons:GTNHLib:0.5.20:dev")
shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0
shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-4.g6b42bca") {
exclude module: "antlr4" // we only want to shadow the runtime module
@@ -70,21 +70,21 @@ dependencies {
compileOnly "org.apache.ant:ant:1.8.2"
// Because who doesn't want NEI
devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.7.27-GTNH:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.4.1: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")
devOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")
compileOnly("com.github.GTNewHorizons:twilightforest:2.7.4:dev") { transitive = false }
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.13.8-GTNH:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:Natura:2.8.2: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:ThaumicHorizons:1.7.1:dev")
compileOnly("com.github.GTNewHorizons:ThaumicHorizons:1.6.4:dev")
compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.2:dev") { transitive = false }
compileOnly('com.github.GTNewHorizons:Backhand:1.6.9') { 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 }
compileOnly("com.falsepattern:endlessids-mc1.7.10:1.5-beta0003:dev") { transitive = false }
@@ -100,7 +100,7 @@ dependencies {
compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675"))
compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684"))
compileOnly("com.github.GTNewHorizons:HoloInventory:2.5.0-GTNH:dev")
compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.13-GTNH:dev")
runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2"))
@@ -111,8 +111,12 @@ dependencies {
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.0-GTNH:dev")
// Tests
testImplementation(platform('org.junit:junit-bom:5.11.4'))
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
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+1 -1
View File
@@ -16,5 +16,5 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.32'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.29'
}
+120
View File
@@ -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, "");
}
}
+135
View File
@@ -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, "");
}
}
@@ -16,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.6.6,);",
+ " after:archaicfix@[0.7.0,);" + " required-after:gtnhlib@[0.4.2,);",
acceptedMinecraftVersions = "[1.7.10]",
acceptableRemoteVersions = "*",
guiFactory = "com.gtnewhorizons.angelica.config.AngelicaGuiConfigFactory")
@@ -1,27 +0,0 @@
package com.gtnewhorizons.angelica.api;
import com.gtnewhorizons.angelica.mixins.interfaces.IPatchedTextureAtlasSprite;
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.util.IIcon;
/**
* Exposes a method to the API that allow mods to add texture update compat
*/
@SuppressWarnings("unused")
public class TextureServices {
@SuppressWarnings("unused")
public static void updateBlockTextureAnimation(IIcon icon, RenderBlocks renderBlocks) {
if (renderBlocks instanceof ITexturesCache texturesCache) {
texturesCache.getRenderedTextures().add(icon);
}
}
@SuppressWarnings("unused")
public static void updateTextureAnimation(IIcon icon) {
if(icon instanceof IPatchedTextureAtlasSprite patchedSprite) {
patchedSprite.markNeedsAnimationUpdate();
}
}
}
@@ -1,7 +1,6 @@
package com.gtnewhorizons.angelica.client.font;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.FontRendererAccessor;
import it.unimi.dsi.fastutil.chars.Char2ShortOpenHashMap;
@@ -11,6 +10,7 @@ import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.nio.ByteBuffer;
@@ -97,10 +97,10 @@ public class BatchingFontRenderer {
private static final int INITIAL_BATCH_SIZE = 256;
private static final ResourceLocation DUMMY_RESOURCE_LOCATION = new ResourceLocation("angelica$dummy",
"this is invalid!");
private FloatBuffer batchVtxPositions = memAllocFloat(INITIAL_BATCH_SIZE * 2);
private ByteBuffer batchVtxColors = memAlloc(INITIAL_BATCH_SIZE * 4);
private FloatBuffer batchVtxTexCoords = memAllocFloat(INITIAL_BATCH_SIZE * 2);
private IntBuffer batchIndices = memAllocInt(INITIAL_BATCH_SIZE / 2 * 3);
private FloatBuffer batchVtxPositions = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private ByteBuffer batchVtxColors = BufferUtils.createByteBuffer(INITIAL_BATCH_SIZE * 4);
private FloatBuffer batchVtxTexCoords = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private IntBuffer batchIndices = BufferUtils.createIntBuffer(INITIAL_BATCH_SIZE / 2 * 3);
private final ObjectArrayList<FontDrawCmd> batchCommands = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
private final ObjectArrayList<FontDrawCmd> batchCommandPool = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
@@ -109,12 +109,12 @@ public class BatchingFontRenderer {
final int oldCap = batchVtxPositions.capacity() / 2;
if (vtxWriterIndex >= oldCap) {
final int newCap = oldCap * 2;
batchVtxPositions = memRealloc(batchVtxPositions, newCap * 2);
batchVtxColors = memRealloc(batchVtxColors, newCap * 4);
batchVtxTexCoords = memRealloc(batchVtxTexCoords, newCap * 2);
batchVtxPositions = CompatMemoryUtil.memReallocDirect(batchVtxPositions, newCap * 2);
batchVtxColors = CompatMemoryUtil.memReallocDirect(batchVtxColors, newCap * 4);
batchVtxTexCoords = CompatMemoryUtil.memReallocDirect(batchVtxTexCoords, newCap * 2);
final int oldIdxCap = batchIndices.capacity();
final int newIdxCap = oldIdxCap * 2;
batchIndices = memRealloc(batchIndices, newIdxCap);
batchIndices = CompatMemoryUtil.memReallocDirect(batchIndices, newIdxCap);
}
final int idx = vtxWriterIndex;
final int idx2 = idx * 2;
@@ -437,6 +437,8 @@ public class BatchingFontRenderer {
chr = MCFONT_CHARS.charAt(lutIndex);
}
final float shadowOffset = unicodeFlag ? 0.5F : 1.0F;
// Check ASCII space, NBSP, NNBSP
if (chr == ' ' || chr == '\u00A0' || chr == '\u202F') {
curX += 4;
@@ -450,7 +452,6 @@ public class BatchingFontRenderer {
final float uSz;
final float vSz;
final float itOff = curItalic ? 1.0F : 0.0F; // italic offset
final float shadowOffset;
final ResourceLocation texture;
if (lutIndex == -1 || unicodeFlag) {
@@ -458,7 +459,6 @@ public class BatchingFontRenderer {
continue;
}
// Draw unicode char
shadowOffset = 0.5F;
final int uniPage = chr / 256;
texture = getUnicodePageLocation(uniPage);
final int startColumn = this.glyphWidth[chr] >>> 4;
@@ -475,7 +475,6 @@ public class BatchingFontRenderer {
} else {
// Draw "ASCII" char
shadowOffset = 1.0F;
uStart = ((lutIndex % 16) * 8) / 128.0F;
vStart = (float) ((lutIndex / 16) * 8) / 128.0F;
xAdvance = this.charWidth[lutIndex];
@@ -62,7 +62,7 @@ public class ModStatus {
}
if (isBackhandLoaded){
isBackhandLoaded = new DefaultArtifactVersion("1.6.9")
isBackhandLoaded = new DefaultArtifactVersion("1.4.1")
.compareTo(
LoadControllerHelper.getOwningMod(Backhand.class).getProcessedVersion()
) <= 0;
@@ -0,0 +1,327 @@
package com.gtnewhorizons.angelica.compat.lwjgl;
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();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static IntBuffer memReallocDirect(IntBuffer old, int capacity) {
IntBuffer newBuf = BufferUtils.createIntBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static FloatBuffer memReallocDirect(FloatBuffer old, int capacity) {
FloatBuffer newBuf = BufferUtils.createFloatBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
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);
/**
* Sets all bytes in a specified block of memory to a fixed value (usually zero).
*
* @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();
}
/*
- 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
*/
//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();
/*
Different runtimes use different names for the Unsafe singleton,
so we cannot use .getDeclaredField and we scan instead. For example:
Oracle: theUnsafe
PERC : m_unsafe_instance
Android: THE_ONE
*/
for (java.lang.reflect.Field field : fields) {
if (!field.getType().equals(sun.misc.Unsafe.class)) {
continue;
}
int modifiers = field.getModifiers();
if (!(java.lang.reflect.Modifier.isStatic(modifiers) && java.lang.reflect.Modifier.isFinal(modifiers))) {
continue;
}
try {
field.setAccessible(true);
return (sun.misc.Unsafe)field.get(null);
} catch (Exception ignored) {
}
break;
}
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;
}
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.");
}
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,24 +1,10 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.compat.ModStatus;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import xonin.backhand.api.core.BackhandUtils;
public enum InteractionHand {
MAIN_HAND,
OFF_HAND;
InteractionHand() {
}
public ItemStack getItemInHand(EntityPlayer player){
if (ModStatus.isBackhandLoaded && this == InteractionHand.OFF_HAND){ // off hand (requires backhand)
return BackhandUtils.getOffhandItem(player);
}
else { // main hand
return player.getHeldItem();
}
}
}
@@ -1,7 +1,6 @@
package com.gtnewhorizons.angelica.compat.mojang;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
@@ -9,8 +8,6 @@ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import javax.imageio.ImageIO;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import lombok.Getter;
import net.coderbot.iris.Iris;
import org.lwjgl.opengl.GL11;
@@ -61,7 +58,7 @@ 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);
try (final MemoryStack stack = stackPush()) {
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);
@@ -138,27 +138,14 @@ public class AngelicaConfig {
@Config.RequiresMcRestart
public static boolean enableZoom;
@Config.Comment("Optimizes in-world item rendering [Experimental]")
@Config.DefaultBoolean(false)
@Config.Comment("Optimizes in-world item rendering")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeInWorldItemRendering_WIP;
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;
@Config.Comment("Render distance for the spinning mob inside mod spawners")
@Config.DefaultDouble(16D)
@Config.RangeDouble(min = 16D, max = 64D)
public static double mobSpawnerRenderDistance;
@Config.Comment("Switches to an alternate FPS limiter that gives more stable frametimes, in exchange for slightly " +
"more latency. Will never introduce more than one frame of latency, and has a lower impact at higher framerates.")
@Config.DefaultBoolean(false)
public static boolean sleepBeforeSwap;
@Config.Comment("Allows unicode languages to use an odd gui scale")
@Config.DefaultBoolean(true)
public static boolean removeUnicodeEvenScaling;
}
@@ -28,10 +28,9 @@ 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 static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
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;
@@ -132,7 +131,7 @@ public abstract class F3Graph {
// Load vertex buffer
vertBuf = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertBuf);
try (final MemoryStack stack = stackPush()) {
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.
@@ -69,7 +69,6 @@ import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;
@@ -961,50 +960,30 @@ public class GLStateManager {
glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, j);
}
public static void trySyncProgram() {
if (AngelicaConfig.enableIris) {
public static void glDrawArrays(int mode, int first, int count) {
// Iris -- TODO: This doesn't seem to work and is related to matchPass()
if(AngelicaConfig.enableIris) {
Iris.getPipelineManager().getPipeline().ifPresent(WorldRenderingPipeline::syncProgram);
}
}
public static void glBegin(int mode) {
trySyncProgram();
GL11.glBegin(mode);
}
public static void glDrawElements(int mode, ByteBuffer indices) {
trySyncProgram();
GL11.glDrawElements(mode, indices);
}
public static void glDrawElements(int mode, IntBuffer indices) {
trySyncProgram();
GL11.glDrawElements(mode, indices);
}
public static void glDrawElements(int mode, ShortBuffer indices) {
trySyncProgram();
GL11.glDrawElements(mode, indices);
}
public static void glDrawElements(int mode, int indices_count, int type, long indices_buffer_offset) {
trySyncProgram();
GL11.glDrawElements(mode, indices_count, type, indices_buffer_offset);
}
public static void glDrawElements(int mode, int count, int type, ByteBuffer indices) {
trySyncProgram();
GL11.glDrawElements(mode, count, type, indices);
GL11.glDrawArrays(mode, first, count);
}
public static void glDrawBuffer(int mode) {
trySyncProgram();
GL11.glDrawBuffer(mode);
}
public static void glDrawArrays(int mode, int first, int count) {
trySyncProgram();
GL11.glDrawArrays(mode, first, count);
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) {
@@ -1261,7 +1240,6 @@ public class GLStateManager {
if(list < 0) {
VBOManager.get(list).render();
} else {
trySyncProgram();
GL11.glCallList(list);
if(glListChanges.containsKey(list)) {
for(Map.Entry<IStateStack<?>, ISettableState<?>> entry : glListChanges.get(list)) {
@@ -136,10 +136,6 @@ public class HUDCaching {
guiForge.callRenderPortal(width, height, partialTicks);
}
if (renderCrosshairsCaptured) {
if (ModStatus.isXaerosMinimapLoaded){
// this fixes the crosshair going invisible when no lines are being drawn under the minimap
GLStateManager.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
}
guiForge.callRenderCrosshairs(width, height);
}
if (ModStatus.isThaumcraftLoaded || ModStatus.isThaumicHorizonsLoaded){
@@ -80,7 +80,7 @@ public enum Mixins {
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_WIP)
.setApplyIf(() -> AngelicaConfig.optimizeInWorldItemRendering)
.addTargetedMod(TargetedMod.VANILLA)),
// Not compatible with the lwjgl debug callbacks, so disable if that's enabled
@@ -137,7 +137,6 @@ public enum Mixins {
,"sodium.MixinRenderGlobal"
,"sodium.MixinWorldClient"
,"sodium.MixinTileEntity"
,"sodium.MixinTileEntityMobSpawner"
,"sodium.MixinEffectRenderer"
,"sodium.MixinTileEntityRendererDispatcher"
,"sodium.MixinLongHashMap"
@@ -152,6 +151,7 @@ public enum Mixins {
,"shaders.MixinGuiIngameForge"
,"shaders.MixinFramebuffer"
,"shaders.MixinItem"
,"shaders.MixinItemRenderer"
,"shaders.MixinLocale"
,"shaders.MixinOpenGlHelper"
,"shaders.MixinRender"
@@ -161,19 +161,6 @@ public enum Mixins {
)
),
IRIS_RENDERING_NOBACKHAND(new Builder("Iris Hand Shaders").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableIris).addExcludedMod(TargetedMod.BACKHAND).addMixinClasses(
"shaders.MixinItemRenderer"
)
),
IRIS_RENDERING_BACKHAND(new Builder("Iris Hand Shaders (Backhand)").addTargetedMod(TargetedMod.VANILLA)
.addTargetedMod(TargetedMod.BACKHAND).setSide(Side.CLIENT)
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableIris).addMixinClasses(
"shaders.MixinItemRendererBackhand"
)
),
IRIS_ACCESSORS(new Builder("Iris Accessors").addTargetedMod(TargetedMod.VANILLA).setSide(Side.CLIENT)
.setPhase(Phase.EARLY).setApplyIf(() -> AngelicaConfig.enableIris).addMixinClasses(
"shaders.accessors.MixinMinecraft"
@@ -231,11 +218,6 @@ public enum Mixins {
"angelica.animation.MixinWorldRenderer",
"angelica.animation.MixinRenderItem")),
SCALED_RESOUTION_UNICODE_FIX(new Builder("Removes unicode languages gui scaling being forced to even values").setPhase(Phase.EARLY)
.setSide(Side.CLIENT).addTargetedMod(TargetedMod.VANILLA)
.setApplyIf(() -> AngelicaConfig.removeUnicodeEvenScaling)
.addMixinClasses("angelica.bugfixes.MixinScaledResolution_UnicodeFix")),
EXTRA_UTILITIES_THREAD_SAFETY(new Builder("Enable thread safety fixes in Extra Utilities").setPhase(Phase.LATE)
.addTargetedMod(TargetedMod.EXTRAUTILS).setSide(Side.CLIENT)
.setApplyIf(() -> CompatConfig.fixExtraUtils)
@@ -537,7 +519,7 @@ public enum Mixins {
&& !MCPatcherForgeConfig.ConnectedTextures.enabled
&& MCPatcherForgeConfig.CustomColors.enabled)
.addTargetedMod(TargetedMod.VANILLA)
.addMixinClasses("mcpatcherforge.ctm_cc.MixinRenderBlocksNoCTM")
.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)
@@ -8,7 +8,6 @@ public enum TargetedMod {
, FASTCRAFT("FastCraft", "fastcraft.Tweaker")
, OPTIFINE("Optifine", "optifine.OptiFineForgeTweaker", "Optifine")
, ARCHAICFIX("ArchaicFix", "org.embeddedt.archaicfix.ArchaicCore", "archaicfix")
, BACKHAND("Backhand","xonin.backhand.coremod.BackhandLoadingPlugin", "backhand")
, BOTANIA("Botania", null, "Botania")
, CAMPFIRE_BACKPORT("CampfireBackport", null, "campfirebackport")
, CHICKENCHUNKS("ChickenChunks", null, "ChickenChunks")
@@ -47,7 +47,6 @@ import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.Direction;
@@ -153,7 +152,7 @@ public class ClientProxy extends CommonProxy {
@SubscribeEvent
public void onKeypress(TickEvent.ClientTickEvent event) {
final boolean isPressed = glsmKeyBinding.getKeyCode() != 0 && GameSettings.isKeyDown(glsmKeyBinding);
final boolean isPressed = glsmKeyBinding.getKeyCode() != 0 && Keyboard.isKeyDown(glsmKeyBinding.getKeyCode());
if (isPressed && !wasGLSMKeyPressed) {
OpenGLDebugging.checkGLSM();
}
@@ -1,23 +1,19 @@
package jss.notfine.proxy;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import jss.notfine.config.NotFineConfig;
import jss.notfine.core.Settings;
import jss.notfine.core.SettingsManager;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraft.client.settings.GameSettings;
public class ClientProxy extends CommonProxy {
@Override
public void preInit(FMLPreInitializationEvent event) {
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
if(!NotFineConfig.allowAdvancedOpenGL) {
Minecraft.getMinecraft().gameSettings.advancedOpengl = false;
}
@@ -33,13 +29,12 @@ public class ClientProxy extends CommonProxy {
}
}
@Override
public void init(FMLInitializationEvent event) { }
@Override
public void postInit(FMLPostInitializationEvent event) {
SettingsManager.settingsFile.loadSettings();
}
@SubscribeEvent
public void worldLoad(WorldEvent.Load event) {
SettingsManager.graphicsUpdated();
}
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.gl.util;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL20;
@@ -18,8 +17,8 @@ public class GlMultiDrawBatch {
private boolean isBuilding;
public GlMultiDrawBatch(int capacity) {
this.bufIndices = memAllocInt(capacity);
this.bufLen = memAllocInt(capacity);
this.bufIndices = BufferUtils.createIntBuffer(capacity);
this.bufLen = BufferUtils.createIntBuffer(capacity);
}
public IntBuffer getIndicesBuffer() {
@@ -60,8 +59,8 @@ public class GlMultiDrawBatch {
}
public void delete() {
memFree(this.bufIndices);
memFree(this.bufLen);
this.bufIndices.clear();
this.bufLen.clear();
this.bufIndices = null;
this.bufLen = null;
@@ -127,15 +127,6 @@ public class SodiumGameOptionPages {
}
}, (opts) -> opts.fullScreen)
.build())
.add(OptionImpl.createBuilder(boolean.class, angelicaOpts)
.setName(I18n.format("options.angelica.sleepbeforeswap"))
.setTooltip(I18n.format("options.angelica.sleepbeforeswap.tooltip"))
.setControl(TickBoxControl::new)
.setBinding((opts, value) -> {
AngelicaConfig.sleepBeforeSwap = value;
}, opts -> AngelicaConfig.sleepBeforeSwap)
.setImpact(OptionImpact.VARIES)
.build())
.add(OptionImpl.createBuilder(boolean.class, vanillaOpts)
.setName(I18n.format("options.vsync"))
.setTooltip(I18n.format("sodium.options.v_sync.tooltip"))
@@ -173,15 +164,6 @@ public class SodiumGameOptionPages {
.setImpact(OptionImpact.MEDIUM)
.build()
)
.add(
OptionImpl.createBuilder(int.class, angelicaOpts)
.setName(I18n.format("options.angelica.mobSpawnerRenderDistance"))
.setTooltip(I18n.format("options.angelica.mobSpawnerRenderDistance.tooltip"))
.setControl(option -> new SliderControl(option, 16, 64, 1, ControlValueFormatter.number()))
.setBinding((options, value) -> AngelicaConfig.mobSpawnerRenderDistance = value, options -> (int) AngelicaConfig.mobSpawnerRenderDistance)
.setImpact(OptionImpact.MEDIUM)
.build()
)
.build());
return new OptionPage(I18n.format("stat.generalButton"), ImmutableList.copyOf(groups));
@@ -196,10 +178,8 @@ public class SodiumGameOptionPages {
.setTooltip(I18n.format("sodium.options.graphics_quality.tooltip"))
.setControl(option -> new CyclingControl<>(option, GraphicsMode.class))
.setBinding(
(opts, value) -> {
opts.fancyGraphics = value.isFancy();
SettingsManager.graphicsUpdated();
},
(opts, value) -> { opts.fancyGraphics = value.isFancy();
SettingsManager.graphicsUpdated(); },
opts -> GraphicsMode.fromBoolean(opts.fancyGraphics))
.setImpact(OptionImpact.HIGH)
.setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD)
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.buffer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.gl.attribute.BufferVertexFormat;
import org.lwjgl.BufferUtils;
@@ -17,7 +16,7 @@ public class VertexBufferBuilder implements VertexBufferView {
public VertexBufferBuilder(BufferVertexFormat vertexFormat, int initialCapacity) {
this.vertexFormat = vertexFormat;
this.buffer = memAlloc(initialCapacity);
this.buffer = BufferUtils.createByteBuffer(initialCapacity);
this.capacity = initialCapacity;
this.writerOffset = 0;
}
@@ -26,7 +25,7 @@ public class VertexBufferBuilder implements VertexBufferView {
// The new capacity will at least as large as the write it needs to service
final int cap = Math.max(this.capacity * 2, this.capacity + len);
this.buffer = memRealloc(this.buffer, cap);
this.buffer = CompatMemoryUtil.memReallocDirect(this.buffer, cap);
this.capacity = cap;
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.formats.glyph.writer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.VanillaVertexTypes;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
@@ -16,13 +15,13 @@ public class GlyphVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe impl
public void writeGlyph(float x, float y, float z, int color, float u, float v, int light) {
long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
memPutFloat(i + 16, u);
memPutFloat(i + 20, v);
memPutInt(i + 24, light);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i + 16, u);
CompatMemoryUtil.memPutFloat(i + 20, v);
CompatMemoryUtil.memPutInt(i + 24, light);
this.advance();
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.formats.line.writer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.VanillaVertexTypes;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
@@ -16,10 +15,10 @@ public class LineVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe imple
public void vertexLine(float x, float y, float z, int color) {
long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
this.advance();
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.formats.particle.writer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.VanillaVertexTypes;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
@@ -16,13 +15,13 @@ public class ParticleVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe i
public void writeParticle(float x, float y, float z, float u, float v, int color, int light) {
long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutFloat(i + 12, u);
memPutFloat(i + 16, v);
memPutInt(i + 20, color);
memPutInt(i + 24, light);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutFloat(i + 12, u);
CompatMemoryUtil.memPutFloat(i + 16, v);
CompatMemoryUtil.memPutInt(i + 20, color);
CompatMemoryUtil.memPutInt(i + 24, light);
this.advance();
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.formats.quad.writer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.VanillaVertexTypes;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
@@ -16,15 +15,15 @@ public class QuadVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe imple
public void writeQuad(float x, float y, float z, int color, float u, float v, int light, int overlay, int normal) {
final long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
memPutFloat(i + 16, u);
memPutFloat(i + 20, v);
memPutInt(i + 24, overlay);
memPutInt(i + 28, light);
memPutInt(i + 32, normal);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i + 16, u);
CompatMemoryUtil.memPutFloat(i + 20, v);
CompatMemoryUtil.memPutInt(i + 24, overlay);
CompatMemoryUtil.memPutInt(i + 28, light);
CompatMemoryUtil.memPutInt(i + 32, normal);
this.advance();
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.model.vertex.formats.screen_quad.writer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.VanillaVertexTypes;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
@@ -16,10 +15,10 @@ public class BasicScreenQuadVertexBufferWriterUnsafe extends VertexBufferWriterU
public void writeQuad(float x, float y, float z, int color) {
long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
this.advance();
}
@@ -1,6 +1,6 @@
package me.jellysquid.mods.sodium.client.render;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import com.gtnewhorizons.angelica.compat.toremove.MatrixStack;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.rendering.RenderingState;
@@ -35,7 +35,6 @@ import me.jellysquid.mods.sodium.client.world.ChunkStatusListener;
import me.jellysquid.mods.sodium.common.util.IdTable;
import me.jellysquid.mods.sodium.common.util.collections.FutureDequeDrain;
import net.coderbot.iris.shadows.ShadowRenderingState;
import net.coderbot.iris.sodium.shadow_map.SwappableChunkRenderManager;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.tileentity.TileEntity;
@@ -48,7 +47,7 @@ import java.util.Collection;
import java.util.Deque;
import java.util.concurrent.CompletableFuture;
public class ChunkRenderManager<T extends ChunkGraphicsState> implements ChunkStatusListener, SwappableChunkRenderManager {
public class ChunkRenderManager<T extends ChunkGraphicsState> implements ChunkStatusListener {
/**
* The maximum distance a chunk can be from the player's camera in order to be eligible for blocking updates.
*/
@@ -250,11 +249,7 @@ public class ChunkRenderManager<T extends ChunkGraphicsState> implements ChunkSt
}
private void addChunk(ChunkRenderContainer<T> render) {
boolean canRebuild = render.canRebuild();
if (AngelicaConfig.enableIris && ShadowRenderingState.areShadowsCurrentlyBeingRendered()) {
canRebuild = false;
}
final boolean canRebuild = AngelicaConfig.enableIris ? !ShadowRenderingState.areShadowsCurrentlyBeingRendered() : render.canRebuild();
if (render.needsRebuild() && canRebuild) {
if (!this.alwaysDeferChunkUpdates && render.needsImportantRebuild()) {
@@ -371,7 +366,9 @@ public class ChunkRenderManager<T extends ChunkGraphicsState> implements ChunkSt
private void reset() {
if(!AngelicaConfig.enableIris || !ShadowRenderingState.areShadowsCurrentlyBeingRendered()) this.rebuildQueue.clear();
if(!AngelicaConfig.enableIris || !ShadowRenderingState.areShadowsCurrentlyBeingRendered()) this.importantRebuildQueue.clear();
if(!AngelicaConfig.enableIris || !ShadowRenderingState.areShadowsCurrentlyBeingRendered()) this.sortQueue.clear();
this.sortQueue.clear();
this.visibleTileEntities.clear();
@@ -552,39 +549,25 @@ public class ChunkRenderManager<T extends ChunkGraphicsState> implements ChunkSt
continue;
}
CompletableFuture<ChunkBuildResult<T>> futureTask = this.builder.scheduleRebuildTaskAsync(render);
if (futureTask != null) {
this.dirty = true;
// Do not allow distant chunks to block rendering
if (this.alwaysDeferChunkUpdates || !this.isChunkPrioritized(render)) {
this.builder.handleCompletion(futureTask);
} else {
futures.add(futureTask);
}
submitted++;
// Limit quantity of updates submitted if we are deferring all important builds
if (this.alwaysDeferChunkUpdates && submitted >= budget)
break;
// Do not allow distant chunks to block rendering
if (this.alwaysDeferChunkUpdates || !this.isChunkPrioritized(render)) {
this.builder.deferRebuild(render);
} else {
// Immediately submit empty data to the queue and do not count this against the budget
this.builder.enqueueUpload(new ChunkBuildResult<>(render, ChunkRenderData.EMPTY));
futures.add(this.builder.scheduleRebuildTaskAsync(render));
}
this.dirty = true;
submitted++;
// Limit quantity of updates submitted if we are deferring all important builds
if (this.alwaysDeferChunkUpdates && submitted >= budget)
break;
}
while (submitted < budget && !this.rebuildQueue.isEmpty()) {
ChunkRenderContainer<T> render = this.rebuildQueue.dequeue();
CompletableFuture<ChunkBuildResult<T>> futureTask = this.builder.scheduleRebuildTaskAsync(render);
if(futureTask != null) {
this.builder.handleCompletion(futureTask);
submitted++;
} else {
// Immediately submit empty data to the queue and do not count this against the budget
this.builder.enqueueUpload(new ChunkBuildResult<>(render, ChunkRenderData.EMPTY));
}
this.builder.deferRebuild(render);
submitted++;
}
// always do at least one sort
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.backends.multidraw;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import com.gtnewhorizons.angelica.compat.mojang.CompatMathHelper;
import me.jellysquid.mods.sodium.client.SodiumClientMod;
import org.lwjgl.MemoryUtil;
@@ -84,10 +83,10 @@ public abstract class ChunkDrawCallBatcher extends StructBuffer {
throw new BufferUnderflowException();
}
memPutInt(this.writePointer , count); // Vertex Count
memPutInt(this.writePointer + 4, instanceCount); // Instance Count
memPutInt(this.writePointer + 8, first); // Vertex Start
memPutInt(this.writePointer + 12, baseInstance); // Base Instance
CompatMemoryUtil.memPutInt(this.writePointer , count); // Vertex Count
CompatMemoryUtil.memPutInt(this.writePointer + 4, instanceCount); // Instance Count
CompatMemoryUtil.memPutInt(this.writePointer + 8, first); // Vertex Start
CompatMemoryUtil.memPutInt(this.writePointer + 12, baseInstance); // Base Instance
this.writePointer += this.stride;
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.backends.multidraw;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.SodiumClientMod;
import org.lwjgl.MemoryUtil;
@@ -33,7 +32,7 @@ public abstract class ChunkDrawParamsVector extends StructBuffer {
protected void growBuffer() {
this.capacity = this.capacity * 2;
this.buffer = memRealloc(this.buffer, this.capacity * this.stride);
this.buffer = CompatMemoryUtil.memReallocDirect(this.buffer, this.capacity * this.stride);
}
public static class UnsafeChunkDrawCallVector extends ChunkDrawParamsVector {
@@ -52,9 +51,9 @@ public abstract class ChunkDrawParamsVector extends StructBuffer {
this.growBuffer();
}
memPutFloat(this.writePointer , x);
memPutFloat(this.writePointer + 4, y);
memPutFloat(this.writePointer + 8, z);
CompatMemoryUtil.memPutFloat(this.writePointer , x);
CompatMemoryUtil.memPutFloat(this.writePointer + 4, y);
CompatMemoryUtil.memPutFloat(this.writePointer + 8, z);
this.writePointer += this.stride;
}
@@ -65,7 +64,7 @@ public abstract class ChunkDrawParamsVector extends StructBuffer {
long offset = this.writePointer - this.basePointer;
this.basePointer = memAddress(this.buffer);
this.basePointer = MemoryUtil.getAddress(this.buffer);
this.writePointer = this.basePointer + offset;
}
@@ -1,6 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.backends.multidraw;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
public class IndirectCommandBufferVector extends StructBuffer {
protected IndirectCommandBufferVector(int capacity) {
@@ -32,6 +32,6 @@ public class IndirectCommandBufferVector extends StructBuffer {
}
protected void growBuffer(int n) {
this.buffer = memRealloc(this.buffer, Math.max(this.buffer.capacity() * 2, this.buffer.capacity() + n));
this.buffer = CompatMemoryUtil.memReallocDirect(this.buffer, Math.max(this.buffer.capacity() * 2, this.buffer.capacity() + n));
}
}
@@ -1,6 +1,7 @@
package me.jellysquid.mods.sodium.client.render.chunk.backends.multidraw;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.MemoryUtil;
import java.nio.ByteBuffer;
@@ -10,7 +11,7 @@ public abstract class StructBuffer {
protected final int stride;
protected StructBuffer(int bytes, int stride) {
this.buffer = memAlloc(bytes * stride);
this.buffer = BufferUtils.createByteBuffer(bytes * stride);
this.stride = stride;
}
@@ -19,7 +20,7 @@ public abstract class StructBuffer {
}
public long getBufferAddress() {
return memAddress(this.buffer);
return MemoryUtil.getAddress(this.buffer);
}
public void delete() {
@@ -5,7 +5,6 @@ import it.unimi.dsi.fastutil.ints.IntArrays;
import me.jellysquid.mods.sodium.client.model.vertex.type.ChunkVertexType;
import me.jellysquid.mods.sodium.client.render.chunk.format.hfp.HFPModelVertexType;
import me.jellysquid.mods.sodium.client.render.chunk.format.sfp.SFPModelVertexType;
import net.coderbot.iris.sodium.vertex_format.terrain_xhfp.XHFPModelVertexType;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@@ -15,10 +14,22 @@ import java.util.BitSet;
public class ChunkBufferSorter {
private static final Class<?> OCULUS_VERTEX_TYPE;
static {
Class<?> clz;
try {
clz = Class.forName("net.coderbot.iris.compat.sodium.impl.vertex_format.terrain_xhfp.XHFPModelVertexType");
} catch(Throwable e) {
clz = null;
}
OCULUS_VERTEX_TYPE = clz;
}
public static void sortStandardFormat(ChunkVertexType vertexType, ByteBuffer buffer, int bufferLen, float x, float y, float z) {
boolean isCompact;
if(vertexType.getClass() == HFPModelVertexType.class || vertexType.getClass() == XHFPModelVertexType.class) {
if(vertexType.getClass() == HFPModelVertexType.class || vertexType.getClass() == OCULUS_VERTEX_TYPE) {
isCompact = true;
} else if(vertexType.getClass() == SFPModelVertexType.class) {
isCompact = false;
@@ -142,8 +142,6 @@ public class ChunkBuildBuffers implements ChunkBuildBuffersExt {
if (sortTranslucent && pass.isTranslucent()) {
ChunkBufferSorter.sortStandardFormat(vertexType, buffer, bufferLen, x, y, z);
meshData.clearSlices();
meshData.setModelSlice(ModelQuadFacing.UNASSIGNED, new BufferSlice(0, bufferLen));
}
meshData.setVertexData(new VertexData(buffer, this.vertexType.getCustomVertexFormat()));
@@ -10,6 +10,7 @@ import me.jellysquid.mods.sodium.client.render.chunk.ChunkGraphicsState;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderBackend;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderContainer;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderBuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderEmptyBuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderRebuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderTranslucencySortTask;
import me.jellysquid.mods.sodium.client.render.pipeline.context.ChunkRenderCacheLocal;
@@ -25,7 +26,6 @@ import net.minecraft.util.ReportedException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joml.Vector3d;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Deque;
@@ -294,10 +294,7 @@ public class ChunkBuilder<T extends ChunkGraphicsState> {
return Runtime.getRuntime().availableProcessors();
}
/**
* Add a completion handler to the given future task so that the result will be processed on the main thread.
*/
public void handleCompletion(CompletableFuture<ChunkBuildResult<T>> future) {
private void handleCompletion(CompletableFuture<ChunkBuildResult<T>> future) {
future.whenComplete((res, ex) -> {
if (ex != null) {
this.failureQueue.add(ex);
@@ -307,6 +304,16 @@ public class ChunkBuilder<T extends ChunkGraphicsState> {
});
}
/**
* Creates a rebuild task and defers it to the work queue. When the task is completed, it will be moved onto the
* completed uploads queued which will then be drained during the next available synchronization point with the
* main thread.
* @param render The render to rebuild
*/
public void deferRebuild(ChunkRenderContainer<T> render) {
handleCompletion(this.scheduleRebuildTaskAsync(render));
}
/**
* Creates a rebuild task and defers it to the work queue. When the task is completed, it will be moved onto the
* completed uploads queued which will then be drained during the next available synchronization point with the
@@ -323,24 +330,16 @@ public class ChunkBuilder<T extends ChunkGraphicsState> {
* synchronization point on the main thread.
* @param result The build task's result
*/
public void enqueueUpload(ChunkBuildResult<T> result) {
private void enqueueUpload(ChunkBuildResult<T> result) {
this.uploadQueue.add(result);
}
/**
* Schedules the rebuild task asynchronously on the worker pool, returning a future wrapping the task.
* @param render The render to rebuild
* @return a future representing the rebuild task, or null if the chunk section is empty
*/
@Nullable
public CompletableFuture<ChunkBuildResult<T>> scheduleRebuildTaskAsync(ChunkRenderContainer<T> render) {
ChunkRenderBuildTask<T> task = this.createRebuildTask(render);
if(task != null) {
return this.schedule(task);
} else {
return null;
}
return this.schedule(this.createRebuildTask(render));
}
/**
@@ -361,7 +360,7 @@ public class ChunkBuilder<T extends ChunkGraphicsState> {
ChunkRenderContext context = WorldSlice.prepare(this.world, render.getChunkPos(), this.sectionCache);
if (context == null) {
return null;
return new ChunkRenderEmptyBuildTask<>(render);
} else {
return new ChunkRenderRebuildTask<>(render, context, render.getRenderOrigin()).withCameraPosition(this.cameraPosition);
}
@@ -17,10 +17,6 @@ public class ChunkMeshData {
this.vertexData = vertexData;
}
public void clearSlices() {
this.parts.clear();
}
public void setModelSlice(ModelQuadFacing facing, BufferSlice slice) {
this.parts.put(facing, slice);
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.format.hfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
import me.jellysquid.mods.sodium.client.render.chunk.format.DefaultModelVertexFormats;
@@ -29,13 +28,13 @@ public class HFPModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe i
private void writeQuadInternal(short x, short y, short z, int color, short u, short v, int light) {
long i = this.writePointer;
memPutShort(i, x);
memPutShort(i + 2, y);
memPutShort(i + 4, z);
memPutInt(i + 8, color);
memPutShort(i + 12, u);
memPutShort(i + 14, v);
memPutInt(i + 16, light);
CompatMemoryUtil.memPutShort(i, x);
CompatMemoryUtil.memPutShort(i + 2, y);
CompatMemoryUtil.memPutShort(i + 4, z);
CompatMemoryUtil.memPutInt(i + 8, color);
CompatMemoryUtil.memPutShort(i + 12, u);
CompatMemoryUtil.memPutShort(i + 14, v);
CompatMemoryUtil.memPutInt(i + 16, light);
this.advance();
}
@@ -1,7 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.format.sfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
import me.jellysquid.mods.sodium.client.render.chunk.format.DefaultModelVertexFormats;
@@ -16,13 +15,13 @@ public class SFPModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe i
public void writeQuad(float x, float y, float z, int color, float u, float v, int light) {
long i = this.writePointer;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
memPutFloat(i + 16, u);
memPutFloat(i + 20, v);
memPutInt(i + 24, encodeLightMapTexCoord(light));
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i + 16, u);
CompatMemoryUtil.memPutFloat(i + 20, v);
CompatMemoryUtil.memPutInt(i + 24, encodeLightMapTexCoord(light));
this.advance();
}
@@ -1,8 +1,6 @@
package me.jellysquid.mods.sodium.client.render.chunk.shader;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import com.gtnewhorizons.angelica.compat.toremove.MatrixStack;
import me.jellysquid.mods.sodium.client.gl.device.RenderDevice;
import me.jellysquid.mods.sodium.client.gl.shader.GlProgram;
@@ -51,7 +49,7 @@ public class ChunkProgram extends GlProgram {
this.fogShader.setup();
if (this.uModelViewProjectionMatrix == -1) return;
try (MemoryStack stack = stackPush()) {
try (MemoryStack stack = MemoryStack.stackPush()) {
GL20.glUniformMatrix4(
this.uModelViewProjectionMatrix,
false,
@@ -0,0 +1,33 @@
package me.jellysquid.mods.sodium.client.render.chunk.tasks;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkGraphicsState;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderContainer;
import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers;
import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildResult;
import me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderData;
import me.jellysquid.mods.sodium.client.render.pipeline.context.ChunkRenderCacheLocal;
import me.jellysquid.mods.sodium.client.util.task.CancellationSource;
/**
* A build task which does no computation and always return an empty build result. These tasks are created whenever
* chunk meshes need to be deleted as the only way to change graphics state is to send a message to the main
* actor thread. In cases where new chunk renders are being created and scheduled, the scheduler will prefer to just
* synchronously update the render's data to an empty state to speed things along.
*/
public class ChunkRenderEmptyBuildTask<T extends ChunkGraphicsState> extends ChunkRenderBuildTask<T> {
private final ChunkRenderContainer<T> render;
public ChunkRenderEmptyBuildTask(ChunkRenderContainer<T> render) {
this.render = render;
}
@Override
public ChunkBuildResult<T> performBuild(ChunkRenderCacheLocal cache, ChunkBuildBuffers buffers, CancellationSource cancellationSource) {
return new ChunkBuildResult<>(this.render, ChunkRenderData.EMPTY);
}
@Override
public void releaseResources() {
}
}
@@ -37,7 +37,6 @@ import java.util.List;
import java.util.Random;
public class BlockRenderer {
private static final BlockPos POS_ZERO = new BlockPos(0, 0, 0);
private final Random random = new XoRoShiRoRandom();
@@ -98,10 +97,9 @@ public class BlockRenderer {
TessellatorManager.startCapturing();
final CapturingTessellator tess = (CapturingTessellator) TessellatorManager.get();
tess.startDrawingQuads();
// Use setTranslation rather than setOffset so that the float data written to the internal buffer
// is done in subchunk-relative coordinates
tess.setOffset(POS_ZERO);
tess.setTranslation(-pos.x, -pos.y, -pos.z);
// RenderBlocks adds the subchunk-relative coordinates as the offset, cancel it out here
tess.setOffset(pos);
renderBlocks.renderBlockByRenderType(block, pos.x, pos.y, pos.z);
final List<QuadView> quads = TessellatorManager.stopCapturingToPooledQuads();
tess.resetOffset();
+1 -1
View File
@@ -537,7 +537,7 @@ public class Iris {
if (level != null) {
if (level.provider == null) return DimensionId.OVERWORLD;
if (level.provider.isHellWorld || level.provider.dimensionId == -1) {
if ((level.provider.isHellWorld || level.provider.hasNoSky) || level.provider.dimensionId == -1) {
return DimensionId.NETHER;
} else if (level.provider.dimensionId == 1) {
return DimensionId.END;
@@ -1,7 +1,6 @@
package net.coderbot.iris.config;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gui.option.IrisVideoSettings;
import java.io.IOException;
import java.io.InputStream;
@@ -123,13 +122,13 @@ public class IrisConfig {
enableShaders = !"false".equals(properties.getProperty("enableShaders"));
disableUpdateMessage = "true".equals(properties.getProperty("disableUpdateMessage"));
// TODO: GUI
try {
IrisVideoSettings.shadowDistance = Integer.parseInt(properties.getProperty("maxShadowRenderDistance", "32"));
} catch (NumberFormatException e) {
Iris.logger.error("Shadow distance setting reset; value is invalid.");
IrisVideoSettings.shadowDistance = 32;
save();
}
// try {
// IrisVideoSettings.shadowDistance = Integer.parseInt(properties.getProperty("maxShadowRenderDistance", "32"));
// } catch (NumberFormatException e) {
// Iris.logger.error("Shadow distance setting reset; value is invalid.");
// IrisVideoSettings.shadowDistance = 32;
// save();
// }
if (shaderPackName != null) {
if (shaderPackName.equals("(internal)") || shaderPackName.isEmpty()) {
@@ -148,7 +147,8 @@ public class IrisConfig {
properties.setProperty("shaderPack", getShaderPackName().orElse(""));
properties.setProperty("enableShaders", enableShaders ? "true" : "false");
properties.setProperty("disableUpdateMessage", disableUpdateMessage ? "true" : "false");
properties.setProperty("maxShadowRenderDistance", String.valueOf(IrisVideoSettings.shadowDistance));
// properties.setProperty("maxShadowRenderDistance", String.valueOf(IrisVideoSettings.shadowDistance));
properties.setProperty("maxShadowRenderDistance", String.valueOf(32));
// NB: This uses ISO-8859-1 with unicode escapes as the encoding
try (OutputStream os = Files.newOutputStream(propertiesPath)) {
properties.store(os, COMMENT);
@@ -1,8 +1,6 @@
package net.coderbot.iris.gl.framebuffer;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import com.gtnewhorizons.angelica.glsm.texture.TextureInfoCache;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
@@ -53,7 +51,7 @@ public class GlFramebuffer extends GlResource {
}
public void noDrawBuffers() {
try (MemoryStack stack = stackPush()) {
try (MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer buffer = stack.mallocInt(1);
buffer.put(GL11.GL_NONE);
RenderSystem.drawBuffers(getGlId(), buffer);
@@ -61,7 +59,7 @@ public class GlFramebuffer extends GlResource {
}
public void drawBuffers(int[] buffers) {
try (MemoryStack stack = stackPush()) {
try (MemoryStack stack = MemoryStack.stackPush()) {
final IntBuffer glBuffers = stack.mallocInt(buffers.length);
int index = 0;
@@ -91,17 +91,6 @@ public class ShaderPackOptionList extends IrisGuiSlot {
final BaseEntry entry = this.entries.get(index);
return entry.mouseClicked(mouseX, mouseY, mouseButton);
}
@Override
public boolean mouseReleased( int mouseX, int mouseY, int button) {
final int relativeY = mouseY - this.top - this.headerPadding + (int) this.amountScrolled - 4;
final int index = relativeY / this.slotHeight;
if (index < 0 || index >= this.entries.size())
return false;
final BaseEntry entry = this.entries.get(index);
return entry.mouseReleased(mouseX, mouseY, button);
}
@Override
protected boolean isSelected(int idx) {
@@ -12,7 +12,6 @@ public abstract class BaseEntry {
}
public abstract boolean mouseClicked(int mouseX, int mouseY, int button);
public abstract boolean mouseReleased(int mouseX, int mouseY, int button);
public abstract void drawEntry(ShaderPackScreen screen, int index, int x, int y, int slotWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isMouseOver);
@@ -108,11 +108,6 @@ public class HeaderEntry extends BaseEntry {
return backButtonResult || utilButtonResult;
}
@Override
public boolean mouseReleased(int mouseX, int mouseY, int button) {
return false;
}
private boolean backButtonClicked(IrisElementRow.TextButtonElement button) {
this.navigation.back();
GuiUtil.playButtonClickSound();
@@ -11,8 +11,8 @@ public class IrisVideoSettings {
public static int shadowDistance = 32;
// TODO: Tell the user to check in the shader options once that's supported.
// private static final String DISABLED_TOOLTIP = I18n.format("options.iris.shadowDistance.disabled");
// private static final String ENABLED_TOOLTIP = I18n.format("options.iris.shadowDistance.enabled");
private static final String DISABLED_TOOLTIP = I18n.format("options.iris.shadowDistance.disabled");
private static final String ENABLED_TOOLTIP = I18n.format("options.iris.shadowDistance.enabled");
public static int getOverriddenShadowDistance(int base) {
return Iris.getPipelineManager().getPipeline()
@@ -78,8 +78,9 @@ public class HandRenderer {
}
public boolean isHandTranslucent(InteractionHand hand) {
ItemStack heldItem = hand.getItemInHand(Minecraft.getMinecraft().thePlayer);
// TODO: Offhand
// Item item = Minecraft.getMinecraft().thePlayer.getItemBySlot(hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND).getItem();
ItemStack heldItem = Minecraft.getMinecraft().thePlayer.getHeldItem();
if (heldItem == null) {
return false;
}
@@ -14,7 +14,6 @@ import java.util.List;
import java.util.Objects;
import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gui.option.IrisVideoSettings;
import net.coderbot.iris.shaderpack.OptionalBoolean;
import net.coderbot.iris.shaderpack.PackDirectives;
import net.coderbot.iris.shaderpack.PackShadowDirectives;
@@ -285,8 +284,8 @@ public class ShadowRenderer {
if (renderMultiplier < 0) {
// TODO: GUI
distance = IrisVideoSettings.shadowDistance * 16; // can be zero :(
//distance = 32 * 16;
// distance = IrisVideoSettings.shadowDistance * 16;
distance = 32 * 16;
setter = "(set by user)";
}
@@ -1,8 +1,6 @@
package net.coderbot.iris.rendertarget;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import lombok.Getter;
@@ -43,7 +41,7 @@ public class RenderTarget {
this.width = builder.width;
this.height = builder.height;
try (MemoryStack stack = stackPush()) {
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer textures = stack.mallocInt(2);
GL11.glGenTextures(textures);
@@ -1,8 +1,6 @@
package net.coderbot.iris.sodium.shader_overrides;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.compat.lwjgl.MemoryStack;
import com.gtnewhorizons.angelica.compat.toremove.MatrixStack;
import com.gtnewhorizons.angelica.glsm.RenderSystem;
import java.nio.FloatBuffer;
@@ -88,7 +86,7 @@ public class IrisChunkProgram extends ChunkProgram {
return;
}
try (MemoryStack stack = stackPush()) {
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer buffer = stack.mallocFloat(16);
matrix.get(buffer);
@@ -1,7 +1,6 @@
package net.coderbot.iris.sodium.vertex_format.entity_xhfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
import me.jellysquid.mods.sodium.client.model.vertex.formats.glyph.GlyphVertexSink;
@@ -33,14 +32,14 @@ public class EntityVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe imp
uSum += u;
vSum += v;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
memPutFloat(i + 16, u);
memPutFloat(i + 20, v);
memPutInt(i + 24, overlay);
memPutInt(i + 28, light);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i + 16, u);
CompatMemoryUtil.memPutFloat(i + 20, v);
CompatMemoryUtil.memPutInt(i + 24, overlay);
CompatMemoryUtil.memPutInt(i + 28, light);
if (vertexCount == 4) {
this.endQuad(normal);
@@ -81,10 +80,10 @@ public class EntityVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe imp
int tangent = NormalHelper.computeTangent(normalX, normalY, normalZ, quad);
for (long vertex = 0; vertex < 4; vertex++) {
memPutFloat(i + 36 - STRIDE * vertex, uSum);
memPutFloat(i + 40 - STRIDE * vertex, vSum);
memPutInt(i + 32 - STRIDE * vertex, normal);
memPutInt(i + 44 - STRIDE * vertex, tangent);
CompatMemoryUtil.memPutFloat(i + 36 - STRIDE * vertex, uSum);
CompatMemoryUtil.memPutFloat(i + 40 - STRIDE * vertex, vSum);
CompatMemoryUtil.memPutInt(i + 32 - STRIDE * vertex, normal);
CompatMemoryUtil.memPutInt(i + 44 - STRIDE * vertex, tangent);
}
uSum = 0;
@@ -1,7 +1,6 @@
package net.coderbot.iris.sodium.vertex_format.entity_xhfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
import me.jellysquid.mods.sodium.client.model.vertex.formats.glyph.GlyphVertexSink;
@@ -33,13 +32,13 @@ public class GlyphVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe impl
uSum += u;
vSum += v;
memPutFloat(i, x);
memPutFloat(i + 4, y);
memPutFloat(i + 8, z);
memPutInt(i + 12, color);
memPutFloat(i + 16, u);
memPutFloat(i + 20, v);
memPutInt(i + 24, light);
CompatMemoryUtil.memPutFloat(i, x);
CompatMemoryUtil.memPutFloat(i + 4, y);
CompatMemoryUtil.memPutFloat(i + 8, z);
CompatMemoryUtil.memPutInt(i + 12, color);
CompatMemoryUtil.memPutFloat(i + 16, u);
CompatMemoryUtil.memPutFloat(i + 20, v);
CompatMemoryUtil.memPutInt(i + 24, light);
if (vertexCount == 4) {
this.endQuad(normal);
@@ -80,10 +79,10 @@ public class GlyphVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe impl
int tangent = NormalHelper.computeTangent(normalX, normalY, normalZ, quad);
for (long vertex = 0; vertex < 4; vertex++) {
memPutFloat(i + 36 - STRIDE * vertex, uSum);
memPutFloat(i + 40 - STRIDE * vertex, vSum);
memPutInt(i + 28 - STRIDE * vertex, normal);
memPutInt(i + 44 - STRIDE * vertex, tangent);
CompatMemoryUtil.memPutFloat(i + 36 - STRIDE * vertex, uSum);
CompatMemoryUtil.memPutFloat(i + 40 - STRIDE * vertex, vSum);
CompatMemoryUtil.memPutInt(i + 28 - STRIDE * vertex, normal);
CompatMemoryUtil.memPutInt(i + 44 - STRIDE * vertex, tangent);
}
uSum = 0;
@@ -1,7 +1,6 @@
package net.coderbot.iris.sodium.vertex_format.entity_xhfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import net.coderbot.iris.vertices.IrisQuadView;
import java.nio.ByteBuffer;
@@ -45,7 +44,7 @@ public abstract class QuadViewEntity implements IrisQuadView {
@Override
float getFloat(long writePointer) {
return memGetFloat(writePointer);
return CompatMemoryUtil.memGetFloat(writePointer);
}
}
@@ -1,7 +1,6 @@
package net.coderbot.iris.sodium.vertex_format.terrain_xhfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import net.coderbot.iris.vertices.IrisQuadView;
import java.nio.ByteBuffer;
@@ -53,7 +52,7 @@ public abstract class QuadViewTerrain implements IrisQuadView {
@Override
short getShort(long writePointer) {
return memGetShort(writePointer);
return CompatMemoryUtil.memGetShort(writePointer);
}
}
@@ -1,7 +1,6 @@
package net.coderbot.iris.sodium.vertex_format.terrain_xhfp;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryUtilities.*;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferView;
import me.jellysquid.mods.sodium.client.model.vertex.buffer.VertexBufferWriterUnsafe;
import me.jellysquid.mods.sodium.client.render.chunk.format.ModelVertexSink;
@@ -55,21 +54,21 @@ public class XHFPModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe
vertexCount++;
// NB: uSum and vSum must already be incremented outside of this function.
memPutShort(i, x);
memPutShort(i + 2, y);
memPutShort(i + 4, z);
memPutInt(i + 8, color);
memPutShort(i + 12, u);
memPutShort(i + 14, v);
memPutShort(i + 16, (short) (light & 0xFFFF));
memPutShort(i + 18, (short) (light >> 16 & 0xFFFF));
CompatMemoryUtil.memPutShort(i, x);
CompatMemoryUtil.memPutShort(i + 2, y);
CompatMemoryUtil.memPutShort(i + 4, z);
CompatMemoryUtil.memPutInt(i + 8, color);
CompatMemoryUtil.memPutShort(i + 12, u);
CompatMemoryUtil.memPutShort(i + 14, v);
CompatMemoryUtil.memPutShort(i + 16, (short) (light & 0xFFFF));
CompatMemoryUtil.memPutShort(i + 18, (short) (light >> 16 & 0xFFFF));
// NB: We don't set midTexCoord, normal, and tangent here, they will be filled in later.
// block ID: We only set the first 2 values, any legacy shaders using z or w will get filled in based on the GLSL spec
// https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_format
// TODO: can we pack this into one short?
memPutShort(i + 36, materialId);
memPutShort(i + 38, renderType);
memPutInt(i + 40, packedMidBlock);
CompatMemoryUtil.memPutShort(i + 36, materialId);
CompatMemoryUtil.memPutShort(i + 38, renderType);
CompatMemoryUtil.memPutInt(i + 40, packedMidBlock);
if (vertexCount == 4) {
vertexCount = 0;
@@ -104,15 +103,15 @@ public class XHFPModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe
uSum *= 0.25f;
vSum *= 0.25f;
memPutFloat(i + 20, uSum);
memPutFloat(i + 20 - STRIDE, uSum);
memPutFloat(i + 20 - STRIDE * 2, uSum);
memPutFloat(i + 20 - STRIDE * 3, uSum);
CompatMemoryUtil.memPutFloat(i + 20, uSum);
CompatMemoryUtil.memPutFloat(i + 20 - STRIDE, uSum);
CompatMemoryUtil.memPutFloat(i + 20 - STRIDE * 2, uSum);
CompatMemoryUtil.memPutFloat(i + 20 - STRIDE * 3, uSum);
memPutFloat(i + 24, vSum);
memPutFloat(i + 24 - STRIDE, vSum);
memPutFloat(i + 24 - STRIDE * 2, vSum);
memPutFloat(i + 24 - STRIDE * 3, vSum);
CompatMemoryUtil.memPutFloat(i + 24, vSum);
CompatMemoryUtil.memPutFloat(i + 24 - STRIDE, vSum);
CompatMemoryUtil.memPutFloat(i + 24 - STRIDE * 2, vSum);
CompatMemoryUtil.memPutFloat(i + 24 - STRIDE * 3, vSum);
uSum = 0;
vSum = 0;
@@ -125,17 +124,17 @@ public class XHFPModelVertexBufferWriterUnsafe extends VertexBufferWriterUnsafe
NormalHelper.computeFaceNormal(normal, quad);
int packedNormal = NormalHelper.packNormal(normal, 0.0f);
memPutInt(i + 32, packedNormal);
memPutInt(i + 32 - STRIDE, packedNormal);
memPutInt(i + 32 - STRIDE * 2, packedNormal);
memPutInt(i + 32 - STRIDE * 3, packedNormal);
CompatMemoryUtil.memPutInt(i + 32, packedNormal);
CompatMemoryUtil.memPutInt(i + 32 - STRIDE, packedNormal);
CompatMemoryUtil.memPutInt(i + 32 - STRIDE * 2, packedNormal);
CompatMemoryUtil.memPutInt(i + 32 - STRIDE * 3, packedNormal);
int tangent = NormalHelper.computeTangent(normal.x, normal.y, normal.z, quad);
memPutInt(i + 28, tangent);
memPutInt(i + 28 - STRIDE, tangent);
memPutInt(i + 28 - STRIDE * 2, tangent);
memPutInt(i + 28 - STRIDE * 3, tangent);
CompatMemoryUtil.memPutInt(i + 28, tangent);
CompatMemoryUtil.memPutInt(i + 28 - STRIDE, tangent);
CompatMemoryUtil.memPutInt(i + 28 - STRIDE * 2, tangent);
CompatMemoryUtil.memPutInt(i + 28 - STRIDE * 3, tangent);
}
this.advance();
@@ -1,8 +1,5 @@
package net.coderbot.iris.texture.util;
import static com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack.*;
import com.gtnewhorizon.gtnhlib.bytebuf.MemoryStack;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
@@ -17,60 +14,43 @@ public class TextureManipulationUtil {
private static int colorFillFBO = -1;
public static void fillWithColor(int textureId, int maxLevel, int rgba) {
try(final MemoryStack stack = stackPush()) {
if (colorFillFBO == -1) {
colorFillFBO = OpenGlHelper.func_153165_e/*glGenFramebuffers*/();
if (colorFillFBO == -1) {
colorFillFBO = OpenGlHelper.func_153165_e/*glGenFramebuffers*/();
}
final int previousFramebufferId = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
// TODO: allocations
final FloatBuffer previousClearColorBuffer = BufferUtils.createFloatBuffer(4);
GL11.glGetFloat(GL11.GL_COLOR_CLEAR_VALUE, previousClearColorBuffer);
final int previousTextureId = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
final IntBuffer previousViewportBuffer = BufferUtils.createIntBuffer(4);
GL11.glGetInteger(GL11.GL_VIEWPORT, previousViewportBuffer);
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, colorFillFBO);
GL11.glClearColor(
(rgba >> 24 & 0xFF) / 255.0f,
(rgba >> 16 & 0xFF) / 255.0f,
(rgba >> 8 & 0xFF) / 255.0f,
(rgba & 0xFF) / 255.0f
);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
for (int level = 0; level <= maxLevel; ++level) {
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);
GL11.glViewport(0, 0, width, height);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, textureId, level);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
if (Minecraft.isRunningOnMac) {
GL11.glGetError();
}
final int previousFramebufferId = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING);
final FloatBuffer previousClearColorBuffer = stack.mallocFloat(4);
GL11.glGetFloat(GL11.GL_COLOR_CLEAR_VALUE, previousClearColorBuffer);
final int previousTextureId = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
final IntBuffer previousViewportBuffer = stack.mallocInt(4);
GL11.glGetInteger(GL11.GL_VIEWPORT, previousViewportBuffer);
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, colorFillFBO);
GL11.glClearColor(
(rgba >> 24 & 0xFF) / 255.0f,
(rgba >> 16 & 0xFF) / 255.0f,
(rgba >> 8 & 0xFF) / 255.0f,
(rgba & 0xFF) / 255.0f);
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
for (int level = 0; level <= maxLevel; ++level) {
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);
GL11.glViewport(0, 0, width, height);
GL30.glFramebufferTexture2D(
GL30.GL_FRAMEBUFFER,
GL30.GL_COLOR_ATTACHMENT0,
GL11.GL_TEXTURE_2D,
textureId,
level);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
if (Minecraft.isRunningOnMac) {
GL11.glGetError();
}
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, 0, level);
}
GL30.glFramebufferTexture2D(
GL30.GL_FRAMEBUFFER,
GL30.GL_COLOR_ATTACHMENT0,
GL11.GL_TEXTURE_2D,
0,
level);
}
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, previousFramebufferId);
GL11.glClearColor(
previousClearColorBuffer.get(0),
previousClearColorBuffer.get(1),
previousClearColorBuffer.get(2),
previousClearColorBuffer.get(3));
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, previousTextureId);
GL11.glViewport(
previousViewportBuffer.get(0),
previousViewportBuffer.get(1),
previousViewportBuffer.get(2),
previousViewportBuffer.get(3));
}
OpenGlHelper.func_153171_g/*glBindFramebuffer*/(GL30.GL_FRAMEBUFFER, previousFramebufferId);
GL11.glClearColor(previousClearColorBuffer.get(0), previousClearColorBuffer.get(1), previousClearColorBuffer.get(2), previousClearColorBuffer.get(3));
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, previousTextureId);
GL11.glViewport(previousViewportBuffer.get(0), previousViewportBuffer.get(1), previousViewportBuffer.get(2), previousViewportBuffer.get(3));
}
}
@@ -76,8 +76,9 @@ public final class IdMapUniforms {
invalidate();
return;
}
ItemStack heldStack = hand.getItemInHand(player);
// ItemStack heldStack = player.getItemInHand(hand);
// TODO: Offhand
ItemStack heldStack = player.getHeldItem();
if (heldStack == null) {
invalidate();
@@ -105,7 +106,9 @@ public final class IdMapUniforms {
}
private IrisItemLightProvider applyOldHandLighting(@NotNull EntityPlayer player, IrisItemLightProvider existing) {
ItemStack offHandStack = InteractionHand.OFF_HAND.getItemInHand(player);
// TODO: Offhand
// ItemStack offHandStack = player.getItemInHand(InteractionHand.OFF_HAND);
ItemStack offHandStack = null;
if (offHandStack == null) {
return existing;
@@ -137,12 +137,8 @@ options.dynamic_lights_shader_force=Dynamic Lights - Forced With Shaders
options.dynamic_lights_shader_force.tooltip=Enabled - Dynamic Lights are shown even when a shader is active, Disabled - Dynamic Lights are disabled when a shader is active.
options.angelica.droppedItemLimit=Dropped Item Render Limit
options.angelica.droppedItemLimit.tooltip=The maximum number of dropped items that will be rendered. Lower values can improve performance.
options.angelica.mobSpawnerRenderDistance=Mob spawner render distance
options.angelica.mobSpawnerRenderDistance.tooltip=Render distance for the spinning mob inside mod spawners
options.angelica.itemdisplaylistcount=Item Renderer Display List Cache Size
options.angelica.itemdisplaylistcount.tooltip=The maximum number of display lists to cache in the optimized item renderer. Higher values will increase performance but increase VRAM usage.
options.angelica.sleepbeforeswap=Alternate FPS Limiter
options.angelica.sleepbeforeswap.tooltip=Switches to an alternate FPS limiter that gives more stable frametimes, in exchange for slightly more latency. Will never introduce more than one frame of latency, and has a lower impact at higher framerates.
pack.iris.select.title=Select
pack.iris.configure.title=Configure
label.iris.true=On
@@ -1,10 +1,7 @@
package com.gtnewhorizons.angelica.mixins.early.angelica;
import com.gtnewhorizons.angelica.AngelicaMod;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import org.lwjgl.input.Keyboard;
@@ -17,16 +14,10 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Minecraft.class)
public abstract class MixinMinecraft {
public class MixinMinecraft {
@Shadow
public GameSettings gameSettings;
@Shadow
public abstract boolean isFramerateLimitBelowMax();
@Shadow
public abstract int getLimitFramerate();
@Unique
private long angelica$lastFrameTime = 0;
@@ -38,38 +29,16 @@ public abstract class MixinMinecraft {
GL11.glEnable(GL11.GL_LIGHTING);
}
@Inject(
method = "func_147120_f",
at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.BEFORE, remap = false)
)
private void angelica$limitFPS(CallbackInfo ci) {
if (!AngelicaConfig.sleepBeforeSwap) return;
if (isFramerateLimitBelowMax()) {
final long target = angelica$lastFrameTime + (long) (1.0 / getLimitFramerate() * 1_000_000) * 1_000;
while (target - System.nanoTime() > 100) {
Thread.yield();
}
}
}
@Inject(
method = "func_147120_f",
at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.AFTER, remap = false)
)
private void angelica$trackFrametimes(CallbackInfo ci) {
if (AngelicaMod.proxy == null) return;
long time = System.nanoTime();
AngelicaMod.proxy.putFrametime(time - angelica$lastFrameTime);
angelica$lastFrameTime = time;
}
@WrapOperation(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;sync(I)V"))
private void angelica$noopFPSLimiter(int fps, Operation<Void> original) {
if (AngelicaConfig.sleepBeforeSwap) return;
original.call(fps);
}
@Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;isShiftKeyDown()Z", shift = At.Shift.AFTER))
private void angelica$setShowFpsGraph(CallbackInfo ci) {
((IGameSettingsExt) gameSettings).angelica$setShowFpsGraph(Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU));
@@ -2,7 +2,6 @@ package com.gtnewhorizons.angelica.mixins.early.angelica.animation;
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFire;
@@ -13,6 +12,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -62,8 +62,8 @@ public class MixinRenderBlocks implements ITexturesCache {
AnimationsRenderUtils.markBlockTextureForUpdate(instance.getFireIcon(1), blockAccess);
}
@ModifyReturnValue(method = "getBlockIconFromSideAndMetadata", at = @At("RETURN"))
public IIcon angelica$markBlockSideAnimationForUpdate(IIcon icon, Block p_147787_1_, int p_147787_2_, int p_147787_3_) {
@ModifyVariable(method = "renderBlockLiquid", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/renderer/RenderBlocks;getBlockIconFromSideAndMetadata(Lnet/minecraft/block/Block;II)Lnet/minecraft/util/IIcon;"))
public IIcon angelica$markFluidAnimationForUpdate(IIcon icon) {
AnimationsRenderUtils.markBlockTextureForUpdate(icon, blockAccess);
if(this.enableSpriteTracking)
@@ -72,6 +72,15 @@ public class MixinRenderBlocks implements ITexturesCache {
return icon;
}
@Inject(method = "drawCrossedSquares", at = @At("HEAD"))
public void angelica$markCrossedSquaresAnimationForUpdate(IIcon icon, double p_147765_2_, double p_147765_4_, double p_147765_6_, float p_147765_8_,
CallbackInfo ci) {
AnimationsRenderUtils.markBlockTextureForUpdate(icon, blockAccess);
if(this.enableSpriteTracking)
this.renderedSprites.add(icon);
}
@Override
public Set<IIcon> getRenderedTextures() {
return renderedSprites;
@@ -1,21 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.angelica.bugfixes;
import net.minecraft.client.gui.ScaledResolution;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(ScaledResolution.class)
public class MixinScaledResolution_UnicodeFix {
// Force unicode languages to use the calculated scaleFactor and not adjust it.
// Can lead to blurry text
@ModifyConstant(method = "<init>", constant = @Constant(intValue = 1, ordinal = 5))
int angelica$ScaledResolutionInit(int constant){
return 0;
}
}
@@ -29,9 +29,9 @@ public abstract class MixinWorld {
}
@ModifyReturnValue(method = "getLightBrightnessForSkyBlocks", at = @At(value = "RETURN"))
private int angelica$dynamiclights_getLightBrightnessForSkyBlocks(int lightmap, int x, int y, int z, int p_72802_4_){
if (DynamicLights.isEnabled() && !getBlock(x, y, z).isOpaqueCube()){
return DynamicLights.get().getLightmapWithDynamicLight(x, y, z, lightmap);
private int angelica$dynamiclights_getLightBrightnessForSkyBlocks(int lightmap, int p_72802_1_, int p_72802_2_, int p_72802_3_, int p_72802_4_){
if (DynamicLights.isEnabled()){
return DynamicLights.get().getLightmapWithDynamicLight(p_72802_1_, p_72802_2_, p_72802_3_, lightmap);
}
return lightmap;
}
@@ -14,6 +14,7 @@ public class MixinItemRenderer {
@Inject(method = "renderItemInFirstPerson", at = @At("HEAD"), cancellable = true)
private void iris$skipTranslucentHands(float partialTicks, CallbackInfo ci) {
if (IrisApi.getInstance().isShaderPackInUse()) {
// TODO: Offhand
boolean isHandTranslucent = HandRenderer.INSTANCE.isHandTranslucent(InteractionHand.MAIN_HAND);
if (HandRenderer.INSTANCE.isRenderingSolid() && isHandTranslucent) {
ci.cancel();
@@ -1,48 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.compat.mojang.InteractionHand;
import net.coderbot.iris.pipeline.HandRenderer;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.renderer.ItemRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import xonin.backhand.client.hooks.ItemRendererHooks;
@Mixin(ItemRenderer.class)
public class MixinItemRendererBackhand {
@Inject(method = "renderItemInFirstPerson", at = @At("HEAD"), cancellable = true)
private void iris$skipTranslucentHands(float partialTicks, CallbackInfo ci) {
if (IrisApi.getInstance().isShaderPackInUse()) {
boolean isHandTranslucent = HandRenderer.INSTANCE.isHandTranslucent(InteractionHand.MAIN_HAND);
if (HandRenderer.INSTANCE.isRenderingSolid() && isHandTranslucent) {
ci.cancel();
if (ModStatus.isBackhandLoaded){
iris$skipTranslucentHandsBackhand(partialTicks, ci);
ItemRendererHooks.renderOffhandReturn(partialTicks);
}
} else if (!HandRenderer.INSTANCE.isRenderingSolid() && !isHandTranslucent) {
ci.cancel();
if (ModStatus.isBackhandLoaded){
iris$skipTranslucentHandsBackhand(partialTicks, ci);
ItemRendererHooks.renderOffhandReturn(partialTicks);
}
}
}
}
// change injection to before Backhand's inject
@Inject(method = "renderItemInFirstPerson", at = @At("RETURN"), cancellable = true, order = 900)
private void iris$skipTranslucentHandsBackhand(float partialTicks, CallbackInfo ci) {
if (ModStatus.isBackhandLoaded && IrisApi.getInstance().isShaderPackInUse()) {
boolean isHandTranslucent = HandRenderer.INSTANCE.isHandTranslucent(InteractionHand.OFF_HAND);
if (HandRenderer.INSTANCE.isRenderingSolid() && isHandTranslucent) {
ci.cancel();
} else if (!HandRenderer.INSTANCE.isRenderingSolid() && !isHandTranslucent) {
ci.cancel();
}
}
}
}
@@ -1,17 +0,0 @@
package com.gtnewhorizons.angelica.mixins.early.sodium;
import com.gtnewhorizons.angelica.config.AngelicaConfig;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityMobSpawner;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(TileEntityMobSpawner.class)
public class MixinTileEntityMobSpawner extends TileEntity {
@Override
public double getMaxRenderDistanceSquared() {
final double d = AngelicaConfig.mobSpawnerRenderDistance;
return d * d;
}
}